Struct 确保D rawRead()是文件中的大端结构

Struct 确保D rawRead()是文件中的大端结构,struct,d,endianness,Struct,D,Endianness,我试图构建一个简单的PNG阅读器,但由于macOS是一个小的endian系统,PNG是一种大端格式,我遇到了一个大问题(至少对我来说,我是D新手) 首先要有一堆代码: static enum IHDR_BitDepth: ubyte { BitDepth1 = 1, BitDepth2 = 2, BitDepth4 = 4, BitDepth8 = 8, BitDepth16 = 16 } static enum IHDR_ColorType:

我试图构建一个简单的PNG阅读器,但由于macOS是一个小的endian系统,PNG是一种大端格式,我遇到了一个大问题(至少对我来说,我是D新手)

首先要有一堆代码:

static enum IHDR_BitDepth: ubyte {
    BitDepth1  = 1,
    BitDepth2  = 2,
    BitDepth4  = 4,
    BitDepth8  = 8,
    BitDepth16 = 16
}

static enum IHDR_ColorType: ubyte {
    Greyscale      = 0,
    TrueColor      = 2,
    Indexed        = 3,
    GreyscaleAlpha = 4,
    TrueColorAlpha = 6
}

static enum IHDR_CompressionMethod: ubyte {
    Deflate = 0
}

static enum IHDR_FilterMethod: ubyte {
    Adaptive = 0
}

static enum IHDR_InterlaceMethod: ubyte {
    NoInterlace    = 0,
    Adam7Interlace = 1
}

struct IHDR {
    align(1): // don't pad this struct so .sizeof works properly
    uint Width;
    uint Height;
    IHDR_BitDepth BitDepth;
    IHDR_ColorType ColorType;
    IHDR_CompressionMethod CompressionMethod;
    IHDR_FilterMethod FilterMethod;
    IHDR_InterlaceMethod InterlaceMethod;
}

// further down the file

File file = File(fname, "r");

// stuff

PngHeaders.IHDR ihdr;
file.rawRead((&ihdr)[0..1]);
writeln(ihdr);
最后一个
writeln
输出:

IHDR(138020665570490880,铸造(IHDR_钻头深度)0,灰度,铸造(IHDR_压缩法)1,铸造(IHDR_过滤器法)34,铸造(IHDR_夹层法)8)

这显然是错误的

我找到了讨论endianness属性的地方,但它还不存在


有没有另一种简单的方法让D将文件(或至少是结构)视为big-endian?我喜欢从文件中读取整个结构的能力,而不必自己读取每个值,因此如果有一种方法可以让我继续这样做,我更愿意这样做。

使用I.e..

所以我实际上更喜欢逐字节读取文件,因为它们中的很多都具有可变长度和长度,所以逐字节执行可以解决这两个问题。(您还可以执行帮助器函数、mixin、属性等,以简化此操作。)

但另一种选择是保持结构与现有结构相同,但编写属性函数来进行转换

struct Header {
    align(1):
    ubyte[4] Width_; // the bytes in the file
    @property int Width() { return bigEndianToNative(Width_); }
    // ditto for the others
   /* snip */
 }
如果你想的话,也许可以做二传。因此,您仍然可以使用rawRead将其清除,但是访问属性可以为您转换


这有优点也有缺点,但我想作为一种选择来回答。

谢谢!这有点糟糕,我不能用structs来做这个。谢谢!我甚至不知道你可以用房地产做这件事。我刚刚写了一个可能是有史以来最丑陋的混音器,但它是可重复使用的,而且很有效。