bit-struct 0.13.5 → 0.17

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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +22 -1
  3. data/LICENSE +56 -0
  4. data/{README.txt → README.md} +94 -92
  5. data/Rakefile +56 -30
  6. data/examples/field-ripper.rb +1 -1
  7. data/examples/ip.rb +6 -6
  8. data/examples/longlong.rb +2 -2
  9. data/examples/md.rb +1 -1
  10. data/examples/modular-def.rb +2 -2
  11. data/examples/native.rb +3 -3
  12. data/examples/ping.rb +1 -1
  13. data/examples/raw.rb +1 -1
  14. data/examples/switch-endian.rb +2 -2
  15. data/examples/vector.rb +2 -2
  16. data/lib/bit-struct.rb +0 -11
  17. data/lib/bit-struct/bit-struct.rb +61 -143
  18. data/lib/bit-struct/char-field.rb +3 -3
  19. data/lib/bit-struct/field.rb +94 -0
  20. data/lib/bit-struct/fields.rb +13 -13
  21. data/lib/bit-struct/float-field.rb +4 -4
  22. data/lib/bit-struct/hex-octet-field.rb +3 -3
  23. data/lib/bit-struct/nested-field.rb +8 -8
  24. data/lib/bit-struct/octet-field.rb +4 -4
  25. data/lib/bit-struct/signed-field.rb +23 -28
  26. data/lib/bit-struct/text-field.rb +2 -2
  27. data/lib/bit-struct/unsigned-field.rb +24 -27
  28. data/lib/bit-struct/vector-field.rb +7 -7
  29. data/lib/bit-struct/vector.rb +24 -22
  30. data/lib/bit-struct/yaml.rb +22 -3
  31. data/test/test-endian.rb +5 -5
  32. data/test/test-vector.rb +6 -6
  33. data/test/test.rb +71 -46
  34. metadata +43 -69
  35. data/.gitignore +0 -3
  36. data/TODO +0 -20
  37. data/tasks/ann.rake +0 -80
  38. data/tasks/bones.rake +0 -20
  39. data/tasks/gem.rake +0 -201
  40. data/tasks/git.rake +0 -40
  41. data/tasks/notes.rake +0 -27
  42. data/tasks/post_load.rake +0 -34
  43. data/tasks/rdoc.rake +0 -51
  44. data/tasks/rubyforge.rake +0 -55
  45. data/tasks/setup.rb +0 -292
  46. data/tasks/spec.rake +0 -54
  47. data/tasks/svn.rake +0 -47
  48. data/tasks/test.rake +0 -40
  49. data/tasks/zentest.rake +0 -36
@@ -13,13 +13,13 @@ class BitStruct
13
13
  "Bad offset, #{offset}, for #{self.class} #{name}." +
14
14
  " Must be multiple of 8."
15
15
  end
16
-
16
+
17
17
  unless length % 8 == 0
18
18
  raise ArgumentError,
19
19
  "Bad length, #{length}, for #{self.class} #{name}." +
20
20
  " Must be multiple of 8."
21
21
  end
22
-
22
+
23
23
  offset_byte = offset / 8
24
24
  length_byte = length / 8
25
25
  last_byte = offset_byte + length_byte - 1
@@ -6,21 +6,18 @@ class BitStruct
6
6
  def self.class_name
7
7
  @class_name ||= "unsigned"
8
8
  end
9
-
9
+
10
10
  def add_accessors_to(cl, attr = name) # :nodoc:
11
11
  offset_byte = offset / 8
12
12
  offset_bit = offset % 8
13
-
13
+
14
14
  length_bit = offset_bit + length
15
15
  length_byte = (length_bit/8.0).ceil
16
16
  last_byte = offset_byte + length_byte - 1
17
-
17
+
18
18
  divisor = options[:fixed] || options["fixed"]
19
19
  divisor_f = divisor && divisor.to_f
20
- # if divisor and not divisor.is_a? Fixnum
21
- # raise ArgumentError, "fixed-point divisor must be a fixnum"
22
- # end
23
-
20
+
24
21
  endian = (options[:endian] || options["endian"]).to_s
25
22
  case endian
26
23
  when "native"
@@ -33,15 +30,15 @@ class BitStruct
33
30
  raise ArgumentError,
34
31
  "Unrecognized endian option: #{endian.inspect}"
35
32
  end
36
-
33
+
37
34
  data_is_big_endian =
38
35
  ([1234].pack(ctl) == [1234].pack(length_byte <= 2 ? "n" : "N"))
39
-
36
+
40
37
  if length_byte == 1
41
38
  rest = 8 - length_bit
42
39
  mask = ["0"*offset_bit + "1"*length + "0"*rest].pack("B8")[0].ord
43
40
  mask2 = ["1"*offset_bit + "0"*length + "1"*rest].pack("B8")[0].ord
