From cec530b9428c475796f7f3a5a897752dbaf9c15e Mon Sep 17 00:00:00 2001 From: Teppo Kurki Date: Sun, 17 Mar 2019 17:12:58 +0200 Subject: [PATCH] feature: add callback interface to parse If a client app wants to keep of track of what output was generated from certain input an event based interface is less than ideal, so add an optional callback to parse(). --- lib/fromPgn.js | 41 +++++++++++++++++++++++------------------ test/test.js | 27 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/lib/fromPgn.js b/lib/fromPgn.js index d094941..3ace263 100644 --- a/lib/fromPgn.js +++ b/lib/fromPgn.js @@ -102,7 +102,7 @@ class Parser extends EventEmitter { this.mixedFormat = this.options.mixedFormat || false } - _parse(pgn, bs, len) { + _parse(pgn, bs, len, cb) { if ( ignoredPgns.indexOf(pgn.pgn) != -1 ) { this.emit('warning', pgn, 'ignoring pgn') return false @@ -155,6 +155,7 @@ class Parser extends EventEmitter { } else { if (packet.lastPacket + 1 != packetIndex) { debug(`PGN ${pgn.pgn} malformed packet for ${pgn.src} received; expected ${packet.lastPacket+1} but got ${packetIndex}`) + cb && cb(`Could not parse ${pgn}`) return; } //console.log(`targetStart: ${FASTPACKET_BUCKET_0_SIZE + FASTPACKET_BUCKET_N_SIZE * (bucket-1)} sourceStart: ${FASTPACKET_BUCKET_N_OFFSET} sourceEned: ${FASTPACKET_BUCKET_N_SIZE}`) @@ -228,24 +229,26 @@ class Parser extends EventEmitter { //console.log(`pgn: ${JSON.stringify(pgn)}`) this.emit('pgn', pgn) + cb && cb(undefined, pgn) return true } catch ( error ) { this.emit('error', pgn, error) + cb && cb(error) return false } } - parse(data) { + parse(data, cb) { if (_.isString(data) ) { - this.parseString(data) + this.parseString(data, cb) } else if ( _.isBuffer(data) ) { - this.parseBuffer(data) + this.parseBuffer(data, cb) } else { - this.parsePgnData(data.pgn, data.length, data.data) + this.parsePgnData(data.pgn, data.length, data.data, cb) } } - parsePgnData(pgn, length, data) { + parsePgnData(pgn, length, data, cb) { var buffer = data if ( !_.isBuffer(data) ) { var array = new Int16Array(length) @@ -257,7 +260,7 @@ class Parser extends EventEmitter { var bv = new BitView(buffer); var bs = new BitStream(bv) - if ( this._parse(pgn, bs, length) ) { + if ( this._parse(pgn, bs, length, cb) ) { debug('parsed pgn %j', pgn) } } @@ -266,11 +269,12 @@ class Parser extends EventEmitter { return sentence.startsWith('$PCDIN,') } - parseN2KOver0183(sentence) { + parseN2KOver0183(sentence, cb) { if ( sentence.startsWith('$PCDIN,') ) { - this.parsePCDIN(sentence) + this.parsePCDIN(sentence, cb) return true } + cb && cb(new Error('Unable to parse N2K over 0183')) return false } @@ -287,7 +291,7 @@ class Parser extends EventEmitter { } } - parsePCDIN(pgn_data) { + parsePCDIN(pgn_data, cb) { var split = pgn_data.split(',') var pgn = {} @@ -304,16 +308,16 @@ class Parser extends EventEmitter { const bs = new BitStream(Buffer.from(data, 'hex')) - if ( this._parse(pgn, bs, data.length/2) ) { + if ( this._parse(pgn, bs, data.length/2, cb) ) { debug('parsed pgn %j', pgn) } } - parseString (pgn_data) { + parseString (pgn_data, cb) { if (typeof pgn_data === 'string' && pgn_data.trim().length > 0) { if ( this.isN2KOver0183(pgn_data) ) { - this.parseN2KOver0183(pgn_data) + this.parseN2KOver0183(pgn_data, cb) return } @@ -357,13 +361,13 @@ class Parser extends EventEmitter { var bv = new BitView(buffer); var bs = new BitStream(bv) - if ( this._parse(pgn, bs, len) ) { + if ( this._parse(pgn, bs, len, cb) ) { debug('parsed pgn %j', pgn) } } } - parseBuffer (pgn_data) { + parseBuffer (pgn_data, cb) { try { var bv = new BitView(pgn_data); var bs = new BitStream(bv) @@ -378,13 +382,14 @@ class Parser extends EventEmitter { var timestamp = bs.readUint32() var len = bs.readUint8() - if ( this._parse(pgn, bs, len) ) { + if ( this._parse(pgn, bs, len, cb) ) { debug('parsed pgn %j', pgn) } } catch ( error ) { + const err = new Error(`error reading pgn ${JSON.stringify(pgn)} ${error}`) + cb && cb(err) this.emit('error', pgn, error) - console.error(`error reading pgn ${JSON.stringify(pgn)} ${error}`) - console.error(error.stack) + console.error(err) return false } } diff --git a/test/test.js b/test/test.js index d820c26..7922489 100644 --- a/test/test.js +++ b/test/test.js @@ -93,3 +93,30 @@ describe('to pgn test data converts', function () { }) }) }) + +describe('callback is called', function (done) { + const testData = require('./pgns/59392') + const fromPgn = new FromPgn({ format: 1 }) + + it('successfully for string input', done => { + fromPgn.parse(testData[0].input, (err, result) => { + result.should.deep.equal(testData[0].expected) + done() + }) + }) + + // it('with error', done => { + // const testData = require('./pgns/59392') + // const fromPgn = new FromPgn({ format: 1 }) + // //error is emitted, so we must have an error handler + // fromPgn.on('error', err => { }) + // fromPgn.parse(testData[0].input.replace(',ff,', ',kk,'), (err, result) => { + // try { + // (typeof err).should.not.equal('undefined') + // done() + // } catch (err) { + // done(err) + // } + // }) + // }) +})