README in bindata-0.9.3 vs README in bindata-0.10.0

- old
+ new

@@ -13,11 +13,11 @@ puts "Rectangle #{name} is #{width} x #{height}" It's ugly, violates DRY and feels like you're writing Perl, not Ruby. There is a better way. - class Rectangle < BinData::MultiValue + class Rectangle < BinData::Record uint16le :len string :name, :read_length => :len uint32le :width uint32le :height end @@ -34,11 +34,11 @@ == Syntax BinData declarations are easy to read. Here's an example. - class MyFancyFormat < BinData::MultiValue + class MyFancyFormat < BinData::Record stringz :comment uint8 :count, :check_value => lambda { (value % 2) == 0 } array :some_ints, :type => :int32be, :initial_length => :count end @@ -60,22 +60,21 @@ The general format of a BinData declaration is a class containing one or more fields. - class MyName < BinData::MultiValue + class MyName < BinData::Record type field_name, :param1 => "foo", :param2 => bar, ... ... end *type* is the name of a supplied type (e.g. <tt>uint32be</tt>, +string+) or a user defined type. For user defined types, convert the class name from CamelCase to lowercase underscore_style. *field_name* is the name by which you can access the data. Use either a -String or a Symbol. You may specify a name as nil, but this is described -later in the tutorial. +String or a Symbol. Each field may have *parameters* for how to process the data. The parameters are passed as a Hash using Symbols for keys. == Handling dependencies between fields @@ -98,11 +97,11 @@ io.putc(str.length) io.write(str) Here's how we'd implement the same example with BinData. - class PascalString < BinData::MultiValue + class PascalString < BinData::Record uint8 :len, :value => lambda { data.length } string :data, :read_length => :len end # reading @@ -118,11 +117,11 @@ ps.write(io) This syntax needs explaining. Let's simplify by examining reading and writing separately. - class PascalStringReader < BinData::MultiValue + class PascalStringReader < BinData::Record uint8 :len string :data, :read_length => :len end This states that when reading the string, the initial length of the string @@ -130,11 +129,11 @@ +len+ field. Note that <tt>:read_length => :len</tt> is syntactic sugar for <tt>:read_length => lambda { len }</tt>, but more on that later. - class PascalStringWriter < BinData::MultiValue + class PascalStringWriter < BinData::Record uint8 :len, :value => lambda { data.length } string :data end This states that the value of +len+ is always equal to the length of +data+. @@ -192,11 +191,11 @@ BinData::Rest:: Consumes the rest of the input stream. == Parameters - class PascalStringWriter < BinData::MultiValue + class PascalStringWriter < BinData::Record uint8 :len, :value => lambda { data.length } string :data end Revisiting the Pascal string writer, we see that a field can take @@ -227,11 +226,11 @@ The endianess of numeric types must be explicitly defined so that the code produced is independent of architecture. Explicitly specifying the endianess of each numeric type can become tedious, so the following shortcut is provided. - class A < BinData::MultiValue + class A < BinData::Record endian :little uint16 :a uint32 :b double :c @@ -239,11 +238,11 @@ array :e, :type => :int16 end is equivalent to: - class A < BinData::MultiValue + class A < BinData::Record uint16le :a uint32le :b double_le :c uint32be :d array :e, :type => :int16le @@ -253,49 +252,49 @@ as reducing the amount of typing necessary. Note that the endian keyword will cascade to nested types, as illustrated with the array in the above example. == Creating custom types -Custom types should be created by subclassing BinData::MultiValue or -BinData::SingleValue. Ocassionally it may be useful to subclass -BinData::Single. Subclassing other classes may have unexpected results +Custom types should be created by subclassing BinData::Record or +BinData::Primitive. Ocassionally it may be useful to subclass +BinData::BasePrimitive. Subclassing other classes may have unexpected results and is unsupported. Let us revisit the Pascal String example. - class PascalString < BinData::MultiValue + class PascalString < BinData::Record uint8 :len, :value => lambda { data.length } string :data, :read_length => :len end We'd like to make PascalString a custom type that behaves like a -BinData::Single object so we can use :initial_value etc. Here's an +BinData::BasePrimitive object so we can use :initial_value etc. Here's an example usage of what we'd like: - class Favourites < BinData::MultiValue + class Favourites < BinData::Record pascal_string :language, :initial_value => "ruby" pascal_string :os, :initial_value => "unix" end f = Favourites.new f.os = "freebsd" - f.to_s #=> "\004ruby\007freebsd" + f.to_binary_s #=> "\004ruby\007freebsd" -We create this type of custom string by inheriting from BinData::SingleValue +We create this type of custom string by inheriting from BinData::Primitive and implementing the #get and #set methods. - class PascalString < BinData::SingleValue + class PascalString < BinData::Primitive uint8 :len, :value => lambda { data.length } string :data, :read_length => :len def get; self.data; end def set(v) self.data = v; end end -If the type we are creating represents a single value then inherit from -BinData::SingleValue, otherwise inherit from BinData::MultiValue. +If the type we are creating represents a primitive value then inherit from +BinData::Primitive, otherwise inherit from BinData::Record. == License BinData is released under the same license as Ruby. -Copyright (c) 2007, 2008 Dion Mendel +Copyright (c) 2007 - 2009 Dion Mendel