44
-
41
+
45
42
  cl.class_eval do
46
43
  if divisor
47
44
  define_method attr do ||
@@ -65,11 +62,11 @@ class BitStruct
65
62
  end
66
63
  end
67
64
  end
68
-
65
+
69
66
  elsif offset_bit == 0 and length % 8 == 0
70
67
  field_length = length
71
68
  byte_range = offset_byte..last_byte
72
-
69
+
73
70
  cl.class_eval do
74
71
  case field_length
75
72
  when 8
@@ -82,7 +79,7 @@ class BitStruct
82
79
  val = (val * divisor).round
83
80
  self[offset_byte] = val
84
81
  end
85
-
82
+
86
83
  else
87
84
  define_method attr do ||
88
85
  self[offset_byte]
@@ -92,7 +89,7 @@ class BitStruct
92
89
  self[offset_byte] = val
93
90
  end
94
91
  end
95
-
92
+
96
93
  when 16, 32
97
94
  if divisor
98
95
  define_method attr do ||
@@ -103,7 +100,7 @@ class BitStruct
103
100
  val = (val * divisor).round
104
101
  self[byte_range] = [val].pack(ctl)
105
102
  end
106
-
103
+
107
104
  else
108
105
  define_method attr do ||
109
106
  self[byte_range].unpack(ctl).first
@@ -113,7 +110,7 @@ class BitStruct
113
110
  self[byte_range] = [val].pack(ctl)
114
111
  end
115
112
  end
116
-
113
+
117
114
  else
118
115
  reader_helper = proc do |substr|
119
116
  bytes = substr.unpack("C*")
@@ -122,7 +119,7 @@ class BitStruct
122
119
  (sum << 8) + byte
123
120
  end
124
121
  end
125
-
122
+
126
123
  writer_helper = proc do |val|
127
124
  bytes = []
128
125
  while val > 0
@@ -136,21 +133,21 @@ class BitStruct
136
133
  bytes.reverse! if data_is_big_endian
137
134
  bytes.pack("C*")
138
135
  end
139
-
136
+
140
137
  if divisor
141
138
  define_method attr do ||
142
139
  reader_helper[self[byte_range]] / divisor_f
143
140
  end
144
-
141
+
145
142
  define_method "#{attr}=" do |val|
146
143
  self[byte_range] = writer_helper[(val * divisor).round]
147
144
  end
148
-
145
+
149
146
  else
150
147
  define_method attr do ||
151
148
  reader_helper[self[byte_range]]
152
149
  end
153
-
150
+
154
151
  define_method "#{attr}=" do |val|
155
152
  self[byte_range] = writer_helper[val]
156
153
  end
@@ -161,10 +158,10 @@ class BitStruct
161
158
  elsif length_byte == 2 # unaligned field that fits within two whole bytes
162
159
  byte_range = offset_byte..last_byte
163
160
  rest = 16 - length_bit
164
-
161
+
165
162
  mask = ["0"*offset_bit + "1"*length + "0"*rest]
166
163
  mask = mask.pack("B16").unpack(ctl).first
167
-
164
+
168
165
  mask2 = ["1"*offset_bit + "0"*length + "1"*rest]
169
166
  mask2 = mask2.pack("B16").unpack(ctl).first
170
167
 
@@ -194,14 +191,14 @@ class BitStruct
194
191
  end
195
192
  end
196
193
  end
197
-
194
+
198
195
  elsif length_byte == 3 # unaligned field that fits within 3 whole bytes
199
196
  byte_range = offset_byte..last_byte
200
197
  rest = 32 - length_bit
201
-
198
+
202
199
  mask = ["0"*offset_bit + "1"*length + "0"*rest]
203
200
  mask = mask.pack("B32").unpack(ctl).first
204
-
201
+
205
202
  mask2 = ["1"*offset_bit + "0"*length + "1"*rest]
206
203
  mask2 = mask2.pack("B32").unpack(ctl).first
207
204
 
@@ -239,7 +236,7 @@ class BitStruct
239
236
  end
240
237
  end
241
238
  end
242
-
239
+
243
240
  else
244
241
  raise "unsupported: #{inspect}"
245
242
  end
@@ -8,12 +8,12 @@ class BitStruct
8
8
  def self.class_name
9
9
  @class_name ||= "vector"
10
10
  end
11
-
11
+
12
12
  # Used in describe.
13
13
  def class_name
14
14
  @class_name ||= vector_class.name[/\w+$/]
15
15
  end
16
-
16
+
17
17
  # Returns the subclass of Vector that is used to manage the value of this
18
18
  # field. If the class was specified in the BitStruct.vector declaration,
19
19
  # #vector_class will return it, otherwise it will be an anonymous class
@@ -39,20 +39,20 @@ class BitStruct
39
39
  "Bad offset, #{offset}, for vector field #{name}." +
