iostruct 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 535a978c6d95f5213d7a7e63523b46788adc2d6ca83c714758e9f30f927f546f
4
- data.tar.gz: 5f52aea99a2615221a62e9b7d3228f129f1320e2a21c8b65eae3fec644e4007a
3
+ metadata.gz: 7b5299fc722f0b62051802a5ec32ac37de25c48b92a5899a77da7494aa6dfa73
4
+ data.tar.gz: dd50d4aa68a79fded59a6720867bea0b4961ca7513d79cf124bda6ad9d5e40fc
5
5
  SHA512:
6
- metadata.gz: 5a7489c0f185fb36a4e54c51273c2b87bd344754522e6584b329f529ed0ae00c8c287a1abf224b4cd3bfc1ed44fa5694c8036c89b3ef881231f8cfb4f773b6b0
7
- data.tar.gz: 4fa626885e4446c846594c1be13b67649928e45e919aabc660cc2c414c7cb225efb29841e5bd856737d905d988f5dd2219dd3c1622c976cb2e656799beb2a0fe
6
+ metadata.gz: b3434b61ba2cac8b9465a91da45d7dd5ee5aadd5eeaba77c3d115a564b7dbb31ecdb37e579bd3b41132af5eff42ad687c12ebf4d69da5a4015e23fa317e5b133
7
+ data.tar.gz: 852776b5bbaacf3ac4107a9755879ca986841e7d415bc16310e7ee6f565b6335b58c2d0730fd5de20ecde7843abe64c30c898855bb48e918e8bd7f83b527b5a0
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IOStruct
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/iostruct.rb CHANGED
@@ -23,6 +23,9 @@ module IOStruct
23
23
 
24
24
  'A' => [1, String ], # arbitrary binary string (remove trailing nulls and ASCII spaces)
25
25
  'a' => [1, String ], # arbitrary binary string
26
+ 'Z' => [1, String ], # arbitrary binary string (remove trailing nulls)
27
+ 'H' => [1, String ], # hex string (high nibble first)
28
+ 'h' => [1, String ], # hex string (low nibble first)
26
29
 
27
30
  'D' => [8, Float ], # double-precision, native format
28
31
  'd' => [8, Float ],
@@ -38,9 +41,10 @@ module IOStruct
38
41
 
39
42
  FieldInfo = Struct.new :type, :size, :offset
40
43
 
41
- def self.new fmt, *names, inspect: :hex
44
+ def self.new fmt, *names, inspect: :hex, **renames
42
45
  fields, size = parse_format(fmt, names)
43
- names = auto_names(fields, size) if names.empty?
46
+ names = auto_names(fields, size) if names.empty?
47
+ names.map!{ |n| renames[n] || n } if renames.any?
44
48
 
45
49
  Struct.new( *names ).tap do |x|
46
50
  x.const_set 'FIELDS', names.zip(fields).to_h
@@ -59,9 +63,13 @@ module IOStruct
59
63
  size, klass = FMTSPEC[type] || raise("Unknown field type #{type.inspect}")
60
64
  len = len.empty? ? 1 : len.to_i
61
65
  case type
62
- when 'A', 'a', 'x'
66
+ when 'A', 'a', 'x', 'Z'
63
67
  fields << FieldInfo.new(klass, size*len, offset) if klass
64
68
  offset += len
69
+ when 'H', 'h'
70
+ # XXX ruby's String#unpack length for hex strings is in characters, not bytes, i.e. "x".unpack("H2") => ["78"]
71
+ fields << FieldInfo.new(klass, size*len/2, offset) if klass
72
+ offset += len/2
65
73
  else
66
74
  len.times do |i|
67
75
  fields << FieldInfo.new(klass, size, offset)
@@ -95,9 +103,9 @@ module IOStruct
95
103
  else
96
104
  raise "[?] don't know how to read from #{src.inspect}"
97
105
  end
98
- if data.size < size
99
- $stderr.puts "[!] #{self.to_s} want #{size} bytes, got #{data.size}"
100
- end
106
+ # if data.size < size
107
+ # $stderr.puts "[!] #{self.to_s} want #{size} bytes, got #{data.size}"
108
+ # end
101
109
  new(*data.unpack(const_get('FORMAT')))
102
110
  end
103
111
  end # ClassMethods
@@ -130,7 +138,7 @@ module IOStruct
130
138
 
131
139
  module HexInspect
132
140
  def to_s
133
- s = "<#{self.class.to_s} " + to_h.map do |k, v|
141
+ "<#{self.class.to_s} " + to_h.map do |k, v|
134
142
  if v.is_a?(Integer) && v > 9
135
143
  "#{k}=0x%x" % v
136
144
  else
@@ -152,7 +160,7 @@ module IOStruct
152
160
  end
153
161
  "#{name}=#{fmt}"
154
162
  end.join(' ') + ">"
155
- sprintf @fmtstr_tbl, *to_a.map{ |v| v.is_a?(String) ? v.inspect : v }
163
+ sprintf @fmtstr_tbl, *to_a.map{ |v| v.is_a?(String) ? v.inspect : (v||0) } # "||0" to avoid "`sprintf': can't convert nil into Integer" error
156
164
  end
157
165
 
158
166
  def inspect
@@ -59,6 +59,20 @@ describe IOStruct do
59
59
  expect(x.y).to eq a[1]
60
60
  end
61
61
 
62
+ it "unpacks hex-string (H)" do
63
+ data = "1234"
64
+ struct = IOStruct.new('H8', :x).read(data)
65
+ expect(struct.x).to eq "31323334"
66
+ expect(struct.pack).to eq data
67
+ end
68
+
69
+ it "unpacks reverse-nibbled hex-string (h)" do
70
+ data = "1234"
71
+ struct = IOStruct.new('h8', :x).read(data)
72
+ expect(struct.x).to eq "13233343"
73
+ expect(struct.pack).to eq data
74
+ end
75
+
62
76
  ['n', 'N', 'S>', 'L>', 'I>'].each do |fmt|
63
77
  it "unpacks unsigned big-endian '#{fmt}'" do
64
78
  a = [12345]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iostruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey "Zed" Zaikin
@@ -89,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  requirements: []
92
- rubygems_version: 3.5.3
92
+ rubygems_version: 3.5.11
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: A Struct that can read/write itself from/to IO-like objects