Last active
April 2, 2017 22:25
-
-
Save pascaldekloe/5653c8bb074ebd29ffcc0deece7495a4 to your computer and use it in GitHub Desktop.
Demo JavaScript Compilation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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