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!

Reply via email to