1 module cerealed.range;
2 
3 import std.range;
4 
5 template isCerealiserRange(R) {
6     enum isCerealiserRange = isOutputRange!(R, ubyte) &&
7         is(typeof(() { auto r = R(); r.clear(); const(ubyte)[] d = r.data; }));
8 }
9 
10 
11 struct DynamicArrayRange {
12     void put(in ubyte val) nothrow @safe {
13         _bytes ~= val;
14     }
15 
16     void put(in ubyte[] val) nothrow @safe {
17         _bytes ~= val;
18     }
19 
20     const(ubyte)[] data() pure const nothrow @property @safe {
21         return _bytes;
22     }
23 
24     void clear() @trusted {
25         if(_bytes !is null) {
26             _bytes = _bytes[0..0];
27             _bytes.assumeSafeAppend();
28         }
29     }
30 
31 private:
32     ubyte[] _bytes;
33     static assert(isCerealiserRange!DynamicArrayRange);
34 }
35 
36 struct ScopeBufferRange {
37     import cerealed.scopebuffer; //change to std.internal scopebuffer in the future
38     ScopeBuffer!ubyte sbuf;
39 
40     alias sbuf this;
41 
42     this(ubyte[] buf) @trusted {
43         sbuf = ScopeBuffer!ubyte(buf);
44     }
45 
46     ~this() {
47         free;
48     }
49 
50     const(ubyte)[] data() pure const nothrow @property @trusted {
51         return sbuf[];
52     }
53 
54     void clear() @trusted {
55         sbuf.length = 0;
56     }
57 
58     void free() @trusted {
59         sbuf.free();
60     }
61 
62     static assert(isCerealiserRange!ScopeBufferRange);
63 }