我要从​​大的二进制​​读取中​​解析小字段​​,用​​模板​​时无法​​组合​​有些操作.

import std.bitmanip, std.system;
ubyte[8192] data;

ubyte[] temp = data[4..6];
ushort us = temp.read!(ushort, Endian.bigEndian);
//上面工作,下面不行.
//为了可读,内部提供默认字节序.
import std.bitmanip, std.system;
ubyte[8192] data;

ushort us = data[4..6].read!(ushort, Endian.bigEndian);

​read()​​用来​​步进​​给定​​缓冲区​​.这样下一个​​read()​​操作很方便,因为语义将是"读个​​ushort​​然后读取​​int"​​等.并且​​read()​​会消耗缓冲区.

要按照​​read()​​方式玩,首先想到​​读​​原始数据进​​存储​​并定义区间(下面数据)供​​read()​​消耗.

但是,它需要通过​​对切片是非常快速​​的,例如​​dropExactly()​​来跳过字节:

void main() {
import std.bitmanip, std.system;
ubyte[8192] storage;
auto data = storage[];

import std.range;
data.dropExactly(4);

ushort us = data.read!(ushort, Endian.bigEndian);
// 数据准备好,用下个来读了
}

或者写​​复制​​​来取​​切片​​​的包装器,这样​​read()​​​消费​​参数​​​而非​​右值​​.

import std.system;

// 与read()唯一不同,删除了'ref':

auto readFrom(T, Endian endianness = Endian.bigEndian, R)(R range) {
import std.bitmanip;
return range.read!(ushort, endianness);
}

void main() {
import std.bitmanip, std.system;
ubyte[8192] data;

ushort us = data[4..6].readFrom!(ushort, Endian.bigEndian);
}

不错:

auto read(T, Endian E = Endian.bigEndian, R)
(R range) {
import bop = std.bitmanip;
return bop.read!(T, E)(range);
}//仍为读.不用`readFrom`

void main() {
import std.system;

ubyte[8] d = [ 0xFF, 0xFF, 0xFF, 0xFF,
0xAA, 0xAA, 0xFF, 0xFF ];
ushort us = d[4..6].read!ushort;
assert(us == 0xAAAA);
}