1 module libd.io.memory;
2 
3 import libd.io.stream;
4 
5 struct MemoryReaderStream
6 {
7     static assert(isStream!MemoryReaderStream);
8 
9     private const(ubyte)[] _data;
10     private size_t  _cursor;
11 
12     nothrow @nogc:
13 
14     this(const ubyte[] data)
15     {
16         this._data = data;
17     }
18 
19     SimpleResult!size_t write(const void[] data)
20     {
21         return typeof(return)(raise("This stream cannot read under any circumstance."));
22     }
23 
24     SimpleResult!size_t read(scope void[] data)
25     {
26         if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
27         auto end = this._cursor + data.length;
28         if(end > this._data.length)
29             end = this._data.length;
30 
31         const amount = end - this._cursor;
32         (cast(ubyte[])data)[0..amount] = this._data[this._cursor..end];
33         this._cursor = end;
34         return typeof(return)(cast(size_t)amount);
35     }
36     
37     bool hasData()
38     {
39         return this._cursor < this._data.length;
40     }
41     
42     bool isOpen()
43     {
44         return this._data !is null;
45     }
46 
47     SimpleResult!size_t getPosition()
48     {
49         if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
50         return typeof(return)(this._cursor);
51     }
52 
53     SimpleResult!void setPosition(size_t position)
54     {
55         import libd.data.format;
56         if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
57         if(position > this._data.length) 
58             return typeof(return)(raise("Cannot set position to {0} as data length is {1}".format(position, this._data.length).value));
59 
60         this._cursor = position;
61         return typeof(return)();
62     }
63 
64     SimpleResult!size_t getSize()
65     {
66         if(!this.isOpen) return typeof(return)(raise("This MemoryReaderStream isn't open."));
67         return typeof(return)(this._data.length);
68     }
69 
70     enum canPosition = true;
71     enum canWrite = false;
72     enum canRead = true;
73 }