├── 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 |
--------------------------------------------------------------------------------