40
40
  " Must be multiple of 8."
41
41
  end
42
-
42
+
43
43
  unless length % 8 == 0
44
44
  raise ArgumentError,
45
45
  "Bad length, #{length}, for vector field #{name}." +
46
46
  " Must be multiple of 8."
47
47
  end
48
-
48
+
49
49
  offset_byte = offset / 8
50
50
  length_byte = length / 8
51
51
  last_byte = offset_byte + length_byte - 1
52
52
  byte_range = offset_byte..last_byte
53
53
 
54
54
  vc = vector_class
55
-
55
+
56
56
  cl.class_eval do
57
57
  define_method attr do ||
58
58
  vc.new(self[byte_range])
@@ -63,12 +63,12 @@ class BitStruct
63
63
  raise ArgumentError, "Size mismatch in vector field assignment " +
64
64
  "to #{attr} with value #{val.inspect}"
65
65
  end
66
-
66
+
67
67
  if val.class != vc
68
68
  warn "Type mismatch in vector field assignment " +
69
69
  "to #{attr} with value #{val.inspect}"
70
70
  end
71
-
71
+
72
72
  self[byte_range] = val
73
73
  end
74
74
  end
@@ -22,7 +22,7 @@ class BitStruct::Vector < String
22
22
  @struct_class = nil
23
23
  end
24
24
  end
25
-
25
+
26
26
  # Called as a class method with a single argument in a user-defined
27
27
  # subclass to specify a particular BitStruct class to use for each entry,
28
28
  # instead of generating an anonymous class. Called without arguments to
@@ -38,7 +38,7 @@ class BitStruct::Vector < String
38
38
  @struct_class.default_options default_options
39
39
  else
40
40
  unless @struct_class
41
- @struct_class = self == BitStruct::Vector ? BitStruct :
41
+ @struct_class = self == BitStruct::Vector ? BitStruct :
42
42
  Class.new(superclass.struct_class)
43
43
  @struct_class.default_options default_options
44
44
  end
@@ -54,7 +54,7 @@ class BitStruct::Vector < String
54
54
  def respond_to?(*m) # :nodoc:
55
55
  orig_respond_to?(*m) || struct_class.respond_to?(*m)
56
56
  end
57
-
57
+
58
58
  # Get or set the hash of default options for the class, which apply to all
59
59
  # fields in the entries. If +h+ is provided, update the default options
60
60
  # with that hash. Default options are inherited.
@@ -70,7 +70,7 @@ class BitStruct::Vector < String
70
70
  end
71
71
  @default_options
72
72
  end
73
-
73
+
74
74
  def describe(*args)
75
75
  fmt = args[0] || BitStruct.describe_format
76
76
  if block_given?
@@ -81,37 +81,37 @@ class BitStruct::Vector < String
81
81
  end
82
82
  end
83
83
  end
84
-
84
+
85
85
  # Convenience method for instances. Returns the BitStruct class that
86
86
  # describes each entry.
87
87
  def struct_class
88
88
  self.class.struct_class
89
89
  end
90
-
91
- # Convenience method for instances. Returns the string length in bytes of
90
+
91
+ # Convenience method for instances. Returns the string length in bytes of
92
92
  # each entry in the vector.
93
93
  def struct_class_length
94
94
  self.class.struct_class.round_byte_length
95
95
  end
96
-
96
+
97
97
  # +arg+ can be an integer (number of entries) or a string
98
98
  # (binary data, such as another Vector of the same size).
99
99
  def initialize arg # :yields: instance
100
100
  case arg
101
101
  when Integer
102
102
  super(struct_class.initial_value * arg)
103
-
103
+
104
104
  else
105
105
  begin
106
106
  super arg
107
107
  rescue NameError
108
108
  raise ArgumentError, "must be string or integer: #{arg.inspect}"
109
109
  end
110
- end
110
+ end
111
111
 
112
112
  yield self if block_given?
113
113
  end
114
-
114
+
115
115
  # Get the +i+-th entry. Returns a *copy* of the entry. If you want to
116
116
  # use this copy to modify the entry, you must modify the copy and then
117
117
  # use #[]= to replace the entry with the copy.
@@ -122,29 +122,29 @@ class BitStruct::Vector < String
122
122
  unless (0...(length / entry_length)).include? i
123
123
  raise ArgumentError, "index out of range: #{i}"
124
124
  end
125
-
125
+
126
126
  sc.new slice(entry_length * i, entry_length)
127
127
  end
128
-
128
+
129
129
  alias _old_replace_substr []=
130
130
 
131
131
  # Set the +i+-th entry to +val+.
132
132
  def []=(i,val)
133
133
  entry_length = struct_class_length
134
-
134
+
135
135
  unless (0...(length / entry_length)).include? i
