Created
July 16, 2018 12:49
-
-
Save JonMagon/8ca22a6ed69a8ec5f96da6eb64e8accb to your computer and use it in GitHub Desktop.
Reading and writing CUInt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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