/util/BufferQueue.js

https://gitlab.com/zhidazhang/webActivity · JavaScript · 430 lines · 149 code · 32 blank · 249 comment · 28 complexity · 7be102e25e0b6ee88071a9c5cb3e7dda MD5 · raw file

  1. /**
  2. * Created by xflin on 2015/12/30.
  3. * xflin@cellcom.com.cn
  4. */
  5. var util = require('util');
  6. var EventEmitter = require('events').EventEmitter;
  7. var Packet = require("../util/Packet");
  8. //rcv queue
  9. MAX_BUFFER_SIZE = 8192*1000;
  10. var toHexString = function(buf) {
  11. if(buf) {
  12. var buffer = "";
  13. var bufV = new DataView(buf);
  14. for (var i=0 ; i < bufV.byteLength && i < 512;i++) {
  15. var b = bufV.getUint8(i);
  16. buffer += (b<=0x0f?"0":"") + b.toString(16) + " ";
  17. //buffer.appendData((b<=0x0f?"0":"") + b.toString(16) + " ");
  18. }
  19. //console.log(buffer);
  20. return buffer;
  21. }
  22. return null;
  23. };
  24. function BufferQueue(size,func) {
  25. EventEmitter.call(this);
  26. _thisBufferQueue = this;
  27. this._size = size | MAX_BUFFER_SIZE;
  28. this._callback = func;
  29. this.init();
  30. }
  31. util.inherits(BufferQueue, EventEmitter);
  32. BufferQueue.prototype.init = function () {
  33. this._idxWrite = 0;
  34. this._idxRead = 0;
  35. this._loopCountWrite = 0;
  36. this._loopCountRead = 0;
  37. this._buffer = new ArrayBuffer(this._size);
  38. if (this._buffer.byteLength === this._size) {
  39. console.log("BufferQueue init ArrayBuffer size "+this._size);
  40. } else {
  41. this._size = this._buffer.byteLength;
  42. console.log("BufferQueue init ArrayBuffer size fail."+this._size);
  43. }
  44. this._bufferU8 = new Uint8Array(this._buffer);
  45. this._bufferView = new DataView(this._buffer);
  46. };
  47. BufferQueue.prototype.clear = function () {
  48. this._idxRead = 0;
  49. this._idxWrite = 0;
  50. this._loopCountRead = 0;
  51. this._loopCountWrite = 0;
  52. //_bufferU8.();
  53. };
  54. BufferQueue.prototype.getWritedCount = function () {
  55. return (this._loopCountWrite * this._size + this._idxWrite);
  56. };
  57. BufferQueue.prototype.getReadCount = function() {
  58. return (this._loopCountRead * this._size + this._idxRead);
  59. };
  60. BufferQueue.prototype.IsFull = function(len) {
  61. return ((this.getLength()+len) > this._size);
  62. };
  63. BufferQueue.prototype.IsWriteEnd = function(len) {
  64. return ((this._idxWrite+len) > this._size);
  65. };
  66. BufferQueue.prototype.IsReadEnd = function(len) {
  67. return ((this._idxRead+len) > this._size);
  68. };
  69. BufferQueue.prototype.getFreeLength = function() {
  70. return ( this._size - (this._idxWrite - this._idxRead)) % this._size;
  71. }
  72. BufferQueue.prototype.getLength = function() {
  73. return (this._idxWrite - this._idxRead + this._size) % this._size;
  74. }
  75. BufferQueue.prototype.nextWriteIdx = function(offset) {
  76. if(this._idxWrite+offset >= this._size)
  77. this._loopCountWrite++;
  78. this._idxWrite = ((this._idxWrite+offset) % this._size);
  79. //console.log("_idxWrite="+this._idxWrite+"["+offset+"]");
  80. };
  81. BufferQueue.prototype.nextReadIdx = function(offset) {
  82. if(this._idxRead+offset >= this._size)
  83. this._loopCountRead++;
  84. this._idxRead = ((this._idxRead + offset) % this._size);
  85. //console.log("_idxRead="+this._idxRead+"["+offset+"]");
  86. };
  87. /*
  88. value -- int
  89. b --- boolean,true littleEndian;false bigEndian
  90. */
  91. BufferQueue.prototype.writeInt = function (value,b) {
  92. if(!this.IsWriteEnd()) {
  93. this._bufferView.setInt32(this._idxWrite, value, b);
  94. this.nextWriteIdx(4);
  95. } else {
  96. }
  97. };
  98. /*
  99. write queue buffer
  100. s --- ArrayBuffer
  101. */
  102. BufferQueue.prototype.writeBytes = function(s) {
  103. if(!s || s.byteLength===0) return;
  104. var frameLen = s.byteLength;
  105. if(!this._bufferU8)
  106. this._bufferU8 = new Uint8Array(this._buffer);
  107. var bufU8 = new Uint8Array(s);
  108. if(this.IsWriteEnd(frameLen)) {
  109. //var buffer1 = s.slice(0, (_size - _idxWrite));
  110. //var buffer2 = s.slice((_size - _idxWrite));
  111. var data1 = bufU8.subarray(0,(this._size - this._idxWrite));//new Uint8Array(s,0,(_size - _idxWrite));
  112. var data2 = bufU8.subarray(data1.length);//new Uint8Array(s,(_size - _idxWrite));
  113. this._bufferU8.set(data1,this._idxWrite);
  114. this._bufferU8.set(data2);
  115. //console.log("_idxWrite 0" + ": " + this._bufferU8[0]);
  116. this.nextWriteIdx(frameLen);
  117. } else {
  118. var data = new Uint8Array(s);
  119. this._bufferU8.set(data,this._idxWrite);
  120. this.nextWriteIdx(frameLen);
  121. }
  122. //console.log("writeBytes:_idxWrite=",this._idxWrite,",writeLen=",frameLen,","+toHexString(s));
  123. var output;
  124. output = this.readBytes();
  125. while(output) {
  126. var pack = new Packet(output.byteLength);
  127. if(pack) {
  128. var ret = pack.parseData(output);
  129. if (ret == 0) {
  130. if(pack.getTs() == 0)
  131. pack.setTs(Math.ceil((new Date()).getTime()/1000));
  132. if(this._callback)
  133. this._callback(pack);
  134. else
  135. this.emit(pack._from, pack);
  136. } else {
  137. console.log("parseData failed:" + ret + ",len=" + output.byteLength);
  138. }
  139. }
  140. output = this.readBytes();
  141. }
  142. };
  143. /*
  144. read from queue buffer
  145. return
  146. ArrayBuffer(frame)
  147. */
  148. BufferQueue.prototype.readBytes = function() {
  149. var frameLen=0;
  150. var buf;
  151. var bufU8;
  152. if(!this._bufferView)
  153. this._bufferView = new DataView(this._buffer);
  154. if(this._bufferView && this.getLength() > 4) {
  155. //frameLen=_bufferView.getUint32(_idxRead,true);
  156. frameLen=this._bufferView.getUint32(this._idxRead);
  157. if( this.getLength() >= (frameLen+4)) {
  158. this.nextReadIdx(4);
  159. //console.log("readBytes:"+frameLen);
  160. if (frameLen > 0) {
  161. buf = new ArrayBuffer(frameLen);
  162. bufU8 = new Uint8Array(buf);
  163. if(this.IsReadEnd(frameLen)) {
  164. var data1 = this._bufferU8.subarray(this._idxRead);//new Uint8Array(_buffer,_idxRead);
  165. var data2 = this._bufferU8.subarray(0,(frameLen - data1.length));//new Uint8Array(_buffer,0,(frameLen - data1.length));
  166. bufU8.set(data1,0);
  167. bufU8.set(data2,data1.length);
  168. } else {
  169. //buf = _buffer.slice(_idxRead, _idxRead + frameLen);
  170. var data3 = this._bufferU8.subarray(this._idxRead,this._idxRead + frameLen);
  171. bufU8.set(data3);
  172. }
  173. this.nextReadIdx(frameLen);
  174. }
  175. //console.log("readBytes:_idxRead=",this._idxRead,",readLen=",frameLen,","+toHexString(buf));
  176. }
  177. }
  178. return buf;
  179. };
  180. /*
  181. //Uint8ClampedArray
  182. var BufferQueue;
  183. BufferQueue = (function (size) {
  184. EventEmitter.call(this);
  185. var _this = this;
  186. var _size;
  187. var _buffer;
  188. var _bufferU8;
  189. var _bufferView;
  190. var _idxWrite;
  191. var _idxRead;
  192. var _loopCountWrite;//:uint=0;
  193. var _loopCountRead;//:uint=0;
  194. var init = function () {
  195. util.inherits(BufferQueue, EventEmitter);
  196. _idxWrite = 0;
  197. _idxRead = 0;
  198. _loopCountWrite = 0;
  199. _loopCountRead = 0;
  200. _size = size | MAX_BUFFER_SIZE;
  201. _buffer = new ArrayBuffer(_size);
  202. if (_buffer.byteLength === _size) {
  203. console.log("BufferQueue init ArrayBuffer size "+_size);
  204. } else {
  205. _size = _buffer.byteLength;
  206. console.log("BufferQueue init ArrayBuffer size fail."+_size);
  207. }
  208. _bufferU8 = new Uint8Array(_buffer);
  209. _bufferView = new DataView(_buffer);
  210. };
  211. _this.clear = function () {
  212. _idxRead = 0;
  213. _idxWrite = 0;
  214. _loopCountRead = 0;
  215. _loopCountWrite = 0;
  216. //_bufferU8.();
  217. };
  218. var getWritedCount = function () {
  219. return (_loopCountWrite * _size + _idxWrite);
  220. };
  221. var getReadCount = function() {
  222. return (_loopCountRead * _size + _idxRead);
  223. };
  224. var IsFull = function(len) {
  225. return ((_this.getLength()+len) > size);
  226. };
  227. var IsWriteEnd = function(len) {
  228. return ((_idxWrite+len) > size);
  229. };
  230. var IsReadEnd = function(len) {
  231. return ((_idxRead+len) > size);
  232. };
  233. _this.getFreeLength = function() {
  234. return ( _size - (_idxWrite - _idxRead)) % _size;
  235. }
  236. _this.getLength = function() {
  237. return (_idxWrite - _idxRead + _size) % _size;
  238. }
  239. var nextWriteIdx = function(offset) {
  240. if(_idxWrite+offset >= _size)
  241. _loopCountWrite++;
  242. _idxWrite = ((_idxWrite+offset) % _size);
  243. //console.log("_idxWrite="+_idxWrite+"["+offset+"]");
  244. };
  245. var nextReadIdx = function(offset) {
  246. if(_idxRead+offset >= _size)
  247. _loopCountRead++;
  248. _idxRead = ((_idxRead + offset) % _size);
  249. //console.log("_idxRead="+_idxRead+"["+offset+"]");
  250. };
  251. _this.writeInt = function (value,b) {
  252. if(!IsWriteEnd()) {
  253. _bufferView.setInt32(_idxWrite, value, b);
  254. nextWriteIdx(4);
  255. } else {
  256. }
  257. };
  258. _this.writeBytes = function(s) {
  259. if(!s || s.byteLength===0) return;
  260. var frameLen = s.byteLength;
  261. if(!_bufferU8)
  262. _bufferU8 = new Uint8Array(_buffer);
  263. var bufU8 = new Uint8Array(s);
  264. if(IsWriteEnd(frameLen)) {
  265. //var buffer1 = s.slice(0, (_size - _idxWrite));
  266. //var buffer2 = s.slice((_size - _idxWrite));
  267. var data1 = bufU8.subarray(0,(_size - _idxWrite));//new Uint8Array(s,0,(_size - _idxWrite));
  268. var data2 = bufU8.subarray(data1.length);//new Uint8Array(s,(_size - _idxWrite));
  269. _bufferU8.set(data1,_idxWrite);
  270. _bufferU8.set(data2);
  271. console.log("_idxWrite 0" + ": " + _bufferU8[0]);
  272. nextWriteIdx(frameLen);
  273. } else {
  274. var data = new Uint8Array(s);
  275. _bufferU8.set(data,_idxWrite);
  276. nextWriteIdx(frameLen);
  277. }
  278. //console.log("writeBytes:_idxWrite=",_idxWrite,",writeLen=",frameLen,","+toHexString(s));
  279. var output;
  280. output = _this.readBytes();
  281. while(output) {
  282. var pack = new Packet(output.byteLength);
  283. if(pack) {
  284. var ret = pack.parseData(output);
  285. if (ret == 0)
  286. _this.emit(pack.from, pack);
  287. else
  288. console.log("parseData failed:" + ret + ",len=" + output.byteLength);
  289. }
  290. output = _this.readBytes();
  291. }
  292. };
  293. _this.readBytes = function() {
  294. var frameLen=0;
  295. var buf;
  296. var bufU8;
  297. if(!_bufferView)
  298. _bufferView = new DataView(_buffer);
  299. if(_bufferView && _this.getLength() > 4) {
  300. //frameLen=_bufferView.getUint32(_idxRead,true);
  301. frameLen=_bufferView.getUint32(_idxRead);
  302. if( _this.getLength() >= (frameLen+4)) {
  303. nextReadIdx(4);
  304. //console.log("readBytes:"+frameLen);
  305. if (frameLen > 0) {
  306. buf = new ArrayBuffer(frameLen);
  307. bufU8 = new Uint8Array(buf);
  308. if(IsReadEnd(frameLen)) {
  309. var data1 = _bufferU8.subarray(_idxRead);//new Uint8Array(_buffer,_idxRead);
  310. var data2 = _bufferU8.subarray(0,(frameLen - data1.length));//new Uint8Array(_buffer,0,(frameLen - data1.length));
  311. bufU8.set(data1,0);
  312. bufU8.set(data2,data1.length);
  313. } else {
  314. //buf = _buffer.slice(_idxRead, _idxRead + frameLen);
  315. var data3 = _bufferU8.subarray(_idxRead,_idxRead + frameLen);
  316. bufU8.set(data3);
  317. }
  318. nextReadIdx(frameLen);
  319. }
  320. //console.log("readBytes:_idxRead=",_idxRead,",readLen=",frameLen,","+toHexString(buf));
  321. }
  322. }
  323. return buf;
  324. };
  325. _this.readSampleBytes = function(byteLength) {
  326. var frameLen=0;
  327. var buf;
  328. var bufU8;
  329. if(!_bufferView)
  330. _bufferView = new DataView(_buffer);
  331. if(_bufferView && _this.getLength() >= byteLength) {
  332. buf = new ArrayBuffer(byteLength);
  333. bufU8 = new Uint8Array(buf);
  334. if(IsReadEnd(byteLength)) {
  335. var data1 = _bufferU8.subarray(_idxRead);//new Uint8Array(_buffer,_idxRead);
  336. var data2 = _bufferU8.subarray(0,(byteLength - data1.length));//new Uint8Array(_buffer,0,(frameLen - data1.length));
  337. bufU8.set(data1,0);
  338. bufU8.set(data2,data1.length);
  339. } else {
  340. //buf = _buffer.slice(_idxRead, _idxRead + frameLen);
  341. var data3 = _bufferU8.subarray(_idxRead,_idxRead + frameLen);
  342. bufU8.set(data3);
  343. }
  344. nextReadIdx(frameLen);
  345. }
  346. return buf;
  347. };
  348. var toHexString = function(buf) {
  349. if(buf) {
  350. var buffer = "";
  351. var bufV = new DataView(buf);
  352. for (var i=0 ; i < bufV.byteLength && i < 512;i++) {
  353. var b = bufV.getUint8(i);
  354. buffer += (b<=0x0f?"0":"") + b.toString(16) + " ";
  355. //buffer.appendData((b<=0x0f?"0":"") + b.toString(16) + " ");
  356. }
  357. //console.log(buffer);
  358. return buffer;
  359. }
  360. return null;
  361. };
  362. init();
  363. });
  364. */
  365. module.exports = BufferQueue;