From: Markus Fischer Date: 2009-06-09T07:05:09+09:00 Subject: Re: binaryparse: length in bytes of block definition? Hi, first, I guess I've to apologize in some way, because I was the OP last week and you kindly, very quickly, posted a suggestion on pastebin and I was completely ignorant. Actually, I was in limbo because I had so many questions and didn't know where to start. Joel VanderWerf wrote: > Can you describe the nesting you are trying to do? Currently, I'm writing a reader for the BSP file format, as described here: http://graphics.stanford.edu/~kekoa/q3/ The week before, I was writing a MD3 model reader, which works already thanks to bit-struct :) Back to the BSP format: since it uses some fixed arrays, and it was one of your post which suggested binaryparse, I tried that one and succeeded so far, except the following: 1) it was incredible hart to get *into* binaryparse as you basically have to learn from the source, as there's no real usable rdoc doc 2) probably due 1), I've no idea how to read float values with it. I just don't get it, I guess :( It does not seem to have out of the box support, however it seems to provide some kind of support via custom packing/unpacking, but I can't figure out how. Due 2), I don't support reading the lumps containing floats ATM. Right now I don't need them, but reading all data is the goal. > Bit-struct does have > some nesting capability, and my working copy now supports embedded > vectors (fixed length arrays of bit-structs). This is an addition in the > last week or so, but I can make it available. > > Nesting example: > > class NestedPart < BitStruct > unsigned :x, 5 > unsigned :y, 3 > char :s, 5*8 > end > > class Container < BitStruct > nest :n1, NestedPart, "Nest 1" > nest :n2, NestedPart, "Nest 2" > end > > The more or less equivalent effect using vectors instead: > > class MyEntry < BitStruct > unsigned :x, 5 > unsigned :y, 3 > char :s, 5*8 > end > > class Container < BitStruct > vector :n, MyEntry, "some entries", :length => 2 > end Now, I wouldn't mind going back to bit-struct for the BSP reading stuff, as I find the documentation outstanding well! However, through binaryparse I discovered one thing I'm really enjoying: it supports direct reading from an IO-type object. So I can pass either a File IO or an StringIO object directory, which is really comfortable. Maybe bit-struct supports that in some way, but I couldn't find anything. Basically, with bit-struct I've to know how much to pass to a BitStruct class. Binaryparse, in contrast, uses the given structure information to know itself how much to consume. class Header < BinaryBlocker::Blocker has_one ... has_one ... end class Datadir < BinaryBlocker::Blocker ... ... end io = File.new("data") Header.new io Datadir.new io That's really nice compared to Header.new io.read(Header.round_byte_length) Datadir.new io.read(Datadir.round_byte_length) But I can see that there are different philosophies at work, given that it's named round_byte_length, because reading single bits wouldn't be really possible that way, therefore the "rest" reader ... About your upcoming addition and your example: how would a simple integer array look like? C-struct example: typedef struct { float normal[3]; float dist; } dplane_t; Ruby (?): class MyFloat < BitStruct float :value, 32 end class Plane < BitStruct vector :normal, MyFloat, :length => 3 float :dist, 32 end This wold mean I need to access plane.normal[0].value I guess ... having not to need the additional .value would be nice, e.g. class Plane < BitStruct vector :normal, :length => 3 do float 32 end float :dist, 32 end Would multiple dimension be supported, too? Like C-style float[2][2] ? class Plane < BitStruct vector :normal, :length => 3 do vector :length => 3 od float 32 end end float :dist, 32 end Ok, I think it's getting out of control now ;) thanks - Markus