jbangert-bindata 1.5.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.
Files changed (71) hide show
  1. data/.gitignore +1 -0
  2. data/BSDL +22 -0
  3. data/COPYING +52 -0
  4. data/ChangeLog.rdoc +204 -0
  5. data/Gemfile +2 -0
  6. data/INSTALL +11 -0
  7. data/NEWS.rdoc +164 -0
  8. data/README.md +54 -0
  9. data/Rakefile +13 -0
  10. data/bindata.gemspec +31 -0
  11. data/doc/manual.haml +407 -0
  12. data/doc/manual.md +1649 -0
  13. data/examples/NBT.txt +149 -0
  14. data/examples/gzip.rb +161 -0
  15. data/examples/ip_address.rb +22 -0
  16. data/examples/list.rb +124 -0
  17. data/examples/nbt.rb +178 -0
  18. data/lib/bindata.rb +33 -0
  19. data/lib/bindata/alignment.rb +83 -0
  20. data/lib/bindata/array.rb +335 -0
  21. data/lib/bindata/base.rb +388 -0
  22. data/lib/bindata/base_primitive.rb +214 -0
  23. data/lib/bindata/bits.rb +87 -0
  24. data/lib/bindata/choice.rb +216 -0
  25. data/lib/bindata/count_bytes_remaining.rb +35 -0
  26. data/lib/bindata/deprecated.rb +50 -0
  27. data/lib/bindata/dsl.rb +312 -0
  28. data/lib/bindata/float.rb +80 -0
  29. data/lib/bindata/int.rb +184 -0
  30. data/lib/bindata/io.rb +274 -0
  31. data/lib/bindata/lazy.rb +105 -0
  32. data/lib/bindata/offset.rb +91 -0
  33. data/lib/bindata/params.rb +135 -0
  34. data/lib/bindata/primitive.rb +135 -0
  35. data/lib/bindata/record.rb +110 -0
  36. data/lib/bindata/registry.rb +92 -0
  37. data/lib/bindata/rest.rb +35 -0
  38. data/lib/bindata/sanitize.rb +290 -0
  39. data/lib/bindata/skip.rb +48 -0
  40. data/lib/bindata/string.rb +145 -0
  41. data/lib/bindata/stringz.rb +96 -0
  42. data/lib/bindata/struct.rb +388 -0
  43. data/lib/bindata/trace.rb +94 -0
  44. data/lib/bindata/version.rb +3 -0
  45. data/setup.rb +1585 -0
  46. data/spec/alignment_spec.rb +61 -0
  47. data/spec/array_spec.rb +331 -0
  48. data/spec/base_primitive_spec.rb +238 -0
  49. data/spec/base_spec.rb +376 -0
  50. data/spec/bits_spec.rb +163 -0
  51. data/spec/choice_spec.rb +263 -0
  52. data/spec/count_bytes_remaining_spec.rb +38 -0
  53. data/spec/deprecated_spec.rb +31 -0
  54. data/spec/example.rb +21 -0
  55. data/spec/float_spec.rb +37 -0
  56. data/spec/int_spec.rb +216 -0
  57. data/spec/io_spec.rb +352 -0
  58. data/spec/lazy_spec.rb +217 -0
  59. data/spec/primitive_spec.rb +202 -0
  60. data/spec/record_spec.rb +530 -0
  61. data/spec/registry_spec.rb +108 -0
  62. data/spec/rest_spec.rb +26 -0
  63. data/spec/skip_spec.rb +27 -0
  64. data/spec/spec_common.rb +58 -0
  65. data/spec/string_spec.rb +300 -0
  66. data/spec/stringz_spec.rb +118 -0
  67. data/spec/struct_spec.rb +350 -0
  68. data/spec/system_spec.rb +380 -0
  69. data/tasks/manual.rake +36 -0
  70. data/tasks/rspec.rake +17 -0
  71. metadata +208 -0
