Skip to content

Instantly share code, notes, and snippets.

@JonMagon
Created July 16, 2018 12:49
Show Gist options
  • Save JonMagon/8ca22a6ed69a8ec5f96da6eb64e8accb to your computer and use it in GitHub Desktop.
Save JonMagon/8ca22a6ed69a8ec5f96da6eb64e8accb to your computer and use it in GitHub Desktop.
Reading and writing CUInt
import std.bitmanip;
import std.range.primitives;
alias read = std.bitmanip.read;
uint read(T : CUInt, R)(auto ref R range)
if (isInputRange!R && is(ElementType!R : const(ubyte))) {
return CUInt(range).value;
}
alias append = std.bitmanip.append;
void append(T : CUInt, R)(R range, uint value)
if (isOutputRange!(R, ubyte)) {
CUInt(range, value);
}
struct CUInt {
uint value;
this(R)(auto ref R rng) if (isInputRange!R && is(ElementType!R : const(ubyte))) {
auto code = rng.peek!ubyte;
switch (code & 0xE0) {
case 0xE0:
rng.read!ubyte;
value = rng.read!uint;
break;
case 0xC0:
value = rng.read!uint & 0x1FFFFFFF;
break;
case 0x80:
case 0xA0:
value = rng.read!ushort & 0x3FFF;
break;
default:
value = rng.read!ubyte;
break;
}
}
this(R)(R rng, int val) if (isOutputRange!(R, ubyte)) {
if (val <= 0x7F)
rng.append!ubyte(*cast(ubyte*) &val);
else if (val < 0x3FFF) {
auto val_ = *cast(ushort*) &val;
val_ |= 0x8000;
rng.append!ushort(val_);
}
else if (val <= 0x1FFFFFFF)
rng.append!uint(val | 0xC0000000);
else {
rng.append!ubyte(0xE0);
rng.append!uint(val);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment