68 lines
1.4 KiB
D
68 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;
|
|
}
|
|
|
|
ubyte[] readBytes(Range)(ref Range data, uint count)
|
|
if (isRandomAccessRange!(Unqual!(Range))
|
|
&& is(ElementType!Range == ubyte) && hasSlicing!Range)
|
|
{
|
|
ubyte[] bytes = new ubyte[count];
|
|
|
|
for (auto i = 0; i < count; i++)
|
|
{
|
|
bytes[i] = data.readByte();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
uint readInt(Range)(ref Range data)
|
|
if (isRandomAccessRange!(Unqual!(Range))
|
|
&& is(ElementType!Range == ubyte) && hasSlicing!Range)
|
|
{
|
|
auto value = littleEndianToNative!uint(data[0 .. 4]);
|
|
data = data[4 .. $];
|
|
return value;
|
|
}
|