struct-fx 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ gem "frozen-objects", ">= 0.2.0"
5
+ gem "bit-packer", ">= 0.1.0"
6
+
7
+ # Add dependencies to develop your gem here.
8
+ # Include everything needed to run rake, tests, features, etc.
9
+ group :development do
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.2"
12
+ gem "riot", ">= 0.12.1"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ bit-packer (0.1.0)
5
+ lookup-hash (>= 0.2.0)
6
+ frozen-objects (0.2.0)
7
+ git (1.2.5)
8
+ hash-utils (0.11.0)
9
+ jeweler (1.5.2)
10
+ bundler (~> 1.0.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ lookup-hash (0.2.0)
14
+ hash-utils (>= 0.11.0)
15
+ rake (0.8.7)
16
+ riot (0.12.2)
17
+ rr
18
+ rr (1.0.2)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ bit-packer (>= 0.1.0)
25
+ bundler (~> 1.0.0)
26
+ frozen-objects (>= 0.2.0)
27
+ jeweler (~> 1.5.2)
28
+ riot (>= 0.12.1)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Martin Kozák
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ StructFx
2
+ ========
3
+
4
+ **struct-fx** provides declarative pure Ruby equivalent of C++ structs.
5
+ Declarations are simple:
6
+
7
+ gif = StructFx::new(data) do
8
+ string (:format) {3}
9
+ string (:version) {3}
10
+ uint16 :width
11
+ uint16 :height
12
+ end
13
+
14
+ See whole real live example:
15
+
16
+ require "struct-fx"
17
+
18
+ # Read and analyze file
19
+
20
+ File.open("./test.gif", "rb") do |io|
21
+ data = io.read(10)
22
+ end
23
+
24
+ gif = StructFx::new(data) do
25
+ string (:format) {3}
26
+ string (:version) {3}
27
+ uint16 :width
28
+ uint16 :height
29
+ end
30
+
31
+ # Get results
32
+
33
+ p gif.length # declared struct length is really 10 bytes
34
+
35
+ p gif.data.format # "GIF"
36
+ p gif.data.version # "89a"
37
+ p gif.data.width # 32
38
+ p gif.data.height # 32 # it's square :-)
39
+
40
+ # Change the values
41
+
42
+ gif.data.version = "87a"
43
+ gif.data.width = 128
44
+ gif.data.height = 128
45
+
46
+ gif.data.to_s # "GIF87a\x80\x00\x80\x00"
47
+
48
+ Supported data types are:
49
+
50
+ * signed and unsigned `integers` (1 to 8 bytes),
51
+ * fixed-size `strings` (specified length),
52
+ * `floats` and `doubles` (4 and 8 bytes),
53
+ * single `chars` (1 byte),
54
+ * `packed bytes` and `flag arrays` (1 byte),
55
+ * skipped data blocks.
56
+
57
+ More detailed documentation is available in `StructFx#declare` method
58
+ documentation and [documentation][2] of the [BitPacker][1] library.
59
+
60
+ Contributing
61
+ ------------
62
+
63
+ 1. Fork it.
64
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
65
+ 3. Commit your changes (`git commit -am "Added something"`).
66
+ 4. Push to the branch (`git push origin 20101220-my-change`).
67
+ 5. Create an [Issue][3] with a link to your branch.
68
+ 6. Enjoy a refreshing Diet Coke and wait.
69
+
70
+ Copyright
71
+ ---------
72
+
73
+ Copyright © 2011 [Martin Kozák][4]. See `LICENSE.txt` for
74
+ further details.
75
+
76
+ [1]: http://github.com/martinkozak/bit-packer
77
+ [2]: http://rubydoc.info/gems/bit-packer/0.1.0/frames
78
+ [3]: http://github.com/martinkozak/struct-fx/issues
79
+ [4]: http://www.martinkozak.net/
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+ require 'rake'
12
+
13
+ require 'jeweler'
14
+ Jeweler::Tasks.new do |gem|
15
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
16
+ gem.name = "struct-fx"
17
+ gem.homepage = "http://github.com/martinkozak/struct-fx"
18
+ gem.license = "MIT"
19
+ gem.summary = 'Declarative pure Ruby equivalent of C/C++ structs.'
20
+ gem.email = "martinkozak@martinkozak.net"
21
+ gem.authors = ["Martin Kozák"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/rdoctask'
30
+ Rake::RDocTask.new do |rdoc|
31
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
32
+
33
+ rdoc.rdoc_dir = 'rdoc'
34
+ rdoc.title = "hash-utils #{version}"
35
+ rdoc.rdoc_files.include('README*')
36
+ rdoc.rdoc_files.include('lib/**/*.rb')
37
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/struct-fx.rb ADDED
@@ -0,0 +1,328 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
4
+
5
+ require "frozen-objects"
6
+ require "bit-packer"
7
+
8
+ ##
9
+ # StructFx builder and analyzer.
10
+ #
11
+
12
+ class StructFx
13
+
14
+ ##
15
+ # Holds resultant data structure.
16
+ #
17
+
18
+ @struct
19
+
20
+ ##
21
+ # Holds type stack.
22
+ #
23
+
24
+ @stack
25
+
26
+ ##
27
+ # Holds data.
28
+ #
29
+
30
+ @data
31
+
32
+ ##
33
+ # Holds raw data.
34
+ # @return [String] raw (original) string data
35
+ #
36
+
37
+ attr_reader :raw
38
+ @raw
39
+
40
+ ##
41
+ # Holds stack in compiled form.
42
+ #
43
+
44
+ @compiled
45
+
46
+ ##
47
+ # Holds types metainformations map.
48
+ #
49
+
50
+ TYPES = Frozen << {
51
+ :int8 => ["c", 1],
52
+ :int16 => ["s", 2],
53
+ :int32 => ["l", 4],
54
+ :int64 => ["q", 8],
55
+ :uint8 => ["C", 1],
56
+ :uint16 => ["S", 2],
57
+ :uint32 => ["L", 4],
58
+ :uint64 => ["Q", 8],
59
+ :float => ["f", 4],
60
+ :double => ["d", 8],
61
+ :char => ["a", 1],
62
+ :string => ["Z", 1],
63
+ :byte => ["C", 1],
64
+ :skip => ["a", 1],
65
+ }
66
+
67
+ ##
68
+ # Holds compiled form structure.
69
+ #
70
+
71
+ Compiled = Struct::new(
72
+ :enabled, :processors, :packing, :unpacking, :lengths, :length
73
+ )
74
+
75
+ ##
76
+ # Constructor.
77
+ #
78
+ # @param [String] data raw string for unpack
79
+ # @param [Proc] block block with declaration
80
+ # @see #declare
81
+ #
82
+
83
+ def initialize(data = nil, &block)
84
+ @stack = [ ]
85
+ self.declare(&block)
86
+
87
+ if not data.nil?
88
+ self << data
89
+ end
90
+ end
91
+
92
+ ##
93
+ # Receives declaration.
94
+ #
95
+ # Adds declaration of bit array items. Can be call multiple times.
96
+ # New delcarations are joind to end of the array.
97
+ #
98
+ # @example
99
+ # struct = StructFx::new("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMOPQRSTUVWXYZ") do
100
+ # int8 :n_int8
101
+ # int16 :n_int16
102
+ # int32 :n_int32
103
+ # int64 :n_int64
104
+ # uint8 :n_uint8
105
+ # uint16 :n_uint16
106
+ # uint32 :n_uint32
107
+ # uint64 :n_uint64
108
+ # skip {2}
109
+ # float :n_float
110
+ # double :n_double
111
+ # char :n_char
112
+ # string (:n_string) {3}
113
+ # byte :n_flags do # byte is usually length 8 bits
114
+ # number (:n_number) {7}
115
+ # boolean :n_boolean
116
+ # end
117
+ # end
118
+ #
119
+ # @param [Proc] block block with declaration
120
+ # @see TYPES
121
+ #
122
+
123
+ def declare(&block)
124
+ self.instance_eval(&block)
125
+ end
126
+
127
+ ##
128
+ # Handles missing methods as declarations.
129
+ #
130
+ # @param [Symbol] name data type of the entry
131
+ # @param [Array] args first argument is expected to be name
132
+ # @param [Proc] block block which returns length of the entry in bits
133
+ # @return [Integer] new length of the packed data
134
+ # @see #declare
135
+ #
136
+
137
+ def method_missing(name, *args, &block)
138
+ if self.class::TYPES.include? name
139
+ self.add(args.shift, name, nil, block)
140
+ else
141
+ raise Exception::new("Invalid type/method specified: '" << name.to_s << "'")
142
+ end
143
+ end
144
+
145
+ ##
146
+ # Returns compiled form.
147
+ # @return [Class] compiled form struct
148
+ #
149
+
150
+ def compiled
151
+ if @compiled.nil?
152
+ @compiled = self.class::Compiled::new([], [], "", "", [], 0)
153
+ types = self.class::TYPES
154
+
155
+ @stack.each do |name, type, args, block|
156
+ type_meta = types[type]
157
+ length = block.nil? ? 1 : block.call()
158
+ pack_char = type_meta[0] + length.to_s
159
+ total_length = type_meta[1] * length
160
+
161
+ @compiled.enabled << (not name.nil?)
162
+ @compiled.processors << args
163
+ @compiled.packing << pack_char
164
+ @compiled.unpacking << pack_char
165
+ @compiled.lengths << total_length
166
+ @compiled.length += total_length
167
+ end
168
+
169
+ end
170
+
171
+ @compiled.enabled.freeze
172
+ @compiled.processors.freeze
173
+ @compiled.packing.freeze
174
+ @compiled.unpacking.freeze
175
+ @compiled.lengths.freeze
176
+
177
+ return @compiled.freeze
178
+ end
179
+
180
+ ##
181
+ # Adds byte BitPacker declaration.
182
+ #
183
+ # @param [Symbol] name name of the entry
184
+ # @param [Proc] block declaration
185
+ # @see
186
+ #
187
+
188
+ def byte(name, &block)
189
+ callback = Proc::new do |value|
190
+ BitPacker::new(value, &block)
191
+ end
192
+
193
+ self.add(name, :byte, callback)
194
+ end
195
+
196
+ ##
197
+ # Adds skipping declaration.
198
+ # @param [Proc] block with length
199
+ #
200
+
201
+ def skip(&block)
202
+ self.add(nil, :skip, nil, block)
203
+ end
204
+
205
+ ##
206
+ # Fills by input data.
207
+ # @param [Integer] value raw integer data for unpack
208
+ #
209
+
210
+ def <<(value)
211
+ if value.bytesize < self.compiled.length
212
+ raise Exception::new("Data are shorter than declaration.")
213
+ end
214
+
215
+ @raw = value.to_s
216
+ @data = nil
217
+ end
218
+
219
+ ##
220
+ # Adds declaration.
221
+ #
222
+ # @param [Symbol] name name of the entry
223
+ # @param [Symbol] type type of the entry
224
+ # @param [Proc] callback postprocessing callback
225
+ # @param [Proc] block length declaration block
226
+ #
227
+
228
+ def add(name, type, callback = nil, block = nil)
229
+ @stack << [name, type, callback, block]
230
+ @struct = nil
231
+ @compiled = nil
232
+ end
233
+
234
+ ##
235
+ # Returns structure analyze.
236
+ # @return [Class] struct with the packed data
237
+ #
238
+
239
+ def data
240
+ if @data.nil?
241
+ values = [ ]
242
+ compiled = self.compiled
243
+ extracted = @raw.unpack(compiled.unpacking)
244
+
245
+ compiled.enabled.each_index do |i|
246
+
247
+ # Skips skipped items
248
+ if not compiled.enabled[i]
249
+ next
250
+ end
251
+
252
+ # Calls postprocessing if required
253
+ callback = compiled.processors[i]
254
+ if callback.nil?
255
+ values << extracted[i]
256
+ else
257
+ values << callback.call(extracted[i])
258
+ end
259
+
260
+ end
261
+
262
+ @data = __struct::new(*values)
263
+ end
264
+
265
+ return @data
266
+ end
267
+
268
+ ##
269
+ # Returns total length of the struct in bytes.
270
+ # @return [Integer] total length of the declaration
271
+ #
272
+
273
+ def length
274
+ self.compiled.length
275
+ end
276
+
277
+ ##
278
+ # Converts to string.
279
+ # @return [String] resultant string according to current data state
280
+ #
281
+
282
+ def to_s
283
+ entries = self.data.entries
284
+ compiled = self.compiled
285
+
286
+ values = [ ]
287
+ length = 0
288
+ delta = 0
289
+
290
+ compiled.enabled.each_index do |i|
291
+
292
+ # Pastes skipped data from RAW
293
+ if not compiled.enabled[i]
294
+ from = length
295
+ to = (length + compiled.lengths[i])
296
+ values << @raw[from...to]
297
+ delta += 1
298
+
299
+ # In otherwise, take value from analyzed data
300
+ else
301
+ values << entries[i - delta] # current item minus count of non-entry (skipped) items
302
+ end
303
+
304
+ length += self.compiled.lengths[i]
305
+ end
306
+
307
+ values.pack(self.compiled.packing)
308
+ end
309
+
310
+
311
+ protected
312
+
313
+ ##
314
+ # Returns data struct.
315
+ #
316
+
317
+ def __struct
318
+ if @struct.nil?
319
+ members = @stack.map { |i| i[0] }
320
+ members.compact!
321
+
322
+ @struct = Struct::new(*members)
323
+ end
324
+
325
+ return @struct
326
+ end
327
+
328
+ end
data/struct-fx.gemspec ADDED
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{struct-fx}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Martin Kozák"]
12
+ s.date = %q{2011-03-02}
13
+ s.email = %q{martinkozak@martinkozak.net}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/struct-fx.rb",
27
+ "struct-fx.gemspec",
28
+ "test",
29
+ "test.gif"
30
+ ]
31
+ s.homepage = %q{http://github.com/martinkozak/struct-fx}
32
+ s.licenses = ["MIT"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.6.0}
35
+ s.summary = %q{Declarative pure Ruby equivalent of C/C++ structs.}
36
+
37
+ if s.respond_to? :specification_version then
38
+ s.specification_version = 3
39
+
40
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
41
+ s.add_runtime_dependency(%q<frozen-objects>, [">= 0.2.0"])
42
+ s.add_runtime_dependency(%q<bit-packer>, [">= 0.1.0"])
43
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
44
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
45
+ s.add_development_dependency(%q<riot>, [">= 0.12.1"])
46
+ else
47
+ s.add_dependency(%q<frozen-objects>, [">= 0.2.0"])
48
+ s.add_dependency(%q<bit-packer>, [">= 0.1.0"])
49
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
50
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
51
+ s.add_dependency(%q<riot>, [">= 0.12.1"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<frozen-objects>, [">= 0.2.0"])
55
+ s.add_dependency(%q<bit-packer>, [">= 0.1.0"])
56
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
58
+ s.add_dependency(%q<riot>, [">= 0.12.1"])
59
+ end
60
+ end
61
+
data/test ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
4
+
5
+ $:.push("./lib")
6
+ require "struct-fx"
7
+ require "riot"
8
+
9
+ context "StructFx (development)" do
10
+ setup do
11
+ StructFx::new("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMOPQRSTUVWXYZ") do
12
+ int8 :n_int8
13
+ int16 :n_int16
14
+ int32 :n_int32
15
+ int64 :n_int64
16
+ uint8 :n_uint8
17
+ uint16 :n_uint16
18
+ uint32 :n_uint32
19
+ uint64 :n_uint64
20
+ skip {2}
21
+ float :n_float
22
+ double :n_double
23
+ char :n_char
24
+ string (:n_string) {3}
25
+ byte :n_flags do
26
+ number (:n_number) {7}
27
+ boolean :n_boolean
28
+ end
29
+ end
30
+ end
31
+
32
+ asserts("correct unpacking") do
33
+ result = true
34
+
35
+ result &= (topic.data.n_int8 == 97)
36
+ result &= (topic.data.n_int16 == 25442)
37
+ result &= (topic.data.n_int32 == 1734763876)
38
+ result &= (topic.data.n_int64 == 8029475498074204520)
39
+ result &= (topic.data.n_uint8 == 112)
40
+ result &= (topic.data.n_uint16 == 29297)
41
+ result &= (topic.data.n_uint32 == 1987409011)
42
+ result &= (topic.data.n_uint64 == 3689065129052829815)
43
+ result &= (topic.data.n_float == 0.00017568175098858774)
44
+ result &= (topic.data.n_double == 1.5839800103804824e+40)
45
+ result &= (topic.data.n_char == ?I)
46
+ result &= (topic.data.n_string == "JKL")
47
+
48
+ result &= (topic.data.n_flags.data.n_number == 38)
49
+ result &= (topic.data.n_flags.data.n_boolean == true)
50
+ end
51
+
52
+ asserts("correct packing") do
53
+ topic.to_s == "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLM"
54
+ end
55
+
56
+ asserts("correct length") do
57
+ topic.length == 49
58
+ end
59
+
60
+ asserts("length failure") do
61
+ begin
62
+ StructFx::new("a") do
63
+ int16 :n_int16
64
+ end
65
+ rescue Exception => e
66
+ e.message == "Data are shorter than declaration."
67
+ end
68
+ end
69
+ end
70
+
71
+ context "StructFx (real-life)" do
72
+ setup do
73
+ data = nil
74
+ File.open("./test.gif", "rb") do |io|
75
+ data = io.read(10)
76
+ end
77
+
78
+ gif = StructFx::new(data) do
79
+ string (:gif) {3}
80
+ string (:version) {3}
81
+ uint16 :width
82
+ uint16 :height
83
+ end
84
+ end
85
+
86
+ asserts("GIF header unpacking") do
87
+ result = true
88
+
89
+ result &= (topic.data.gif == "GIF")
90
+ result &= (topic.data.version == "89a")
91
+ result &= (topic.data.width == 32)
92
+ result &= (topic.data.height == 32)
93
+ end
94
+
95
+ asserts("GIF header packing") do
96
+ topic.data.width = 128
97
+ topic.data.height = 128
98
+ topic.data.version = "87a"
99
+
100
+ topic.to_s.force_encoding("ASCII") == "GIF87a\x80\x00\x80\x00".force_encoding("ASCII")
101
+ end
102
+
103
+ end
data/test.gif ADDED
Binary file
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: struct-fx
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - "Martin Koz\xC3\xA1k"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-03-02 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: frozen-objects
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.2.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: bit-packer
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.1.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: bundler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.0
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: jeweler
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 1.5.2
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: riot
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 0.12.1
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ description:
72
+ email: martinkozak@martinkozak.net
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files:
78
+ - LICENSE.txt
79
+ - README.md
80
+ files:
81
+ - .document
82
+ - Gemfile
83
+ - Gemfile.lock
84
+ - LICENSE.txt
85
+ - README.md
86
+ - Rakefile
87
+ - VERSION
88
+ - lib/struct-fx.rb
89
+ - struct-fx.gemspec
90
+ - test
91
+ - test.gif
92
+ has_rdoc: true
93
+ homepage: http://github.com/martinkozak/struct-fx
94
+ licenses:
95
+ - MIT
96
+ post_install_message:
97
+ rdoc_options: []
98
+
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 2568357356524022812
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.6.0
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: Declarative pure Ruby equivalent of C/C++ structs.
123
+ test_files: []
124
+