Struct 确保D rawRead()是文件中的大端结构
我试图构建一个简单的PNG阅读器,但由于macOS是一个小的endian系统,PNG是一种大端格式,我遇到了一个大问题(至少对我来说,我是D新手) 首先要有一堆代码: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:
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来做这个。谢谢!我甚至不知道你可以用房地产做这件事。我刚刚写了一个可能是有史以来最丑陋的混音器,但它是可重复使用的,而且很有效。