Skip to content

Instantly share code, notes, and snippets.

@pascaldekloe pascaldekloe/Colfer.js
Last active Apr 2, 2017

Embed
What would you like to do?
Demo JavaScript Compilation
// Code generated by colf(1); DO NOT EDIT.
// The compiler used schema file demo.colf for package demo.
// Package demo offers a demonstration.
// These comment lines will end up in the generated code.
var demo = new function() {
const EOF = 'colfer: EOF';
// The upper limit for serial byte sizes.
var colferSizeMax = 16 * 1024 * 1024;
// The upper limit for the number of elements in a list.
var colferListMax = 64 * 1024;
// Constructor.
// Course is the grounds where the game of golf is played.
// When init is provided all enumerable properties are merged into the new object a.k.a. shallow cloning.
this.Course = function(init) {
this.ID = 0;
this.name = '';
this.holes = [];
this.image = new Uint8Array(0);
this.tags = [];
for (var p in init) this[p] = init[p];
}
// Serializes the object into an Uint8Array.
// All null entries in property holes will be replaced with a new demo.Hole.
// All null entries in property tags will be replaced with an empty String.
this.Course.prototype.marshal = function() {
var segs = [];
if (this.ID) {
if (this.ID < 0)
throw 'colfer: demo/Course field ID out of reach: ' + this.ID;
if (this.ID > Number.MAX_SAFE_INTEGER)
throw 'colfer: demo/Course field ID exceeds Number.MAX_SAFE_INTEGER';
if (this.ID < 0x2000000000000) {
var seg = [0];
encodeVarint(seg, this.ID);
segs.push(seg);
} else {
var bytes = new Uint8Array(9);
bytes[0] = 0 | 128;
var view = new DataView(bytes.buffer);
view.setUint32(1, this.ID / 0x100000000);
view.setUint32(5, this.ID % 0x100000000);
segs.push(bytes)
}
}
if (this.name) {
var utf = encodeUTF8(this.name);
var seg = [1];
encodeVarint(seg, utf.length);
segs.push(seg);
segs.push(utf)
}
if (this.holes && this.holes.length) {
var a = this.holes;
if (a.length > colferListMax)
throw 'colfer: demo.course.holes length exceeds colferListMax';
var seg = [2];
encodeVarint(seg, a.length);
segs.push(seg);
for (var i = 0; i < a.length; i++) {
var v = a[i];
if (v == null) {
v = new demo.Hole();
a[i] = v;
}
segs.push(v.marshal());
};
}
if (this.image && this.image.length) {
var seg = [3];
encodeVarint(seg, this.image.length);
segs.push(seg);
segs.push(this.image);
}
if (this.tags && this.tags.length) {
var a = this.tags;
if (a.length > colferListMax)
throw 'colfer: demo.course.tags length exceeds colferListMax';
var seg = [4];
encodeVarint(seg, a.length);
segs.push(seg);
for (var i = 0; i < a.length; i++) {
var s = a[i];
if (s == null) {
s = "";
a[i] = s;
}
var utf = encodeUTF8(s);
seg = [];
encodeVarint(seg, utf.length);
segs.push(seg);
segs.push(utf)
}
}
var size = 1;
segs.forEach(function(seg) {
size += seg.length;
});
if (size > colferSizeMax)
throw 'colfer: demo.course serial size ' + size + ' exceeds ' + colferListMax + ' bytes';
var bytes = new Uint8Array(size);
var i = 0;
segs.forEach(function(seg) {
bytes.set(seg, i);
i += seg.length;
});
bytes[i] = 127;
return bytes;
}
// Deserializes the object from an Uint8Array and returns the number of bytes read.
this.Course.prototype.unmarshal = function(data) {
if (!data || ! data.length) throw EOF;
var header = data[0];
var i = 1;
var readHeader = function() {
if (i >= data.length) throw EOF;
header = data[i++];
}
var readVarint = function() {
var pos = 0, result = 0;
while (pos != 8) {
var c = data[i+pos];
result += (c & 127) * Math.pow(128, pos);
++pos;
if (c < 128) {
i += pos;
if (result > Number.MAX_SAFE_INTEGER) break;
return result;
}
if (pos == data.length) throw EOF;
}
return -1;
}
if (header == 0) {
var x = readVarint();
if (x < 0) throw 'colfer: demo/Course field ID exceeds Number.MAX_SAFE_INTEGER';
this.ID = x;
readHeader();
} else if (header == (0 | 128)) {
if (i + 8 > data.length) throw EOF;
var view = new DataView(data.buffer);
var x = view.getUint32(i) * 0x100000000;
x += view.getUint32(i + 4);
if (x > Number.MAX_SAFE_INTEGER)
throw 'colfer: demo/Course field ID exceeds Number.MAX_SAFE_INTEGER';
this.ID = x;
i += 8;
readHeader();
}
if (header == 1) {
var size = readVarint();
if (size < 0)
throw 'colfer: demo.course.name size exceeds Number.MAX_SAFE_INTEGER';
else if (size > colferSizeMax)
throw 'colfer: demo.course.name size ' + size + ' exceeds ' + colferSizeMax + ' UTF-8 bytes';
var to = i + size;
if (to > data.length) throw EOF;
this.name = decodeUTF8(data.subarray(i, to));
i = to;
readHeader();
}
if (header == 2) {
var length = readVarint();
if (length < 0)
throw 'colfer: demo.course.holes length exceeds Number.MAX_SAFE_INTEGER';
if (length > colferListMax)
throw 'colfer: demo.course.holes length ' + length + ' exceeds ' + colferListMax + ' elements';
while (--length >= 0) {
var o = new demo.Hole();
i += o.unmarshal(data.subarray(i));
this.holes.push(o);
}
readHeader();
}
if (header == 3) {
var size = readVarint();
if (size < 0)
throw 'colfer: demo.course.image size exceeds Number.MAX_SAFE_INTEGER';
else if (size > colferSizeMax)
throw 'colfer: demo.course.image size ' + size + ' exceeds ' + colferSizeMax + ' bytes';
var to = i + size;
if (to > data.length) throw EOF;
this.image = data.subarray(i, to);
i = to;
readHeader();
}
if (header == 4) {
var length = readVarint();
if (length < 0)
throw 'colfer: demo.course.tags length exceeds Number.MAX_SAFE_INTEGER';
if (length > colferListMax)
throw 'colfer: demo.course.tags length ' + length + ' exceeds ' + colferListMax + ' elements';
while (--length >= 0) {
var size = readVarint();
if (size < 0)
throw 'colfer: demo.course.tags element ' + this.tags.length + ' size exceeds Number.MAX_SAFE_INTEGER';
else if (size > colferSizeMax)
throw 'colfer: demo.course.tags element ' + this.tags.length + ' size ' + size + ' exceeds ' + colferSizeMax + ' UTF-8 bytes';
var to = i + size;
if (to > data.length) throw EOF;
this.tags.push(decodeUTF8(data.subarray(i, to)));
i = to;
}
readHeader();
}
if (header != 127) throw 'colfer: unknown header at byte ' + (i - 1);
if (i > colferSizeMax)
throw 'colfer: demo.course serial size ' + size + ' exceeds ' + colferSizeMax + ' bytes';
return i;
}
// Constructor.
// When init is provided all enumerable properties are merged into the new object a.k.a. shallow cloning.
this.Hole = function(init) {
// Lat is the latitude of the cup.
this.lat = 0;
// Lon is the longitude of the cup.
this.lon = 0;
// Par is the difficulty index.
this.par = 0;
// Water marks the presence of water.
this.water = false;
// Sand marks the presence of sand.
this.sand = false;
for (var p in init) this[p] = init[p];
}
// Serializes the object into an Uint8Array.
this.Hole.prototype.marshal = function() {
var segs = [];
if (this.lat || Number.isNaN(this.lat)) {
var bytes = new Uint8Array(9);
bytes[0] = 0;
new DataView(bytes.buffer).setFloat64(1, this.lat);
segs.push(bytes);
}
if (this.lon || Number.isNaN(this.lon)) {
var bytes = new Uint8Array(9);
bytes[0] = 1;
new DataView(bytes.buffer).setFloat64(1, this.lon);
segs.push(bytes);
}
if (this.par) {
if (this.par > 255 || this.par < 0)
throw 'colfer: demo/Hole field par out of reach: ' + this.par;
segs.push([2, this.par]);
}
if (this.water)
segs.push([3]);
if (this.sand)
segs.push([4]);
var size = 1;
segs.forEach(function(seg) {
size += seg.length;
});
if (size > colferSizeMax)
throw 'colfer: demo.hole serial size ' + size + ' exceeds ' + colferListMax + ' bytes';
var bytes = new Uint8Array(size);
var i = 0;
segs.forEach(function(seg) {
bytes.set(seg, i);
i += seg.length;
});
bytes[i] = 127;
return bytes;
}
// Deserializes the object from an Uint8Array and returns the number of bytes read.
this.Hole.prototype.unmarshal = function(data) {
if (!data || ! data.length) throw EOF;
var header = data[0];
var i = 1;
var readHeader = function() {
if (i >= data.length) throw EOF;
header = data[i++];
}
var readVarint = function() {
var pos = 0, result = 0;
while (pos != 8) {
var c = data[i+pos];
result += (c & 127) * Math.pow(128, pos);
++pos;
if (c < 128) {
i += pos;
if (result > Number.MAX_SAFE_INTEGER) break;
return result;
}
if (pos == data.length) throw EOF;
}
return -1;
}
if (header == 0) {
if (i + 8 > data.length) throw EOF;
this.lat = new DataView(data.buffer).getFloat64(i);
i += 8;
readHeader();
}
if (header == 1) {
if (i + 8 > data.length) throw EOF;
this.lon = new DataView(data.buffer).getFloat64(i);
i += 8;
readHeader();
}
if (header == 2) {
if (i + 1 >= data.length) throw EOF;
this.par = data[i++];
header = data[i++];
}
if (header == 3) {
this.water = true;
readHeader();
}
if (header == 4) {
this.sand = true;
readHeader();
}
if (header != 127) throw 'colfer: unknown header at byte ' + (i - 1);
if (i > colferSizeMax)
throw 'colfer: demo.hole serial size ' + size + ' exceeds ' + colferSizeMax + ' bytes';
return i;
}
// private section
var encodeVarint = function(bytes, x) {
while (x > 127) {
bytes.push(x|128);
x /= 128;
}
bytes.push(x&127);
return bytes;
}
var encodeUTF8 = function(s) {
var i = 0;
var bytes = new Uint8Array(s.length * 4);
for (var ci = 0; ci != s.length; ci++) {
var c = s.charCodeAt(ci);
if (c < 128) {
bytes[i++] = c;
continue;
}
if (c < 2048) {
bytes[i++] = c >> 6 | 192;
} else {
if (c > 0xd7ff && c < 0xdc00) {
if (++ci == s.length) throw 'UTF-8 encode: incomplete surrogate pair';
var c2 = s.charCodeAt(ci);
if (c2 < 0xdc00 || c2 > 0xdfff) throw 'UTF-8 encode: second char code 0x' + c2.toString(16) + ' at index ' + ci + ' in surrogate pair out of range';
c = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);
bytes[i++] = c >> 18 | 240;
bytes[i++] = c>> 12 & 63 | 128;
} else { // c <= 0xffff
bytes[i++] = c >> 12 | 224;
}
bytes[i++] = c >> 6 & 63 | 128;
}
bytes[i++] = c & 63 | 128;
}
return bytes.subarray(0, i);
}
var decodeUTF8 = function(bytes) {
var s = '';
var i = 0;
while (i < bytes.length) {
var c = bytes[i++];
if (c > 127) {
if (c > 191 && c < 224) {
if (i >= bytes.length) throw 'UTF-8 decode: incomplete 2-byte sequence';
c = (c & 31) << 6 | bytes[i] & 63;
} else if (c > 223 && c < 240) {
if (i + 1 >= bytes.length) throw 'UTF-8 decode: incomplete 3-byte sequence';
c = (c & 15) << 12 | (bytes[i] & 63) << 6 | bytes[++i] & 63;
} else if (c > 239 && c < 248) {
if (i+2 >= bytes.length) throw 'UTF-8 decode: incomplete 4-byte sequence';
c = (c & 7) << 18 | (bytes[i] & 63) << 12 | (bytes[++i] & 63) << 6 | bytes[++i] & 63;
} else throw 'UTF-8 decode: unknown multibyte start 0x' + c.toString(16) + ' at index ' + (i - 1);
++i;
}
if (c <= 0xffff) s += String.fromCharCode(c);
else if (c <= 0x10ffff) {
c -= 0x10000;
s += String.fromCharCode(c >> 10 | 0xd800)
s += String.fromCharCode(c & 0x3FF | 0xdc00)
} else throw 'UTF-8 decode: code point 0x' + c.toString(16) + ' exceeds UTF-16 reach';
}
return s;
}
}
// NodeJS:
if (typeof exports !== 'undefined') exports.demo = demo;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.