summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/JSONStream/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/JSONStream/index.js')
-rwxr-xr-xdeps/npm/node_modules/JSONStream/index.js243
1 files changed, 243 insertions, 0 deletions
diff --git a/deps/npm/node_modules/JSONStream/index.js b/deps/npm/node_modules/JSONStream/index.js
new file mode 100755
index 0000000000..701b1fa4ae
--- /dev/null
+++ b/deps/npm/node_modules/JSONStream/index.js
@@ -0,0 +1,243 @@
+#! /usr/bin/env node
+
+'use strict'
+
+var Parser = require('jsonparse')
+ , through = require('through')
+
+/*
+
+ the value of this.stack that creationix's jsonparse has is weird.
+
+ it makes this code ugly, but his problem is way harder that mine,
+ so i'll forgive him.
+
+*/
+
+exports.parse = function (path, map) {
+ var header, footer
+ var parser = new Parser()
+ var stream = through(function (chunk) {
+ if('string' === typeof chunk)
+ chunk = new Buffer(chunk)
+ parser.write(chunk)
+ },
+ function (data) {
+ if(data)
+ stream.write(data)
+ if (header)
+ stream.emit('header', header)
+ if (footer)
+ stream.emit('footer', footer)
+ stream.queue(null)
+ })
+
+ if('string' === typeof path)
+ path = path.split('.').map(function (e) {
+ if (e === '$*')
+ return {emitKey: true}
+ else if (e === '*')
+ return true
+ else if (e === '') // '..'.split('.') returns an empty string
+ return {recurse: true}
+ else
+ return e
+ })
+
+
+ var count = 0, _key
+ if(!path || !path.length)
+ path = null
+
+ parser.onValue = function (value) {
+ if (!this.root)
+ stream.root = value
+
+ if(! path) return
+
+ var i = 0 // iterates on path
+ var j = 0 // iterates on stack
+ var emitKey = false;
+ while (i < path.length) {
+ var key = path[i]
+ var c
+ j++
+
+ if (key && !key.recurse) {
+ c = (j === this.stack.length) ? this : this.stack[j]
+ if (!c) return
+ if (! check(key, c.key)) {
+ setHeaderFooter(c.key, value)
+ return
+ }
+ emitKey = !!key.emitKey;
+ i++
+ } else {
+ i++
+ var nextKey = path[i]
+ if (! nextKey) return
+ while (true) {
+ c = (j === this.stack.length) ? this : this.stack[j]
+ if (!c) return
+ if (check(nextKey, c.key)) {
+ i++;
+ if (!Object.isFrozen(this.stack[j]))
+ this.stack[j].value = null
+ break
+ } else {
+ setHeaderFooter(c.key, value)
+ }
+ j++
+ }
+ }
+
+ }
+ if (j !== this.stack.length) return
+
+ count ++
+ var actualPath = this.stack.slice(1).map(function(element) { return element.key }).concat([this.key])
+ var data = this.value[this.key]
+ if(null != data)
+ if(null != (data = map ? map(data, actualPath) : data)) {
+ data = emitKey ? { value: data, key: this.key } : data;
+ stream.queue(data)
+ }
+ delete this.value[this.key]
+ for(var k in this.stack)
+ if (!Object.isFrozen(this.stack[k]))
+ this.stack[k].value = null
+
+ // emit header
+ if (header) {
+ stream.emit('header', header);
+ header = false;
+ }
+ }
+ parser._onToken = parser.onToken;
+
+ parser.onToken = function (token, value) {
+ parser._onToken(token, value);
+ if (this.stack.length === 0) {
+ if (stream.root) {
+ if(!path)
+ stream.queue(stream.root)
+ count = 0;
+ stream.root = null;
+ }
+ }
+ }
+
+ parser.onError = function (err) {
+ if(err.message.indexOf("at position") > -1)
+ err.message = "Invalid JSON (" + err.message + ")";
+ stream.emit('error', err)
+ }
+
+ return stream
+
+ function setHeaderFooter(key, value) {
+ // header has not been emitted yet
+ if (header !== false) {
+ header = header || {}
+ header[key] = value
+ }
+
+ // footer has not been emitted yet but header has
+ if (footer !== false && header === false) {
+ footer = footer || {}
+ footer[key] = value
+ }
+ }
+}
+
+function check (x, y) {
+ if ('string' === typeof x)
+ return y == x
+ else if (x && 'function' === typeof x.exec)
+ return x.exec(y)
+ else if ('boolean' === typeof x || 'object' === typeof x)
+ return x
+ else if ('function' === typeof x)
+ return x(y)
+ return false
+}
+
+exports.stringify = function (op, sep, cl, indent) {
+ indent = indent || 0
+ if (op === false){
+ op = ''
+ sep = '\n'
+ cl = ''
+ } else if (op == null) {
+
+ op = '[\n'
+ sep = '\n,\n'
+ cl = '\n]\n'
+
+ }
+
+ //else, what ever you like
+
+ var stream
+ , first = true
+ , anyData = false
+ stream = through(function (data) {
+ anyData = true
+ try {
+ var json = JSON.stringify(data, null, indent)
+ } catch (err) {
+ return stream.emit('error', err)
+ }
+ if(first) { first = false ; stream.queue(op + json)}
+ else stream.queue(sep + json)
+ },
+ function (data) {
+ if(!anyData)
+ stream.queue(op)
+ stream.queue(cl)
+ stream.queue(null)
+ })
+
+ return stream
+}
+
+exports.stringifyObject = function (op, sep, cl, indent) {
+ indent = indent || 0
+ if (op === false){
+ op = ''
+ sep = '\n'
+ cl = ''
+ } else if (op == null) {
+
+ op = '{\n'
+ sep = '\n,\n'
+ cl = '\n}\n'
+
+ }
+
+ //else, what ever you like
+
+ var first = true
+ var anyData = false
+ var stream = through(function (data) {
+ anyData = true
+ var json = JSON.stringify(data[0]) + ':' + JSON.stringify(data[1], null, indent)
+ if(first) { first = false ; this.queue(op + json)}
+ else this.queue(sep + json)
+ },
+ function (data) {
+ if(!anyData) this.queue(op)
+ this.queue(cl)
+
+ this.queue(null)
+ })
+
+ return stream
+}
+
+if(!module.parent && process.title !== 'browser') {
+ process.stdin
+ .pipe(exports.parse(process.argv[2]))
+ .pipe(exports.stringify('[', ',\n', ']\n', 2))
+ .pipe(process.stdout)
+}