[PoC] Parse integer data
This adds a very rough, unfinished implementation for parsing little- and big-endian integers, based on my question here: https://github.com/nodejs/llparse/issues/31
See also these 2 PRs:
- https://github.com/indutny/llparse-builder/pull/1
- https://github.com/indutny/llparse-frontend/pull/1
This only includes the code to generate JS output (for now), and has no tests at all. 🤷♂ I'll try to flesh this out if I can find some more time.
Example input
const { LLParse } = require('./lib/api.js');
const p = new LLParse('colmetadata');
p.property('i16', 'userType');
p.property('i8', 'flags');
p.property('i8', 'type');
p.property('i32', 'dataLength');
p.property('i8', 'scale');
p.property('i8', 'precision');
p.property('i8', 'schemaPresent');
p.property('i8', 'dbNameLength');
p.property('i8', 'owningSchemaLength');
p.property('i16', 'xmlSchemaCollectionLength');
p.property('i8', 'collationLength');
p.property('i8', 'typeNameLength');
p.property('i16', 'assemblyNameLength');
const onCollation = p.span(p.code.span('on_collation'));
const onDbName = p.span(p.code.span('on_db_name'));
const onOwningSchema = p.span(p.code.span('on_owning_schema'));
const onXmlSchemaCollection = p.span(p.code.span('on_xml_schema_collection'));
const onTypeName = p.span(p.code.span('on_type_name'));
const onAssemblyName = p.span(p.code.span('on_assembly_name'));
const done = p.pause(1, "done");
function readUInt8(field, next) {
return p.uIntLE(field, 1).skipTo(next);
}
function readUInt16LE(field, next) {
return p.uIntLE(field, 2).skipTo(next);
}
function readUInt32LE(field, next) {
return p.uIntLE(field, 4).skipTo(next);
}
const dataLengthByte = readUInt8('dataLength', done);
const dataLengthShort = readUInt16LE('dataLength', done);
const dataLengthLong = readUInt32LE('dataLength', done);
const dataLengthByteWithScaleAndPrecision = readUInt8('dataLength', readUInt8('scale', readUInt8('precision', done)));
const collation = p.invoke(p.code.update('collationLength', 5)).
otherwise(
onCollation.start(
p.consume('collationLength').otherwise(onCollation.end(done)
)
)
);
const dataLengthShortWithCollation = readUInt16LE('dataLength', collation);
const dataLengthLongWithCollation = readUInt32LE('dataLength', collation);
function readBVarChar(name, span, next) {
return readUInt8(name + 'Length', span.start(p.consume(name + 'Length').otherwise(span.end(next))));
}
function readUsVarChar(name, span, next) {
return readUInt16LE(name + 'Length', span.start(p.consume(name + 'Length').otherwise(span.end(next))));
}
const schema = readUInt8('schemaPresent', p.invoke(p.code.load('schemaPresent'), {
0x01: readBVarChar('dbName', onDbName,
readBVarChar('owningSchema', onOwningSchema,
readUsVarChar('xmlSchemaCollection', onXmlSchemaCollection, done)
)
)
}).skipTo(done));
const udtInfo = readBVarChar('dbName', onDbName,
readBVarChar('owningSchema', onOwningSchema,
readBVarChar('typeName', onTypeName,
readUsVarChar('assemblyName', onAssemblyName, done)
)
)
);
const dataLengthShortWithUDTInfo = readUInt16LE('dataLength', udtInfo);
const TYPES = {
NULL: 0x1F,
TINYINT: 0x30,
BIT: 0x32,
SMALLINT: 0x34,
INT: 0x38,
SMALLDATETIME: 0x3A,
REAL: 0x3B,
MONEY: 0x3C,
DATETIME: 0x3D,
FLOAT: 0x3E,
SMALLMONEY: 0x7A,
BIGINT: 0x7F,
GUID: 0x24,
INTN: 0x26,
DECIMAL: 0x37,
NUMERIC: 0x3F,
BITN: 0x68,
DECIMALN: 0x6A,
NUMERICN: 0x6C,
FLOATN: 0x6D,
MONEYN: 0x6E,
DATETIMEN: 0x6F,
DATEN: 0x28,
TIMEN: 0x29,
DATETIME2N: 0x2A,
DATETIMEOFFSETN: 0x2B,
CHAR: 0x2F,
VARCHAR: 0x27,
BINARY: 0x2D,
VARBINARY: 0x25,
BIGVARBINARY: 0xA5,
BIGVARCHAR: 0xA7,
BIGBINARY: 0xAD,
BIGCHAR: 0XAF,
NVARCHAR: 0xE7,
NCHAR: 0xEF,
XML: 0xF1,
UDT: 0xF0,
TEXT: 0x23,
IMAGE: 0x22,
NTEXT: 0x63,
VARIANT: 0x62
}
const colmetadata =
readUInt32LE.call(null, 'userType',
readUInt16LE('flags',
readUInt8('type',
p.invoke(p.code.load('type'), {
[TYPES.NULL]: done,
[TYPES.TINYINT]: done,
[TYPES.SMALLINT]: done,
[TYPES.INT]: done,
[TYPES.BIGINT]: done,
[TYPES.REAL]: done,
[TYPES.FLOAT]: done,
[TYPES.SMALLMONEY]: done,
[TYPES.MONEY]: done,
[TYPES.BIT]: done,
[TYPES.SMALLDATETIME]: done,
[TYPES.DATETIME]: done,
[TYPES.INTN]: dataLengthByte,
[TYPES.FLOATN]: dataLengthByte,
[TYPES.MONEYN]: dataLengthByte,
[TYPES.BITN]: dataLengthByte,
[TYPES.GUID]: dataLengthByte,
[TYPES.DATETIMEN]: dataLengthByte,
[TYPES.TIMEN]: dataLengthByte,
[TYPES.DATETIME2N]: dataLengthByte,
[TYPES.DATETIMEOFFSETN]: dataLengthByte,
[TYPES.VARIANT]: dataLengthLong,
[TYPES.IMAGE]: dataLengthLong,
[TYPES.VARCHAR]: dataLengthByte,
[TYPES.CHAR]: dataLengthByte,
[TYPES.VARBINARY]: dataLengthByte,
[TYPES.BINARY]: dataLengthByte,
[TYPES.BIGVARCHAR]: dataLengthShortWithCollation,
[TYPES.BIGCHAR]: dataLengthShortWithCollation,
[TYPES.BIGVARBINARY]: dataLengthShort,
[TYPES.BIGBINARY]: dataLengthShort,
[TYPES.NVARCHAR]: dataLengthShortWithCollation,
[TYPES.NCHAR]: dataLengthShortWithCollation,
[TYPES.TEXT]: dataLengthLongWithCollation,
[TYPES.NTEXT]: dataLengthLongWithCollation,
[TYPES.XML]: schema,
[TYPES.NUMERICN]: dataLengthByteWithScaleAndPrecision,
[TYPES.DECIMALN]: dataLengthByteWithScaleAndPrecision,
[TYPES.NUMERIC]: dataLengthByteWithScaleAndPrecision,
[TYPES.DECIMAL]: dataLengthByteWithScaleAndPrecision,
[TYPES.UDT]: dataLengthShortWithUDTInfo
}).otherwise(p.error(1, "Unknown type"))
)
)
);
done.otherwise(colmetadata);
p.property('i8', 'field');
const artifacts = p.build(colmetadata, { js: { module: 'commonjs' } });
console.log(artifacts.js); // buffer
Example output
'use strict';
module.exports = (binding) => {
function unreachable() {
throw new Error('Unreachable');
}
const S_ERROR = 0;
const S_N_COLMETADATA__N_PAUSE = 1;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4 = 2;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3 = 3;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2 = 4;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE = 5;
const S_N_COLMETADATA__N_SPAN_END_ON_COLLATION = 6;
const S_N_COLMETADATA__N_CONSUME_COLLATIONLENGTH = 7;
const S_N_COLMETADATA__N_SPAN_START_ON_COLLATION = 8;
const S_N_COLMETADATA__N_INVOKE_UPDATE_COLLATIONLENGTH = 9;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4_1 = 10;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3_1 = 11;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2_1 = 12;
const S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_1 = 13;
const S_N_COLMETADATA__N_DATALENGTH_UINT_8 = 14;
const S_N_COLMETADATA__N_PRECISION_UINT_8 = 15;
const S_N_COLMETADATA__N_SCALE_UINT_8 = 16;
const S_N_COLMETADATA__N_DATALENGTH_UINT_8_1 = 17;
const S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2 = 18;
const S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE = 19;
const S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_1 = 20;
const S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1 = 21;
const S_N_COLMETADATA__N_SPAN_END_ON_ASSEMBLY_NAME = 22;
const S_N_COLMETADATA__N_CONSUME_ASSEMBLYNAMELENGTH = 23;
const S_N_COLMETADATA__N_SPAN_START_ON_ASSEMBLY_NAME = 24;
const S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE_BYTE2 = 25;
const S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE = 26;
const S_N_COLMETADATA__N_SPAN_END_ON_TYPE_NAME = 27;
const S_N_COLMETADATA__N_CONSUME_TYPENAMELENGTH = 28;
const S_N_COLMETADATA__N_SPAN_START_ON_TYPE_NAME = 29;
const S_N_COLMETADATA__N_TYPENAMELENGTH_UINT_8 = 30;
const S_N_COLMETADATA__N_SPAN_END_ON_OWNING_SCHEMA = 31;
const S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH = 32;
const S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA = 33;
const S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8 = 34;
const S_N_COLMETADATA__N_SPAN_END_ON_DB_NAME = 35;
const S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH = 36;
const S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME = 37;
const S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8 = 38;
const S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_2 = 39;
const S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_2 = 40;
const S_N_COLMETADATA__N_SPAN_END_ON_XML_SCHEMA_COLLECTION = 41;
const S_N_COLMETADATA__N_CONSUME_XMLSCHEMACOLLECTIONLENGTH = 42;
const S_N_COLMETADATA__N_SPAN_START_ON_XML_SCHEMA_COLLECTION = 43;
const S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE_BYTE2 = 44;
const S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE = 45;
const S_N_COLMETADATA__N_SPAN_END_ON_OWNING_SCHEMA_1 = 46;
const S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH_1 = 47;
const S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA_1 = 48;
const S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8_1 = 49;
const S_N_COLMETADATA__N_SPAN_END_ON_DB_NAME_1 = 50;
const S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH_1 = 51;
const S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME_1 = 52;
const S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8_1 = 53;
const S_N_COLMETADATA__N_INVOKE_LOAD_SCHEMAPRESENT = 54;
const S_N_COLMETADATA__N_SCHEMAPRESENT_UINT_8 = 55;
const S_N_COLMETADATA__N_ERROR = 56;
const S_N_COLMETADATA__N_INVOKE_LOAD_TYPE = 57;
const S_N_COLMETADATA__N_TYPE_UINT_8 = 58;
const S_N_COLMETADATA__N_FLAGS_UINT_16_LE_BYTE2 = 59;
const S_N_COLMETADATA__N_FLAGS_UINT_16_LE = 60;
const S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE4 = 61;
const S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE3 = 62;
const S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE2 = 63;
const S_N_COLMETADATA__N_USERTYPE_UINT_32_LE = 64;
const on_db_name = binding.on_db_name;
const on_owning_schema = binding.on_owning_schema;
const on_xml_schema_collection = binding.on_xml_schema_collection;
const on_type_name = binding.on_type_name;
const on_assembly_name = binding.on_assembly_name;
const on_collation = binding.on_collation;
class Parser {
constructor() {
this._index = 0;
this._current = S_N_COLMETADATA__N_USERTYPE_UINT_32_LE;
this._status = 0;
this.error = 0;
this.reason = null;
this.errorOff = 0;
this.userType = 0;
this.flags = 0;
this.type = 0;
this.dataLength = 0;
this.scale = 0;
this.precision = 0;
this.schemaPresent = 0;
this.dbNameLength = 0;
this.owningSchemaLength = 0;
this.xmlSchemaCollectionLength = 0;
this.collationLength = 0;
this.typeNameLength = 0;
this.assemblyNameLength = 0;
this.field = 0;
this._spanOff0 = -1;
this._spanCb0 = null;
}
_on_db_name(buf, off, offEnd) {
return on_db_name(this, buf, off, offEnd);
}
_on_owning_schema(buf, off, offEnd) {
return on_owning_schema(this, buf, off, offEnd);
}
_on_xml_schema_collection(buf, off, offEnd) {
return on_xml_schema_collection(this, buf, off, offEnd);
}
_on_type_name(buf, off, offEnd) {
return on_type_name(this, buf, off, offEnd);
}
_on_assembly_name(buf, off, offEnd) {
return on_assembly_name(this, buf, off, offEnd);
}
_on_collation(buf, off, offEnd) {
return on_collation(this, buf, off, offEnd);
}
_colmetadata__c_load_type(buf, off) {
return this.type;
}
_colmetadata__c_update_collationLength(buf, off) {
this.collationLength = 5;
return 0;
}
_colmetadata__c_load_schemaPresent(buf, off) {
return this.schemaPresent;
}
_run(current, buf, off) {
let match;
for (;;) {
switch (current | 0) {
case S_N_COLMETADATA__N_PAUSE: {
this.error = 0x1;
this.reason = "done";
this.errorOff = off;
this._current = S_N_COLMETADATA__N_USERTYPE_UINT_32_LE
return S_ERROR;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4;
}
this.dataLength += buf[off] * 2 ** 24;
off++;
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3;
}
this.dataLength += buf[off] * 2 ** 16;
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2;
}
this.dataLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_COLLATION: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_collation(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_PAUSE;
return S_ERROR;
}
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_COLLATIONLENGTH: {
let avail = buf.length - off;
const need = this.collationLength;
if (avail >= need) {
off += need;
this.collationLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_COLLATION;
continue;
}
this.collationLength -= avail;
return S_N_COLMETADATA__N_CONSUME_COLLATIONLENGTH;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_COLLATION: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_COLLATION;
}
this._spanOff0 = off;
this._spanCb0 = this._on_collation;
current = S_N_COLMETADATA__N_CONSUME_COLLATIONLENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_INVOKE_UPDATE_COLLATIONLENGTH: {
switch (this._colmetadata__c_update_collationLength(buf, off) | 0) {
default:
current = S_N_COLMETADATA__N_SPAN_START_ON_COLLATION;
continue;
}
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4_1;
}
this.dataLength += buf[off] * 2 ** 24;
off++;
current = S_N_COLMETADATA__N_INVOKE_UPDATE_COLLATIONLENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3_1;
}
this.dataLength += buf[off] * 2 ** 16;
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE4_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2_1;
}
this.dataLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE3_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_1;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_BYTE2_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_8;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_PRECISION_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_PRECISION_UINT_8;
}
this.precision = buf[off];
off++;
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SCALE_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SCALE_UINT_8;
}
this.scale = buf[off];
off++;
current = S_N_COLMETADATA__N_PRECISION_UINT_8;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_8_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_8_1;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_SCALE_UINT_8;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2;
}
this.dataLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_1;
}
this.dataLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_INVOKE_UPDATE_COLLATIONLENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_ASSEMBLY_NAME: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_assembly_name(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_PAUSE;
return S_ERROR;
}
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_ASSEMBLYNAMELENGTH: {
let avail = buf.length - off;
const need = this.assemblyNameLength;
if (avail >= need) {
off += need;
this.assemblyNameLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_ASSEMBLY_NAME;
continue;
}
this.assemblyNameLength -= avail;
return S_N_COLMETADATA__N_CONSUME_ASSEMBLYNAMELENGTH;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_ASSEMBLY_NAME: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_ASSEMBLY_NAME;
}
this._spanOff0 = off;
this._spanCb0 = this._on_assembly_name;
current = S_N_COLMETADATA__N_CONSUME_ASSEMBLYNAMELENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE_BYTE2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE_BYTE2;
}
this.assemblyNameLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_ASSEMBLY_NAME;
continue;
unreachable();
}
case S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE: {
if (off === buf.length) {
return S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE;
}
this.assemblyNameLength = buf[off];
off++;
current = S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE_BYTE2;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_TYPE_NAME: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_type_name(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE;
return S_ERROR;
}
current = S_N_COLMETADATA__N_ASSEMBLYNAMELENGTH_UINT_16_LE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_TYPENAMELENGTH: {
let avail = buf.length - off;
const need = this.typeNameLength;
if (avail >= need) {
off += need;
this.typeNameLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_TYPE_NAME;
continue;
}
this.typeNameLength -= avail;
return S_N_COLMETADATA__N_CONSUME_TYPENAMELENGTH;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_TYPE_NAME: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_TYPE_NAME;
}
this._spanOff0 = off;
this._spanCb0 = this._on_type_name;
current = S_N_COLMETADATA__N_CONSUME_TYPENAMELENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_TYPENAMELENGTH_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_TYPENAMELENGTH_UINT_8;
}
this.typeNameLength = buf[off];
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_TYPE_NAME;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_OWNING_SCHEMA: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_owning_schema(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_TYPENAMELENGTH_UINT_8;
return S_ERROR;
}
current = S_N_COLMETADATA__N_TYPENAMELENGTH_UINT_8;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH: {
let avail = buf.length - off;
const need = this.owningSchemaLength;
if (avail >= need) {
off += need;
this.owningSchemaLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_OWNING_SCHEMA;
continue;
}
this.owningSchemaLength -= avail;
return S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA;
}
this._spanOff0 = off;
this._spanCb0 = this._on_owning_schema;
current = S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8;
}
this.owningSchemaLength = buf[off];
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_DB_NAME: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_db_name(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8;
return S_ERROR;
}
current = S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH: {
let avail = buf.length - off;
const need = this.dbNameLength;
if (avail >= need) {
off += need;
this.dbNameLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_DB_NAME;
continue;
}
this.dbNameLength -= avail;
return S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME;
}
this._spanOff0 = off;
this._spanCb0 = this._on_db_name;
current = S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8;
}
this.dbNameLength = buf[off];
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_2;
}
this.dataLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_2;
}
this.dataLength = buf[off];
off++;
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_BYTE2_2;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_XML_SCHEMA_COLLECTION: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_xml_schema_collection(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_PAUSE;
return S_ERROR;
}
current = S_N_COLMETADATA__N_PAUSE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_XMLSCHEMACOLLECTIONLENGTH: {
let avail = buf.length - off;
const need = this.xmlSchemaCollectionLength;
if (avail >= need) {
off += need;
this.xmlSchemaCollectionLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_XML_SCHEMA_COLLECTION;
continue;
}
this.xmlSchemaCollectionLength -= avail;
return S_N_COLMETADATA__N_CONSUME_XMLSCHEMACOLLECTIONLENGTH;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_XML_SCHEMA_COLLECTION: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_XML_SCHEMA_COLLECTION;
}
this._spanOff0 = off;
this._spanCb0 = this._on_xml_schema_collection;
current = S_N_COLMETADATA__N_CONSUME_XMLSCHEMACOLLECTIONLENGTH;
continue;
unreachable();
}
case S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE_BYTE2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE_BYTE2;
}
this.xmlSchemaCollectionLength += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_XML_SCHEMA_COLLECTION;
continue;
unreachable();
}
case S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE: {
if (off === buf.length) {
return S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE;
}
this.xmlSchemaCollectionLength = buf[off];
off++;
current = S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE_BYTE2;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_OWNING_SCHEMA_1: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_owning_schema(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE;
return S_ERROR;
}
current = S_N_COLMETADATA__N_XMLSCHEMACOLLECTIONLENGTH_UINT_16_LE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH_1: {
let avail = buf.length - off;
const need = this.owningSchemaLength;
if (avail >= need) {
off += need;
this.owningSchemaLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_OWNING_SCHEMA_1;
continue;
}
this.owningSchemaLength -= avail;
return S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH_1;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA_1;
}
this._spanOff0 = off;
this._spanCb0 = this._on_owning_schema;
current = S_N_COLMETADATA__N_CONSUME_OWNINGSCHEMALENGTH_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8_1;
}
this.owningSchemaLength = buf[off];
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_OWNING_SCHEMA_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_END_ON_DB_NAME_1: {
const start = this._spanOff0;
this._spanOff0 = -1;
const err = this._on_db_name(buf, start, off) | 0;
if (err !== 0) {
this.error = err;
this.errorOff = off;
this._current = S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8_1;
return S_ERROR;
}
current = S_N_COLMETADATA__N_OWNINGSCHEMALENGTH_UINT_8_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH_1: {
let avail = buf.length - off;
const need = this.dbNameLength;
if (avail >= need) {
off += need;
this.dbNameLength = 0;
current = S_N_COLMETADATA__N_SPAN_END_ON_DB_NAME_1;
continue;
}
this.dbNameLength -= avail;
return S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH_1;
unreachable();
}
case S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME_1;
}
this._spanOff0 = off;
this._spanCb0 = this._on_db_name;
current = S_N_COLMETADATA__N_CONSUME_DBNAMELENGTH_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8_1: {
if (off === buf.length) {
return S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8_1;
}
this.dbNameLength = buf[off];
off++;
current = S_N_COLMETADATA__N_SPAN_START_ON_DB_NAME_1;
continue;
unreachable();
}
case S_N_COLMETADATA__N_INVOKE_LOAD_SCHEMAPRESENT: {
switch (this._colmetadata__c_load_schemaPresent(buf, off) | 0) {
case 1:
current = S_N_COLMETADATA__N_DBNAMELENGTH_UINT_8_1;
continue;
default:
off++;
current = S_N_COLMETADATA__N_PAUSE;
continue;
}
unreachable();
}
case S_N_COLMETADATA__N_SCHEMAPRESENT_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_SCHEMAPRESENT_UINT_8;
}
this.schemaPresent = buf[off];
off++;
current = S_N_COLMETADATA__N_INVOKE_LOAD_SCHEMAPRESENT;
continue;
unreachable();
}
case S_N_COLMETADATA__N_ERROR: {
this.error = 0x1;
this.reason = "Unknown type";
this.errorOff = off;
this._current = S_ERROR;
return S_ERROR;
unreachable();
}
case S_N_COLMETADATA__N_INVOKE_LOAD_TYPE: {
switch (this._colmetadata__c_load_type(buf, off) | 0) {
case 31:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 34:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE;
continue;
case 35:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_1;
continue;
case 36:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 37:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 38:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 39:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 41:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 42:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 43:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 45:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 47:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 48:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 50:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 52:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 55:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8_1;
continue;
case 56:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 58:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 59:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 60:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 61:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 62:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 63:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8_1;
continue;
case 98:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE;
continue;
case 99:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_32_LE_1;
continue;
case 104:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 106:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8_1;
continue;
case 108:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8_1;
continue;
case 109:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 110:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 111:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_8;
continue;
case 122:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 127:
current = S_N_COLMETADATA__N_PAUSE;
continue;
case 165:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE;
continue;
case 167:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1;
continue;
case 173:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE;
continue;
case 175:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1;
continue;
case 231:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1;
continue;
case 239:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_1;
continue;
case 240:
current = S_N_COLMETADATA__N_DATALENGTH_UINT_16_LE_2;
continue;
case 241:
current = S_N_COLMETADATA__N_SCHEMAPRESENT_UINT_8;
continue;
default:
current = S_N_COLMETADATA__N_ERROR;
continue;
}
unreachable();
}
case S_N_COLMETADATA__N_TYPE_UINT_8: {
if (off === buf.length) {
return S_N_COLMETADATA__N_TYPE_UINT_8;
}
this.type = buf[off];
off++;
current = S_N_COLMETADATA__N_INVOKE_LOAD_TYPE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_FLAGS_UINT_16_LE_BYTE2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_FLAGS_UINT_16_LE_BYTE2;
}
this.flags += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_TYPE_UINT_8;
continue;
unreachable();
}
case S_N_COLMETADATA__N_FLAGS_UINT_16_LE: {
if (off === buf.length) {
return S_N_COLMETADATA__N_FLAGS_UINT_16_LE;
}
this.flags = buf[off];
off++;
current = S_N_COLMETADATA__N_FLAGS_UINT_16_LE_BYTE2;
continue;
unreachable();
}
case S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE4: {
if (off === buf.length) {
return S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE4;
}
this.userType += buf[off] * 2 ** 24;
off++;
current = S_N_COLMETADATA__N_FLAGS_UINT_16_LE;
continue;
unreachable();
}
case S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE3: {
if (off === buf.length) {
return S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE3;
}
this.userType += buf[off] * 2 ** 16;
off++;
current = S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE4;
continue;
unreachable();
}
case S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE2: {
if (off === buf.length) {
return S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE2;
}
this.userType += buf[off] * 2 ** 8;
off++;
current = S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE3;
continue;
unreachable();
}
case S_N_COLMETADATA__N_USERTYPE_UINT_32_LE: {
if (off === buf.length) {
return S_N_COLMETADATA__N_USERTYPE_UINT_32_LE;
}
this.userType = buf[off];
off++;
current = S_N_COLMETADATA__N_USERTYPE_UINT_32_LE_BYTE2;
continue;
unreachable();
}
}
}
unreachable();
}
execute(buf) {
// check lingering errors
if (this.error !== 0) {
return this.error;
}
// restart spans
if (this._spanOff0 !== -1) {
this._spanOff0 = 0;
}
const next = this._run(this._current, buf, 0);
if (next === S_ERROR) {
return this.error;
}
this._current = next;
// execute spans
if (this._spanOff0 !== -1) {
const error = this._spanCb0(buf, this._spanOff0, buf.length) | 0;
if (error !== 0) {
this.error = error;
this.errorOff = buf.length;
return error;
}
}
return 0;
}
}
return Parser;
};
@indutny I see that properties don't carry any sign information - is that a purposeful design decision in llparse? Does that mean that property access in C needs to be casted appropriately to not get the unsigned value? Am I missing something? 🤔
@arthurschreiber this is a design decision that was historically motivated by bitcode output. C has to cast fields if a signed access is required.