diff options
Diffstat (limited to 'deps/npm/node_modules/JSONStream/index.js')
-rwxr-xr-x | deps/npm/node_modules/JSONStream/index.js | 243 |
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) +} |