Class: Arf::Wire::Frame
- Inherits:
-
Object
- Object
- Arf::Wire::Frame
- Defined in:
- lib/arf/wire/frame.rb
Constant Summary collapse
- MAGIC =
"arf"
- MAGIC_SIZE =
3
- STREAM_ID_SIZE =
4
- FRAME_KIND_SIZE =
1
- FLAGS_SIZE =
1
- LENGTH_SIZE =
2
- FRAME_SIZE =
MAGIC_SIZE + STREAM_ID_SIZE + FRAME_KIND_SIZE + FLAGS_SIZE + LENGTH_SIZE
Instance Attribute Summary collapse
-
#flags ⇒ Object
Returns the value of attribute flags.
-
#frame_kind ⇒ Object
Returns the value of attribute frame_kind.
-
#length ⇒ Object
Returns the value of attribute length.
-
#payload ⇒ Object
Returns the value of attribute payload.
-
#stream_id ⇒ Object
Returns the value of attribute stream_id.
Class Method Summary collapse
Instance Method Summary collapse
- #bytes(compressor) ⇒ Object
- #decompress(compressor) ⇒ Object
- #empty? ⇒ Boolean
- #specialize(compressor) ⇒ Object
- #validate_kind(expected, associated) ⇒ Object
- #validate_size(size) ⇒ Object
Instance Attribute Details
#flags ⇒ Object
Returns the value of attribute flags.
14 15 16 |
# File 'lib/arf/wire/frame.rb', line 14 def flags @flags end |
#frame_kind ⇒ Object
Returns the value of attribute frame_kind.
14 15 16 |
# File 'lib/arf/wire/frame.rb', line 14 def frame_kind @frame_kind end |
#length ⇒ Object
Returns the value of attribute length.
14 15 16 |
# File 'lib/arf/wire/frame.rb', line 14 def length @length end |
#payload ⇒ Object
Returns the value of attribute payload.
15 16 17 |
# File 'lib/arf/wire/frame.rb', line 15 def payload @payload end |
#stream_id ⇒ Object
Returns the value of attribute stream_id.
14 15 16 |
# File 'lib/arf/wire/frame.rb', line 14 def stream_id @stream_id end |
Class Method Details
.from_io(io) ⇒ Object
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 |
# File 'lib/arf/wire/frame.rb', line 26 def self.from_io(io) buf = StringIO.new read_exactly(io, buf, FRAME_SIZE) raise MagicNumberMismatchError if buf.read(3) != Frame::MAGIC stream_id = Wire.decode_uint32(buf) raw_kind = buf.readbyte frame_kind = Wire::FRAME_TO_SYMBOL[raw_kind] raise UnknownFrameKindError, raw_kind unless frame_kind flags = buf.readbyte length = Wire.decode_uint16(buf) payload = nil if length.positive? payload = StringIO.new read_exactly(io, payload, length) end new.tap do |f| f.stream_id = stream_id f.frame_kind = frame_kind f.flags = flags f.payload = payload f.length = length end end |
.read_exactly(io, into, n) ⇒ Object
19 20 21 22 23 24 |
# File 'lib/arf/wire/frame.rb', line 19 def self.read_exactly(io, into, n) into.truncate(0) into.write(io.read(n - into.length)) until into.length == n into.rewind into end |
Instance Method Details
#bytes(compressor) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/arf/wire/frame.rb', line 53 def bytes(compressor) @payload = IO::COMPRESSOR[compressor].compress(@payload) @length = @payload&.length || 0 IO::Buffer.new .write_raw(MAGIC) .write_raw(Wire.encode_uint32(@stream_id || 0)) .write_raw([SYMBOL_TO_FRAME[@frame_kind]].pack("C*")) .write_raw(@flags || 0) .write_raw(Wire.encode_uint16(@length)) .write_raw(@payload&.string || "") .string end |
#decompress(compressor) ⇒ Object
84 85 86 87 |
# File 'lib/arf/wire/frame.rb', line 84 def decompress(compressor) @payload = IO::COMPRESSOR[compressor].decompress(@payload) @length = @payload&.length || 0 end |
#empty? ⇒ Boolean
17 |
# File 'lib/arf/wire/frame.rb', line 17 def empty? = length ? length.zero? : true |
#specialize(compressor) ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/arf/wire/frame.rb', line 102 def specialize(compressor) cls = BaseFrame.frame_by_kind(@frame_kind) raise UnknownFrameKindError, @frame_kind if cls.nil? decompress(compressor) cls.new(self) end |
#validate_kind(expected, associated) ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/arf/wire/frame.rb', line 67 def validate_kind(expected, associated) raise FrameMismatchError.new(expected, @frame_kind) if @frame_kind != expected if associated && (@stream_id.nil? || @stream_id.zero?) raise UnexpectedUnassociatedFrameError, @frame_kind elsif !associated && (!@stream_id.nil? && @stream_id != 0) raise UnexpectedAssociatedFrameError, @frame_kind end end |
#validate_size(size) ⇒ Object
77 78 79 80 81 82 |
# File 'lib/arf/wire/frame.rb', line 77 def validate_size(size) return unless @length != size raise InvalidFrameLengthError, "invalid length for frame #{@frame_kind} " \ "#{size} bytes are required, received #{@length}" end |