@kobold/excel
Version:
Kobold excel data handler
209 lines (158 loc) • 7.47 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js/object/define-property");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports.Row = void 0;
var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js/instance/index-of"));
var _findIndex = _interopRequireDefault(require("@babel/runtime-corejs3/core-js/instance/find-index"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
var _files = require("./files");
var _utilities = require("./utilities");
// uint16 subrowId
const SUBROW_HEADER_SIZE = 2;
class Row {
static get sheet() {
if (this._sheet != null) {
return this._sheet;
}
throw new Error(`Missing \`static sheet\` declaration on ${this.name}.`);
}
static set sheet(value) {
this._sheet = value;
}
// TODO: Consider moving row parsing logic to an external class so consumers aren't dodging all the private members
// That, or use es private fields?
constructor(opts) {
(0, _defineProperty2.default)(this, "index", void 0);
(0, _defineProperty2.default)(this, "subIndex", void 0);
(0, _defineProperty2.default)(this, "sheetHeader", void 0);
(0, _defineProperty2.default)(this, "data", void 0);
(0, _defineProperty2.default)(this, "currentColumn", 0);
this.index = opts.index;
this.subIndex = opts.subIndex;
this.sheetHeader = opts.sheetHeader;
this.data = opts.data;
}
getColumnDefinition(opts) {
if ((opts === null || opts === void 0 ? void 0 : opts.offset) != null) {
var _context;
const index = (0, _findIndex.default)(_context = this.sheetHeader.columns).call(_context, column => column.offset === opts.offset);
(0, _utilities.assert)(index !== -1, `Explicit offset ${opts.offset} does not match any column definitions.`);
this.currentColumn = index;
} else if ((opts === null || opts === void 0 ? void 0 : opts.column) != null) {
this.currentColumn = opts.column;
}
(0, _utilities.assert)(this.currentColumn < this.sheetHeader.columns.length, `Defined column ${this.currentColumn} exceeds maximum of ${this.sheetHeader.columns.length - 1}`);
const baseDefinition = this.sheetHeader.columns[this.currentColumn++];
const offset = this.sheetHeader.variant === _files.Variant.SUBROWS ? this.calculateSubrowOffset(baseDefinition.offset) : baseDefinition.offset;
return { ...baseDefinition,
offset
};
}
calculateSubrowOffset(baseOffset) {
const subrowOffset = this.subIndex * (this.sheetHeader.rowSize + SUBROW_HEADER_SIZE);
return subrowOffset + SUBROW_HEADER_SIZE + baseOffset;
}
unknown(opts) {
const definition = this.getColumnDefinition(opts);
switch (definition.dataType) {
case _files.ColumnDataType.BOOLEAN:
case _files.ColumnDataType.PACKED_BOOL_0:
case _files.ColumnDataType.PACKED_BOOL_1:
case _files.ColumnDataType.PACKED_BOOL_2:
case _files.ColumnDataType.PACKED_BOOL_3:
case _files.ColumnDataType.PACKED_BOOL_4:
case _files.ColumnDataType.PACKED_BOOL_5:
case _files.ColumnDataType.PACKED_BOOL_6:
case _files.ColumnDataType.PACKED_BOOL_7:
return this.boolean(opts);
case _files.ColumnDataType.STRING:
return this.string(opts);
case _files.ColumnDataType.INT_8:
case _files.ColumnDataType.UINT_8:
case _files.ColumnDataType.INT_16:
case _files.ColumnDataType.UINT_16:
case _files.ColumnDataType.INT_32:
case _files.ColumnDataType.UINT_32:
case _files.ColumnDataType.FLOAT_32:
return this.number(opts);
case _files.ColumnDataType.INT_64:
case _files.ColumnDataType.UINT_64:
return this.bigint(opts);
default:
throw new _utilities.UnreachableError(definition.dataType);
}
}
string(opts) {
var _context2;
// Subrow sheets nessecarily cannot contain strings
(0, _utilities.assert)(this.sheetHeader.variant !== _files.Variant.SUBROWS, `Sheets of type SUBROWS do not support string values`);
const definition = this.getColumnDefinition(opts);
(0, _utilities.assert)(definition.dataType === _files.ColumnDataType.STRING, this.getUnsupportedMessage('string', definition)); // Get the specified offset of the start of the string, and search from there
// for the following null byte, marking the end.
const stringOffset = this.data.readUInt32BE(definition.offset);
const dataOffset = stringOffset + this.sheetHeader.rowSize;
const nullByteOffset = (0, _indexOf.default)(_context2 = this.data).call(_context2, 0, dataOffset);
return this.data.toString('utf8', dataOffset, nullByteOffset);
}
boolean(opts) {
const definition = this.getColumnDefinition(opts);
switch (definition.dataType) {
case _files.ColumnDataType.BOOLEAN:
return this.data.readUInt8(definition.offset) !== 0;
case _files.ColumnDataType.PACKED_BOOL_0:
case _files.ColumnDataType.PACKED_BOOL_1:
case _files.ColumnDataType.PACKED_BOOL_2:
case _files.ColumnDataType.PACKED_BOOL_3:
case _files.ColumnDataType.PACKED_BOOL_4:
case _files.ColumnDataType.PACKED_BOOL_5:
case _files.ColumnDataType.PACKED_BOOL_6:
case _files.ColumnDataType.PACKED_BOOL_7:
{
const bit = 1 << definition.dataType - _files.ColumnDataType.PACKED_BOOL_0;
const value = this.data.readUInt8(definition.offset);
return (value & bit) === bit;
}
} // TODO: assert.fail
throw new Error(this.getUnsupportedMessage('boolean', definition));
}
number(opts) {
const definition = this.getColumnDefinition(opts);
switch (definition.dataType) {
case _files.ColumnDataType.INT_8:
return this.data.readInt8(definition.offset);
case _files.ColumnDataType.UINT_8:
return this.data.readUInt8(definition.offset);
case _files.ColumnDataType.INT_16:
return this.data.readInt16BE(definition.offset);
case _files.ColumnDataType.UINT_16:
return this.data.readUInt16BE(definition.offset);
case _files.ColumnDataType.INT_32:
return this.data.readInt32BE(definition.offset);
case _files.ColumnDataType.UINT_32:
return this.data.readUInt32BE(definition.offset);
case _files.ColumnDataType.FLOAT_32:
return this.data.readFloatBE(definition.offset);
} // TODO: assert.fail
throw new Error(this.getUnsupportedMessage('number', definition));
}
bigint(opts) {
const definition = this.getColumnDefinition(opts);
switch (definition.dataType) {
case _files.ColumnDataType.INT_64:
return this.data.readBigInt64BE(definition.offset);
case _files.ColumnDataType.UINT_64:
return this.data.readBigUInt64BE(definition.offset);
} // TODO: assert.fail
throw new Error(this.getUnsupportedMessage('bigint', definition));
}
getUnsupportedMessage(requestedType, column) {
var _context3;
const columnIndex = (0, _indexOf.default)(_context3 = this.sheetHeader.columns).call(_context3, column);
return `Unsupported ${requestedType} data type ${_files.ColumnDataType[column.dataType]} at offset ${column.offset} (column ${columnIndex})`;
}
}
exports.Row = Row;
(0, _defineProperty2.default)(Row, "_sheet", void 0);