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 '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.1.2"
Class Method Summary collapse
- .auto_names(fields, size) ⇒ Object
- .new(fmt, *names, inspect: :hex) ⇒ Object
-
.parse_format(fmt, names) ⇒ Object
self.new.
Class Method Details
.auto_names(fields, size) ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/iostruct.rb', line 75 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) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/iostruct.rb', line 41 def self.new fmt, *names, inspect: :hex fields, size = parse_format(fmt, names) names = auto_names(fields, size) if names.empty? 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
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/iostruct.rb', line 55 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' fields << FieldInfo.new(klass, size*len, offset) if klass offset += len else len.times do |i| fields << FieldInfo.new(klass, size, offset) offset += size end end end [fields, offset] end |