UNPKG

@kobold/excel

Version:

Kobold excel data handler

209 lines (158 loc) 7.47 kB
"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);