cm3d2tool/source/cm3d2/util.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;
}