1 module yu.tools.buffer.sectionbuffer; 2 3 import yu.tools.buffer; 4 import yu.bytes; 5 import std.experimental.allocator.common; 6 import std.algorithm : swap; 7 import core.stdc.string; 8 9 @trusted final class SectionBuffer(Alloc) : IBuffer 10 { 11 import yu.container.vector; 12 alias BufferVector = Vector!(ubyte[], Alloc, false); 13 14 static if (stateSize!(Alloc) != 0) 15 { 16 alias ALLOC = Alloc; 17 this(uint sectionSize, Alloc alloc) 18 { 19 _alloc = clloc; 20 _sectionSize = sectionSize; 21 _buffer = BufferVector(4, alloc); 22 _buffer.destroyFun = &destroyBuffer; 23 } 24 25 @property allocator() 26 { 27 return _store.allocator; 28 } 29 30 private Alloc _alloc; 31 } 32 else 33 { 34 alias ALLOC = typeof(Alloc.instance); 35 this(uint sectionSize) 36 { 37 _sectionSize = sectionSize; 38 _buffer = BufferVector(4); 39 _buffer.destroyFun = &destroyBuffer; 40 } 41 42 alias _alloc = Alloc.instance; 43 } 44 45 static void destroyBuffer(ref ALLOC alloc, ref ubyte[] data) nothrow{ 46 import std.exception; 47 if(data.length > 0) 48 collectException( _alloc.deallocate(data)); 49 } 50 51 void reserve(size_t size) 52 { 53 assert(size > 0); 54 size_t sec_size = size / _sectionSize; 55 if (sec_size < _buffer.length) 56 { 57 _buffer.removeBack(_buffer.length - sec_size); 58 } 59 else if (_buffer.length < sec_size) 60 { 61 size_t a_size = sec_size - _buffer.length; 62 for (size_t i = 0; i < a_size; ++i) 63 { 64 _buffer.insertBack(cast(ubyte[]) _alloc.allocate(_sectionSize)); //new ubyte[_sectionSize]);// 65 } 66 } 67 size_t lsize = size - (_buffer.length * _sectionSize); 68 _buffer.insertBack(cast(ubyte[]) _alloc.allocate(lsize)); //new ubyte[lsize]); 69 _rSize = 0; 70 _wSize = 0; 71 } 72 73 size_t maxSize() 74 { 75 if (_buffer.empty()) 76 return size_t.max; 77 size_t leng = _buffer[_buffer.length - 1].length; 78 if (leng == _sectionSize) 79 return size_t.max; 80 else 81 { 82 return (_buffer.length - 1) * _sectionSize + leng; 83 } 84 } 85 86 @property void clearWithMemory() 87 { 88 _buffer.clear(); 89 90 _rSize = 0; 91 _wSize = 0; 92 } 93 94 pragma(inline) @property void clear() 95 { 96 if (maxSize() != size_t.max) 97 { 98 _buffer.removeBack(); 99 } 100 _rSize = 0; 101 _wSize = 0; 102 } 103 104 pragma(inline) size_t swap(ref BufferVector uarray) 105 { 106 auto size = _wSize; 107 .swap(uarray, _buffer); 108 _rSize = 0; 109 _wSize = 0; 110 return size; 111 } 112 113 override @property bool eof() const 114 { 115 return isEof; 116 } 117 118 override void rest(size_t size = 0) 119 { 120 _rSize = size; 121 } 122 123 override @property size_t length() const 124 { 125 return _wSize; 126 } 127 128 pragma(inline, true) @property size_t stectionSize() 129 { 130 return _sectionSize; 131 } 132 133 pragma(inline) size_t read(ubyte[] data) 134 { 135 size_t rlen = 0; 136 return read(data.length, delegate(in ubyte[] dt) { 137 auto len = rlen; 138 rlen += dt.length; 139 data[len .. rlen] = dt[]; 140 141 }); 142 143 } 144 145 override size_t read(size_t size, scope void delegate(in ubyte[]) cback) //回调模式,数据不copy 146 { 147 size_t len = _wSize - _rSize; 148 size_t maxlen = size < len ? size : len; 149 size_t rcount = readCount(); 150 size_t rsite = readSite(); 151 size_t rlen = 0, tlen; 152 while (rcount < _buffer.length) 153 { 154 ubyte[] by = cast(ubyte[])(_buffer[rcount]); 155 tlen = maxlen - rlen; 156 len = by.length - rsite; 157 if (len >= tlen) 158 { 159 cback(by[rsite .. (tlen + rsite)]); 160 rlen += tlen; 161 _rSize += tlen; 162 break; 163 } 164 else 165 { 166 cback(by[rsite .. $]); 167 _rSize += len; 168 rlen += len; 169 rsite = 0; 170 ++rcount; 171 } 172 } 173 //_rSize += maxlen; 174 return maxlen; 175 } 176 177 override size_t write(in ubyte[] data) 178 { 179 size_t len = maxSize() - _wSize; 180 size_t maxlen = data.length < len ? data.length : len; 181 size_t wcount = writeCount(); 182 size_t wsite = writeSite(); 183 size_t wlen = 0, tlen; 184 size_t maxSize = maxSize; 185 while (_wSize < maxSize) 186 { 187 if (wcount == _buffer.length) 188 { 189 _buffer.insertBack(cast(ubyte[]) _alloc.allocate(_sectionSize)); //new ubyte[_sectionSize]);// 190 } 191 ubyte[] by = cast(ubyte[])_buffer[wcount]; 192 tlen = maxlen - wlen; 193 len = by.length - wsite; 194 if (len >= tlen) 195 { 196 by[wsite .. (wsite + tlen)] = data[wlen .. (wlen + tlen)]; 197 break; 198 } 199 else 200 { 201 by[wsite .. (wsite + len)] = data[wlen .. (wlen + len)]; 202 wlen += len; 203 wsite = 0; 204 ++wcount; 205 } 206 } 207 _wSize += maxlen; 208 return maxlen; 209 } 210 211 override size_t set(size_t pos, in ubyte[] data) 212 { 213 import core.stdc.string : memcpy; 214 if(pos >= _wSize || data.length == 0) return 0; 215 size_t len = _wSize - pos; 216 len = len > data.length ? data.length : len; 217 auto sect = pos / _sectionSize; 218 auto ssite = pos % _sectionSize; 219 ubyte[] by = cast(ubyte[])_buffer[sect]; 220 if(ssite + len < by.length){ 221 ubyte * ptr = by.ptr + ssite; 222 memcpy(ptr, data.ptr, len); 223 } else { 224 auto tlen = by.length - ssite; 225 ubyte * ptr = by.ptr + ssite; 226 memcpy(ptr, data.ptr, tlen); 227 by = cast(ubyte[])_buffer[sect + 1]; 228 memcpy(by.ptr,(data.ptr + tlen),(len -tlen)); 229 } 230 return len; 231 } 232 233 /* 234 * 会自动跳过找到的\r\n字段 235 **/ 236 override size_t readLine(scope void delegate(in ubyte[]) cback) //回调模式,数据不copy 237 { 238 if (isEof()) 239 return 0; 240 size_t size = _rSize; 241 size_t wsite = writeSite(); 242 size_t wcount = writeCount(); 243 ubyte[] byptr, by; 244 while (!isEof()) 245 { 246 size_t rcount = readCount(); 247 size_t rsite = readSite(); 248 by = _buffer[rcount]; 249 if (rcount == wcount) 250 { 251 byptr = by[rsite .. wsite]; 252 } 253 else 254 { 255 byptr = by[rsite .. $]; 256 } 257 ptrdiff_t site = findCharByte(byptr, cast(ubyte) '\n'); 258 if (site < 0) 259 { 260 cback(byptr); 261 rsite = 0; 262 ++rcount; 263 _rSize += byptr.length; 264 } 265 else 266 { 267 auto tsize = (_rSize + site); 268 if (site > 0) 269 { 270 size_t ts = site - 1; 271 if (byptr[ts] == cast(ubyte) '\r') 272 { 273 site = ts; 274 } 275 } 276 cback(byptr[0 .. site]); 277 278 _rSize = tsize + 1; 279 size += 1; 280 break; 281 } 282 283 } 284 return _rSize - size; 285 } 286 287 override size_t readAll(scope void delegate(in ubyte[]) cback) //回调模式,数据不copy 288 { 289 size_t maxlen = _wSize - _rSize; 290 size_t rcount = readCount(); 291 size_t rsite = readSite(); 292 size_t wcount = writeCount(); 293 size_t wsize = writeSite(); 294 ubyte[] rbyte; 295 while (rcount <= wcount && !isEof()) 296 { 297 ubyte[] by = _buffer[rcount]; 298 if (rcount == wcount) 299 { 300 rbyte = by[rsite .. wsize]; 301 } 302 else 303 { 304 rbyte = by[rsite .. $]; 305 } 306 cback(rbyte); 307 _rSize += rbyte.length; 308 rsite = 0; 309 ++rcount; 310 } 311 return _wSize - _rSize; 312 } 313 314 /* 315 * 会自动跳过找到的data字段 316 **/ 317 override size_t readUtil(in ubyte[] data, scope void delegate(in ubyte[]) cback) //data.length 必须小于分段大小! 318 { 319 if (data.length == 0 || isEof() || data.length >= _sectionSize) 320 return 0; 321 auto ch = data[0]; 322 323 size_t size = _rSize; 324 size_t wsite = writeSite(); 325 size_t wcount = writeCount(); 326 ubyte[] byptr, by; 327 while (!isEof()) 328 { 329 size_t rcount = readCount(); 330 size_t rsite = readSite(); 331 by = _buffer[rcount]; 332 if (rcount == wcount) 333 { 334 byptr = by[rsite .. wsite]; 335 } 336 else 337 { 338 byptr = by[rsite .. $]; 339 } 340 ptrdiff_t site = findCharByte(byptr, ch); 341 if (site == -1) 342 { 343 cback(byptr); 344 rsite = 0; 345 ++rcount; 346 _rSize += byptr.length; 347 } 348 else 349 { 350 auto tsize = (_rSize + site); 351 size_t i = 1; 352 size_t j = tsize + 1; 353 for (; i < data.length && j < _wSize; ++i, ++j) 354 { 355 if (data[i] != this[j]) 356 { 357 cback(byptr[0 .. site + 1]); 358 _rSize = tsize + 1; 359 goto next; //没找对,进行下次查找 360 } 361 } //循环正常执行完毕,表示 362 cback(byptr[0 .. site]); 363 _rSize = tsize + data.length; 364 size += data.length; 365 break; 366 367 next: 368 continue; 369 } 370 } 371 return (_rSize - size); 372 } 373 374 pragma(inline) ref ubyte opIndex(size_t i) 375 { 376 assert(i < _wSize); 377 size_t count = i / _sectionSize; 378 size_t site = i % _sectionSize; 379 return _buffer[count][site]; 380 } 381 382 pragma(inline, true) @property readSize() const 383 { 384 return _rSize; 385 } 386 387 override size_t readPos() 388 { 389 return _rSize; 390 } 391 392 pragma(inline, true) @property readCount() const 393 { 394 return _rSize / _sectionSize; 395 } 396 397 pragma(inline, true) @property readSite() const 398 { 399 return _rSize % _sectionSize; 400 } 401 402 pragma(inline, true) @property writeCount() const 403 { 404 return _wSize / _sectionSize; 405 } 406 407 pragma(inline, true) @property writeSite() const 408 { 409 return _wSize % _sectionSize; 410 } 411 412 private: 413 pragma(inline, true) @property bool isEof() const 414 { 415 return (_rSize >= _wSize); 416 } 417 418 size_t _rSize; 419 size_t _wSize; 420 size_t _sectionSize; 421 BufferVector _buffer; 422 } 423 424 unittest 425 { 426 import std.stdio; 427 import std.experimental.allocator.mallocator; 428 429 string data = "hello world. hello world. hello world. hello world. hello world. hello world. hello world. hello world. hello world. hello world. hello world. hello world. hello world."; 430 auto buf = new SectionBuffer!Mallocator(5); 431 buf.reserve(data.length); 432 writeln("buffer max size:", buf.maxSize()); 433 writeln("buffer size:", buf.length); 434 writeln("buffer write :", buf.write(cast(ubyte[]) data)); 435 writeln("buffer size:", buf.length); 436 ubyte[] dt; 437 dt.length = 13; 438 writeln("buffer read size =", buf.read(dt)); 439 writeln("buffer read data =", cast(string) dt); 440 441 writeln("\r\n"); 442 443 auto buf2 = new SectionBuffer!Mallocator(3); 444 writeln("buffer2 max size:", buf2.maxSize()); 445 writeln("buffer2 size:", buf2.length); 446 writeln("buffer2 write :", buf2.write(cast(ubyte[]) data)); 447 writeln("buffer2 size:", buf2.length); 448 ubyte[] dt2; 449 dt2.length = 13; 450 writeln("buffer2 read size =", buf2.read(dt2)); 451 writeln("buffer2 read data =", cast(string) dt2); 452 453 writeln("\r\nswitch \r\n"); 454 455 auto tary = SectionBuffer!Mallocator.BufferVector(); 456 buf.swap(tary); 457 writeln("buffer size:", buf.length); 458 writeln("buffer max size:", buf.maxSize()); 459 writeln("Array!(ubyte[]) length : ", tary.length); 460 size_t len = tary.length < 5 ? tary.length : 5; 461 for (size_t i = 0; i < len; ++i) 462 { 463 write("i = ", i); 464 writeln(" ,ubyte[] = ", cast(string) tary[i]); 465 } 466 467 buf.reserve(data.length); 468 writeln("buffer max size:", buf.maxSize()); 469 writeln("buffer size:", buf.length); 470 writeln("buffer write :", buf.write(cast(ubyte[]) data)); 471 writeln("buffer size:", buf.length); 472 writeln("\n 1."); 473 474 /* dt.length = 1; 475 writeln("buffer read size =",buf.read(dt)); 476 writeln("buffer read data =",cast(string)dt);*/ 477 478 data = "ewarwaerewtretr54654654kwjoerjopiwrjeo;jmq;lkwejoqwiurwnblknhkjhnjmq1111dewrewrjmqrtee"; 479 buf = new SectionBuffer!Mallocator(5); 480 // buf.reserve(data.length); 481 writeln("buffer max size:", buf.maxSize()); 482 writeln("buffer size:", buf.length); 483 writeln("buffer write :", buf.write(cast(ubyte[]) data)); 484 writeln("buffer size:", buf.length); 485 486 foreach (i; 0 .. 4) 487 { 488 ubyte[] tbyte; 489 writeln("\n\nbuffer readutil size:", buf.readUtil(cast(ubyte[]) "jmq", 490 delegate(in ubyte[] data) { 491 //writeln("\t data :", cast(string)data); 492 //writeln("\t read size: ", buf._rSize); 493 tbyte ~= data; 494 })); 495 if (tbyte.length > 0) 496 { 497 writeln("\n buffer readutil data:", cast(string) tbyte); 498 writeln("\t _Rread size: ", buf._rSize); 499 writeln("\t _Wread size: ", buf._wSize); 500 } 501 else 502 { 503 writeln("\n buffer readutil data eof"); 504 } 505 } 506 //buf.clear(); 507 //buf2.clear(); 508 writeln("hahah"); 509 destroy(buf); 510 destroy(buf2); 511 }