What is the D way to map a binary file to a structure?
cym13 via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Aug 31 05:35:47 PDT 2015
On Monday, 31 August 2015 at 01:01:32 UTC, mzfhhhh wrote:
> On Saturday, 29 August 2015 at 12:56:08 UTC, cym13 wrote:
>> Hi,
>>
>> Let's say I have a simple binary file whose structure is
>> well-known. Here is
>> an example which stores points:
>>
>> struct Point {
>> long x;
>> long y;
>> long z;
>> }
>>
>> struct BinFile {
>> uint magicNumber; // Some identifier
>> ulong pointsNumber;
>> Point[] points; // Array of pointsNumber points.
>> }
>>
>> What is the best way to read some file and fill a structure
>> with it? Would
>> reading the file into a void[] and then casting it to the
>> struct work with
>> things like internal struct padding?
>
> struct Point {
> long x;
> long y;
> long z;
> }
>
> struct BinFile {
> uint magicNumber; // Some identifier
> ulong pointsNumber;
> Point[] points; // Array of pointsNumber points.
>
> this(ubyte [] buf)
> {
> auto f = cast(BinFile *)buf.ptr;
> this = cast(BinFile)*f;
> this.points =
> (cast(Point*)&f.points)[0..cast(uint)this.pointsNumber];
> }
> }
Thank you, this is what I was looking for :) I had to combine it
with align(1) though. Complete working example:
import std.conv;
import std.stdio;
align(1)
struct Point {
long x;
long y;
long z;
}
struct BinFile {
align(1):
uint magicNumber; // Some identifier
ulong pointsNumber;
Point[] points; // Array of pointsNumber points.
this(ubyte [] buf)
{
auto f = cast(BinFile *)buf.ptr;
this = cast(BinFile)*f;
this.points = (cast(Point*)&f.points)[0..pointsNumber];
}
}
void main(string[] args) {
/*
auto f = File(args[1], "rb");
ubyte[] buffer = [];
foreach (chunk ; f.byChunk(4096))
buffer ~= chunk;
*/
ubyte[] buffer = [
0xef, 0xbe, 0xad, 0xde, //
magicNumber
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
pointsNumber
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
points[0].x
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
points[0].y
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
points[0].z
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
points[1].x
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
points[1].y
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
points[1].z
];
auto bf = BinFile(buffer);
writefln("Magic number: %x", bf.magicNumber);
writeln("Number of points: ", bf.pointsNumber);
writeln("Points:");
foreach (p ; bf.points)
writeln(" ", p);
}
Thanks all!
More information about the Digitalmars-d-learn
mailing list