1 module collie.codec.http.httpwritebuffer; 2 3 import kiss.buffer; 4 import kiss.net.struct_; 5 import kiss.event.task; 6 7 @trusted abstract class HttpWriteBuffer : StreamWriteBuffer, WriteBuffer 8 { 9 override abstract size_t write(in ubyte[] data); 10 11 override abstract size_t set(size_t pos, in ubyte[] data); 12 13 override abstract @property size_t length() const; 14 15 void setFinalTask(AbstractTask task){ 16 _task = task; 17 } 18 19 override void doFinish() nothrow{ 20 if(_task !is null) 21 _task.job(); 22 } 23 private: 24 AbstractTask _task; 25 } 26 27 class HTTPByteBuffer(Alloc) : HttpWriteBuffer 28 { 29 import kiss.bytes; 30 import kiss.container.Vector; 31 import std.experimental.allocator.common; 32 33 alias BufferStore = Vector!(ubyte,Alloc); 34 35 static if (stateSize!(Alloc) != 0) 36 { 37 this(Alloc alloc) 38 { 39 _store = BufferStore(1024,alloc); 40 } 41 42 @property allocator(){return _store.allocator;} 43 44 } else { 45 this() 46 { 47 _store = BufferStore(1024); 48 } 49 } 50 51 ~this(){ 52 destroy(_store); 53 } 54 55 override size_t write(in ubyte[] data) 56 { 57 size_t len = _store.length; 58 ()@trusted{_store.insertBack(cast(ubyte[])data);}(); 59 return _store.length - len; 60 } 61 62 override size_t set(size_t pos, in ubyte[] data) 63 { 64 import core.stdc..string : memcpy; 65 if(pos >= _store.length || data.length == 0) return 0; 66 size_t len = _store.length - pos; 67 len = len > data.length ? data.length : len; 68 ()@trusted{ 69 ubyte * ptr = cast(ubyte *)(_store.ptr + pos); 70 memcpy(ptr, data.ptr, len); 71 }(); 72 73 return len; 74 } 75 76 void rest(size_t size){ 77 _rsize = size; 78 } 79 80 override const(ubyte)[] sendData() nothrow 81 { 82 size_t len = _rsize + 4096;// 一次最大发送4K 83 len = _store.length < len ? _store.length : len; 84 auto _data = _store.data(); 85 return _data[_rsize .. len]; 86 } 87 88 override bool popSize(size_t size) nothrow 89 { 90 _rsize += size; 91 return _rsize >= _store.length; 92 } 93 94 override void doFinish() nothrow{ 95 _store.clear(); 96 super.doFinish(); 97 } 98 99 override size_t length() const{ 100 return _store.length; 101 } 102 private: 103 BufferStore _store; 104 size_t _rsize = 0; 105 }