tnetstrings
Version:
A fully-featured tnetstrings library, isomorphic to JSON
139 lines • 4.19 kB
JavaScript
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;
}