Commit ba5bc34a authored by ZettaScript's avatar ZettaScript
Browse files

Initial commit

parents
This diff is collapsed.
# UBJSON-JS
## What is UBJSON?
UBJSON is a binary alternative to JSON, fully compatible with it. [It is described here.](http://ubjson.org)
## Why this library?
I found only one JavaScript library for parsing and dumping UBJSON ([by Shelacek](https://bitbucket.org/shelacek/ubjson/src/master/)), but it is made for NodeJS, not fully compatible with browsers and does not handle binary values (in addition, that implementation is too complex).
## Use it
Currently, this library only handles parsing. It is very simple:
<script type="text/javascript" src="ubjson.js"></script>
var raw = hex2bin("7b24552355035506666f6f626172ff55054c6f72656d455505697073756d55");
var data = ubjson_parse(raw);
// -> Object { foobar: 255, Lorem: 69, ipsum: 85 }
The following features aren't implemented yet:
* UBJSON encoding
* Parsing type int64
* Parsing type float32
* Parsing type float64
* Parsing type high-precision number
## License
This library is licensed under GNU AGPL v3+.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="ubjson.js"></script>
<title>UBJSON JS test</title>
</head>
<body>
<fieldset>
<legend>Decode UBJSON</legend>
<p>Result is logged in console.</p>
<label for="ubjson_decode_hex">raw UBJSON (hex):</label><br />
<textarea id="ubjson_decode_hex"></textarea><br />
<input type="button" value="Decode" onclick="console.log(ubjson_parse(hex2bin(document.getElementById('ubjson_decode_hex').value)));"
</fieldset>
</body>
</html>
/*
* JavaScript UBJSON parsing library (browser-compatible)
*
* CopyLeft 2019 Pascal Engélibert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
function hex2bin(h) {
var b = new Uint8Array(h.length/2);
for(var i=0,j=0; i<h.length; i+=2,j++) {
b[j] = parseInt(h[i]+h[i+1], 16);
}
return b;
}
/**
* @param {Uint8Array} raw UBJSON value
* @param {object} start Offset
* @param {number} marker Type marker, if not in raw
* @param {boolean} bin Convert `{$U#` to Uint8Array instead of Array
*/
function ubjson_parse(raw, start=null, marker=null, bin=true) {
if(!start)
start = {v: 0};
if(marker == null) {
marker = raw[start.v];
start.v ++;
}
switch(marker) {
case 90: // Z: null
return null;
break;
case 78: // N: no-op
return;
break;
case 84: // T: true
return true;
break;
case 70: // F: false
return false;
break;
case 105: // i: int8
var v = raw[start.v];
start.v ++;
return v - 256 * (v > 127);
break;
case 85: // U: uint8
start.v ++;
return raw[start.v-1];
break;
case 73: // I: int16
start.v += 2;
return ((raw[start.v-2] << 8) | raw[start.v-1]) - 65536 * (raw[start.v-2] > 127);
break;
case 108: // l: int32
start.v += 4;
return ((raw[start.v-4] << 24) | (raw[start.v-3] << 16) | (raw[start.v-2] << 8) | raw[start.v-1]);
break;
case 76: // L: int64
// TODO
break;
case 100: // d: float32
// TODO
break;
case 68: // D: float64
// TODO
break;
case 72: // H: high-precision number
// TODO
break;
case 67: // C: char
start.v ++;
return String.fromCharCode(raw[start.v-1]);
break;
case 83: // S: string
var l = ubjson_parse(raw, start);
var s = "";
for(var i=0; i<l; i++) {
s += String.fromCharCode(raw[start.v+i]);
}
start.v += l;
return s;
break;
case 91: // [: array
var m = null;
if(raw[start.v] == 36) { // $
m = raw[start.v+1];
start.v += 2;
}
var r = [];
if(raw[start.v] == 35) { // #
start.v ++;
for(var l=ubjson_parse(raw, start); l>0; l--) {
r.push(ubjson_parse(raw, start, m));
}
if(bin && m == 85) // U
r = new Uint8Array(r);
}
else {
while(raw[start.v] != 93) { // ]
r.push(ubjson_parse(raw, start, m));
}
start.v ++;
}
return r;
break;
case 123: // {: object
var m = null;
if(raw[start.v] == 36) { // $
m = raw[start.v+1];
start.v += 2;
}
var r = {};
if(raw[start.v] == 35) { // #
start.v ++;
for(var l=ubjson_parse(raw, start); l>0; l--) {
var s = ubjson_parse(raw, start, 83); // S
r[s] = ubjson_parse(raw, start, m);
}
}
else {
while(raw[start.v] != 125) { // }
var s = ubjson_parse(raw, start, 83); // S
r[s] = ubjson_parse(raw, start, m);
}
start.v ++;
}
return r;
break;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment