August 31, 2015 Re: What is the D way to map a binary file to a structure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | 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]; } } |
August 31, 2015 Re: What is the D way to map a binary file to a structure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mzfhhhh | 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! |
Copyright © 1999-2021 by the D Language Foundation