1 /* 2 * This file was automatically generated by sel-utils and 3 * released under the MIT License. 4 * 5 * License: https://github.com/sel-project/sel-utils/blob/master/LICENSE 6 * Repository: https://github.com/sel-project/sel-utils 7 */ 8 9 module sul.utils.var; 10 11 import std.traits : isNumeric, isIntegral, isSigned, isUnsigned, Unsigned; 12 13 struct var(T) if(isNumeric!T && isIntegral!T && T.sizeof > 1) { 14 15 alias U = Unsigned!T; 16 17 public static immutable U MASK = U.max - 0x7F; 18 public static immutable size_t MAX_BYTES = T.sizeof * 8 / 7 + (T.sizeof * 8 % 7 == 0 ? 0 : 1); 19 public static immutable size_t RIGHT_SHIFT = (T.sizeof * 8) - 1; 20 21 public static pure nothrow @safe ubyte[] encode(T value) { 22 ubyte[] buffer; 23 static if(isUnsigned!T) { 24 U unsigned = value; 25 } else { 26 U unsigned; 27 if(value >= 0) { 28 unsigned = cast(U)(value << 1); 29 } else if(value < 0) { 30 unsigned = cast(U)((-value << 1) - 1); 31 } 32 } 33 while((unsigned & MASK) != 0) { 34 buffer ~= unsigned & 0x7F | 0x80; 35 unsigned >>>= 7; 36 } 37 buffer ~= unsigned & 0xFF; 38 return buffer; 39 } 40 41 public static pure nothrow @trusted T decode(ubyte[] buffer, size_t index=0) { 42 return decode(buffer, &index); 43 } 44 45 public static pure nothrow @safe T decode(ubyte[] buffer, size_t* index) { 46 if(buffer.length <= *index) return T.init; 47 U unsigned = 0; 48 size_t j, k; 49 do { 50 k = buffer[*index]; 51 unsigned |= cast(U)(k & 0x7F) << (j++ * 7); 52 } while(++*index < buffer.length && j < MAX_BYTES && (k & 0x80) != 0); 53 static if(isUnsigned!T) { 54 return unsigned; 55 } else { 56 T value = unsigned >> 1; 57 if(unsigned & 1) { 58 value++; 59 return -value; 60 } else { 61 return value; 62 } 63 } 64 } 65 66 public static pure nothrow @trusted T fromBuffer(ref ubyte[] buffer) { 67 size_t index = 0; 68 auto ret = decode(buffer, &index); 69 buffer = buffer[index..$]; 70 return ret; 71 } 72 73 public enum stringof = "var" ~ T.stringof; 74 75 } 76 77 alias varshort = var!short; 78 79 alias varushort = var!ushort; 80 81 alias varint = var!int; 82 83 alias varuint = var!uint; 84 85 alias varlong = var!long; 86 87 alias varulong = var!ulong; 88