Class: BinaryCodec::BinaryParser
- Inherits:
-
Object
- Object
- BinaryCodec::BinaryParser
- Defined in:
- lib/binary-codec/serdes/binary_parser.rb
Instance Attribute Summary collapse
-
#definitions ⇒ Object
readonly
Returns the value of attribute definitions.
Instance Method Summary collapse
- #end?(custom_end = nil) ⇒ Boolean
-
#initialize(hex_bytes = '') ⇒ BinaryParser
constructor
A new instance of BinaryParser.
- #peek ⇒ Object
- #read(n) ⇒ Object
- #read_field ⇒ Object
- #read_field_header ⇒ Object
- #read_field_value(field) ⇒ Object
- #read_type(type) ⇒ Object
- #read_uint16 ⇒ Object
- #read_uint32 ⇒ Object
- #read_uint8 ⇒ Object
- #read_uint_n(n) ⇒ Object
- #read_variable_length ⇒ Object
- #read_variable_length_length ⇒ Object
- #size ⇒ Object
- #skip(n) ⇒ Object
- #type_for_field(field) ⇒ Object
Constructor Details
#initialize(hex_bytes = '') ⇒ BinaryParser
9 10 11 12 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 9 def initialize(hex_bytes = '') @bytes = hex_to_bytes(hex_bytes) @definitions = Definitions.instance end |
Instance Attribute Details
#definitions ⇒ Object (readonly)
Returns the value of attribute definitions.
7 8 9 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 7 def definitions @definitions end |
Instance Method Details
#end?(custom_end = nil) ⇒ Boolean
61 62 63 64 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 61 def end?(custom_end = nil) length = @bytes.length length == 0 || (!custom_end.nil? && length <= custom_end) end |
#peek ⇒ Object
14 15 16 17 18 19 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 14 def peek if @bytes.empty? raise StandardError.new end @bytes[0] end |
#read(n) ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 28 def read(n) if n > @bytes.length raise StandardError.new('End of byte stream reached') end slice = @bytes[0, n] skip(n) slice end |
#read_field ⇒ Object
108 109 110 111 112 113 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 108 def read_field field_header = read_field_header field_name = @definitions.get_field_name_from_header(field_header) @definitions.get_field_instance(field_name) end |
#read_field_header ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 86 def read_field_header type = read_uint8 nth = type & 15 type >>= 4 if type == 0 type = read_uint8 if type == 0 || type < 16 raise StandardError.new("Cannot read FieldOrdinal, type_code #{type} out of range") end end if nth == 0 nth = read_uint8 if nth == 0 || nth < 16 raise StandardError.new("Cannot read FieldOrdinal, field_code #{nth} out of range") end end FieldHeader.new(type: type, nth: nth) # (type << 16) | nth for read_field_ordinal end |
#read_field_value(field) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 123 def read_field_value(field) type = SerializedType.get_type_by_name(field.type) if type.nil? raise StandardError.new("unsupported: (#{field.name}, #{field.type.name})") end size_hint = field.is_variable_length_encoded ? read_variable_length_length : nil value = type.from_parser(self, size_hint) if value.nil? raise StandardError.new("from_parser for (#{field.name}, #{field.type.name}) -> nil") end value end |
#read_type(type) ⇒ Object
115 116 117 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 115 def read_type(type) type.from_parser(self) end |
#read_uint16 ⇒ Object
49 50 51 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 49 def read_uint16 read_uint_n(2) end |
#read_uint32 ⇒ Object
53 54 55 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 53 def read_uint32 read_uint_n(4) end |
#read_uint8 ⇒ Object
45 46 47 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 45 def read_uint8 read_uint_n(1) end |
#read_uint_n(n) ⇒ Object
38 39 40 41 42 43 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 38 def read_uint_n(n) if n <= 0 || n > 4 raise StandardError.new('invalid n') end read(n).reduce(0) { |a, b| (a << 8) | b } end |
#read_variable_length ⇒ Object
66 67 68 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 66 def read_variable_length read(read_variable_length_length) end |
#read_variable_length_length ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 70 def read_variable_length_length b1 = read_uint8 if b1 <= 192 b1 elsif b1 <= 240 b2 = read_uint8 193 + (b1 - 193) * 256 + b2 elsif b1 <= 254 b2 = read_uint8 b3 = read_uint8 12481 + (b1 - 241) * 65536 + b2 * 256 + b3 else raise StandardError.new('Invalid variable length indicator') end end |
#size ⇒ Object
57 58 59 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 57 def size @bytes.length end |
#skip(n) ⇒ Object
21 22 23 24 25 26 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 21 def skip(n) if n > @bytes.length raise StandardError.new end @bytes = @bytes[n..-1] end |
#type_for_field(field) ⇒ Object
119 120 121 |
# File 'lib/binary-codec/serdes/binary_parser.rb', line 119 def type_for_field(field) field.associated_type end |