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 }