D Lang: std.bitmanip 将数据读入struct

D Lang: std.bitmanip read data into struct

我找到了这个函数:https://dlang.org/phobos/std_bitmanip.html#.read

T read(T, Endian endianness = Endian.bigEndian, R)(ref R range)
    if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const(ubyte))); 

但是我不明白如何将数据读入结构。

是否可以使用这样的东西?

struct MyType {
    uint value;        

    this(ubyte act) { // wtf.peek!ubyte();
        switch (act) {
            case 0:
                value = wtf.read!uint();
                break;
            case 1:
                wtf.read!ubyte(); // seek
                value = wtf.read!uint() | 0x7;
                break;
            ...
        }
    }
}
...
buffer.read!MyType();

我不完全理解您的代码结构 - wtf 来自哪里?

在我看来,您误解了要传递给 MyType 的构造函数的内容 - 您可能应该将范围传递给它,然后使用 std.bitmanip.read 读取它。不过,我可能误解了您的代码:

import std.range;
import std.bitmanip;

struct MyType {
    uint value;
    this(R)(auto ref R rng) if (isInputRange!R && is(ElementType!R : const(ubyte)))
    {
        auto act = rng.peek!ubyte;
        switch (act) {
            case 0:
                value = rng.read!uint;
                break;
            case 1:
                rng.read!ubyte;
                value = rng.read!uint;
                break;
            // ...
            default: assert(0);
        }
    }
}

unittest {
    ubyte[] buffer = [0x01,0x12,0x34,0x56,0x78];
    auto a = MyType(buffer);
    assert(buffer.length == 0);
    assert(a.value == 0x12345678);
}

如您所见,我只是调用 MyType 的构造函数并将数组作为参数,但如果您确实需要,也可以将其包装在 read 函数中:

alias read = std.bitmanip.read;
T read(T : MyType, R)(auto ref R range)
if (isInputRange!R && is(ElementType!R : const(ubyte)))
{
    return MyType(range);
}
unittest {
    ubyte[] buffer = [0x01,0x12,0x34,0x56,0x78];
    auto a = buffer.read!MyType;
    assert(buffer.length == 0);
    assert(a.value == 0x12345678);
}