/modules/_as/utils/ByteArray.js

https://github.com/teamdstn/dstnation · JavaScript · 564 lines · 514 code · 36 blank · 14 comment · 58 complexity · fc9ce18628e1ec7116f717fc88541131 MD5 · raw file

  1. /**
  2. * @namespace utils
  3. * @requires
  4. * @class BitmapData
  5. * @author Hayato Araki - http://www.arahaya.com/
  6. */
  7. function ByteArray()
  8. {
  9. this.float_pbias = Math.pow(2, 126);
  10. this.float_psgnd = Math.pow(2, 23);
  11. this.FLOAT_POSITIVE_INFINITY = (2 - Math.pow(2, -23)) * Math.pow(2, 127);
  12. this.FLOAT_NEGATIVE_INFINITY = -this.FLOAT_POSITIVE_INFINITY;
  13. this.double_pbias = Math.pow(2, 1022);
  14. this.double_psgnd = Math.pow(2, 52);
  15. this.DOUBLE_POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
  16. this.DOUBLE_NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY;
  17. this.__init__();
  18. /*
  19. * http://with-love-from-siberia.blogspot.com/2009/11/ieee754-converter.html
  20. */
  21. this.floatToBytes=function(n)
  22. {
  23. if (isNaN(n)) {
  24. return [0xff, 0xff, 0xff, 0xff];
  25. }
  26. if (n >= this.FLOAT_POSITIVE_INFINITY) {
  27. return [0x7f, 0x80, 0x00, 0x00];
  28. }
  29. if (n <= this.FLOAT_NEGATIVE_INFINITY) {
  30. return [0xff, 0x80, 0x00, 0x00];
  31. }
  32. if (n === 0) {
  33. return [0x00, 0x00, 0x00, 0x00];
  34. }
  35. var s = n < 0 ? 0x80 : 0;
  36. var t = Math.log((s ? -n : n)) / 0.6931471805599453;
  37. var p = Math.floor(t);
  38. var e, m;
  39. if (p < -126) {
  40. e = 0;
  41. m = this.float_psgnd * n * this.float_pbias;
  42. }
  43. else {
  44. e = p + 127;
  45. m = this.float_psgnd * (Math.pow(2, t - p) - 1);
  46. }
  47. var result = [0, 0, 0, 0];
  48. for (var i = 3; i > 0; --i)
  49. {
  50. var x = Math.floor(m / 0x100);
  51. result[i] = m - x * 0x100;
  52. m = x;
  53. }
  54. result[3] = (result[3] + 0.5) | 0;
  55. result[1] += (e & 0x01) << 7;
  56. result[0] = (e >> 1) + s;
  57. return result;
  58. };
  59. this.doubleToBytes=function (n)
  60. {
  61. if (isNaN(n)) {
  62. return [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
  63. }
  64. if (n >= this.DOUBLE_POSITIVE_INFINITY) {
  65. return [0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
  66. }
  67. if (n <= this.DOUBLE_NEGATIVE_INFINITY) {
  68. return [0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
  69. }
  70. if (n === 0) {
  71. return [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
  72. }
  73. var s = n < 0 ? 0x80 : 0;
  74. var t = Math.log((s ? -n : n)) / 0.6931471805599453;
  75. var p = Math.floor(t);
  76. var e, m;
  77. if (p < -1022) {
  78. e = 0;
  79. m = this.double_psgnd * n * this.double_pbias;
  80. }
  81. else {
  82. e = p + 1023;
  83. m = this.double_psgnd * (Math.pow(2, t - p) - 1);
  84. }
  85. var result = [0, 0, 0, 0, 0, 0, 0, 0];
  86. for (var i = 7; i > 0; --i)
  87. {
  88. var x = Math.floor(m / 0x100);
  89. result[i] = m - x * 0x100;
  90. m = x;
  91. }
  92. result[7] = (result[7] + 0.5) | 0;
  93. result[1] += (e & 0x0f) << 4;
  94. result[0] = (e >> 4) + s;
  95. return result;
  96. };
  97. this.bytesToNumber=function(bytes, bias, pbias, psgnd)
  98. {
  99. var n = bytes.length;
  100. var s = bytes[0] & 0x80;
  101. var e, m;
  102. if (n == 4) {
  103. e = ((bytes[0] & 0x7f) << 1) + (bytes[1] >> 7);
  104. m = bytes[1] & 0x7f;
  105. }
  106. else {
  107. e = ((bytes[0] & 0x7f) << 4) + (bytes[1] >> 4);
  108. m = bytes[1] & 0x0f;
  109. }
  110. for (var i = 2; i < n; i++)
  111. {
  112. m = m * 0x100 + bytes[i];
  113. }
  114. if (e == bias * 2 + 1) {
  115. if (m) { return 0 / 0; }
  116. return (s ? -1 : +1) / 0;
  117. }
  118. var result = e ?
  119. (m / psgnd + 1) * Math.pow(2, e - bias) :
  120. m / psgnd / pbias;
  121. return s ? -result : result;
  122. };
  123. this.bytesToFloat=function(bytes)
  124. {
  125. return bytesToNumber(bytes, 127, this.float_pbias, this.float_psgnd);
  126. };
  127. this.bytesToDouble=function(bytes)
  128. {
  129. return bytesToNumber(bytes, 1023, this.double_pbias, this.double_psgnd);
  130. };
  131. var suffix = (this.__bigEndian) ? 'B' : 'L';
  132. this.readShort = this['__readShort' + suffix];
  133. this.readUnsignedShort = this['__readUnsignedShort' + suffix];
  134. this.readInt = this['__readInt' + suffix];
  135. this.readUnsignedInt = this['__readUnsignedInt' + suffix];
  136. this.readFloat = this['__readFloat' + suffix];
  137. this.readDouble = this['__readDouble' + suffix];
  138. this.writeShort = this['__writeShort' + suffix];
  139. this.writeInt = this['__writeInt' + suffix];
  140. this.writeFloat = this['__writeFloat' + suffix];
  141. this.writeDouble = this['__writeDouble' + suffix];
  142. };
  143. ByteArray.prototype = new Array();
  144. ByteArray.constructor = ByteArray;
  145. ByteArray.prototype.__init__ = function()
  146. {
  147. this.__bigEndian = true;
  148. this.__position = 0;
  149. };
  150. ByteArray.prototype.compress = function()
  151. {
  152. };
  153. ByteArray.prototype.uncompress = function()
  154. {
  155. };
  156. ByteArray.prototype.readBoolean = function()
  157. {
  158. var start = this.__position;
  159. var end = start + 1;
  160. if (end > this.length) { throwCustomError(null,2030,"Error");}
  161. var value = this[start];
  162. this.__position = end;
  163. return (value) ? true : false;
  164. };
  165. ByteArray.prototype.readByte = function()
  166. {
  167. var start = this.__position;
  168. var end = start + 1;
  169. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  170. var value = this[start];
  171. this.__position = end;
  172. return (value & 0x80) ? -((value ^ 0xFF) + 1) : value;
  173. };
  174. ByteArray.prototype.readUnsignedByte = function()
  175. {
  176. var start = this.__position;
  177. var end = start + 1;
  178. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  179. var value = this[start];
  180. this.__position = end;
  181. return value;
  182. };
  183. ByteArray.prototype.__readShortB = function()
  184. {
  185. var start = this.__position;
  186. var end = start + 2;
  187. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  188. var value = this[start] << 8 | (this[start+1] & 0xFF);
  189. this.__position = end;
  190. return (value & 0x8000) ? -((value ^ 0xFFFF) + 1) : value;
  191. };
  192. ByteArray.prototype.__readShortL = function()
  193. {
  194. var start = this.__position;
  195. var end = start + 2;
  196. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  197. var value = this[end] << 8 | (this[end-1] & 0xFF);
  198. this.__position = end;
  199. return (value & 0x8000) ? -((value ^ 0xFFFF) + 1) : value;
  200. };
  201. ByteArray.prototype.__readUnsignedShortB = function()
  202. {
  203. var start = this.__position;
  204. var end = start + 2;
  205. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  206. var value = this[start] << 8 | (this[start+1] & 0xFF);
  207. this.__position = end;
  208. return value;
  209. };
  210. ByteArray.prototype.__readUnsignedShortL = function()
  211. {
  212. var start = this.__position;
  213. var end = start + 2;
  214. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  215. var value = this[start] << 8 | (this[start+1] & 0xFF);
  216. this.__position = end;
  217. return value;
  218. };
  219. ByteArray.prototype.__readIntB = function()
  220. {
  221. var start = this.__position;
  222. var end = start + 4;
  223. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  224. var value = (this[start] << 24 | (0xFF & this[start+1]) << 16 | (0xFF & this[start+2]) << 8 | (0xFF & this[start+3])) >>> 0;
  225. this.__position = end;
  226. return (value & 0x80000000) ? -((value ^ 0xFFFFFFFF) + 1) : value;
  227. };
  228. ByteArray.prototype.__readIntL = function()
  229. {
  230. var start = this.__position;
  231. var end = start + 4;
  232. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  233. var value = (this[end] << 24 | (0xFF & this[end-1]) << 16 | (0xFF & this[end-2]) << 8 | (0xFF & this[end-3])) >>> 0;
  234. this.__position = end;
  235. return (value & 0x80000000) ? -((value ^ 0xFFFFFFFF) + 1) : value;
  236. };
  237. ByteArray.prototype.__readUnsignedIntB = function()
  238. {
  239. var start = this.__position;
  240. var end = start + 4;
  241. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  242. var value = (this[start] << 24 | (0xFF & this[start+1]) << 16 | (0xFF & this[start+2]) << 8 | (0xFF & this[start+3])) >>> 0;
  243. this.__position = end;
  244. return value;
  245. };
  246. ByteArray.prototype.__readUnsignedIntL = function()
  247. {
  248. var start = this.__position;
  249. var end = start + 4;
  250. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  251. var value = (this[end] << 24 | (0xFF & this[end-1]) << 16 | (0xFF & this[end-2]) << 8 | (0xFF & this[end-3])) >>> 0;
  252. this.__position = end;
  253. return value;
  254. };
  255. ByteArray.prototype.__readFloatB = function()
  256. {
  257. var start = this.__position;
  258. var end = start + 4;
  259. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  260. var value = bytesToFloat(this.slice(start, end));
  261. this.__position = end;
  262. return value;
  263. };
  264. ByteArray.prototype.__readFloatL = function()
  265. {
  266. var start = this.__position;
  267. var end = start + 4;
  268. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  269. var value = bytesToFloat(this.slice(start, end).reverse());
  270. this.__position = end;
  271. return value;
  272. };
  273. ByteArray.prototype.__readDoubleB = function()
  274. {
  275. var start = this.__position;
  276. var end = start + 8;
  277. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  278. var value = bytesToDouble(this.slice(start, end));
  279. this.__position = end;
  280. return value;
  281. };
  282. ByteArray.prototype.__readDoubleL = function()
  283. {
  284. var start = this.__position;
  285. var end = start + 8;
  286. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  287. var value = bytesToDouble(this.slice(start, end).reverse());
  288. this.__position = end;
  289. return value;
  290. };
  291. ByteArray.prototype.readMultiByte = function(length, charset)
  292. {
  293. //probably not going to support
  294. return this.readUTFBytes(length);
  295. };
  296. ByteArray.prototype.readObject = function()
  297. {
  298. //someday
  299. };
  300. ByteArray.prototype.readUTF = function()
  301. {
  302. var length = this.readShort();
  303. return this.readUTFBytes(length);
  304. };
  305. ByteArray.prototype.readUTFBytes = function(length)
  306. {
  307. var start = this.__position;
  308. var end = start + length;
  309. if (end > this.length) { throwCustomError(null,2030,"Error"); }
  310. var chars = [];
  311. for (var i = start, c = 0; i < end;)
  312. {
  313. chars[c++] = String.fromCharCode(this[i++]);
  314. }
  315. this.__position = end;
  316. var s = chars.join("");
  317. return decodeURIComponent(escape(s));
  318. };
  319. ByteArray.prototype.writeByte = function(value)
  320. {
  321. var position = this.__position;
  322. this[position++] = value & 0xFF;
  323. this.__position = position;
  324. if (position > this.length) { this.length = position; }
  325. };
  326. ByteArray.prototype.writeBytes = function(bytes, offset, length)
  327. {
  328. offset = offset | 0;
  329. length = length | 0 || bytes.length - offset;
  330. var position = this.__position;
  331. for (var i = offset; i < length; ++i)
  332. {
  333. this[position++] = bytes[i];
  334. }
  335. this.__position = position;
  336. if (position > this.length) { this.length = position; }
  337. };
  338. ByteArray.prototype.__writeShortB = function(value)
  339. {
  340. var position = this.__position;
  341. this[position++] = value >> 8 & 0xFF;
  342. this[position++] = value & 0xFF;
  343. this.__position = position;
  344. if (position > this.length) { this.length = position; }
  345. };
  346. ByteArray.prototype.__writeShortL = function(value)
  347. {
  348. var position = this.__position;
  349. this[position++] = value & 0xFF;
  350. this[position++] = value >> 8 & 0xFF;
  351. this.__position = position;
  352. if (position > this.length) { this.length = position; }
  353. };
  354. ByteArray.prototype.__writeIntB = function(value)
  355. {
  356. var position = this.__position;
  357. this[position++] = value >> 24 & 0xFF;
  358. this[position++] = value >> 16 & 0xFF;
  359. this[position++] = value >> 8 & 0xFF;
  360. this[position++] = value & 0xFF;
  361. this.__position = position;
  362. if (position > this.length) { this.length = position; }
  363. };
  364. ByteArray.prototype.__writeIntL = function(value)
  365. {
  366. var position = this.__position;
  367. this[position++] = value & 0xFF;
  368. this[position++] = value >> 8 & 0xFF;
  369. this[position++] = value >> 16 & 0xFF;
  370. this[position++] = value >> 24 & 0xFF;
  371. this.__position = position;
  372. if (position > this.length) { this.length = position; }
  373. };
  374. ByteArray.prototype.writeUnsignedInt = function(value)
  375. {
  376. this.writeInt(value >>> 0);
  377. };
  378. ByteArray.prototype.__writeFloatB = function(value)
  379. {
  380. var bytes = floatToBytes(value);
  381. var position = this.__position;
  382. this[position++] = bytes[0];
  383. this[position++] = bytes[1];
  384. this[position++] = bytes[2];
  385. this[position++] = bytes[3];
  386. this.__position = position;
  387. if (position > this.length) { this.length = position; }
  388. };
  389. ByteArray.prototype.__writeFloatL = function(value)
  390. {
  391. var bytes = floatToBytes(value);
  392. var position = this.__position;
  393. this[position++] = bytes[3];
  394. this[position++] = bytes[2];
  395. this[position++] = bytes[1];
  396. this[position++] = bytes[0];
  397. this.__position = position;
  398. if (position > this.length) { this.length = position; }
  399. };
  400. ByteArray.prototype.__writeDoubleB = function(value)
  401. {
  402. var bytes = doubleToBytes(value);
  403. var position = this.__position;
  404. this[position++] = bytes[0];
  405. this[position++] = bytes[1];
  406. this[position++] = bytes[2];
  407. this[position++] = bytes[3];
  408. this[position++] = bytes[4];
  409. this[position++] = bytes[5];
  410. this[position++] = bytes[6];
  411. this[position++] = bytes[7];
  412. this.__position = position;
  413. if (position > this.length) { this.length = position; }
  414. };
  415. ByteArray.prototype.__writeDoubleL = function(value)
  416. {
  417. var bytes = doubleToBytes(value);
  418. var position = this.__position;
  419. this[position++] = bytes[7];
  420. this[position++] = bytes[6];
  421. this[position++] = bytes[5];
  422. this[position++] = bytes[4];
  423. this[position++] = bytes[3];
  424. this[position++] = bytes[2];
  425. this[position++] = bytes[1];
  426. this[position++] = bytes[0];
  427. this.__position = position;
  428. if (position > this.length) { this.length = position; }
  429. };
  430. ByteArray.prototype.writeMultiByte = function(value, charSet)
  431. {
  432. //probably not going to support
  433. this.writeUTFBytes(value);
  434. };
  435. ByteArray.prototype.writeObject = function(value)
  436. {
  437. //someday
  438. };
  439. ByteArray.prototype.writeUTF = function(value)
  440. {
  441. var str = unescape(encodeURIComponent(value));
  442. var length = str.length;
  443. if (length > 0xFFFF) {
  444. throw new RangeError('Error #2006 : The supplied index is out of bounds.');
  445. }
  446. this.writeShort(length);
  447. var position = this.__position;
  448. for (var i = 0; i < length; ++i)
  449. {
  450. this[position++] = str.charCodeAt(i);
  451. }
  452. this.__position = position;
  453. if (position > this.length) { this.length = position; }
  454. };
  455. ByteArray.prototype.writeUTFBytes = function(value)
  456. {
  457. var str = unescape(encodeURIComponent(value));
  458. var length = str.length;
  459. var position = this.__position;
  460. for (var i = 0; i < length; ++i)
  461. {
  462. this[position++] = str.charCodeAt(i);
  463. }
  464. this.__position = position;
  465. if (position > this.length) { this.length = position; }
  466. };
  467. ByteArray.prototype.__get__bytesAvailable = function()
  468. {
  469. return this.length - this.__position;
  470. };
  471. ByteArray.prototype.__get__endian = function()
  472. {
  473. return (this.__bigEndian) ? Endian.BIG_ENDIAN : Endian.LITTLE_ENDIAN;
  474. };
  475. ByteArray.prototype.__set__endian = function(v)
  476. {
  477. this.__bigEndian = (v == Endian.BIG_ENDIAN);
  478. var suffix = (this.__bigEndian) ? 'B' : 'L';
  479. this.readShort = this['__readShort' + suffix];
  480. this.readUnsignedShort = this['__readUnsignedShort' + suffix];
  481. this.readInt = this['__readInt' + suffix];
  482. this.readUnsignedInt = this['__readUnsignedInt' + suffix];
  483. this.readFloat = this['__readFloat' + suffix];
  484. this.readDouble = this['__readDouble' + suffix];
  485. this.writeShort = this['__writeShort' + suffix];
  486. this.writeInt = this['__writeInt' + suffix];
  487. this.writeFloat = this['__writeFloat' + suffix];
  488. this.writeDouble = this['__writeDouble' + suffix];
  489. };
  490. ByteArray.prototype.__get__position = function()
  491. {
  492. return this.__position;
  493. };
  494. ByteArray.prototype.__set__position = function(v)
  495. {
  496. if (v > this.length) {
  497. //fill the array with zeros until length == position
  498. var len = v - this.length;
  499. for (var i = 0; i < len; ++i)
  500. {
  501. this.push(0);
  502. }
  503. }
  504. this.__position = v | 0;
  505. };
  506. ByteArray.prototype.toString = function()
  507. {
  508. return this.join("");
  509. return this.map(function(element, index, array)
  510. {
  511. return String.fromCharCode(element);
  512. }, this).join("");
  513. };
  514. ByteArray.prototype.toArray = function()
  515. {
  516. return this.splice(0);
  517. };
  518. ByteArray.prototype.readInt = ByteArray.prototype.__readIntB;
  519. ByteArray.prototype.readFloat = ByteArray.prototype.__readFloatB;
  520. ByteArray.prototype.writeBoolean = ByteArray.prototype.writeByte;
  521. ByteArray.prototype.writeDouble = ByteArray.prototype.__writeDoubleB;
  522. ByteArray.prototype.readUnsignedShort = ByteArray.prototype.__readUnsignedShortB;
  523. ByteArray.prototype.readUnsignedInt = ByteArray.prototype.__readUnsignedIntB;
  524. ByteArray.prototype.readDouble = ByteArray.prototype.__readDoubleB;
  525. ByteArray.prototype.writeShort = ByteArray.prototype.__writeShortB;
  526. ByteArray.prototype.writeInt = ByteArray.prototype.__writeIntB;
  527. ByteArray.prototype.readShort = ByteArray.prototype.__readShortB;
  528. ByteArray.prototype.writeFloat = ByteArray.prototype.__writeFloatB;