ByteBuffer.as 9.4 KB

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