1 /* 2 * Collie - An asynchronous event-driven network framework using Dlang development 3 * 4 * Copyright (C) 2015-2017 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: putao's Dlang team 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 module collie.codec.mqtt.bytebuf; 12 13 import std.stdio; 14 import std.conv; 15 import core.memory; 16 import std.algorithm : swap; 17 import kiss.container.Vector; 18 19 import core.stdc..string; 20 21 //default big end 22 23 final class ByteBuf 24 { 25 alias BufferVector = Vector!(ubyte); 26 27 this() 28 { 29 _readIndex = _writeIndex = 0; 30 } 31 32 this(ubyte[] data ) 33 { 34 _readIndex = _writeIndex = 0; 35 writeBytes(data); 36 } 37 38 ~this() 39 { 40 clear(); 41 } 42 43 void reset() 44 { 45 if(_buffer.length > 0) 46 { 47 _readIndex = 0; 48 _writeIndex = cast(int)_buffer.length; 49 } 50 } 51 52 ByteBuf readSlice(int len) 53 { 54 if(len > _buffer.length || len + _readIndex > _buffer.length) 55 { 56 throw new Exception("IndexOutOfBoundsException"); 57 } 58 ubyte[] da; 59 for(int i= 0 ; i < len;i++) 60 { 61 da ~= _buffer[_readIndex+i]; 62 } 63 _readIndex += len; 64 return new ByteBuf(da); 65 } 66 67 int readerIndex() 68 { 69 return _readIndex; 70 } 71 72 int writerIndex() 73 { 74 return _writeIndex; 75 } 76 77 // to utf-8 string 78 string toString(int index,int len) 79 { 80 if(len > _buffer.length || index + len > _buffer.length) 81 { 82 writeln("IndexOutOfBoundsException -->readindex: ",index,"read len : ",len,"buf len :",_buffer.length); 83 throw new Exception("IndexOutOfBoundsException"); 84 } 85 ubyte[] da; 86 for(int i= 0 ; i < len;i++) 87 { 88 da ~= _buffer[index+i]; 89 } 90 //writeln("bytebuf tostring----> ",da," ",cast(string)(cast(byte[])da)); 91 return cast(string)(da); 92 } 93 94 void skipBytes(int skipsize) 95 { 96 if(_readIndex + skipsize > _writeIndex) 97 { 98 writeln("_readInxde : ",_readIndex,"skipsize :",skipsize,"_writeIndex : ",_writeIndex); 99 throw new Exception("IndexOutOfBoundsException"); 100 } 101 _readIndex += skipsize; 102 } 103 104 short readUnsignedByte() 105 { 106 if(_readIndex > _writeIndex || _readIndex < 0) 107 { 108 throw new Exception("buf cannot read"); 109 } 110 111 short va = cast(short)(_buffer[_readIndex] & 0xff); 112 _readIndex++; 113 return va; 114 } 115 116 ubyte readByte() 117 { 118 if(_readIndex > _writeIndex || _readIndex < 0) 119 { 120 throw new Exception("buf cannot read"); 121 } 122 123 ubyte va = cast(ubyte)_buffer[_readIndex]; 124 _readIndex++; 125 return va; 126 } 127 128 void writeByte(int value) 129 { 130 ubyte data = cast(ubyte)(value & 0xff); 131 writeByte(data); 132 133 if(_readIndex < 0) 134 _readIndex = 0; 135 } 136 137 void writeByte(ubyte value) 138 { 139 _buffer.insertBack(value); 140 _writeIndex++; 141 if(_readIndex < 0) 142 _readIndex = 0; 143 } 144 145 void writeShort(int value) 146 { 147 ubyte d1 = cast(ubyte)((value >> 8) & 0xff); 148 writeByte(d1); 149 ubyte d2 = cast(ubyte)(value & 0xff); 150 writeByte(d2); 151 152 if(_readIndex < 0) 153 _readIndex = 0; 154 } 155 156 void writeBytes(ubyte[] value) 157 { 158 _buffer.insertBack(value); 159 _writeIndex += value.length; 160 if(_readIndex < 0) 161 _readIndex = 0; 162 } 163 164 void writeBytes(ubyte[] value, int srcIndex, int length ) 165 { 166 ubyte[] data = value[srcIndex .. srcIndex+length]; 167 //writeln("writeBytes ---> : ",data); 168 _buffer.insertBack(data); 169 _writeIndex += length; 170 if(_readIndex < 0) 171 _readIndex = 0; 172 } 173 174 ubyte[] data() 175 { 176 return _buffer.data().dup; 177 } 178 179 pragma(inline, true) final const @property size_t length() 180 { 181 return _buffer.length; 182 } 183 184 // pragma(inline) void opAssign( ByteBuf s) 185 // { 186 // this._readIndex = s._readIndex; 187 // this._writeIndex = s._writeIndex; 188 // this._buffer = s._buffer.dup; 189 // } 190 191 192 @property void clear() 193 { 194 _buffer.clear(); 195 _readIndex = _writeIndex = 0; 196 //logDebug("\n\tclear()!!! \n"); 197 } 198 private: 199 BufferVector _buffer ; 200 int _readIndex; 201 int _writeIndex; 202 } 203