├── ByteBuffer.as ├── ByteBuffer.html ├── ByteBuffer.js ├── README.md ├── package.json └── test.js /ByteBuffer.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.utils.*; 4 | 5 | /** 6 | * ByteBuffer对应的as版本 7 | * sample code: 8 | //压包操作 9 | var sbuf:ByteBuffer = new ByteBuffer(); 10 | var ba:ByteArray = new ByteArray(); 11 | ba.writeMultiByte('123vstring','utf-8'); 12 | ba.position = 0; 13 | var buffer:ByteArray = sbuf.string('abc123你好')//变长字符串,前两个字节表示长度 14 | .int32(-999).uint32(999).float(-0.5) 15 | .int64(9999999).double(-0.000005).short(32767).ushort(65535) 16 | .byte(255) 17 | .vstring('abcd',5)//定长字符串,不足的字节补0x00 18 | .byteArray(ba,10)//字节数组,不足字节补0x00 19 | .pack();//结尾调用打包方法 20 | 21 | trace(buffer); 22 | 23 | //解包操作 24 | var rbuf:ByteBuffer = new ByteBuffer(buffer); 25 | //解包出来是一个数组 26 | var arr:Array = rbuf.string()//变长字符串,前两个字节表示长度 27 | .int32().uint32().float() 28 | .int64().double().short().ushort() 29 | .byte() 30 | .vstring(null,5)//定长字符串,不足的字节补0x00 31 | .byteArray(null,10)//字节数组,不足字节补0x00 32 | .unpack();//结尾调用解包方法 33 | 34 | trace(arr); 35 | * @author yoyo 2014 https://github.com/play175/ByteBuffer 36 | */ 37 | public class ByteBuffer 38 | { 39 | public static const Type_Byte:int = 1; 40 | public static const Type_Short:int = 2; 41 | public static const Type_UShort:int = 3; 42 | public static const Type_Int32:int = 4; 43 | public static const Type_UInt32:int = 5; 44 | public static const Type_String:int = 6;//变长字符串,前两个字节表示长度 45 | public static const Type_VString:int = 7;//定长字符串 46 | public static const Type_Int64:int = 8; 47 | public static const Type_Float:int = 9; 48 | public static const Type_Double:int = 10; 49 | public static const Type_ByteArray:int = 11; 50 | 51 | 52 | private var _org_buf:ByteArray; 53 | private var _encoding:String = 'utf-8'; 54 | private var _offset:int; 55 | private var _list:Array = []; 56 | private var _endian:String = 'B'; 57 | 58 | public function ByteBuffer(org_buf:ByteArray = null,offset:int = 0) 59 | { 60 | _org_buf = org_buf; 61 | _offset = offset || 0; 62 | setEndian(); 63 | } 64 | 65 | /**指定文字编码**/ 66 | public function encoding (encode:String):ByteBuffer{ 67 | _encoding = encode; 68 | return this; 69 | } 70 | 71 | private function setEndian(ba:ByteArray = null):void 72 | { 73 | if (ba == null) ba = _org_buf; 74 | if (ba)ba.endian = _endian == 'B'?Endian.BIG_ENDIAN:Endian.LITTLE_ENDIAN; 75 | } 76 | 77 | /**指定字节序 为BigEndian**/ 78 | public function bigEndian ():ByteBuffer{ 79 | _endian = 'B'; 80 | setEndian(); 81 | return this; 82 | } 83 | 84 | /**指定字节序 为LittleEndian**/ 85 | public function littleEndian ():ByteBuffer{ 86 | _endian = 'L'; 87 | setEndian(); 88 | return this; 89 | } 90 | 91 | public function byte (val:int = undefined,index:int = undefined):ByteBuffer{ 92 | if (arguments.length == 0) { 93 | _org_buf.position = _offset; 94 | _list.push(_org_buf.readByte()); 95 | _offset+=1; 96 | }else{ 97 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_Byte,d:val,l:1}); 98 | _offset += 1; 99 | } 100 | return this; 101 | } 102 | 103 | public function short (val:int = undefined,index:int = undefined):ByteBuffer{ 104 | if(arguments.length == 0){ 105 | _org_buf.position = _offset; 106 | _list.push(_org_buf.readShort()); 107 | _offset+=2; 108 | }else{ 109 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_Short,d:val,l:2}); 110 | _offset += 2; 111 | } 112 | return this; 113 | } 114 | 115 | public function ushort (val:int = undefined,index:int = undefined):ByteBuffer{ 116 | if(arguments.length == 0){ 117 | _org_buf.position = _offset; 118 | _list.push(_org_buf.readUnsignedShort()); 119 | _offset+=2; 120 | }else{ 121 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_UShort,d:val,l:2}); 122 | _offset += 2; 123 | } 124 | return this; 125 | } 126 | 127 | public function int32 (val:int = undefined,index:int = undefined):ByteBuffer{ 128 | if(arguments.length == 0){ 129 | _org_buf.position = _offset; 130 | _list.push(_org_buf.readInt()); 131 | _offset+=4; 132 | }else{ 133 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_Int32,d:val,l:4}); 134 | _offset += 4; 135 | } 136 | return this; 137 | } 138 | 139 | public function uint32 (val:int = undefined,index:int = undefined):ByteBuffer{ 140 | if(arguments.length == 0){ 141 | _org_buf.position = _offset; 142 | _list.push(_org_buf.readUnsignedInt()); 143 | _offset+=4; 144 | }else{ 145 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_UInt32,d:val,l:4}); 146 | _offset += 4; 147 | } 148 | return this; 149 | } 150 | 151 | /** 152 | * 变长字符串 前2个字节表示字符串长度 153 | **/ 154 | public function string (val:String = undefined,index:int = undefined):ByteBuffer{ 155 | var len:int = 0; 156 | if(!val){ 157 | _org_buf.position = _offset; 158 | len = _org_buf.readUnsignedShort(); 159 | _offset+=2; 160 | _org_buf.position = _offset; 161 | _list.push(_org_buf.readMultiByte(len,_encoding)); 162 | _offset+=len; 163 | }else{ 164 | len = stringByteLen(val); 165 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_String,d:val,l:len}); 166 | _offset += len + 2; 167 | } 168 | return this; 169 | } 170 | 171 | /** 172 | * 定长字符串 val为null时,读取定长字符串(需指定长度len) 173 | **/ 174 | public function vstring (val:String = undefined,len:int = undefined,index:int = undefined):ByteBuffer{ 175 | if(!val){ 176 | _org_buf.position = _offset; 177 | _list.push(_org_buf.readMultiByte(len,_encoding)); 178 | _offset+=len; 179 | }else{ 180 | _list.splice((arguments.length >= 3) ? index : _list.length,0,{t:Type_VString,d:val,l:len}); 181 | _offset += len; 182 | } 183 | return this; 184 | } 185 | 186 | public function int64 (val:Number = undefined,index:int = undefined):ByteBuffer{ 187 | if(arguments.length == 0){ 188 | _org_buf.position = _offset; 189 | _list.push(_org_buf.readDouble()); 190 | _offset+=8; 191 | }else{ 192 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_Int64,d:val,l:8}); 193 | _offset += 8; 194 | } 195 | return this; 196 | } 197 | 198 | public function float (val:Number = undefined,index:int = undefined):ByteBuffer{ 199 | if(arguments.length == 0){ 200 | _org_buf.position = _offset; 201 | _list.push(_org_buf.readFloat()); 202 | _offset+=4; 203 | }else{ 204 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_Float,d:val,l:4}); 205 | _offset += 4; 206 | } 207 | return this; 208 | } 209 | 210 | public function double (val:Number = undefined,index:int = undefined):ByteBuffer{ 211 | if(arguments.length == 0){ 212 | _org_buf.position = _offset; 213 | _list.push(_org_buf.readDouble()); 214 | _offset+=8; 215 | }else{ 216 | _list.splice((arguments.length >= 2) ? index : _list.length,0,{t:Type_Double,d:val,l:8}); 217 | _offset += 8; 218 | } 219 | return this; 220 | } 221 | 222 | /** 223 | * 写入或读取一段字节数组 224 | **/ 225 | public function byteArray (val:ByteArray = undefined,len:int = undefined,index:int = undefined):ByteBuffer{ 226 | var arr:ByteArray; 227 | if(!val){ 228 | _org_buf.position = _offset; 229 | arr = new ByteArray(); 230 | setEndian(arr); 231 | arr.position = 0; 232 | _org_buf.readBytes(arr, 0, len); 233 | _list.push(arr); 234 | _offset+=len; 235 | }else { 236 | //拷贝字节数组 237 | arr = new ByteArray(); 238 | setEndian(arr); 239 | arr.position = 0; 240 | arr.writeBytes(val, val.position, val.bytesAvailable); 241 | arr.position = 0; 242 | _list.splice((arguments.length >= 3) ? index : _list.length,0,{t:Type_ByteArray,d:arr,l:len}); 243 | _offset += len; 244 | } 245 | return this; 246 | } 247 | 248 | /** 249 | * 解包成数据数组 250 | **/ 251 | public function unpack ():Array{ 252 | return _list; 253 | } 254 | 255 | /** 256 | * 打包成二进制,在前面加上2个字节表示包长 257 | **/ 258 | public function packWithHead ():ByteArray { 259 | return pack(true); 260 | } 261 | 262 | /** 263 | * 打包成二进制 264 | * @param ifHead 是否在前面加上2个字节表示包长 265 | **/ 266 | public function pack (ifHead:Boolean = false):ByteArray{ 267 | _org_buf = new ByteArray(); 268 | setEndian(); 269 | _org_buf.position = 0; 270 | if(ifHead){ 271 | _org_buf.writeShort(_offset); 272 | } 273 | var i:int, j:int,end:int; 274 | for (i = 0; i < _list.length; i++) { 275 | switch(_list[i].t){ 276 | case Type_Byte: 277 | _org_buf.writeByte(_list[i].d); 278 | break; 279 | case Type_Short: 280 | _org_buf.writeShort(_list[i].d); 281 | break; 282 | case Type_UShort: 283 | _org_buf.writeShort(_list[i].d); 284 | break; 285 | case Type_Int32: 286 | _org_buf.writeInt(_list[i].d); 287 | break; 288 | case Type_UInt32: 289 | _org_buf.writeUnsignedInt(_list[i].d); 290 | break; 291 | case Type_String: 292 | //前2个字节表示字符串长度 293 | _org_buf.writeShort(_list[i].l); 294 | _org_buf.writeMultiByte(_list[i].d, _encoding); 295 | break; 296 | case Type_VString: 297 | var vlen:int = stringByteLen(_list[i].d);//字符串实际长度 298 | _org_buf.writeMultiByte(_list[i].d, _encoding); 299 | //补齐\0 300 | for(j = _org_buf.position,end = _org_buf.position + (_list[i].l - vlen);j 2 | 3 | 4 | 5 | 6 | ByteBuffer for browser 7 | 8 | 9 | 10 | 426 | 427 | 428 | -------------------------------------------------------------------------------- /ByteBuffer.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ByteBuffer 3 | * yoyo 2012 https://github.com/play175/ByteBuffer 4 | * new BSD Licensed 5 | */ 6 | 7 | var Type_Byte = 1; 8 | var Type_Short = 2; 9 | var Type_UShort = 3; 10 | var Type_Int32 = 4; 11 | var Type_UInt32 = 5; 12 | var Type_String = 6;//变长字符串,前两个字节表示长度 13 | var Type_VString = 7;//定长字符串 14 | var Type_Int64 = 8; 15 | var Type_Float = 9; 16 | var Type_Double = 10; 17 | var Type_ByteArray = 11; 18 | 19 | /* 20 | * 构造方法 21 | * @param org_buf 需要解包的二进制 22 | * @param offset 指定数据在二进制的初始位置 默认是0 23 | */ 24 | var ByteBuffer = function (org_buf,offset) { 25 | 26 | var _org_buf = org_buf; 27 | var _encoding = 'utf8'; 28 | var _offset = offset || 0; 29 | var _list = []; 30 | var _endian = 'B'; 31 | 32 | //指定文字编码 33 | this.encoding = function(encode){ 34 | _encoding = encode; 35 | return this; 36 | }; 37 | 38 | //指定字节序 为BigEndian 39 | this.bigEndian = function(){ 40 | _endian = 'B'; 41 | return this; 42 | }; 43 | 44 | //指定字节序 为LittleEndian 45 | this.littleEndian = function(){ 46 | _endian = 'L'; 47 | return this; 48 | }; 49 | 50 | this.byte = function(val,index){ 51 | if(val == undefined || val == null){ 52 | _list.push(_org_buf.readUInt8(_offset)); 53 | _offset+=1; 54 | }else{ 55 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_Byte,d:val,l:1}); 56 | _offset += 1; 57 | } 58 | return this; 59 | }; 60 | 61 | this.short = function(val,index){ 62 | if(val == undefined || val == null){ 63 | _list.push(_org_buf['readInt16'+_endian+'E'](_offset)); 64 | _offset+=2; 65 | }else{ 66 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_Short,d:val,l:2}); 67 | _offset += 2; 68 | } 69 | return this; 70 | }; 71 | 72 | this.ushort = function(val,index){ 73 | if(val == undefined || val == null){ 74 | _list.push(_org_buf['readUInt16'+_endian+'E'](_offset)); 75 | _offset+=2; 76 | }else{ 77 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_UShort,d:val,l:2}); 78 | _offset += 2; 79 | } 80 | return this; 81 | }; 82 | 83 | this.int32 = function(val,index){ 84 | if(val == undefined || val == null){ 85 | _list.push(_org_buf['readInt32'+_endian+'E'](_offset)); 86 | _offset+=4; 87 | }else{ 88 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_Int32,d:val,l:4}); 89 | _offset += 4; 90 | } 91 | return this; 92 | }; 93 | 94 | this.uint32 = function(val,index){ 95 | if(val == undefined || val == null){ 96 | _list.push(_org_buf['readUInt32'+_endian+'E'](_offset)); 97 | _offset+=4; 98 | }else{ 99 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_UInt32,d:val,l:4}); 100 | _offset += 4; 101 | } 102 | return this; 103 | }; 104 | 105 | /** 106 | * 变长字符串 前2个字节表示字符串长度 107 | **/ 108 | this.string = function(val,index){ 109 | if(val == undefined || val == null){ 110 | var len = _org_buf['readInt16'+_endian+'E'](_offset); 111 | _offset+=2; 112 | _list.push(_org_buf.toString(_encoding, _offset, _offset+len)); 113 | _offset+=len; 114 | }else{ 115 | var len = 0; 116 | if(val)len = Buffer.byteLength(val, _encoding); 117 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_String,d:val,l:len}); 118 | _offset += len + 2; 119 | } 120 | return this; 121 | }; 122 | 123 | /** 124 | * 定长字符串 val为null时,读取定长字符串(需指定长度len) 125 | **/ 126 | this.vstring = function(val,len,index){ 127 | if(!len){ 128 | throw new Error('vstring must got len argument'); 129 | return this; 130 | } 131 | if(val == undefined || val == null){ 132 | var vlen = 0;//实际长度 133 | for(var i = _offset;i<_offset +len;i++){ 134 | if(_org_buf[i]>0)vlen++; 135 | } 136 | _list.push(_org_buf.toString(_encoding, _offset, _offset+vlen)); 137 | _offset+=len; 138 | }else{ 139 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_VString,d:val,l:len}); 140 | _offset += len; 141 | } 142 | return this; 143 | }; 144 | 145 | this.int64 = function(val,index){ 146 | if(val == undefined || val == null){ 147 | _list.push(_org_buf['readDouble'+_endian+'E'](_offset)); 148 | _offset+=8; 149 | }else{ 150 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_Int64,d:val,l:8}); 151 | _offset += 8; 152 | } 153 | return this; 154 | }; 155 | 156 | this.float = function(val,index){ 157 | if(val == undefined || val == null){ 158 | _list.push(_org_buf['readFloat'+_endian+'E'](_offset)); 159 | _offset+=4; 160 | }else{ 161 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_Float,d:val,l:4}); 162 | _offset += 4; 163 | } 164 | return this; 165 | }; 166 | 167 | this.double = function(val,index){ 168 | if(val == undefined || val == null){ 169 | _list.push(_org_buf['readDouble'+_endian+'E'](_offset)); 170 | _offset+=8; 171 | }else{ 172 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_Double,d:val,l:8}); 173 | _offset += 8; 174 | } 175 | return this; 176 | }; 177 | 178 | /** 179 | * 写入或读取一段字节数组 180 | **/ 181 | this.byteArray = function(val,len,index){ 182 | if(!len){ 183 | throw new Error('byteArray must got len argument'); 184 | return this; 185 | } 186 | if(val == undefined || val == null){ 187 | var arr = []; 188 | for(var i = _offset;i<_offset +len;i++){ 189 | if(i<_org_buf.length){ 190 | arr.push(_org_buf.readUInt8(i)); 191 | }else{ 192 | arr.push(0); 193 | } 194 | } 195 | _list.push(arr); 196 | _offset+=len; 197 | }else{ 198 | _list.splice(index != undefined ? index : _list.length,0,{t:Type_ByteArray,d:val,l:len}); 199 | _offset += len; 200 | } 201 | return this; 202 | }; 203 | 204 | /** 205 | * 解包成数据数组 206 | **/ 207 | this.unpack = function(){ 208 | return _list; 209 | }; 210 | 211 | /** 212 | * 打包成二进制,在前面加上2个字节表示包长 213 | **/ 214 | this.packWithHead = function(){ 215 | return this.pack(true); 216 | }; 217 | 218 | /** 219 | * 打包成二进制 220 | * @param ifHead 是否在前面加上2个字节表示包长 221 | **/ 222 | this.pack = function(ifHead){ 223 | _org_buf = new Buffer((ifHead)?_offset+2:_offset); 224 | var offset = 0; 225 | if(ifHead){ 226 | _org_buf['writeUInt16'+_endian+'E'](_offset,offset); 227 | offset+=2; 228 | } 229 | for (var i = 0; i < _list.length; i++) { 230 | switch(_list[i].t){ 231 | case Type_Byte: 232 | _org_buf.writeUInt8(_list[i].d,offset); 233 | offset+=_list[i].l; 234 | break; 235 | case Type_Short: 236 | _org_buf['writeInt16'+_endian+'E'](_list[i].d,offset); 237 | offset+=_list[i].l; 238 | break; 239 | case Type_UShort: 240 | _org_buf['writeUInt16'+_endian+'E'](_list[i].d,offset); 241 | offset+=_list[i].l; 242 | break; 243 | case Type_Int32: 244 | _org_buf['writeInt32'+_endian+'E'](_list[i].d,offset); 245 | offset+=_list[i].l; 246 | break; 247 | case Type_UInt32: 248 | _org_buf['writeUInt32'+_endian+'E'](_list[i].d,offset); 249 | offset+=_list[i].l; 250 | break; 251 | case Type_String: 252 | //前2个字节表示字符串长度 253 | _org_buf['writeInt16'+_endian+'E'](_list[i].l,offset); 254 | offset+=2; 255 | _org_buf.write(_list[i].d, offset, _encoding); 256 | offset+=_list[i].l; 257 | break; 258 | case Type_VString: 259 | var vlen = Buffer.byteLength(_list[i].d, _encoding);//字符串实际长度 260 | _org_buf.write(_list[i].d, offset, _encoding); 261 | //补齐\0 262 | for(var j = offset + vlen;j", 12 | "repository" : {"type": "git", "url": "https://github.com/play175/ByteBuffer.git"}, 13 | "main": "ByteBuffer.js", 14 | "version" : "0.3.0" 15 | } -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var ByteBuffer = require('./ByteBuffer'); 2 | 3 | /*************************基本操作****************************/ 4 | 5 | //压包操作 6 | var sbuf = new ByteBuffer(); 7 | var buffer = sbuf.string('abc123你好')//变长字符串,前两个字节表示长度 8 | .int32(-999).uint32(999).float(-0.5) 9 | .int64(9999999).double(-0.000005).short(32767).ushort(65535) 10 | .byte(255) 11 | .vstring('abcd',5)//定长字符串,不足的字节补0x00 12 | .byteArray([65,66,67,68,69],5)//字节数组,不足字节补0x00 13 | .pack();//结尾调用打包方法 14 | 15 | console.log(buffer); 16 | 17 | //解包操作 18 | var rbuf = new ByteBuffer(buffer); 19 | //解包出来是一个数组 20 | var arr = rbuf.string()//变长字符串,前两个字节表示长度 21 | .int32().uint32().float() 22 | .int64().double().short().ushort() 23 | .byte() 24 | .vstring(null,5)//定长字符串,不足的字节补0x00 25 | .byteArray(null,5)//字节数组,不足字节补0x00 26 | .unpack();//结尾调用解包方法 27 | 28 | console.log(arr); 29 | 30 | 31 | /*************************更多操作****************************/ 32 | 33 | //指定字符编码(默认:utf8):utf8/ascii/ 34 | var sbuf = new ByteBuffer().encoding('ascii'); 35 | 36 | //指定字节序(默认:BigEndian) 37 | var sbuf = new ByteBuffer().littleEndian(); 38 | 39 | //指定数据在二进制的初始位置 默认是0 40 | var sbuf = new ByteBuffer(buffer,2); 41 | 42 | //插入数据到指定位置 43 | var sbuf = new ByteBuffer(); 44 | sbuf.int32(9999,0);//把这个int32数据插入到ByteBuffer的第一个位置 45 | 46 | //在打包的时候在开始位置插入一个short型表示包长(通信层中的包头) 47 | var buffer = sbuf.packWithHead(); 48 | --------------------------------------------------------------------------------