jbangert-bindata 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
+