UNPKG

tnetstrings

Version:

A fully-featured tnetstrings library, isomorphic to JSON

139 lines 4.19 kB
var TNETS; TNETS = (function() { var assert, dumpArray, dumpObject, isArray, parse, parseArray, parseChunk, parseObject, parsePair, parsePayload, stringify; assert = function(test, msg) { if (!test) { throw msg; } }; if (typeof Array.isArray === 'function') { isArray = Array.isArray; } else { isArray = function(a) { return Object.prototype.toString.call(a) === '[object Array]'; }; } parsePayload = function(data) { var colonIndex, extra, length, payload, payloadType, remain; assert(data, "invalid data to parseChunk, it's empty."); colonIndex = data.indexOf(':'); assert(colonIndex > 0, "invalid length spec"); length = data.slice(0, colonIndex); extra = data.slice(colonIndex + 1); assert(!/\D/.test(length), "non-numeric characters in length spec"); length = +length; payload = extra.slice(0, length); payloadType = extra.charAt(length); remain = extra.slice(length + 1); return [payload, payloadType, remain]; }; parseArray = function(data) { var result, value, _ref; result = []; while (data.length > 0) { _ref = parseChunk(data), value = _ref[0], data = _ref[1]; result[result.length] = value; } return result; }; parsePair = function(data) { var extra, key, value, _ref, _ref2; _ref = parseChunk(data), key = _ref[0], extra = _ref[1]; assert(extra.length, "Unbalanced dictionary"); _ref2 = parseChunk(extra), value = _ref2[0], extra = _ref2[1]; return [key, value, extra]; }; parseObject = function(data) { var key, result, value, _ref; result = {}; while (data.length > 0) { _ref = parsePair(data), key = _ref[0], value = _ref[1], data = _ref[2]; result[key] = value; } return result; }; dumpArray = function(arr) { var el, payload; payload = ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = arr.length; _i < _len; _i++) { el = arr[_i]; _results.push(stringify(el)); } return _results; })()).join(''); return "" + payload.length + ":" + payload + "]"; }; dumpObject = function(obj) { var k, payload, v; payload = ((function() { var _results; _results = []; for (k in obj) { v = obj[k]; _results.push(stringify(k) + stringify(v)); } return _results; })()).join(''); return "" + payload.length + ":" + payload + "}"; }; parseChunk = function(data) { var payload, payloadType, remain, value, _ref; _ref = parsePayload(data), payload = _ref[0], payloadType = _ref[1], remain = _ref[2]; value = (function() { switch (payloadType) { case '#': case '^': return +payload; case '}': return parseObject(payload); case ']': return parseArray(payload); case '!': return payload === 'true'; case ',': return payload; case '~': assert(payload.length === 0, "payload size must be zero for null"); return null; default: return assert(false, "invalid payload type: " + payloadType); } })(); return [value, remain]; }; parse = function(data) { return parseChunk(data)[0]; }; stringify = function(obj, opts) { var type; opts || (opts = {}); if (!(obj != null)) { return '0:~'; } assert(typeof obj !== 'function', "TNETS can't stringify a function"); if (typeof obj === 'string' || obj instanceof String) { return "" + obj.length + ":" + obj + ","; } else if (typeof obj === 'number') { type = Math.floor(obj) === obj && opts.type !== 'float' ? '#' : '^'; obj = '' + obj; return "" + obj.length + ":" + obj + type; } else if (typeof obj === 'boolean') { obj = '' + obj; return "" + obj.length + ":" + obj + "!"; } else if (isArray(obj)) { return dumpArray(obj); } else { return dumpObject(obj); } }; return { parse: parse, parseChunk: parseChunk, stringify: stringify }; })(); if (typeof exports !== 'undefined') { exports.TNETS = TNETS; }