ByteBuffer.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*!
  2. * ByteBuffer
  3. * yoyo 2012 https://github.com/play175/ByteBuffer
  4. * new BSD Licensed
  5. */
  6. var Type_Byte = 1;
  7. var Type_Short = 2;
  8. var Type_UShort = 3;
  9. var Type_Int32 = 4;
  10. var Type_UInt32 = 5;
  11. var Type_String = 6;//变长字符串,前两个字节表示长度
  12. var Type_VString = 7;//定长字符串
  13. var Type_Int64 = 8;
  14. var Type_Float = 9;
  15. var Type_Double = 10;
  16. var Type_ByteArray = 11;
  17. /*
  18. * 构造方法
  19. * @param org_buf 需要解包的二进制
  20. * @param offset 指定数据在二进制的初始位置 默认是0
  21. */
  22. var ByteBuffer = function (org_buf,offset) {
  23. var _org_buf = org_buf;
  24. var _encoding = 'utf8';
  25. var _offset = offset || 0;
  26. var _list = [];
  27. var _endian = 'B';
  28. //指定文字编码
  29. this.encoding = function(encode){
  30. _encoding = encode;
  31. return this;
  32. };
  33. //指定字节序 为BigEndian
  34. this.bigEndian = function(){
  35. _endian = 'B';
  36. return this;
  37. };
  38. //指定字节序 为LittleEndian
  39. this.littleEndian = function(){
  40. _endian = 'L';
  41. return this;
  42. };
  43. this.byte = function(val,index){
  44. if(val == undefined || val == null){
  45. _list.push(_org_buf.readUInt8(_offset));
  46. _offset+=1;
  47. }else{
  48. _list.splice(index != undefined ? index : _list.length,0,{t:Type_Byte,d:val,l:1});
  49. _offset += 1;
  50. }
  51. return this;
  52. };
  53. this.short = function(val,index){
  54. if(val == undefined || val == null){
  55. _list.push(_org_buf['readInt16'+_endian+'E'](_offset));
  56. _offset+=2;
  57. }else{
  58. _list.splice(index != undefined ? index : _list.length,0,{t:Type_Short,d:val,l:2});
  59. _offset += 2;
  60. }
  61. return this;
  62. };
  63. this.ushort = function(val,index){
  64. if(val == undefined || val == null){
  65. _list.push(_org_buf['readUInt16'+_endian+'E'](_offset));
  66. _offset+=2;
  67. }else{
  68. _list.splice(index != undefined ? index : _list.length,0,{t:Type_UShort,d:val,l:2});
  69. _offset += 2;
  70. }
  71. return this;
  72. };
  73. this.int32 = function(val,index){
  74. if(val == undefined || val == null){
  75. _list.push(_org_buf['readInt32'+_endian+'E'](_offset));
  76. _offset+=4;
  77. }else{
  78. _list.splice(index != undefined ? index : _list.length,0,{t:Type_Int32,d:val,l:4});
  79. _offset += 4;
  80. }
  81. return this;
  82. };
  83. this.uint32 = function(val,index){
  84. if(val == undefined || val == null){
  85. _list.push(_org_buf['readUInt32'+_endian+'E'](_offset));
  86. _offset+=4;
  87. }else{
  88. _list.splice(index != undefined ? index : _list.length,0,{t:Type_UInt32,d:val,l:4});
  89. _offset += 4;
  90. }
  91. return this;
  92. };
  93. /**
  94. * 变长字符串 前2个字节表示字符串长度
  95. **/
  96. this.string = function(val,index){
  97. if(val == undefined || val == null){
  98. var len = _org_buf['readInt16'+_endian+'E'](_offset);
  99. _offset+=2;
  100. _list.push(_org_buf.toString(_encoding, _offset, _offset+len));
  101. _offset+=len;
  102. }else{
  103. var len = 0;
  104. if(val)len = Buffer.byteLength(val, _encoding);
  105. _list.splice(index != undefined ? index : _list.length,0,{t:Type_String,d:val,l:len});
  106. _offset += len + 2;
  107. }
  108. return this;
  109. };
  110. /**
  111. * 定长字符串 val为null时,读取定长字符串(需指定长度len)
  112. **/
  113. this.vstring = function(val,len,index){
  114. if(!len){
  115. throw new Error('vstring must got len argument');
  116. return this;
  117. }
  118. if(val == undefined || val == null){
  119. var vlen = 0;//实际长度
  120. for(var i = _offset;i<_offset +len;i++){
  121. if(_org_buf[i]>0)vlen++;
  122. }
  123. _list.push(_org_buf.toString(_encoding, _offset, _offset+vlen));
  124. _offset+=len;
  125. }else{
  126. _list.splice(index != undefined ? index : _list.length,0,{t:Type_VString,d:val,l:len});
  127. _offset += len;
  128. }
  129. return this;
  130. };
  131. this.int64 = function(val,index){
  132. if(val == undefined || val == null){
  133. _list.push(_org_buf['readDouble'+_endian+'E'](_offset));
  134. _offset+=8;
  135. }else{
  136. _list.splice(index != undefined ? index : _list.length,0,{t:Type_Int64,d:val,l:8});
  137. _offset += 8;
  138. }
  139. return this;
  140. };
  141. this.float = function(val,index){
  142. if(val == undefined || val == null){
  143. _list.push(_org_buf['readFloat'+_endian+'E'](_offset));
  144. _offset+=4;
  145. }else{
  146. _list.splice(index != undefined ? index : _list.length,0,{t:Type_Float,d:val,l:4});
  147. _offset += 4;
  148. }
  149. return this;
  150. };
  151. this.double = function(val,index){
  152. if(val == undefined || val == null){
  153. _list.push(_org_buf['readDouble'+_endian+'E'](_offset));
  154. _offset+=8;
  155. }else{
  156. _list.splice(index != undefined ? index : _list.length,0,{t:Type_Double,d:val,l:8});
  157. _offset += 8;
  158. }
  159. return this;
  160. };
  161. /**
  162. * 写入或读取一段字节数组
  163. **/
  164. this.byteArray = function(val,len,index){
  165. if(!len){
  166. throw new Error('byteArray must got len argument');
  167. return this;
  168. }
  169. if(val == undefined || val == null){
  170. var arr = [];
  171. for(var i = _offset;i<_offset +len;i++){
  172. if(i<_org_buf.length){
  173. arr.push(_org_buf.readUInt8(i));
  174. }else{
  175. arr.push(0);
  176. }
  177. }
  178. _list.push(arr);
  179. _offset+=len;
  180. }else{
  181. _list.splice(index != undefined ? index : _list.length,0,{t:Type_ByteArray,d:val,l:len});
  182. _offset += len;
  183. }
  184. return this;
  185. };
  186. /**
  187. * 解包成数据数组
  188. **/
  189. this.unpack = function(){
  190. return _list;
  191. };
  192. /**
  193. * 打包成二进制,在前面加上2个字节表示包长
  194. **/
  195. this.packWithHead = function(){
  196. return this.pack(true);
  197. };
  198. /**
  199. * 打包成二进制
  200. * @param ifHead 是否在前面加上2个字节表示包长
  201. **/
  202. this.pack = function(ifHead){
  203. _org_buf = new Buffer((ifHead)?_offset+2:_offset);
  204. var offset = 0;
  205. if(ifHead){
  206. _org_buf['writeUInt16'+_endian+'E'](_offset,offset);
  207. offset+=2;
  208. }
  209. for (var i = 0; i < _list.length; i++) {
  210. switch(_list[i].t){
  211. case Type_Byte:
  212. _org_buf.writeUInt8(_list[i].d,offset);
  213. offset+=_list[i].l;
  214. break;
  215. case Type_Short:
  216. _org_buf['writeInt16'+_endian+'E'](_list[i].d,offset);
  217. offset+=_list[i].l;
  218. break;
  219. case Type_UShort:
  220. _org_buf['writeUInt16'+_endian+'E'](_list[i].d,offset);
  221. offset+=_list[i].l;
  222. break;
  223. case Type_Int32:
  224. _org_buf['writeInt32'+_endian+'E'](_list[i].d,offset);
  225. offset+=_list[i].l;
  226. break;
  227. case Type_UInt32:
  228. _org_buf['writeUInt32'+_endian+'E'](_list[i].d,offset);
  229. offset+=_list[i].l;
  230. break;
  231. case Type_String:
  232. //前2个字节表示字符串长度
  233. _org_buf['writeInt16'+_endian+'E'](_list[i].l,offset);
  234. offset+=2;
  235. _org_buf.write(_list[i].d,_encoding,offset);
  236. offset+=_list[i].l;
  237. break;
  238. case Type_VString:
  239. var vlen = Buffer.byteLength(_list[i].d, _encoding);//字符串实际长度
  240. _org_buf.write(_list[i].d,_encoding,offset);
  241. //补齐\0
  242. for(var j = offset + vlen;j<offset+_list[i].l;j++){
  243. _org_buf.writeUInt8(0,j);
  244. }
  245. offset+=_list[i].l;
  246. break;
  247. case Type_Int64:
  248. _org_buf['writeDouble'+_endian+'E'](_list[i].d,offset);
  249. offset+=_list[i].l;
  250. break;
  251. case Type_Float:
  252. _org_buf['writeFloat'+_endian+'E'](_list[i].d,offset);
  253. offset+=_list[i].l;
  254. break;
  255. case Type_Double:
  256. _org_buf['writeDouble'+_endian+'E'](_list[i].d,offset);
  257. offset+=_list[i].l;
  258. break;
  259. case Type_ByteArray:
  260. var indx = 0;
  261. for(var j = offset;j<offset+_list[i].l;j++){
  262. if(indx<_list[i].d.length){
  263. _org_buf.writeUInt8(_list[i].d[indx],j);
  264. }else{//不够的话,后面补齐0x00
  265. _org_buf.writeUInt8(0,j);
  266. }
  267. indx++
  268. }
  269. offset+=_list[i].l;
  270. break;
  271. }
  272. }
  273. return _org_buf;
  274. };
  275. /**
  276. * 未读数据长度
  277. **/
  278. this.getAvailable = function(){
  279. if(!_org_buf)return _offset;
  280. return _org_buf.length - _offset;
  281. };
  282. }
  283. module.exports = exports = ByteBuffer;