1 module asdf.outputarray; 2 3 import asdf.asdf; 4 5 version(X86_64) 6 version = X86_Any; 7 else 8 version(X86) 9 version = X86_Any; 10 11 package struct OutputArray 12 { 13 import core.memory; 14 15 ubyte[] data; 16 size_t shift; 17 18 pure: 19 20 auto result() 21 { 22 return Asdf(data[0 .. shift]); 23 } 24 25 this(size_t initialLength) 26 { 27 assert(initialLength >= 32); 28 const len = initialLength % 16 ? (initialLength + 16) / 16 * 16 : initialLength; 29 data = cast(ubyte[]) GC.malloc(len)[0 .. len]; 30 } 31 32 size_t skip(size_t len) 33 { 34 auto ret = shift; 35 shift += len; 36 if(shift > data.length) 37 extend; 38 return ret; 39 } 40 41 void put(in char[] str) 42 { 43 size_t newShift = shift + str.length; 44 if(newShift > data.length) 45 extend(str.length); 46 data[shift .. newShift] = cast(ubyte[])str; 47 //assert(newShift > shift); 48 shift = newShift; 49 } 50 51 void put1(ubyte b) 52 { 53 put1(b, shift); 54 shift += 1; 55 } 56 57 void put(char b) 58 { 59 put1(cast(ubyte)b); 60 } 61 62 void put4(uint b) 63 { 64 put4(b, shift); 65 shift += 4; 66 } 67 68 void put1(ubyte b, size_t sh) 69 { 70 assert(sh <= data.length); 71 if(sh == data.length) 72 extend; 73 data[sh] = b; 74 } 75 76 void put4(uint b, size_t sh) 77 { 78 immutable newShift = sh + 4; 79 if(newShift > data.length) 80 extend; 81 version (X86_Any) 82 *cast(uint*) (data.ptr + sh) = b; 83 else 84 *cast(ubyte[4]*) (data.ptr + sh) = cast(ubyte[4]) cast(uint[1]) [b]; 85 } 86 87 void extend(size_t len) 88 { 89 size_t length = (data.length) * 2 + len; 90 void[] t = data; 91 t = GC.realloc(t.ptr, length)[0 .. length]; 92 data = cast(ubyte[])t; 93 } 94 95 void extend() 96 { 97 size_t length = (data.length) * 2; 98 void[] t = data; 99 t = GC.realloc(t.ptr, length)[0 .. length]; 100 data = cast(ubyte[])t; 101 } 102 }