62 lines
1.4 KiB
D
62 lines
1.4 KiB
D
module cm3d2.util;
|
|
|
|
import std.bitmanip;
|
|
import std.range;
|
|
import std.traits;
|
|
|
|
ubyte readByte(Range)(ref Range data)
|
|
if (isRandomAccessRange!(Unqual!Range)
|
|
&& is(ElementType!Range == ubyte) && hasSlicing!Range)
|
|
{
|
|
auto value = data[0];
|
|
data = data[1 .. $];
|
|
return value;
|
|
}
|
|
|
|
Range readBytes(Range)(ref Range data, size_t count)
|
|
if (isRandomAccessRange!(Unqual!Range)
|
|
&& is(ElementType!Range == ubyte) && hasSlicing!Range)
|
|
{
|
|
auto bytes = data[0 .. count];
|
|
data = data[count .. $];
|
|
return bytes;
|
|
}
|
|
|
|
string readString(Range)(ref Range data)
|
|
if (isRandomAccessRange!(Unqual!Range)
|
|
&& is(ElementType!Range == ubyte) && hasSlicing!Range)
|
|
{
|
|
auto length = 0;
|
|
ubyte[] chars;
|
|
|
|
while (true)
|
|
{
|
|
auto lengthByte = data.readByte();
|
|
|
|
if (length != 0 && lengthByte < 128)
|
|
{
|
|
break;
|
|
}
|
|
|
|
length = length << 8 | lengthByte;
|
|
|
|
if (lengthByte < 128)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
auto value = cast(string) data[0 .. length];
|
|
data = data[length .. $];
|
|
|
|
return value;
|
|
}
|
|
|
|
Integer readInteger(Integer, Range)(ref Range data)
|
|
if (isRandomAccessRange!(Unqual!Range) && is(ElementType!Range == ubyte) && hasSlicing!Range)
|
|
{
|
|
auto value = littleEndianToNative!Integer(data[0 .. Integer.sizeof]);
|
|
data = data[Integer.sizeof .. $];
|
|
return value;
|
|
}
|