index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. var Chainsaw = require('chainsaw');
  2. var EventEmitter = require('events').EventEmitter;
  3. var Buffers = require('buffers');
  4. var Vars = require('./lib/vars.js');
  5. var Stream = require('stream').Stream;
  6. exports = module.exports = function (bufOrEm, eventName) {
  7. if (Buffer.isBuffer(bufOrEm)) {
  8. return exports.parse(bufOrEm);
  9. }
  10. var s = exports.stream();
  11. if (bufOrEm && bufOrEm.pipe) {
  12. bufOrEm.pipe(s);
  13. }
  14. else if (bufOrEm) {
  15. bufOrEm.on(eventName || 'data', function (buf) {
  16. s.write(buf);
  17. });
  18. bufOrEm.on('end', function () {
  19. s.end();
  20. });
  21. }
  22. return s;
  23. };
  24. exports.stream = function (input) {
  25. if (input) return exports.apply(null, arguments);
  26. var pending = null;
  27. function getBytes (bytes, cb, skip) {
  28. pending = {
  29. bytes : bytes,
  30. skip : skip,
  31. cb : function (buf) {
  32. pending = null;
  33. cb(buf);
  34. },
  35. };
  36. dispatch();
  37. }
  38. var offset = null;
  39. function dispatch () {
  40. if (!pending) {
  41. if (caughtEnd) done = true;
  42. return;
  43. }
  44. if (typeof pending === 'function') {
  45. pending();
  46. }
  47. else {
  48. var bytes = offset + pending.bytes;
  49. if (buffers.length >= bytes) {
  50. var buf;
  51. if (offset == null) {
  52. buf = buffers.splice(0, bytes);
  53. if (!pending.skip) {
  54. buf = buf.slice();
  55. }
  56. }
  57. else {
  58. if (!pending.skip) {
  59. buf = buffers.slice(offset, bytes);
  60. }
  61. offset = bytes;
  62. }
  63. if (pending.skip) {
  64. pending.cb();
  65. }
  66. else {
  67. pending.cb(buf);
  68. }
  69. }
  70. }
  71. }
  72. function builder (saw) {
  73. function next () { if (!done) saw.next() }
  74. var self = words(function (bytes, cb) {
  75. return function (name) {
  76. getBytes(bytes, function (buf) {
  77. vars.set(name, cb(buf));
  78. next();
  79. });
  80. };
  81. });
  82. self.tap = function (cb) {
  83. saw.nest(cb, vars.store);
  84. };
  85. self.into = function (key, cb) {
  86. if (!vars.get(key)) vars.set(key, {});
  87. var parent = vars;
  88. vars = Vars(parent.get(key));
  89. saw.nest(function () {
  90. cb.apply(this, arguments);
  91. this.tap(function () {
  92. vars = parent;
  93. });
  94. }, vars.store);
  95. };
  96. self.flush = function () {
  97. vars.store = {};
  98. next();
  99. };
  100. self.loop = function (cb) {
  101. var end = false;
  102. saw.nest(false, function loop () {
  103. this.vars = vars.store;
  104. cb.call(this, function () {
  105. end = true;
  106. next();
  107. }, vars.store);
  108. this.tap(function () {
  109. if (end) saw.next()
  110. else loop.call(this)
  111. }.bind(this));
  112. }, vars.store);
  113. };
  114. self.buffer = function (name, bytes) {
  115. if (typeof bytes === 'string') {
  116. bytes = vars.get(bytes);
  117. }
  118. getBytes(bytes, function (buf) {
  119. vars.set(name, buf);
  120. next();
  121. });
  122. };
  123. self.skip = function (bytes) {
  124. if (typeof bytes === 'string') {
  125. bytes = vars.get(bytes);
  126. }
  127. getBytes(bytes, function () {
  128. next();
  129. });
  130. };
  131. self.scan = function find (name, search) {
  132. if (typeof search === 'string') {
  133. search = new Buffer(search);
  134. }
  135. else if (!Buffer.isBuffer(search)) {
  136. throw new Error('search must be a Buffer or a string');
  137. }
  138. var taken = 0;
  139. pending = function () {
  140. var pos = buffers.indexOf(search, offset + taken);
  141. var i = pos-offset-taken;
  142. if (pos !== -1) {
  143. pending = null;
  144. if (offset != null) {
  145. vars.set(
  146. name,
  147. buffers.slice(offset, offset + taken + i)
  148. );
  149. offset += taken + i + search.length;
  150. }
  151. else {
  152. vars.set(
  153. name,
  154. buffers.slice(0, taken + i)
  155. );
  156. buffers.splice(0, taken + i + search.length);
  157. }
  158. next();
  159. dispatch();
  160. } else {
  161. i = Math.max(buffers.length - search.length - offset - taken, 0);
  162. }
  163. taken += i;
  164. };
  165. dispatch();
  166. };
  167. self.peek = function (cb) {
  168. offset = 0;
  169. saw.nest(function () {
  170. cb.call(this, vars.store);
  171. this.tap(function () {
  172. offset = null;
  173. });
  174. });
  175. };
  176. return self;
  177. };
  178. var stream = Chainsaw.light(builder);
  179. stream.writable = true;
  180. var buffers = Buffers();
  181. stream.write = function (buf) {
  182. buffers.push(buf);
  183. dispatch();
  184. };
  185. var vars = Vars();
  186. var done = false, caughtEnd = false;
  187. stream.end = function () {
  188. caughtEnd = true;
  189. };
  190. stream.pipe = Stream.prototype.pipe;
  191. Object.getOwnPropertyNames(EventEmitter.prototype).forEach(function (name) {
  192. stream[name] = EventEmitter.prototype[name];
  193. });
  194. return stream;
  195. };
  196. exports.parse = function parse (buffer) {
  197. var self = words(function (bytes, cb) {
  198. return function (name) {
  199. if (offset + bytes <= buffer.length) {
  200. var buf = buffer.slice(offset, offset + bytes);
  201. offset += bytes;
  202. vars.set(name, cb(buf));
  203. }
  204. else {
  205. vars.set(name, null);
  206. }
  207. return self;
  208. };
  209. });
  210. var offset = 0;
  211. var vars = Vars();
  212. self.vars = vars.store;
  213. self.tap = function (cb) {
  214. cb.call(self, vars.store);
  215. return self;
  216. };
  217. self.into = function (key, cb) {
  218. if (!vars.get(key)) {
  219. vars.set(key, {});
  220. }
  221. var parent = vars;
  222. vars = Vars(parent.get(key));
  223. cb.call(self, vars.store);
  224. vars = parent;
  225. return self;
  226. };
  227. self.loop = function (cb) {
  228. var end = false;
  229. var ender = function () { end = true };
  230. while (end === false) {
  231. cb.call(self, ender, vars.store);
  232. }
  233. return self;
  234. };
  235. self.buffer = function (name, size) {
  236. if (typeof size === 'string') {
  237. size = vars.get(size);
  238. }
  239. var buf = buffer.slice(offset, Math.min(buffer.length, offset + size));
  240. offset += size;
  241. vars.set(name, buf);
  242. return self;
  243. };
  244. self.skip = function (bytes) {
  245. if (typeof bytes === 'string') {
  246. bytes = vars.get(bytes);
  247. }
  248. offset += bytes;
  249. return self;
  250. };
  251. self.scan = function (name, search) {
  252. if (typeof search === 'string') {
  253. search = new Buffer(search);
  254. }
  255. else if (!Buffer.isBuffer(search)) {
  256. throw new Error('search must be a Buffer or a string');
  257. }
  258. vars.set(name, null);
  259. // simple but slow string search
  260. for (var i = 0; i + offset <= buffer.length - search.length + 1; i++) {
  261. for (
  262. var j = 0;
  263. j < search.length && buffer[offset+i+j] === search[j];
  264. j++
  265. );
  266. if (j === search.length) break;
  267. }
  268. vars.set(name, buffer.slice(offset, offset + i));
  269. offset += i + search.length;
  270. return self;
  271. };
  272. self.peek = function (cb) {
  273. var was = offset;
  274. cb.call(self, vars.store);
  275. offset = was;
  276. return self;
  277. };
  278. self.flush = function () {
  279. vars.store = {};
  280. return self;
  281. };
  282. self.eof = function () {
  283. return offset >= buffer.length;
  284. };
  285. return self;
  286. };
  287. // convert byte strings to unsigned little endian numbers
  288. function decodeLEu (bytes) {
  289. var acc = 0;
  290. for (var i = 0; i < bytes.length; i++) {
  291. acc += Math.pow(256,i) * bytes[i];
  292. }
  293. return acc;
  294. }
  295. // convert byte strings to unsigned big endian numbers
  296. function decodeBEu (bytes) {
  297. var acc = 0;
  298. for (var i = 0; i < bytes.length; i++) {
  299. acc += Math.pow(256, bytes.length - i - 1) * bytes[i];
  300. }
  301. return acc;
  302. }
  303. // convert byte strings to signed big endian numbers
  304. function decodeBEs (bytes) {
  305. var val = decodeBEu(bytes);
  306. if ((bytes[0] & 0x80) == 0x80) {
  307. val -= Math.pow(256, bytes.length);
  308. }
  309. return val;
  310. }
  311. // convert byte strings to signed little endian numbers
  312. function decodeLEs (bytes) {
  313. var val = decodeLEu(bytes);
  314. if ((bytes[bytes.length - 1] & 0x80) == 0x80) {
  315. val -= Math.pow(256, bytes.length);
  316. }
  317. return val;
  318. }
  319. function words (decode) {
  320. var self = {};
  321. [ 1, 2, 4, 8 ].forEach(function (bytes) {
  322. var bits = bytes * 8;
  323. self['word' + bits + 'le']
  324. = self['word' + bits + 'lu']
  325. = decode(bytes, decodeLEu);
  326. self['word' + bits + 'ls']
  327. = decode(bytes, decodeLEs);
  328. self['word' + bits + 'be']
  329. = self['word' + bits + 'bu']
  330. = decode(bytes, decodeBEu);
  331. self['word' + bits + 'bs']
  332. = decode(bytes, decodeBEs);
  333. });
  334. // word8be(n) == word8le(n) for all n
  335. self.word8 = self.word8u = self.word8be;
  336. self.word8s = self.word8bs;
  337. return self;
  338. }