Module: OnStomp::Connections::Serializers::Stomp_1

Included in:
Stomp_1_0, Stomp_1_1
Defined in:
lib/onstomp/connections/serializers/stomp_1.rb

Overview

Classes that mix this in must define split_header and prepare_parsed_frame The method frame_to_string_base is provided as a factoring out of the common tasks of serializing a frame for STOMP 1.0 and STOMP 1.1.

Instance Method Summary (collapse)

Instance Method Details

- (Object) bytes_to_frame(buffer)

Note:

It is NOT safe to invoke this method from multiple threads as-is.

Takes a buffer of strings and constructs all the frames it can from the data. The parser builds a "current frame" and updates it with attributes as they are parsed from the buffer. It is only safe to invoke this method from a single thread as no synchronization is being performed. This will work fine with the threaded processor as it performs its calls all within a single thread, but if you wish to develop your own processor that can call Base#io_process_read across separate threads, you will have to implement your own synchronization strategy.

Parameters:

  • buffer (Array<String>)


141
142
143
144
145
146
147
148
149
150
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 141

def bytes_to_frame buffer
  until buffer.first.nil? && @parse_state != :completed
    if @parse_state == :completed
      yield @cur_frame
      reset_parser
    else
      __send__(:parse_#{@parse_state}", buffer)
    end
  end
end

- (Object) finish_body(body)

Called when a frame's body has been fully read from the buffer. This method will set the frame's body attribute, call prepare_parsed_frame with the "current frame", and tell the parser to move on to the next state.

Parameters:

  • body (String)


123
124
125
126
127
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 123

def finish_body body
  @cur_frame.body = body
  prepare_parsed_frame @cur_frame
  @parse_state = :completed
end

- (Object) finish_command(command)

Called when a frame's command has been fully read from the buffer. This method will create a new "current frame", set its command attribute, and tell the parser to move on to the next state.

Parameters:

  • command (String)


93
94
95
96
97
98
99
100
101
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 93

def finish_command command
  @cur_frame = OnStomp::Components::Frame.new
  if command.empty?
    @parse_state = :completed
  else
    @cur_frame.command = command
    @parse_state = :header_line
  end
end

- (Object) finish_header_line(headline)

Called when a header line has been fully read from the buffer. This method will split the header line into a name/value pair, append the header to the "current frame" and tell the parser to move on to the next state

Parameters:

  • headline (String)


109
110
111
112
113
114
115
116
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 109

def finish_header_line headline
  if headline.empty?
    @parse_state = :body
  else
    k,v = split_header(headline)
    @cur_frame.headers.append(k, v)
  end
end

- (String) frame_to_bytes(frame)

Takes the result of frame_to_string and passes it along. Ruby 1.8.7 treats strings as a collection of bytes, so we don't need to do any further work.

Returns:

  • (String)


156
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 156

def frame_to_bytes(frame); frame_to_string(frame); end

- (Object) frame_to_string_base(frame)

The common elements of serializing a frame as a string in STOMP 1.0 and STOMP 1.1 protocols.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 16

def frame_to_string_base frame
  if frame.command
    frame.force_content_length
    str = "#{frame.command}\n"
    frame.headers.inject(str) do |acc, (k,v)|
      acc << yield(k,v)
    end
    str << "\n"
    str << "#{frame.body}" if frame.body
    str << "\000"
    str
  else
    "\n"
  end
end

- (Object) parse_body(buffer)

Parses a frame body from the buffer

Parameters:

  • buffer (Array<String>)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 58

def parse_body buffer
  data = buffer.shift
  if rlen = @cur_frame.content_length
    rlen -= @parse_accum.length
  end
  body_upto = rlen ? (rlen < data.length && rlen) : data.index("\000")
  if body_upto
    if data[body_upto, 1] != "\000"
      raise OnStomp::MalformedFrameError, 'missing terminator'
    end
    parser_flush(buffer, data, body_upto, :finish_body)
  else
    @parse_accum << data
  end
end

- (Object) parse_command(buffer)

Parses a frame command from the buffer

Parameters:

  • buffer (Array<String>)


34
35
36
37
38
39
40
41
42
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 34

def parse_command buffer
  data = buffer.shift
  eol = data.index("\n")
  if eol
    parser_flush(buffer, data, eol, :finish_command)
  else
    @parse_accum << data
  end
end

- (Object) parse_header_line(buffer)

Parses a frame header line from the buffer

Parameters:

  • buffer (Array<String>)


46
47
48
49
50
51
52
53
54
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 46

def parse_header_line buffer
  data = buffer.shift
  eol = data.index("\n")
  if eol
    parser_flush(buffer, data, eol, :finish_header_line)
  else
    @parse_accum << data
  end
end

- (Object) parser_flush(buffer, data, idx, meth)

Adds the substring data[0...idx] to the parser's accumulator, unshifts the remaining data back onto the buffer, and calls meth with the parser's accumulated string.

Parameters:

  • buffer (Array<String>)
  • data (String)
  • idx (Fixnum)
  • meth (Symbol)


81
82
83
84
85
86
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 81

def parser_flush buffer, data, idx, meth
  remain = data[(idx+1)..-1]
  buffer.unshift(remain) unless remain.empty?
  __send__ meth, (@parse_accum + data[0...idx])
  @parse_accum = ''
end

- (Object) reset_parser

Resets the parser that converts byte strings to frames



8
9
10
11
12
# File 'lib/onstomp/connections/serializers/stomp_1.rb', line 8

def reset_parser
  @parse_accum = ''
  @cur_frame = nil
  @parse_state = :command
end