iostruct 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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