1 module utile.binary.streams; 2 import std.mmfile, utile.binary, utile.misc, utile.except; 3 4 struct MemoryStream 5 { 6 this(in void[] data) 7 { 8 _p = cast(ubyte*)data.ptr; 9 _end = _p + data.length; 10 } 11 12 bool read(ubyte[] v) 13 { 14 if (length < v.length) 15 return false; 16 17 v[] = _p[0 .. v.length]; 18 _p += v.length; 19 20 return true; 21 } 22 23 bool read(ref ubyte[] v, size_t len) 24 { 25 if (length < len) 26 return false; 27 28 v = _p[0 .. len].dup; 29 _p += len; 30 31 return true; 32 } 33 34 bool readstr(E)(ref E[] v, size_t maxLen) 35 { 36 auto start = cast(E*)_p; 37 38 auto t = start; 39 auto r = length / E.sizeof; 40 41 for (; r && *t && maxLen; r--, t++, maxLen--) 42 { 43 } 44 45 if (r || !maxLen) 46 { 47 v = start[0 .. t - start].dup; 48 _p = cast(ubyte*)(t + (maxLen ? 1 : 0)); 49 50 return true; 51 } 52 53 return false; 54 } 55 56 bool write(in ubyte[] v) 57 { 58 if (length < v.length) 59 return false; 60 61 _p[0 .. v.length] = v; 62 _p += v.length; 63 64 return true; 65 } 66 67 bool rskip(size_t cnt) 68 { 69 if (length < cnt) 70 return false; 71 72 _p += cnt; 73 return true; 74 } 75 76 bool wskip(size_t cnt) 77 { 78 if (length < cnt) 79 return false; 80 81 _p += cnt; 82 return true; 83 } 84 85 const data() 86 { 87 return _p[0 .. length]; 88 } 89 90 const length() 91 { 92 return _end - _p; 93 } 94 95 private: 96 ubyte* _p, _end; 97 } 98 99 struct AppendStream 100 { 101 bool write(in ubyte[] v) 102 { 103 data ~= v; 104 return true; 105 } 106 107 bool wskip(size_t cnt) 108 { 109 data.length += cnt; 110 return true; 111 } 112 113 const length() 114 { 115 return 0; 116 } 117 118 ubyte[] data; 119 } 120 121 struct LengthCalcStream 122 { 123 bool write(in ubyte[] v) 124 { 125 _written += v.length; 126 return true; 127 } 128 129 bool wskip(size_t cnt) 130 { 131 _written += cnt; 132 return true; 133 } 134 135 const length() 136 { 137 return 0; 138 } 139 140 private: 141 mixin publicProperty!(size_t, `written`); 142 }