136
136
  raise ArgumentError, "index out of range: #{i}"
137
137
  end
138
-
138
+
139
139
  unless val.length == entry_length
140
140
  raise ArgumentError, "wrong entry length: #{val.length} != #{entry_length}"
141
141
  end
142
-
142
+
143
143
  _old_replace_substr(entry_length * i, entry_length, val)
144
144
  end
145
-
145
+
146
146
  ## TODO: [i..j] etc.
147
-
147
+
148
148
  # Iterate over entries.
149
149
  def each
150
150
  entry_length = struct_class_length
@@ -152,8 +152,8 @@ class BitStruct::Vector < String
152
152
  yield self[i]
153
153
  end
154
154
  end
155
-
156
- def inspect(opts = BitStruct::DEFAULT_INSPECT_OPTS)
155
+
156
+ def inspect_with_options(opts = BitStruct::DEFAULT_INSPECT_OPTS)
157
157
  if opts[:include_class]
158
158
  opts = opts.dup
159
159
  opts[:include_class] = false
@@ -161,12 +161,14 @@ class BitStruct::Vector < String
161
161
  else
162
162
  s = ""
163
163
  end
164
-
164
+
165
165
  s << entries.map{|entry| entry.inspect(opts)}.join(opts[:separator])
166
166
  lb, rb = opts[:brackets]
167
167
  [lb, s, rb].join
168
168
  end
169
-
169
+
170
+ alias inspect inspect_with_options
171
+
170
172
  def inspect_detailed
171
173
  inspect(BitStruct::DETAILED_INSPECT_OPTS)
172
174
  end
@@ -7,7 +7,7 @@ class BitStruct
7
7
  end
8
8
 
9
9
  YAML.add_ruby_type(/^bitstruct/) do |type, val|
10
- subtype, subclass = YAML.read_type_class(type, Object)
10
+ _subtype, subclass = YAML.read_type_class(type, Object)
11
11
  subclass.new(val)
12
12
  end
13
13
 
@@ -27,8 +27,27 @@ class BitStruct
27
27
  end
28
28
  end
29
29
 
30
+ elsif RUBY_VERSION =~ /^2\./
31
+ def encode_with coder
32
+ yaml_fields = fields.select {|field| field.inspectable?}
33
+ props = yaml_fields.map {|f| f.name.to_s}
34
+ if (rest_field = self.class.rest_field)
35
+ props << rest_field.name.to_s
36
+ end
37
+ props.each do |prop|
38
+ coder[prop] = send(prop)
39
+ end
40
+ end
41
+
42
+ def init_with coder
43
+ self << self.class.initial_value
44
+ coder.map.each do |k, v|
45
+ send("#{k}=", v)
46
+ end
47
+ end
48
+
30
49
  else
31
- yaml_as "tag:path.berkeley.edu,2006:bitstruct"
50
+ yaml_tag "tag:github.com:vjoel/bit-struct"
32
51
 
33
52
  def to_yaml_properties # :nodoc:
34
53
  yaml_fields = fields.select {|field| field.inspectable?}
@@ -55,7 +74,7 @@ class BitStruct
55
74
  raise YAML::TypeError, "Invalid BitStruct: " + val.inspect
56
75
  end
57
76
 
58
- bitstruct_name, bitstruct_type = YAML.read_type_class( tag, BitStruct )
77
+ _bitstruct_name, bitstruct_type = YAML.read_type_class( tag, BitStruct )
59
78
 
60
79
  st = bitstruct_type.new
61
80
 
data/test/test-endian.rb CHANGED
@@ -1,28 +1,28 @@
1
- require 'test/unit'
1
+ require 'minitest/autorun'
2
2
  require 'bit-struct'
3
3
 
4
- class Test_Endian < Test::Unit::TestCase
4
+ class Test_Endian < Minitest::Test
5
5
  class Endian < BitStruct
6
6
  unsigned :f_big, 32, :endian => :big
7
7
  unsigned :f_little, 32, :endian => :little
8
8
  unsigned :f_native, 32, :endian => :native
9
9
  unsigned :f_network, 32, :endian => :network
10
10
  end
11
-
11
+
12
12
  attr_reader :bs
13
13
 
14
14
  def setup
15
15
  @bs = Endian.new
16
16
  bs.f_big = bs.f_little = bs.f_native = bs.f_network = 0x01020304
17
17
  end
18
-
18
+
19
19
  def test_readers
20
20
  assert_equal(0x01020304, bs.f_big)
21
21
  assert_equal(0x01020304, bs.f_little)
22
22
  assert_equal(0x01020304, bs.f_native)
23
23
  assert_equal(0x01020304, bs.f_network)
24
24
  end
25
-
25
+
26
26
  def test_writers
27
27
  bs.fields.each do |field|
28
28
  byte_offset = field.offset / 8