1 module yu.tools.buffer.wrapbuffer;
2 
3 import yu.tools.buffer;
4 import yu.bytes;
5 
6 class WrapBuffer : IBuffer
7 {
8 	this(ubyte[] data, size_t writed = 0)
9 	{
10 		_data = data;
11 		_wsize = writed;
12 	}
13 	pragma(inline,true)
14 		void clear()
15 	{
16 		_rsize = 0;
17 		_wsize = 0;
18 	}
19 
20 	override @property bool eof() const
21 	{
22 		return (_rsize >= _wsize);
23 	}
24 	override size_t read(size_t size,scope  void delegate(in ubyte[]) cback)
25 	{
26 		size_t len = _wsize - _rsize;
27 		len = size < len ? size : len;
28 		if (len > 0)
29 			cback(_data[_rsize .. (_rsize + len)]);
30 		_rsize += len;
31 		return len;
32 	}
33 
34 	override size_t write(in ubyte[] dt)
35 	{
36 		import core.stdc.string : memcpy;
37 		size_t len = _data.length - _wsize;
38 		len = dt.length < len ? dt.length : len;
39 		if (len > 0)
40 		{
41 			auto begin = _wsize;
42 			_wsize += len;
43 			ubyte * ptr = cast(ubyte *)(_data.ptr + begin);
44 			memcpy(ptr, dt.ptr, len);
45 		}
46 		return len;
47 	}
48 
49 	override size_t set(size_t pos, in ubyte[] data)
50 	{
51 		import core.stdc.string : memcpy;
52 		if(pos >= _wsize || data.length == 0) return 0;
53 		size_t len = _wsize - pos;
54 		len = len > data.length ? data.length : len;
55 		ubyte * ptr = cast(ubyte *)(_data.ptr + pos);
56 		memcpy(ptr, data.ptr, len);
57 		return len;
58 	}
59 
60 	override void rest(size_t size = 0){
61 		_rsize = size;
62 	}
63 
64 	override size_t readPos() {
65 		return _rsize;
66 	}
67 
68 	ubyte[] data()
69 	{
70 		return _data[_rsize .. _wsize];
71 	}
72 
73 	override @property size_t length() const { return _wsize; }
74 	
75 	override size_t readLine(scope void delegate(in ubyte[]) cback) //回调模式,数据不copy
76 	{
77 		if(eof()) return 0;
78 		ubyte[] tdata = _data[_rsize.._wsize];
79 		size_t size = _rsize;
80 		ptrdiff_t index = findCharByte(tdata,cast(ubyte)'\n');
81 		if(index < 0){
82 			_rsize += tdata.length;
83 			cback(tdata);
84 		} else {
85 			_rsize += (index + 1);
86 			size += 1;
87 			if(index > 0){
88 				size_t ts = index -1;
89 				if(_data[ts] == cast(ubyte)'\r') {
90 					index = ts;
91 				}
92 			}
93 			cback(tdata[0..index]);
94 		}
95 
96 		return _rsize - size;
97 	}
98 	
99 	override size_t readAll(scope void delegate(in ubyte[]) cback)
100 	{
101 		if(eof()) return 0;
102 		ubyte[] tdata = _data[_rsize.._wsize];
103 		_rsize = _wsize;
104 		cback(tdata);
105 		return data.length;
106 	}
107 	
108 	override size_t readUtil(in ubyte[] chs, scope void delegate(in ubyte[]) cback)
109 	{
110 		if(eof()) return 0;
111 		ubyte[] tdata = _data[_rsize.._wsize];
112 		size_t size = _rsize;
113 		ptrdiff_t index = findCharBytes(tdata,chs);
114 		if(index < 0){
115 			_rsize += tdata.length;
116 			cback(tdata);
117 		} else {
118 			_rsize += (index + chs.length);
119 			size += chs.length;
120 			cback(tdata[0..index]);
121 		}
122 		return _rsize - size;
123 	}
124 
125 private:
126 	ubyte[] _data;
127 	size_t _rsize = 0;
128 	size_t _wsize = 0;
129 }
130 
131 unittest
132 {
133 	import std.stdio;
134 	ubyte[] __buffer = new ubyte[4096];
135 	string data = "hello world. hello world.\n hello world. hello world. hello \nworld. hello\r\n world. hello world. hello world. hello world. hello world. hello world. hello world. hello world.";
136 	auto buf = new WrapBuffer(__buffer);
137 	writeln("buffer write :", buf.write(cast(ubyte[]) data));
138 	writeln("buffer  size:", buf.length);
139 	assert(buf.length == data.length);
140 	ubyte[] dt;
141 	dt.length = 13;
142 	writeln("buffer read size =", buf.read(13,(in ubyte[] data2){dt[] = data2[];}));
143 	writeln("buffer read data =", cast(string) dt);
144 
145 	
146 	buf.rest();
147 	string datat;
148 	buf.readLine((in ubyte[] data2){datat ~= (cast(string)data2);});
149 	writeln(datat);
150 	assert(datat == "hello world. hello world.");	
151 
152 }