@@ -0,0 +1,54 @@
1
+ # What is BinData?
2
+
3
+ Do you ever find yourself writing code like this?
4
+
5
+ ```ruby
6
+ io = File.open(...)
7
+ len = io.read(2).unpack("v")
8
+ name = io.read(len)
9
+ width, height = io.read(8).unpack("VV")
10
+ puts "Rectangle #{name} is #{width} x #{height}"
11
+ ```
12
+
13
+ It’s ugly, violates DRY and feels like you’re writing Perl, not Ruby.
14
+
15
+ There is a better way. Here’s how you’d write the above using BinData.
16
+
17
+ ```ruby
18
+ class Rectangle < BinData::Record
19
+ endian :little
20
+ uint16 :len
21
+ string :name, :read_length => :len
22
+ uint32 :width
23
+ uint32 :height
24
+ end
25
+
26
+ io = File.open(...)
27
+ r = Rectangle.read(io)
28
+ puts "Rectangle #{r.name} is #{r.width} x #{r.height}"
29
+ ```
30
+
31
+ BinData makes it easy to create new data types. It supports all the common
32
+ primitive datatypes that are found in structured binary data formats. Support
33
+ for dependent and variable length fields is built in.
34
+
35
+ # Installation
36
+
37
+ $ gem install bindata
38
+
39
+ -or-
40
+
41
+ $ sudo ruby setup.rb
42
+
43
+ # Documentation
44
+
45
+ [http://bindata.rubyforge.org/manual.html](http://bindata.rubyforge.org/manual.html)
46
+
47
+ -or-
48
+
49
+ $ rake manual
50
+
51
+ # Contact
52
+
53
+ If you have any queries / bug reports / suggestions, please contact me
54
+ (Dion Mendel) via email at dion@lostrealm.com
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rake/clean'
6
+
7
+ task :clobber do
8
+ rm_rf 'pkg'
9
+ end
10
+
11
+ task :default => :spec
12
+
13
+ Dir['tasks/**/*.rake'].each { |t| load t }
@@ -0,0 +1,31 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require 'bindata/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'jbangert-bindata'
6
+ s.version = BinData::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.summary = 'A declarative way to read and write binary file formats'
9
+ s.author = 'Dion Mendel'
10
+ s.email = 'dion@lostrealm.com'
11
+ s.homepage = 'http://github.com/jbangert/bindata'
12
+ s.require_path = 'lib'
13
+ s.has_rdoc = true
14
+ s.extra_rdoc_files = ['NEWS.rdoc']
15
+ s.rdoc_options << '--main' << 'NEWS.rdoc'
16
+ s.files = `git ls-files`.split("\n")
17
+
18
+ s.add_development_dependency('rake')
19
+ s.add_development_dependency('rspec', [">= 2.10.0"])
20
+ s.add_development_dependency('haml', ["< 4.0.0"])
21
+ s.add_development_dependency('maruku')
22
+ s.add_development_dependency('syntax')
23
+ s.description = <<-END.gsub(/^ +/, "")
24
+ BinData is a declarative way to read and write binary file formats.
25
+
26
+ This means the programmer specifies *what* the format of the binary
27
+ data is, and BinData works out *how* to read and write data in this
28
+ format. It is an easier ( and more readable ) alternative to
29
+ ruby's #pack and #unpack methods.
30
+ END
31
+ end
@@ -0,0 +1,407 @@
1
+ !!!
2
+ %html{ :xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en" }
3
+ %head
4
+ %meta{ :content => "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
5
+ %meta{ :name => "description", :content =>"How to easily read and write binary data in Ruby" }
6
+ %meta{ :keywords =>"ruby, binary, binary data, parse binary data, read binary data, write binary data, binary file, read binary file, write binary file" }
7
+ %title
8
+ Reading, writing and parsing binary data in Ruby
9
+ :javascript
10
+ var TINY={};function T$(i){return document.getElementById(i)}function T$$(e,p){return p.getElementsByTagName(e)}TINY.accordion=function(){function slider(n){this.n=n;this.a=[]}slider.prototype.init=function(t,e,m,o,k){var a=T$(t),i=s=0,n=a.childNodes,l=n.length;this.s=k||0;this.m=m||0;for(i;i<l;i++){var v=n[i];if(v.nodeType!=3){this.a[s]={};this.a[s].h=h=T$$(e,v)[0];this.a[s].c=c=T$$('div',v)[0];h.onclick=new Function(this.n+'.pr(0,'+s+')');if(o==s){h.className=this.s;c.style.height='auto';c.d=1}else{c.style.height=0;c.d=-1}s++}}this.l=s};slider.prototype.pr=function(f,d){for(var i=0;i<this.l;i++){var h=this.a[i].h,c=this.a[i].c,k=c.style.height;k=k=='auto'?1:parseInt(k);clearInterval(c.t);if((k!=1&&c.d==-1)&&(f==1||i==d)){c.style.height='';c.m=c.offsetHeight;c.style.height=k+'px';c.d=1;h.className=this.s;su(c,1)}else if(k>0&&(f==-1||this.m||i==d)){c.d=-1;h.className='';su(c,-1)}}};function su(c){c.t=setInterval(function(){sl(c)},20)};function sl(c){var h=c.offsetHeight,d=c.d==1?c.m-h:h;c.style.height=h+(Math.ceil(d/5)*c.d)+'px';c.style.opacity=h/c.m;c.style.filter='alpha(opacity='+h*100/c.m+')';if((c.d==1&&h>=c.m)||(c.d!=1&&h==1)){if(c.d==1){c.style.height='auto'}clearInterval(c.t)}};return{slider:slider}}();
11
+
12
+ var menu1, menu2, menu3, menu4, menu5, menu6, menu7;
13
+ var menu8, menu9, menu10, menu11, menu12, menu13, menu14, menu15;
14
+
15
+ function init_accordion() {
16
+ menu1 = new TINY.accordion.slider("menu1"); menu1.init("menu1","a",1,-1);
17
+ menu2 = new TINY.accordion.slider("menu2"); menu2.init("menu2","a",1,-1);
18
+ menu3 = new TINY.accordion.slider("menu3"); menu3.init("menu3","a",1,-1);
19
+ menu4 = new TINY.accordion.slider("menu4"); menu4.init("menu4","a",1,-1);
20
+ menu5 = new TINY.accordion.slider("menu5"); menu5.init("menu5","a",1,-1);
21
+ menu6 = new TINY.accordion.slider("menu6"); menu6.init("menu6","a",1,-1);
22
+ menu7 = new TINY.accordion.slider("menu7"); menu7.init("menu7","a",1,-1);
23
+ menu8 = new TINY.accordion.slider("menu8"); menu8.init("menu8","a",1,-1);
24
+ menu9 = new TINY.accordion.slider("menu9"); menu9.init("menu9","a",1,-1);
25
+ menu10 = new TINY.accordion.slider("menu10"); menu10.init("menu10","a",1,-1);
26
+ menu11 = new TINY.accordion.slider("menu11"); menu11.init("menu11","a",1,-1);
27
+ menu12 = new TINY.accordion.slider("menu12"); menu12.init("menu12","a",1,-1);
28
+ menu13 = new TINY.accordion.slider("menu13"); menu13.init("menu13","a",1,-1);
29
+ menu14 = new TINY.accordion.slider("menu14"); menu14.init("menu14","a",1,-1);
30
+ menu15 = new TINY.accordion.slider("menu15"); menu15.init("menu15","a",1,-1);
31
+ };
32
+ window.onload = init_accordion;
33
+
34
+ %style{:type => "text/css", :media => "screen"}
35
+ :plain
36
+ body {
37
+ margin:0; padding:0; border:0;
38
+ height:100%; max-height:100%;
39
+ overflow:hidden;
40
+ background-color:#FFF;
41
+ }
42
+
43
+ #left_frame {
44
+ position:absolute; overflow:hidden;
45
+ top:0; bottom:0; left:0;
46
+ width:240px; height:100%;
47
+ }
48
+
49
+ #main_frame {
50
+ position:fixed; overflow:auto;
51
+ top:0; right:0; bottom:0; left:240px;
52
+ }
53
+
54
+ * html body { /*IE6 hack*/
55
+ padding: 0 0 0 240px;
56
+ }
57
+ * html #main_frame { /*IE6 hack*/
58
+ height: 100%; width: 100%;
59
+ }
60
+
61
+ .menu_top_level {margin:5px;}
62
+ .menu_top_level ul {list-style:none; margin:0; padding:0;}
63
+ .menu_top_level li {margin-top:5px;}
64
+ .menu_top_level .acc-section {overflow:hidden;}
65
+ .menu_top_level .acc-content {width:100%; margin:0; padding:0; background:#FFF}
66
+
67
+ .menu_top_level li a {
68
+ display:block; cursor:pointer; text-decoration: none;
69
+ border:1px solid #9BC;
70
+ padding: 0;
71
+ font:bold 12px/2 Verdana, Arial, Helvetica;
72
+ }
73
+ .menu_top_level li a:link, .menu_top_level li a:visited { color: #131; background:#FFE;}
74
+ .menu_top_level li a:hover {background: #9C9; color:#FFE;}
75
+
76
+ .menu_top_level .level1 li a { padding-left: 15px; }
77
+ .menu_top_level .level2 li a { padding-left: 30px; }
78
+ .menu_top_level .level3 li a { padding-left: 45px; }
79
+
80
+ #main_content {
81
+ margin: 20px; padding-left: 3em;
82
+ width: 40em;
83
+ font-family: Georgia, Times;
84
+ }
85
+
86
+ #main_content h1 { margin-left: -1em;}
87
+ #main_content h2 { margin-left: -1em;}
88
+
89
+ #main_content pre {
90
+ margin-left: 2em; padding: 4px;
91
+ background-color: #EFF;
92
+ border: solid 1px #BDD;
93
+ }
94
+
95
+ #main_content .ruby .normal {}
96
+ #main_content .ruby .comment { color: #005; font-style: italic; }
97
+ #main_content .ruby .keyword { color: #A00; font-weight: bold; }
98
+ #main_content .ruby .method { color: #077; }
99
+ #main_content .ruby .class { color: #074; }
100
+ #main_content .ruby .module { color: #050; }
101
+ #main_content .ruby .punct { color: #447; font-weight: bold; }
102
+ #main_content .ruby .symbol { color: #099; }
103
+ #main_content .ruby .string { color: #944; background: #FFE; }
104
+ #main_content .ruby .char { color: #F07; }
105
+ #main_content .ruby .ident { color: #004; }
106
+ #main_content .ruby .constant { color: #07F; }
107
+ #main_content .ruby .regex { color: #B66; background: #FEF; }
108
+ #main_content .ruby .number { color: #F99; }
109
+ #main_content .ruby .attribute { color: #7BB; }
110
+ #main_content .ruby .global { color: #7FB; }
111
+ #main_content .ruby .expr { color: #227; }
112
+ #main_content .ruby .escape { color: #277; }
113
+ %script{:type => "text/javascript"}
114
+ :plain
115
+ var _gaq = _gaq || [];
116
+ _gaq.push(['_setAccount', 'UA-20958115-1']);
117
+ _gaq.push(['_trackPageview']);
118
+
119
+ (function() {
120
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
121
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
122
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
123
+ })();
124
+
125
+ %body
126
+ #left_frame
127
+ .menu_top_level
128
+ %ul.level1#menu1
129
+ %li
130
+ %a{ :href => "#bindata" }
131
+ BinData
132
+ .acc-section
133
+ .acc-content
134
+ %ul.level2#menu2
135
+ %li
136
+ %a{ :href => "#what_is_it_for" }
137
+ What is it for?
138
+ .acc-section
139
+ .acc-content
140
+ %li
141
+ %a{ :href => "#license" }
142
+ License
143
+ .acc-section
144
+ .acc-content
145
+ %li
146
+ %a{ :href => "#donate" }
147
+ Donate
148
+ .acc-section
149
+ .acc-content
150
+ %li
151
+ %a{ :href => "#installation" }
152
+ Installation
153
+ .acc-section
154
+ .acc-content
155
+ %li
156
+ %a{ :href => "#overview" }
157
+ Overview
158
+ .acc-section
159
+ .acc-content
160
+ %li
161
+ %a{ :href => "#records" }
162
+ Records
163
+ .acc-section
164
+ .acc-content
165
+ %ul.level2#menu3
166
+ %li
167
+ %a{ :href => "#specifying_default_endian" }
168
+ Specifying default endian
169
+ .acc-section
170
+ .acc-content
171
+ %li
172
+ %a{ :href => "#dependencies_between_fields" }
173
+ Dependencies between fields
174
+ .acc-section
175
+ .acc-content
176
+ %li
177
+ %a{ :href => "#nested_records" }
178
+ Nested Records
179
+ .acc-section
180
+ .acc-content
181
+ %li
182
+ %a{ :href => "#optional_fields" }
183
+ Optional fields
184
+ .acc-section
185
+ .acc-content
186
+ %li
187
+ %a{ :href => "#primitive_types" }
188
+ Primitive Types
189
+ .acc-section
190
+ .acc-content
191
+ %ul.level2#menu4
192
+ %li
193
+ %a{ :href => "#numerics" }
194
+ Numerics
195
+ .acc-section
196
+ .acc-content
197
+ %ul.level3#menu5
198
+ %li
199
+ %a{ :href => "#byte_based_integers" }
200
+ Byte based integers
201
+ .acc-section
202
+ .acc-content
203
+ %li
204
+ %a{ :href => "#bit_based_integers" }
205
+ Bit based integers
206
+ .acc-section
207
+ .acc-content
208
+ %li
209
+ %a{ :href => "#floating_point_numbers" }
210
+ Floating point numbers
211
+ .acc-section
212
+ .acc-content
213
+ %li
214
+ %a{ :href => "#example" }
215
+ Example
216
+ .acc-section
217
+ .acc-content
218
+ %li
219
+ %a{ :href => "#strings" }
220
+ Strings
221
+ .acc-section
222
+ .acc-content
223
+ %ul.level3#menu6
224
+ %li
225
+ %a{ :href => "#fixed_sized_strings" }
226
+ Fixed Sized Strings
227
+ .acc-section
228
+ .acc-content
229
+ %li
230
+ %a{ :href => "#zero_terminated_strings" }
231
+ Zero Terminated Strings
232
+ .acc-section
233
+ .acc-content
234
+ %li
235
+ %a{ :href => "#user_defined_primitive_types" }
236
+ User-defined Primitive Types
237
+ .acc-section
238
+ .acc-content
239
+ %ul.level3#menu7
240
+ %li
241
+ %a{ :href => "#advanced_user_defined_primitive_types" }
242
+ Advanced Example
243
+ .acc-section
244
+ .acc-content
245
+ %li
246
+ %a{ :href => "#compound_types" }
247
+ Compound Types
248
+ .acc-section
249
+ .acc-content
250
+ %ul.level2#menu8
251
+ %li
252
+ %a{ :href => "#arrays" }
253
+ Arrays
254
+ .acc-section
255
+ .acc-content
256
+ %ul.level3#menu9
257
+ %li
258
+ %a{ :href => "#array_syntax" }
259
+ Array syntax
260
+ .acc-section
261
+ .acc-content
262
+ %li
263
+ %a{ :href => "#array_parameters" }
264
+ Array parameters
265
+ .acc-section
266
+ .acc-content
267
+ %li
268
+ %a{ :href => "#choices" }
269
+ Choices
270
+ .acc-section
271
+ .acc-content
272
+ %ul.level3#menu10
273
+ %li
274
+ %a{ :href => "#choice_syntax" }
275
+ Choice syntax
276
+ .acc-section
277
+ .acc-content
278
+ %li
279
+ %a{ :href => "#choice_parameters" }
280
+ Choice parameters
281
+ .acc-section
282
+ .acc-content
283
+ %li
284
+ %a{ :href => "#default_selection" }
285
+ Default Selection
286
+ .acc-section
287
+ .acc-content
288
+ %li
289
+ %a{ :href => "#common_operations" }
290
+ Common Operations
291
+ .acc-section
292
+ .acc-content
293
+ %ul.level2#menu11
294
+ %li
295
+ %a{ :href => "#reading_and_writing" }
296
+ Reading and writing
297
+ .acc-section
298
+ .acc-content
299
+ %li
300
+ %a{ :href => "#manipulating" }
301
+ Manipulating
302
+ .acc-section
303
+ .acc-content
304
+ %li
305
+ %a{ :href => "#inspecting" }
306
+ Inspecting
307
+ .acc-section
308
+ .acc-content
309
+ %li
310
+ %a{ :href => "#advanced_topics" }
311
+ Advanced Topics
312
+ .acc-section
313
+ .acc-content
314
+ %ul.level2#menu12
315
+ %li
316
+ %a{ :href => "#debugging" }
317
+ Debugging
318
+ .acc-section
319
+ .acc-content
320
+ %ul.level3#menu13
321
+ %li
322
+ %a{ :href => "#tracing" }
323
+ Tracing
324
+ .acc-section
325
+ .acc-content
326
+ %li
327
+ %a{ :href => "#rest" }
328
+ Rest
329
+ .acc-section
330
+ .acc-content
331
+ %li
332
+ %a{ :href => "#hidden_fields" }
333
+ Hidden fields
334
+ .acc-section
335
+ .acc-content
336
+ %li
337
+ %a{ :href => "#parameterizing_user_defined_types" }
338
+ Parameterizing Types
339
+ .acc-section
340
+ .acc-content
341
+ %ul.level3#menu14
342
+ %li
343
+ %a{ :href => "#mandatory_parameters" }
344
+ Mandatory Parameters
345
+ .acc-section
346
+ .acc-content
347
+ %li
348
+ %a{ :href => "#default_parameters" }
349
+ Default Parameters
350
+ .acc-section
351
+ .acc-content
352
+ %li
353
+ %a{ :href => "#extending_existing_types" }
354
+ Extending existing Types
355
+ .acc-section
356
+ .acc-content
357
+ %li
358
+ %a{ :href => "#dynamically_creating_types" }
359
+ Dynamically creating Types
360
+ .acc-section
361
+ .acc-content
362
+ %li
363
+ %a{ :href => "#skipping_over_unused_data" }
364
+ Skipping over unused data
365
+ .acc-section
366
+ .acc-content
367
+ %li
368
+ %a{ :href => "#determining_stream_length" }
369
+ Determining stream length
370
+ .acc-section
371
+ .acc-content
372
+ %li
373
+ %a{ :href => "#advanced_bitfields" }
374
+ Advanced Bitfields
375
+ .acc-section
376
+ .acc-content
377
+ %li
378
+ %a{ :href => "#faq" }
379
+ FAQ
380
+ .acc-section
381
+ .acc-content
382
+ %ul.level2#menu15
383
+ %li
384
+ %a{ :href => "#im_using_ruby_19_how_do_i_use_string_encodings_with_bindata" }
385
+ String encoding - Ruby 1.9
386
+ .acc-section
387
+ .acc-content
388
+ %li
389
+ %a{ :href => "#how_do_i_speed_up_initialization" }
390
+ Performance
391
+ .acc-section
392
+ .acc-content
393
+ %li
394
+ %a{ :href => "#how_do_i_model_this_complex_nested_format" }
395
+ Recursive declarations
396
+ .acc-section
397
+ .acc-content
398
+ %li
399
+ %a{ :href => "#alternatives" }
400
+ Alternatives
401
+ .acc-section
402
+ .acc-content
403
+ #main_frame
404
+ #main_content
405
+ :maruku
406
+ #{File.read("doc/manual.md")}
407
+