Module: IOStruct
- Defined in:
- lib/iostruct.rb,
lib/iostruct/version.rb
Defined Under Namespace
Modules: ClassMethods, HexInspect, InstanceMethods Classes: FieldInfo
Constant Summary collapse
- FMTSPEC =
{ 'C' => [1, Integer ], # 8-bit unsigned (unsigned char) 'S' => [2, Integer ], # 16-bit unsigned, native endian (uint16_t) 'I' => [4, Integer ], # 32-bit unsigned, native endian (uint32_t) 'L' => [4, Integer ], # 32-bit unsigned, native endian (uint32_t) 'Q' => [8, Integer ], # 64-bit unsigned, native endian (uint64_t) 'c' => [1, Integer ], # 8-bit signed (signed char) 's' => [2, Integer ], # 16-bit signed, native endian (int16_t) 'i' => [4, Integer ], # 32-bit signed, native endian (int32_t) 'l' => [4, Integer ], # 32-bit signed, native endian (int32_t) 'q' => [8, Integer ], # 64-bit signed, native endian (int64_t) 'n' => [2, Integer ], # 16-bit unsigned, network (big-endian) byte order 'N' => [4, Integer ], # 32-bit unsigned, network (big-endian) byte order 'v' => [2, Integer ], # 16-bit unsigned, VAX (little-endian) byte order 'V' => [4, Integer ], # 32-bit unsigned, VAX (little-endian) byte order 'A' => [1, String ], # arbitrary binary string (remove trailing nulls and ASCII spaces) 'a' => [1, String ], # arbitrary binary string 'Z' => [1, String ], # arbitrary binary string (remove trailing nulls) 'H' => [1, String ], # hex string (high nibble first) 'h' => [1, String ], # hex string (low nibble first) 'D' => [8, Float ], # double-precision, native format 'd' => [8, Float ], 'F' => [4, Float ], # single-precision, native format 'f' => [4, Float ], 'E' => [8, Float ], # double-precision, little-endian byte order 'e' => [4, Float ], # single-precision, little-endian byte order 'G' => [8, Float ], # double-precision, network (big-endian) byte order 'g' => [4, Float ], # single-precision, network (big-endian) byte order 'x' => [1, nil ], # skip forward one byte }.freeze
- VERSION =
"0.2.0"
Class Method Summary collapse
- .auto_names(fields, size) ⇒ Object
- .new(fmt, *names, inspect: :hex, **renames) ⇒ Object
-
.parse_format(fmt, names) ⇒ Object
self.new.
Class Method Details
.auto_names(fields, size) ⇒ Object
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/iostruct.rb', line 83 def self.auto_names fields, size names = [] offset = 0 fields.each do |f| names << sprintf("f%x", offset).to_sym offset += f.size end #raise "size mismatch: #{size} != #{offset}" if size != offset names end |
.new(fmt, *names, inspect: :hex, **renames) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/iostruct.rb', line 44 def self.new fmt, *names, inspect: :hex, **renames fields, size = parse_format(fmt, names) names = auto_names(fields, size) if names.empty? names.map!{ |n| renames[n] || n } if renames.any? Struct.new( *names ).tap do |x| x.const_set 'FIELDS', names.zip(fields).to_h x.const_set 'FORMAT', fmt x.const_set 'SIZE', size x.extend ClassMethods x.include InstanceMethods x.include HexInspect if inspect == :hex end end |
.parse_format(fmt, names) ⇒ Object
self.new
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/iostruct.rb', line 59 def self.parse_format(fmt, names) offset = 0 fields = [] fmt.scan(/([a-z])(\d*)/i).map do |type,len| size, klass = FMTSPEC[type] || raise("Unknown field type #{type.inspect}") len = len.empty? ? 1 : len.to_i case type when 'A', 'a', 'x', 'Z' fields << FieldInfo.new(klass, size*len, offset) if klass offset += len when 'H', 'h' # XXX ruby's String#unpack length for hex strings is in characters, not bytes, i.e. "x".unpack("H2") => ["78"] fields << FieldInfo.new(klass, size*len/2, offset) if klass offset += len/2 else len.times do |i| fields << FieldInfo.new(klass, size, offset) offset += size end end end [fields, offset] end |