Class: RSpec::Bash::MessageDecoder

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec/bash/message_decoder.rb

Constant Summary collapse

READING_FRAME_COUNT =
1
READING_FRAME_SZ =
2
READING_FRAME =
3
RE_NUMBER =
/\d/

Class Method Summary collapse

Class Method Details

.decode(buffer) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rspec/bash/message_decoder.rb', line 9

def self.decode(buffer)
  state = READING_FRAME_COUNT
  buffersz = buffer.length
  frames = []
  frame_buf = ''
  frame_count_buf = ''
  frame_count = Float::INFINITY
  framesz_buf = ''
  framesz = Float::INFINITY
  cursor = 0

  while cursor < buffersz && frames.count < frame_count
    char = buffer[cursor]
    cursor += 1

    case state
    when READING_FRAME_COUNT
      case char
      when ';'
        state = READING_FRAME_SZ
        frame_count = frame_count_buf.to_i
        frame_count_buf = ''
        framesz_buf = ''
      when /\d/
        frame_count_buf += char
      else
        return nil, "invalid payload: illegal character in header '#{char}' (#{cursor}/#{buffersz})"
      end
    when READING_FRAME_SZ
      case char
      when ';'
        state = READING_FRAME
        frame_buf = ''
        framesz = framesz_buf.to_i
        framesz_buf = ''
      when /\d/
        framesz_buf += char
      else
        return nil, "invalid payload: illegal character in frame header '#{char}' (#{cursor}/#{buffersz})"
      end
    when READING_FRAME
      frame_buf += char

      if frame_buf.length == framesz
        state = READING_FRAME_SZ
        frames.push(frame_buf)
        framesz = Float::INFINITY
      end
    end
  end

  if frames.count != frame_count
    return nil, "invalid payload: expected #{frame_count} frames but got #{frames.count}"
  end

  [ frames.map do |frame|
    frame_class, frame_content = frame[0..1].to_i, frame.slice(2..-1)
  end ]
end