BinData is a Ruby library that offers a declarative way to read and write binary file formats.
Do you ever find yourself writing code like this?
io = File.open(...)
len = io.read(2).unpack("v")
name = io.read(len)
width, height = io.read(8).unpack("VV")
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
uint16le :len
string :name, :read_length => :len
uint32le :width
uint32le :height
end
io = File.open(...)
r = Rectangle.read(io)
puts "Rectangle #{r.name} is #{r.width} x #{r.height}"
BinData makes it easy to specify the structure of the data you are manipulating.
Syntax:
BinData declarations are easy to read. Here's an example.
class MyFancyFormat < BinData::MultiValue
stringz :comment
uint8 :count, :check_value => lambda { (value % 2) == 0 }
array :some_ints, :type => :int32be, :initial_length => :count
end
The structure of the data in this example is:
1. A zero terminated string
2. An unsigned 8bit integer which must by even
3. A sequence of unsigned 32bit integers in big endian form, the total number of which is determined by the value of the 8bit integer.
The BinData declaration matches the english description closely. Just for fun, lets look at how we'd implement this using pack and unpack. Here's the writing code, have a go at the reading code.
comment = "this is a comment"
some_ints = [2, 3, 8, 9, 1, 8]
File.open(...) do |io|
io.write([comment, some_ints.size, *some_ints].pack("Z*CN*"))
end
The general format of a BinData declaration is a class containing one or more fields.
class MyName < BinData::MultiValue
type field_name, :param1 => "foo", :param2 => bar, ...
...
end
type is the name of a supplied type (e.g. uint32be, 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.
Each field may have parameters for how to process the data. The parameters are passed as a Hash using Symbols for keys.
Product's homepage
Requirements:
· Ruby
· RubyGems