-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsonsparser.js
More file actions
57 lines (52 loc) · 1.47 KB
/
jsonsparser.js
File metadata and controls
57 lines (52 loc) · 1.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
'use strict'
const Duplex = require('stream').Duplex
const EventEmitter = require('events')
module.exports = class JSONsparser extends Duplex {
constructor(options = {}) {
// read JSONs from Stream
options.readableObjectMode = true
super(options)
// JSON is complete when brackets count is 0
this._brackets = 0
// Raw character from source
this._jsonStr = ''
// Pending JSONs to push
this._jsons = []
// JSON availability notifier
this._emitter = new EventEmitter()
}
_read() {
// Wait if no json ready
if(this._jsons.length === 0) {
var self = this
this._emitter.once('json', () => {
self.push(self._jsons.shift())
})
} else {
this._jsons.shift()
}
}
_write(chunk, encoding, callback) {
for(let char of chunk.toString()) {
if(char === '{' || char === '[') this._brackets++
if(this._brackets > 0) this._jsonStr += char
if((char === '}' || char === ']') && this._brackets > 0) this._brackets--
if(this._brackets === 0 && this._jsonStr.length !== 0) {
let json
try {
json = JSON.parse(this._jsonStr)
} catch(error) {
return process.nextTick(() => {
/// Emit error on parsing fail
callback(error)
})
}
this._jsons.push(json)
this._jsonStr = ''
// Notify pending jsons availability
this._emitter.emit('json')
}
}
process.nextTick(callback)
}
}