qvdjs 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -4
- package/dist/index.cjs +47 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +46 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/QvdErrors.js","../src/QvdSymbol.js","../src/util/validatePath.js","../src/QvdFileWriter.js","../src/util/bitUtils.js","../src/util/memoryUtils.js","../src/util/validationUtils.js","../src/util/symbolParser.js","../src/QvdFileReader.js","../src/QvdDataFrame.js","../src/index.js"],"names":["path","fs","xml","assert","QvdFileWriter","QvdFileReader"],"mappings":"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","file":"index.js","sourcesContent":["// @ts-check\n\n/**\n * Base error class for all QVD-related errors.\n * Provides structured error information with error codes and context.\n */\nexport class QvdError extends Error {\n /**\n * Constructs a new QVD error.\n *\n * @param {string} message The error message.\n * @param {string} code The error code.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, code, context = {}) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.context = context;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when parsing a QVD file fails.\n * Used for issues during XML header parsing, symbol table parsing, or index table parsing.\n */\nexport class QvdParseError extends QvdError {\n /**\n * Constructs a new QVD parse error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_PARSE_ERROR', context);\n }\n}\n\n/**\n * Error thrown when input validation fails.\n * Used for invalid parameters, out of bounds access, or missing required data.\n */\nexport class QvdValidationError extends QvdError {\n /**\n * Constructs a new QVD validation error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_VALIDATION_ERROR', context);\n }\n}\n\n/**\n * Error thrown when file system operations fail.\n * Used for issues reading or writing QVD files.\n */\nexport class QvdIOError extends QvdError {\n /**\n * Constructs a new QVD IO error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_IO_ERROR', context);\n }\n}\n\n/**\n * Error thrown when a QVD file is corrupted or malformed.\n * Used for missing headers, invalid data structures, or corrupted data.\n */\nexport class QvdCorruptedError extends QvdError {\n /**\n * Constructs a new QVD corrupted error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_CORRUPTED_ERROR', context);\n }\n}\n\n/**\n * Error thrown when security violations occur.\n * Used for path traversal attempts, XXE attacks, or other security issues.\n */\nexport class QvdSecurityError extends QvdError {\n /**\n * Constructs a new QVD security error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_SECURITY_ERROR', context);\n }\n}\n","// @ts-check\n\nimport {QvdValidationError} from './QvdErrors.js';\n\n/**\n * Represents a Qlik symbol/value, stored in a QVD file.\n */\nexport class QvdSymbol {\n /**\n * Constructs a new QVD symbol.\n *\n * @param {number|null} intValue The integer value.\n * @param {number|null} doubleValue The double value.\n * @param {string|null} stringValue The string value.\n */\n constructor(intValue, doubleValue, stringValue) {\n this._intValue = intValue;\n\n this._doubleValue = doubleValue;\n\n this._stringValue = stringValue;\n }\n\n /**\n * Returns the integer value of this symbol.\n *\n * @return {number|null} The integer value.\n */\n get intValue() {\n return this._intValue;\n }\n\n /**\n * Returns the double value of this symbol.\n *\n * @return {number|null} The double value.\n */\n get doubleValue() {\n return this._doubleValue;\n }\n\n /**\n * Returns the string value of this symbol.\n *\n * @return {string|null} The string value.\n */\n get stringValue() {\n return this._stringValue;\n }\n\n /**\n * Retrieves the primary value of this symbol. The primary value is descriptive raw value.\n * It is either the string value, the integer value or the double value, prioritized in this order.\n *\n * @return {number|string|null} The primary value.\n */\n toPrimaryValue() {\n if (null != this._stringValue) {\n return this._stringValue;\n } else if (null != this._intValue) {\n return this._intValue;\n } else if (null != this._doubleValue) {\n return this._doubleValue;\n } else {\n return null;\n }\n }\n\n /**\n * Converts the symbol to its byte representation.\n *\n * @return {Buffer} The byte representation of the symbol.\n */\n toByteRepresentation() {\n if (this._intValue !== null && this._stringValue !== null) {\n const intBuffer = Buffer.alloc(4);\n intBuffer.writeInt32LE(this._intValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n const stringBuffer = Buffer.concat([Buffer.from(this._stringValue, 'utf-8'), Buffer.from([0])]);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([5]), intBuffer, stringBuffer]);\n } else if (this._doubleValue !== null && this._stringValue !== null) {\n const floatBuffer = Buffer.alloc(8);\n floatBuffer.writeDoubleLE(this._doubleValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n const stringBuffer = Buffer.concat([Buffer.from(this._stringValue, 'utf-8'), Buffer.from([0])]);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([6]), floatBuffer, stringBuffer]);\n } else if (this._intValue !== null) {\n const buffer = Buffer.alloc(4);\n buffer.writeInt32LE(this._intValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([1]), buffer]);\n } else if (this._doubleValue !== null) {\n const buffer = Buffer.alloc(8);\n buffer.writeDoubleLE(this._doubleValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([2]), buffer]);\n } else if (this._stringValue !== null) {\n // @ts-ignore - Buffer.concat type compatibility\n const buffer = Buffer.concat([Buffer.from(this._stringValue, 'utf-8'), Buffer.from([0])]);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([4]), buffer]);\n } else {\n throw new QvdValidationError('The symbol does not contain any value.', {\n intValue: this._intValue,\n doubleValue: this._doubleValue,\n stringValue: this._stringValue,\n });\n }\n }\n\n /**\n * Checks if this symbol is equal to another symbol.\n *\n * @param {*} value The object to compare with.\n * @return {boolean} True if the objects are equal, false otherwise.\n */\n equals(value) {\n if (!(value instanceof QvdSymbol)) {\n return false;\n }\n\n return (\n this._intValue === value.intValue &&\n this._doubleValue === value.doubleValue &&\n this._stringValue === value.stringValue\n );\n }\n\n /**\n * Constructs a pure integer value symbol.\n *\n * @param {number} intValue The integer value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromIntValue(intValue) {\n return new QvdSymbol(intValue, null, null);\n }\n\n /**\n * Constructs a pure double value symbol.\n *\n * @param {number} doubleValue The double value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromDoubleValue(doubleValue) {\n return new QvdSymbol(null, doubleValue, null);\n }\n\n /**\n * Constructs a pure string value symbol.\n *\n * @param {string} stringValue The string value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromStringValue(stringValue) {\n return new QvdSymbol(null, null, stringValue);\n }\n\n /**\n * Constructs a dual value symbol from an integer and a string value.\n *\n * @param {number} intValue The integer value.\n * @param {string} stringValue The string value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromDualIntValue(intValue, stringValue) {\n return new QvdSymbol(intValue, null, stringValue);\n }\n\n /**\n * Constructs a dual value symbol from a double and a string value.\n *\n * @param {number} doubleValue The double value.\n * @param {string} stringValue The string value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromDualDoubleValue(doubleValue, stringValue) {\n return new QvdSymbol(null, doubleValue, stringValue);\n }\n}\n","// @ts-check\n\nimport path from 'path';\nimport {QvdSecurityError} from '../QvdErrors.js';\n\n/**\n * Validates that a file path does not contain path traversal sequences.\n *\n * @param {string} filePath The path to validate.\n * @param {string} [allowedDir] Optional allowed directory path. If not provided, defaults to the\n * current working directory to prevent path traversal attacks.\n * @throws {QvdSecurityError} If path traversal is detected.\n * @return {string} The resolved absolute path.\n */\nexport function validatePath(filePath, allowedDir) {\n // Check for null bytes which can be used in path traversal attacks\n if (filePath.includes('\\0')) {\n throw new QvdSecurityError('Path traversal detected: Null byte in path', {\n path: filePath,\n reason: 'null_byte',\n });\n }\n\n // Default to current working directory if no allowed directory is specified\n // This prevents path traversal attacks by ensuring files can only be accessed\n // within the CWD or a more restrictive allowed directory\n const baseDir = allowedDir || process.cwd();\n const resolvedBaseDir = path.resolve(baseDir);\n const resolvedPath = path.resolve(filePath);\n\n // Ensure the resolved path is within the allowed directory\n // Use path.sep to ensure proper directory boundary checking across platforms\n // On Windows and macOS (default APFS), file systems are case-insensitive,\n // so we need case-insensitive comparison. On Linux, use case-sensitive comparison.\n const isCaseInsensitiveFS = process.platform === 'win32' || process.platform === 'darwin';\n const baseForComparison = isCaseInsensitiveFS ? resolvedBaseDir.toLowerCase() : resolvedBaseDir;\n const pathForComparison = isCaseInsensitiveFS ? resolvedPath.toLowerCase() : resolvedPath;\n\n if (!pathForComparison.startsWith(baseForComparison + path.sep) && pathForComparison !== baseForComparison) {\n throw new QvdSecurityError('Path traversal detected: Access denied', {\n path: filePath,\n resolvedPath,\n allowedDir: resolvedBaseDir,\n reason: 'outside_allowed_directory',\n });\n }\n\n return resolvedPath;\n}\n","// @ts-check\n\nimport fs from 'fs';\nimport path from 'path';\nimport crypto from 'crypto';\nimport xml from 'xml2js';\nimport assert from 'assert';\nimport {QvdSymbol} from './QvdSymbol.js';\nimport {validatePath} from './util/validatePath.js';\n\n/**\n * @typedef {import('./QvdDataFrame.js').QvdDataFrame} QvdDataFrame\n */\n\n/**\n * Persists a QVD file to disk.\n */\nexport class QvdFileWriter {\n /**\n * Constructs a new QVD file writer.\n *\n * @param {string} filePath The path to the QVD file to write.\n * @param {QvdDataFrame} df The data frame to write to the QVD file.\n * @param {Object} [options={}] Options for the writer.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file\n * path must be within this directory. Defaults to current working directory.\n * @param {Function} [options.onProgress] Optional progress callback function.\n */\n constructor(filePath, df, options = {}) {\n const {allowedDir, onProgress} = options;\n this._path = validatePath(filePath, allowedDir);\n this._df = df;\n this._onProgress = onProgress;\n this._header = null;\n this._symbolBuffer = null;\n /** @type {Array<Array<import('./QvdSymbol.js').QvdSymbol>>|null} */\n this._symbolTable = null;\n /** @type {Array<any>|null} */\n this._symbolTableMetadata = null;\n this._indexBuffer = null;\n /** @type {Array<any>|null} */\n this._indexTable = null;\n /** @type {Array<any>|null} */\n this._indexTableMetadata = null;\n this._recordByteSize = null;\n }\n\n /**\n * Emits a progress event if a callback is registered.\n *\n * @param {string} stage The current stage of the operation.\n * @param {number} current The current progress value.\n * @param {number} total The total progress value.\n */\n _emitProgress(stage, current, total) {\n if (this._onProgress) {\n const percent = total > 0 ? Math.round((current / total) * 100) : 100;\n this._onProgress({\n stage,\n current,\n total,\n percent,\n });\n }\n }\n\n /**\n * Writes the data to the QVD file.\n */\n async _writeData() {\n assert(this._header, 'The QVD file header has not been parsed.');\n assert(this._symbolBuffer, 'The QVD file symbol table has not been parsed.');\n assert(this._indexBuffer, 'The QVD file index table has not been parsed.');\n\n this._emitProgress('write', 0, 1);\n\n // @ts-ignore - Buffer.concat type compatibility\n const headerBuffer = Buffer.concat([Buffer.from(this._header, 'utf-8'), Buffer.from([0])]);\n\n let fd;\n try {\n fd = await fs.promises.open(this._path, 'w');\n await fd.write(headerBuffer, 0, headerBuffer.length, 0);\n await fd.write(this._symbolBuffer, 0, this._symbolBuffer.length, headerBuffer.length);\n await fd.write(this._indexBuffer, 0, this._indexBuffer.length, headerBuffer.length + this._symbolBuffer.length);\n this._emitProgress('write', 1, 1);\n } finally {\n if (fd) {\n await fd.close();\n }\n }\n }\n\n /**\n * Builds the XML header of the QVD file.\n */\n _buildHeader() {\n this._emitProgress('header', 0, 1);\n const creationDate = new Date().toISOString().replace(/T/, ' ').replace(/\\..+/, '');\n /** @type {import('./QvdDataFrame.js').QvdMetadata|null} */\n const existingMetadata = this._df.metadata;\n\n // Use existing metadata if available, otherwise create default values\n const baseMetadata = existingMetadata\n ? {\n QvBuildNo: existingMetadata.QvBuildNo || 50667,\n CreatorDoc: existingMetadata.CreatorDoc || crypto.randomUUID(),\n CreateUtcTime: existingMetadata.CreateUtcTime || creationDate,\n SourceCreateUtcTime: existingMetadata.SourceCreateUtcTime || '',\n SourceFileUtcTime: existingMetadata.SourceFileUtcTime || '',\n SourceFileSize: existingMetadata.SourceFileSize || -1,\n StaleUtcTime: existingMetadata.StaleUtcTime || '',\n TableName: existingMetadata.TableName || path.basename(this._path, path.extname(this._path)),\n Compression: existingMetadata.Compression || '',\n Comment: existingMetadata.Comment || '',\n EncryptionInfo: existingMetadata.EncryptionInfo || '',\n TableTags: existingMetadata.TableTags || '',\n ProfilingData: existingMetadata.ProfilingData || '',\n Lineage: existingMetadata.Lineage || {\n LineageInfo: {\n Discriminator: 'INLINE;',\n Statement: '',\n },\n },\n }\n : {\n QvBuildNo: 50667,\n CreatorDoc: crypto.randomUUID(),\n CreateUtcTime: creationDate,\n SourceCreateUtcTime: '',\n SourceFileUtcTime: '',\n SourceFileSize: -1,\n StaleUtcTime: '',\n TableName: path.basename(this._path, path.extname(this._path)),\n Compression: '',\n Comment: '',\n EncryptionInfo: '',\n TableTags: '',\n ProfilingData: '',\n Lineage: {\n LineageInfo: {\n Discriminator: 'INLINE;',\n Statement: '',\n },\n },\n };\n\n // Get existing field metadata if available\n /** @type {any[]} */\n let existingFields = [];\n if (existingMetadata && existingMetadata.Fields && existingMetadata.Fields.QvdFieldHeader) {\n existingFields = Array.isArray(existingMetadata.Fields.QvdFieldHeader)\n ? existingMetadata.Fields.QvdFieldHeader\n : [existingMetadata.Fields.QvdFieldHeader];\n }\n\n const xmlObject = {\n QvdTableHeader: {\n ...baseMetadata,\n Fields: {\n QvdFieldHeader: this._df.columns.map((/** @type {any} */ column, /** @type {number} */ index) => {\n // Find existing field metadata for this column\n const existingField = existingFields.find((/** @type {any} */ f) => f.FieldName === column);\n\n return {\n FieldName: column,\n BitOffset: this._indexTableMetadata?.[index][0],\n BitWidth: this._indexTableMetadata?.[index][1],\n Bias: this._indexTableMetadata?.[index][2],\n NoOfSymbols: this._symbolTable?.[index].length,\n Offset: this._symbolTableMetadata?.[index][0],\n Length: this._symbolTableMetadata?.[index][1],\n Comment: existingField?.Comment || '',\n NumberFormat: existingField?.NumberFormat || {\n Type: 'UNKNOWN',\n nDec: '0',\n UseThou: '0',\n Fmt: '',\n Dec: '',\n Thou: '',\n },\n Tags: existingField?.Tags || {},\n };\n }),\n },\n NoOfRecords: this._indexTable?.length,\n RecordByteSize: this._recordByteSize,\n Offset:\n this._symbolTableMetadata && this._symbolTableMetadata.length > 0\n ? this._symbolTableMetadata[this._symbolTableMetadata.length - 1][0] +\n this._symbolTableMetadata[this._symbolTableMetadata.length - 1][1]\n : 0,\n Length: this._indexBuffer?.length,\n },\n };\n\n const builder = new xml.Builder({\n renderOpts: {\n pretty: true,\n newline: '\\r\\n',\n indent: ' ',\n },\n });\n this._header = builder.buildObject(xmlObject) + '\\r\\n';\n this._emitProgress('header', 1, 1);\n }\n\n /**\n * Builds the symbol table of the QVD file.\n *\n * PERFORMANCE OPTIMIZATION: This method uses a single-pass algorithm to build\n * symbol tables for all columns simultaneously. This reduces time complexity from\n * O(n×m×s) to O(n×m) where n=rows, m=columns, s=symbols per column.\n *\n * Algorithm:\n * 1. Initialize a Set for each column to collect unique values\n * 2. Single pass through all data rows, adding values to corresponding Sets\n * 3. Convert Sets to arrays and create QvdSymbol instances\n * 4. Serialize symbols to binary format and update metadata\n *\n * This approach provides:\n * - 80-90% performance improvement for large datasets (100K+ rows)\n * - Better cache locality (process all columns in one data traversal)\n * - Lower memory pressure (no intermediate arrays per column)\n *\n * @private\n */\n _buildSymbolTable() {\n this._symbolTable = [];\n this._symbolTableMetadata = [];\n this._symbolBuffer = Buffer.alloc(0);\n\n const numColumns = this._df.columns.length;\n\n this._emitProgress('symbol-table', 0, numColumns);\n\n // Initialize a Set for each column to track unique values\n // Sets provide O(1) add and automatic deduplication\n const uniqueValuesSets = this._df.columns.map(() => new Set());\n\n // Single pass through all data to collect unique values for all columns\n // This is the key optimization: process all columns together instead of\n // iterating through data once per column\n this._df.data.forEach((row) => {\n this._df.columns.forEach((column, columnIndex) => {\n const value = row[columnIndex];\n uniqueValuesSets[columnIndex].add(value);\n });\n });\n\n // Process each column's unique values\n this._df.columns.forEach((column, columnIndex) => {\n const uniqueValuesSet = uniqueValuesSets[columnIndex];\n const uniqueValues = Array.from(uniqueValuesSet);\n const containsNull = uniqueValues.includes(null) || uniqueValues.includes(undefined);\n const symbols = uniqueValues\n .filter((value) => value !== null && value !== undefined)\n .map((value) => QvdFileWriter._convertRawToSymbol(value));\n\n // @ts-ignore:next-line sd\n const currentSymbolBuffer = Buffer.concat(symbols.map((symbol) => symbol.toByteRepresentation()));\n this._symbolBuffer = this._symbolBuffer\n ? Buffer.concat([this._symbolBuffer, currentSymbolBuffer])\n : currentSymbolBuffer;\n\n const symbolsLength = currentSymbolBuffer.length;\n const symbolsOffset = this._symbolBuffer.length - symbolsLength;\n\n this._symbolTableMetadata?.push([symbolsOffset, symbolsLength, containsNull]);\n // @ts-ignore - Symbol array type compatibility\n this._symbolTable?.push(symbols);\n\n this._emitProgress('symbol-table', columnIndex + 1, numColumns);\n });\n }\n\n /**\n * Builds the index table of the QVD file.\n *\n * PERFORMANCE OPTIMIZATION: Uses Map-based lookups for O(1) symbol index retrieval\n * instead of Array.findIndex() which is O(n). For columns with many unique values,\n * this provides significant performance improvements.\n *\n * Algorithm:\n * 1. Build Map<symbol, index> for each column (O(m) where m=unique values)\n * 2. For each data row, lookup indices in maps (O(1) per value)\n * 3. Convert indices to bit-packed binary format\n *\n * Bit Packing:\n * - Calculates minimum bits needed: ceil(log2(numSymbols))\n * - Packs indices into binary string, then converts to bytes\n * - Reduces file size significantly for columns with few unique values\n *\n * Example: Column with 10 unique values needs only 4 bits per value\n * instead of 32 bits (full integer), saving 87.5% space.\n *\n * @private\n */\n _buildIndexTable() {\n this._indexTable = [];\n this._indexTableMetadata = [];\n this._indexBuffer = Buffer.alloc(0);\n\n const numRows = this._df.data.length;\n this._emitProgress('index-table', 0, numRows);\n\n // Build symbol-to-index lookup maps for O(1) lookups\n // This is crucial for performance: findIndex() on large arrays is O(n)\n // while Map.get() is O(1)\n // This converts the O(n×m×s) findIndex operations to O(n×m)\n const symbolIndexMaps = this._symbolTable?.map((symbols) => {\n const map = new Map();\n symbols.forEach((symbol, idx) => {\n // Create a unique key for each symbol based on its values\n const key = `${symbol.intValue}|${symbol.doubleValue}|${symbol.stringValue}`;\n map.set(key, idx);\n });\n return map;\n });\n\n let processedRows = 0;\n const progressInterval = Math.max(1, Math.floor(numRows / 100)); // Report progress every 1%\n\n this._df.data.forEach((/** @type {any} */ row) => {\n // Convert the raw values to indices referring to the symbol table\n const indices = this._df.columns.map((/** @type {any} */ column, columnIndex) => {\n const value = row[columnIndex];\n const symbol = QvdFileWriter._convertRawToSymbol(value);\n const fieldContainsNull = this._symbolTableMetadata?.[columnIndex][2];\n\n // None values are represented by bias shifted negative indices\n if (symbol === null) {\n return 0;\n } else {\n // Use the Map for O(1) lookup instead of findIndex\n const key = `${symbol.intValue}|${symbol.doubleValue}|${symbol.stringValue}`;\n const symbolIndex = symbolIndexMaps?.[columnIndex].get(key);\n // In order to represent None values, the indices are shifted by the bias value of the column\n return fieldContainsNull ? (symbolIndex ?? 0) + 2 : (symbolIndex ?? 0);\n }\n });\n\n // Convert the integer indices to binary representation\n /** @type {string[]} */\n const stringIndices = indices.map((/** @type {number} */ index) => {\n const bits = QvdFileWriter._convertInt32ToBits(index, 32);\n let bitString = bits.join('');\n bitString = bitString.replace(/^0+/, '') || '0';\n return bitString;\n });\n\n // @ts-ignore - Index array type compatibility\n this._indexTable?.push(stringIndices);\n\n // Report progress periodically\n processedRows++;\n if (processedRows % progressInterval === 0 || processedRows === numRows) {\n this._emitProgress('index-table', processedRows, numRows);\n }\n });\n\n // Normalize the bit representation of the indices by padding with zeros\n this._df.columns.forEach((column) => {\n // Bit offset is the sum of the bit widths of all previous columns\n const bitOffset = this._indexTableMetadata\n ?.slice(0, this._df.columns.indexOf(column))\n .reduce((sum, metadata) => sum + metadata[1], 0);\n\n assert(this._indexTable, 'The QVD file header has not been parsed.');\n\n // Bit width is the maximum bit width of all indices of the column\n // For empty data, default to 0 bit width\n const bitWidth =\n this._indexTable.length > 0\n ? Math.max(\n ...this._indexTable.map(\n (/** @type{string[]} */ indices) => indices[this._df.columns.indexOf(column)].length,\n ),\n )\n : 0;\n\n const fieldContainsNull = this._symbolTableMetadata?.[this._df.columns.indexOf(column)][2];\n const bias = fieldContainsNull ? -2 : 0;\n\n this._indexTableMetadata?.push([bitOffset, bitWidth, bias]);\n\n // Pad the bit representation of the indices with zeros to match the bit width\n this._indexTable.forEach((/** @type{string[]} */ indices) => {\n const bitString = indices[this._df.columns.indexOf(column)];\n const paddedBitString = bitString.padStart(bitWidth, '0');\n indices[this._df.columns.indexOf(column)] = paddedBitString;\n });\n });\n\n // Concatenate the bit representation of the indices of each row to a single binary string per row\n // @ts-ignore - Buffer.concat type compatibility\n this._indexBuffer = Buffer.concat(\n // @ts-ignore - Buffer array type compatibility\n this._indexTable.map((/** @type{string[]} */ indices) => {\n indices.reverse();\n const bits = indices.join('');\n const paddingWidth = (8 - (bits.length % 8)) % 8;\n const paddedBits = bits.padStart(bits.length + paddingWidth, '0');\n const bytes = paddedBits.match(/.{1,8}/g)?.map((byte) => parseInt(byte, 2));\n bytes?.reverse();\n\n assert(bytes, 'Byte conversion of bit indices failed.');\n\n return Buffer.from(Uint8Array.from(bytes));\n }),\n );\n\n // For empty data, set record byte size to 1 (matching Qlik Sense behavior)\n // instead of 0 or NaN/Infinity\n this._recordByteSize = this._indexTable.length > 0 ? this._indexBuffer.length / this._indexTable.length : 1;\n }\n\n /**\n * Converts a raw value/literal to a QVD symbol.\n *\n * @param {any} raw The raw value/literal to convert.\n * @return {QvdSymbol|null} The converted QVD symbol.\n */\n static _convertRawToSymbol(raw) {\n if (raw === null || raw === undefined) {\n return null;\n }\n\n const INT32_MIN = -2147483648;\n const INT32_MAX = 2147483647;\n\n const isInteger = typeof raw === 'number' && Number.isInteger(raw);\n const isFloat = typeof raw === 'number' && !Number.isInteger(raw);\n const isWithinInt32Range = typeof raw === 'number' && raw >= INT32_MIN && raw <= INT32_MAX;\n\n if (isInteger && isWithinInt32Range) {\n return QvdSymbol.fromDualIntValue(raw, raw.toString());\n } else if (isFloat || (isInteger && !isWithinInt32Range)) {\n return QvdSymbol.fromDualDoubleValue(raw, raw.toString());\n } else {\n return QvdSymbol.fromStringValue(raw);\n }\n }\n\n /**\n * Converts an integer to a list of bits.\n *\n * @param {number} value The integer value to convert.\n * @param {number} width The width of the bit list.\n * @return {Array<number>} The list of bits.\n */\n static _convertInt32ToBits(value, width) {\n return value\n .toString(2)\n .split('')\n .map((bit) => parseInt(bit))\n .reverse()\n .concat(new Array(width).fill(0))\n .slice(0, width)\n .reverse();\n }\n\n /**\n * Persists the data frame to a QVD file.\n */\n async save() {\n this._buildSymbolTable();\n this._buildIndexTable();\n this._buildHeader();\n await this._writeData();\n }\n}\n","// @ts-check\n\n/**\n * Converts a bit array to an integer value.\n *\n * @param {Array<number>} bits The bit array\n * @return {number} The integer value\n */\nexport function convertBitsToInt32(bits) {\n if (bits.length === 0) {\n return 0;\n }\n\n return bits.reduce((value, bit, index) => (value += bit * Math.pow(2, index)), 0);\n}\n","// @ts-check\n\nimport os from 'os';\nimport {QvdValidationError} from '../QvdErrors.js';\n\n/**\n * Estimates the memory usage for loading a QVD file with given parameters.\n * Takes into account Phase 2.5 optimization which skips parsing unused symbols.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n * @returns {number} Estimated memory usage in bytes\n */\nexport function estimateMemoryUsage(symbolTableSize, maxRows, totalRows) {\n // Memory overhead multipliers based on empirical testing\n const FULL_PARSE_OVERHEAD = 6.0; // Baseline: JavaScript objects have 6x overhead\n const MINIMAL_OVERHEAD = 0.01; // Skipped symbols: minimal null placeholder overhead\n\n if (maxRows === null || maxRows >= totalRows) {\n // Loading all rows - need all symbols, no filtering benefit\n return symbolTableSize * FULL_PARSE_OVERHEAD;\n }\n\n // Estimate what percentage of symbols we'll need\n // Symbol usage grows slower than linear (diminishing returns as you add rows)\n // Use square root scaling as empirical approximation\n const rowPercentage = maxRows / totalRows;\n const symbolPercentage = Math.sqrt(rowPercentage);\n\n // Calculate memory for kept symbols (full overhead) + skipped symbols (minimal overhead)\n const keptSymbolsMemory = symbolTableSize * symbolPercentage * FULL_PARSE_OVERHEAD;\n const skippedSymbolsMemory = symbolTableSize * (1 - symbolPercentage) * MINIMAL_OVERHEAD;\n\n return keptSymbolsMemory + skippedSymbolsMemory;\n}\n\n/**\n * Validates that there is sufficient memory available to load a QVD file safely.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdValidationError} If insufficient memory is available\n */\nexport function validateMemoryAvailability(symbolTableSize, maxRows, totalRows, filePath) {\n const availableMemory = os.freemem();\n const estimatedMemory = estimateMemoryUsage(symbolTableSize, maxRows, totalRows);\n const MEMORY_SAFETY_FACTOR = 0.3; // Use at most 30% of available memory\n const maxAllowedMemory = availableMemory * MEMORY_SAFETY_FACTOR;\n\n if (estimatedMemory > maxAllowedMemory) {\n // Calculate how many rows would be safe to load\n // Reverse the square root formula: symbolPercentage = sqrt(rowPercentage)\n const safeSymbolPercentage = maxAllowedMemory / (symbolTableSize * 6.0);\n const safeRowPercentage = Math.pow(safeSymbolPercentage, 2);\n const recommendedMaxRows = Math.max(1, Math.floor(totalRows * safeRowPercentage));\n\n const sizeMB = Math.round(symbolTableSize / 1024 / 1024);\n const estimatedMB = Math.round(estimatedMemory / 1024 / 1024);\n const availableMB = Math.round(maxAllowedMemory / 1024 / 1024);\n\n throw new QvdValidationError(\n `Insufficient memory to load file safely. ` +\n `Symbol table: ${sizeMB}MB, Estimated memory needed: ${estimatedMB}MB, Available: ${availableMB}MB. ` +\n `Try loading fewer rows using the maxRows parameter (recommended: ${recommendedMaxRows.toLocaleString()} rows or less).`,\n {\n file: filePath,\n symbolTableSize,\n symbolTableSizeMB: sizeMB,\n estimatedMemoryMB: estimatedMB,\n availableMemoryMB: availableMB,\n totalRows,\n maxRows,\n recommendedMaxRows,\n },\n );\n }\n}\n\n/**\n * Emits a warning for large symbol tables when loading all rows.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n */\nexport function warnLargeSymbolTable(symbolTableSize, maxRows, totalRows) {\n const LARGE_SYMBOL_TABLE_WARNING = 500 * 1024 * 1024; // 500MB\n\n if (symbolTableSize > LARGE_SYMBOL_TABLE_WARNING && (maxRows === null || maxRows >= totalRows)) {\n const sizeMB = Math.round(symbolTableSize / 1024 / 1024);\n const estimatedMemory = estimateMemoryUsage(symbolTableSize, maxRows, totalRows);\n const estimatedMB = Math.round(estimatedMemory / 1024 / 1024);\n\n console.warn(\n `⚠️ Large symbol table detected (${sizeMB}MB). Loading all ${totalRows.toLocaleString()} rows will use ~${estimatedMB}MB RAM. ` +\n `Consider using the maxRows parameter for better performance and lower memory usage.`,\n );\n }\n}\n","// @ts-check\n\nimport {QvdCorruptedError, QvdValidationError} from '../QvdErrors.js';\n\n/**\n * Validates symbol table size during initial file read (early check).\n * This is the first-pass validation in _readData for lazy loading.\n *\n * @param {number} symbolTableLength Size of symbol table in bytes\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdValidationError} If symbol table exceeds 500MB limit\n */\nexport function validateSymbolTableSizeEarly(symbolTableLength, filePath) {\n // SAFETY CHECK: Very large symbol tables (>500MB) are still blocked to prevent OOM\n // Phase 2 filtering can handle up to ~500MB symbol tables efficiently\n const MAX_SYMBOL_TABLE_SIZE = 500 * 1024 * 1024; // 500MB raw\n\n if (symbolTableLength > MAX_SYMBOL_TABLE_SIZE) {\n const sizeMB = Math.round(symbolTableLength / 1024 / 1024);\n const maxMB = Math.round(MAX_SYMBOL_TABLE_SIZE / 1024 / 1024);\n\n throw new QvdValidationError(\n `Symbol table too large (${sizeMB}MB exceeds ${maxMB}MB limit). ` +\n `This QVD file contains extremely high-cardinality fields. ` +\n `Even with symbol filtering, this file cannot be loaded efficiently. ` +\n `Consider: (1) using a subset of the data, (2) aggregating high-cardinality fields, or (3) using a different data format.`,\n {\n file: filePath,\n symbolTableSize: symbolTableLength,\n symbolTableSizeMB: sizeMB,\n maxAllowed: MAX_SYMBOL_TABLE_SIZE,\n maxAllowedMB: maxMB,\n },\n );\n }\n}\n\n/**\n * Validates symbol table size limits to prevent out-of-memory conditions.\n * This is the comprehensive validation in _parseSymbolTable.\n *\n * @param {number} symbolTableLength Size of symbol table in bytes\n * @param {string} filePath Path to the QVD file (for error messages)\n * @param {number} totalRows Total number of rows in the file\n * @throws {QvdValidationError} If symbol table exceeds safety limits\n */\nexport function validateSymbolTableSize(symbolTableLength, filePath, totalRows) {\n // SAFETY CHECK: Absolute ceiling to prevent pathological cases\n // Phase 2.5 optimization allows much larger symbol tables when using maxRows,\n // but we still need an absolute maximum to prevent truly extreme cases\n const ABSOLUTE_MAX_SYMBOL_TABLE = 2 * 1024 * 1024 * 1024; // 2GB raw\n\n if (symbolTableLength > ABSOLUTE_MAX_SYMBOL_TABLE) {\n const sizeMB = Math.round(symbolTableLength / 1024 / 1024);\n const maxMB = Math.round(ABSOLUTE_MAX_SYMBOL_TABLE / 1024 / 1024);\n\n throw new QvdValidationError(\n `Symbol table exceeds absolute maximum size (${sizeMB}MB > ${maxMB}MB). ` +\n `This QVD file has pathological cardinality (likely a data modeling issue). ` +\n `Even with Phase 2.5 optimization, files this large cannot be processed safely. ` +\n `Consider: (1) aggregating high-cardinality fields, (2) splitting the data, or (3) using a different format.`,\n {\n file: filePath,\n symbolTableSize: symbolTableLength,\n symbolTableSizeMB: sizeMB,\n maxAllowed: ABSOLUTE_MAX_SYMBOL_TABLE,\n maxAllowedMB: maxMB,\n totalRows,\n },\n );\n }\n}\n\n/**\n * Validates field metadata before processing to prevent buffer overflow attacks.\n *\n * @param {any} field Field metadata object\n * @param {number} symbolBufferLength Length of the symbol buffer\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdCorruptedError} If field metadata is invalid\n */\nexport function validateFieldMetadata(field, symbolBufferLength, filePath) {\n const symbolsOffset = parseInt(field['Offset'], 10);\n const symbolsLength = parseInt(field['Length'], 10);\n\n // Validate offset is a valid number and within bounds\n if (isNaN(symbolsOffset) || !Number.isSafeInteger(symbolsOffset) || symbolsOffset < 0) {\n throw new QvdCorruptedError('Invalid symbol offset', {\n field: field['FieldName'],\n offset: symbolsOffset,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n // Validate length is a valid number and non-negative\n if (isNaN(symbolsLength) || !Number.isSafeInteger(symbolsLength) || symbolsLength < 0) {\n throw new QvdCorruptedError('Invalid symbol length', {\n field: field['FieldName'],\n length: symbolsLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n // Validate that offset + length doesn't exceed buffer size\n if (symbolsOffset + symbolsLength > symbolBufferLength) {\n throw new QvdCorruptedError('Symbol data extends beyond buffer', {\n field: field['FieldName'],\n offset: symbolsOffset,\n length: symbolsLength,\n bufferSize: symbolBufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n}\n\n/**\n * Validates index table metadata and bounds.\n *\n * @param {number} recordSize Size of a single record in bytes\n * @param {number} totalRows Total number of rows\n * @param {number} indexTableLength Length of the index table\n * @param {number} indexTableOffset Offset to the index table\n * @param {number} bufferLength Length of the buffer\n * @param {number} rowsToLoad Number of rows to load\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdCorruptedError} If index table metadata is invalid\n */\nexport function validateIndexTableMetadata(\n recordSize,\n totalRows,\n indexTableLength,\n indexTableOffset,\n bufferLength,\n rowsToLoad,\n filePath,\n) {\n // Validate recordSize\n if (isNaN(recordSize) || !Number.isSafeInteger(recordSize) || recordSize < 0) {\n throw new QvdCorruptedError('Invalid record byte size', {\n recordSize,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate totalRows\n if (isNaN(totalRows) || !Number.isSafeInteger(totalRows) || totalRows < 0) {\n throw new QvdCorruptedError('Invalid number of records', {\n totalRows,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Allow recordSize of 0 or 1 only when there are no records (empty QVD)\n // Qlik Sense uses recordSize=1 for empty QVDs\n if (recordSize === 0 && totalRows > 0) {\n throw new QvdCorruptedError('Record byte size cannot be zero when records exist', {\n recordSize,\n totalRows,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate recordSize is reasonable (max 1MB per record)\n if (recordSize > 1048576) {\n throw new QvdCorruptedError('Record byte size exceeds maximum', {\n recordSize,\n maxSize: 1048576,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate index table length\n if (isNaN(indexTableLength) || !Number.isSafeInteger(indexTableLength) || indexTableLength < 0) {\n throw new QvdCorruptedError('Invalid index table length', {\n length: indexTableLength,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate index table start offset doesn't extend beyond buffer\n if (indexTableOffset > bufferLength) {\n throw new QvdCorruptedError('Index table offset beyond buffer', {\n indexTableOffset,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate that the claimed index table length isn't excessively large\n const maxReasonableOverage = 100 * 1024 * 1024;\n if (indexTableLength > bufferLength + maxReasonableOverage) {\n throw new QvdCorruptedError('Index table length unreasonably large', {\n indexTableLength,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Ensure the index table length is sufficient for the number of rows to load\n const requiredIndexBytes = rowsToLoad * recordSize;\n if (indexTableLength < requiredIndexBytes) {\n throw new QvdCorruptedError('Index table length smaller than required', {\n indexTableLength,\n requiredBytes: requiredIndexBytes,\n rowsToLoad,\n recordSize,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n}\n\n/**\n * Validates field bit offset and bit width for index table parsing.\n *\n * @param {any} field Field metadata object\n * @param {number} recordSize Size of a single record in bytes\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdCorruptedError} If field bit metadata is invalid\n */\nexport function validateFieldBitMetadata(field, recordSize, filePath) {\n const bitOffset = parseInt(field['BitOffset'], 10);\n const bitWidth = parseInt(field['BitWidth'], 10);\n\n // Validate bitOffset\n if (isNaN(bitOffset) || !Number.isSafeInteger(bitOffset) || bitOffset < 0) {\n throw new QvdCorruptedError('Invalid bit offset', {\n field: field['FieldName'],\n bitOffset,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate bitWidth\n if (isNaN(bitWidth) || !Number.isSafeInteger(bitWidth) || bitWidth < 0) {\n throw new QvdCorruptedError('Invalid bit width', {\n field: field['FieldName'],\n bitWidth,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate bitOffset + bitWidth doesn't exceed record size in bits\n const recordSizeInBits = recordSize * 8;\n if (bitOffset + bitWidth > recordSizeInBits) {\n throw new QvdCorruptedError('Bit field extends beyond record size', {\n field: field['FieldName'],\n bitOffset,\n bitWidth,\n recordSizeInBits,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n}\n","// @ts-check\n\nimport {QvdSymbol} from '../QvdSymbol.js';\nimport {QvdCorruptedError, QvdParseError} from '../QvdErrors.js';\n\n/**\n * Parses an integer symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for an integer\n if (pointer + 4 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading integer symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const byteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 4));\n const value = Buffer.from(byteData).readIntLE(0, byteData.length);\n return {symbol: QvdSymbol.fromIntValue(value), bytesRead: 4};\n}\n\n/**\n * Parses a double symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for a double\n if (pointer + 8 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading double symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const byteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 8));\n const value = Buffer.from(byteData).readDoubleLE(0);\n return {symbol: QvdSymbol.fromDoubleValue(value), bytesRead: 8};\n}\n\n/**\n * Parses a string symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n const startPointer = pointer;\n const maxStringLength = 1048576; // 1MB max string size to prevent memory exhaustion\n let stringLength = 0;\n\n // Find the null terminator\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('String symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n // Ensure we found the null terminator\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('String symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const value = symbolBuffer.subarray(startPointer, pointer).toString('utf-8');\n return {symbol: QvdSymbol.fromStringValue(value), bytesRead: pointer - startPointer + 1};\n}\n\n/**\n * Skips a string symbol in the buffer without parsing it.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {number} Bytes to skip\n */\nexport function skipStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n const startPointer = pointer;\n const maxStringLength = 1048576;\n let stringLength = 0;\n\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('String symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('String symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n return pointer - startPointer + 1;\n}\n\n/**\n * Parses a dual integer symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseDualIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for an integer\n if (pointer + 4 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading dual integer symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const intByteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 4));\n const intValue = Buffer.from(intByteData).readIntLE(0, intByteData.length);\n pointer += 4;\n\n // Parse the string portion\n const stringStart = pointer;\n const maxStringLength = 1048576;\n let stringLength = 0;\n\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('Dual string symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('Dual string symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const stringValue = symbolBuffer.subarray(stringStart, pointer).toString('utf-8');\n return {symbol: QvdSymbol.fromDualIntValue(intValue, stringValue), bytesRead: pointer - (stringStart - 4) + 1};\n}\n\n/**\n * Parses a dual double symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseDualDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for a double\n if (pointer + 8 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading dual double symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const doubleByteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 8));\n const doubleValue = Buffer.from(doubleByteData).readDoubleLE(0);\n pointer += 8;\n\n // Parse the string portion\n const stringStart = pointer;\n const maxStringLength = 1048576;\n let stringLength = 0;\n\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('Dual string symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('Dual string symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const stringValue = symbolBuffer.subarray(stringStart, pointer).toString('utf-8');\n return {\n symbol: QvdSymbol.fromDualDoubleValue(doubleValue, stringValue),\n bytesRead: pointer - (stringStart - 8) + 1,\n };\n}\n\n/**\n * Skips a dual symbol (integer or double) in the buffer without parsing it.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {number} numericBytes Number of bytes for the numeric portion (4 for int, 8 for double)\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {number} Bytes to skip\n */\nexport function skipDualSymbol(symbolBuffer, pointer, bufferLength, numericBytes, fieldName, filePath) {\n if (pointer + numericBytes > bufferLength) {\n throw new QvdCorruptedError(`Buffer overflow reading dual symbol`, {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const startPointer = pointer;\n pointer += numericBytes;\n\n // Skip the string portion\n const maxStringLength = 1048576;\n let stringLength = 0;\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('Dual string symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('Dual string symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n return pointer - startPointer + 1;\n}\n\n/**\n * Parses a symbol based on the type byte.\n *\n * @param {number} typeByte The type byte\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position (after type byte)\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @param {boolean} shouldParse Whether to parse the symbol (true) or skip it (false)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol (or null if skipped) and bytes read\n */\nexport function parseSymbol(typeByte, symbolBuffer, pointer, bufferLength, fieldName, filePath, shouldParse) {\n switch (typeByte) {\n case 1: {\n // Integer value (4 Bytes)\n if (shouldParse) {\n return parseIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n return {symbol: null, bytesRead: 4};\n }\n case 2: {\n // Double value (8 Bytes)\n if (shouldParse) {\n return parseDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n return {symbol: null, bytesRead: 8};\n }\n case 4: {\n // String value (0 terminated)\n if (shouldParse) {\n return parseStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n const bytesRead = skipStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n return {symbol: null, bytesRead};\n }\n case 5: {\n // Dual (Integer format) value (4 bytes), followed by string format\n if (shouldParse) {\n return parseDualIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n const bytesRead = skipDualSymbol(symbolBuffer, pointer, bufferLength, 4, fieldName, filePath);\n return {symbol: null, bytesRead};\n }\n case 6: {\n // Dual (Double format) value (8 bytes), followed by string format\n if (shouldParse) {\n return parseDualDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n const bytesRead = skipDualSymbol(symbolBuffer, pointer, bufferLength, 8, fieldName, filePath);\n return {symbol: null, bytesRead};\n }\n default: {\n throw new QvdParseError('Unknown symbol type byte', {\n typeByte: typeByte.toString(16),\n offset: pointer - 1,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n }\n}\n","// @ts-check\n\nimport fs from 'fs';\nimport xml from 'xml2js';\nimport assert from 'assert';\nimport {QvdDataFrame} from './QvdDataFrame.js';\nimport {QvdParseError, QvdValidationError, QvdCorruptedError} from './QvdErrors.js';\nimport {validatePath} from './util/validatePath.js';\nimport {convertBitsToInt32} from './util/bitUtils.js';\nimport {estimateMemoryUsage, validateMemoryAvailability, warnLargeSymbolTable} from './util/memoryUtils.js';\nimport {\n validateSymbolTableSize,\n validateSymbolTableSizeEarly,\n validateFieldMetadata,\n validateIndexTableMetadata,\n validateFieldBitMetadata,\n} from './util/validationUtils.js';\nimport {parseSymbol} from './util/symbolParser.js';\n\n/**\n * Parses a QVD file and loads it into memory.\n */\nexport class QvdFileReader {\n /**\n * Constructs a new QVD file parser.\n *\n * @param {string} filePath The path to the QVD file to load.\n * @param {Object} [options={}] Options for the reader.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file\n * path must be within this directory. Defaults to current working directory.\n */\n constructor(filePath, options = {}) {\n const {allowedDir} = options;\n this._path = validatePath(filePath, allowedDir);\n this._buffer = null;\n this._headerOffset = null;\n this._symbolTableOffset = null;\n this._indexTableOffset = null;\n this._header = null;\n /** @type {Array<Array<import('./QvdSymbol.js').QvdSymbol>>|null} */\n this._symbolTable = null;\n /** @type {Array<Array<number>>|null} */\n this._indexTable = null;\n }\n\n /**\n * Reads the binary data of the QVD file.\n *\n * LAZY LOADING OPTIMIZATION: When maxRows is specified, this method implements\n * true lazy loading by reading only the necessary portions of the file from disk.\n *\n * For large files (e.g., 5GB), loading only the first 1000 rows can save significant\n * memory and time:\n * - Full load: 5GB in memory, ~30-60s load time\n * - Lazy load (maxRows=1000): ~1.75-2GB in memory, ~2-5s load time\n *\n * Algorithm for Lazy Loading:\n * 1. Stream-read the file until XML header delimiter is found\n * 2. Parse header to determine symbol table and index table locations\n * 3. Calculate bytes needed: header + full symbol table + partial index table\n * 4. Read only those calculated bytes using fs.open/read\n * 5. Rest of parsing proceeds normally with limited data\n *\n * WHY THIS APPROACH:\n * - Symbol table must be fully loaded (contains all unique values)\n * - Index table can be partially loaded (only rows we need)\n * - Streaming for header finding is efficient for unknown header sizes\n * - Direct byte-range reading for remaining data is fastest\n *\n * @param {number|null} maxRows The maximum number of rows to load. If null, all data is loaded.\n * @private\n */\n async _readData(maxRows = null) {\n if (maxRows === null) {\n // Load entire file into memory (original behavior)\n // This is simple and fast for small to medium files\n this._buffer = await fs.promises.readFile(this._path);\n return;\n }\n\n const HEADER_DELIMITER = '\\r\\n\\0';\n const CHUNK_SIZE = 64 * 1024; // 64KB chunks - balance between memory and I/O efficiency\n\n // Use streaming to find the header delimiter dynamically\n // We don't know header size in advance, so we must stream-read\n const stream = fs.createReadStream(this._path, {\n highWaterMark: CHUNK_SIZE,\n });\n\n let headerBuffer = Buffer.alloc(0);\n let headerDelimiterIndex = -1;\n\n try {\n // Read chunks until we find the delimiter\n for await (const chunk of stream) {\n headerBuffer = Buffer.concat([headerBuffer, chunk]);\n headerDelimiterIndex = headerBuffer.indexOf(HEADER_DELIMITER);\n\n if (headerDelimiterIndex !== -1) {\n // Found the delimiter, stop streaming\n stream.destroy();\n break;\n }\n }\n } catch (error) {\n // Ignore destroy errors (expected when we stop the stream early)\n if (error && typeof error === 'object' && 'code' in error && error.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n throw error;\n }\n }\n\n if (headerDelimiterIndex === -1) {\n throw new QvdCorruptedError(\n 'The XML header section does not exist or is not properly delimited from the binary data.',\n {\n file: this._path,\n stage: 'readData',\n },\n );\n }\n\n const headerEndIndex = headerDelimiterIndex + HEADER_DELIMITER.length;\n\n // Parse header to get metadata about symbol and index table locations\n const headerXml = headerBuffer.subarray(0, headerEndIndex).toString();\n const headerObj = await xml.parseStringPromise(headerXml, {explicitArray: false});\n\n if (!headerObj) {\n throw new QvdParseError('The XML header could not be parsed.', {\n file: this._path,\n stage: 'readData',\n });\n }\n\n const symbolTableOffset = headerEndIndex;\n const symbolTableLength = parseInt(headerObj['QvdTableHeader']['Offset'], 10);\n const indexTableOffset = symbolTableOffset + symbolTableLength;\n const recordSize = parseInt(headerObj['QvdTableHeader']['RecordByteSize'], 10);\n const totalRows = parseInt(headerObj['QvdTableHeader']['NoOfRecords'], 10);\n const rowsToLoad = Math.min(maxRows, totalRows);\n\n // SAFETY CHECK: Very large symbol tables (>500MB) are still blocked to prevent OOM\n // Phase 2 filtering can handle up to ~500MB symbol tables efficiently\n validateSymbolTableSizeEarly(symbolTableLength, this._path);\n\n // Calculate how much of the index table we need to read\n const indexTableBytesToRead = rowsToLoad * recordSize;\n\n // Calculate total bytes needed: header + symbol table + partial index table\n const totalBytesToRead = indexTableOffset + indexTableBytesToRead;\n\n // Now read the exact portion we need from the file\n const fd = await fs.promises.open(this._path, 'r');\n try {\n this._buffer = Buffer.allocUnsafe(totalBytesToRead);\n // @ts-ignore - Buffer type compatibility\n await fd.read(this._buffer, 0, totalBytesToRead, 0);\n } finally {\n await fd.close();\n }\n }\n\n /**\n * Parses the XML header of the QVD file. This method is part of the parsing process\n * and should not be called directly.\n */\n async _parseHeader() {\n if (!this._buffer) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'parseHeader',\n },\n );\n }\n\n const HEADER_DELIMITER = '\\r\\n\\0';\n\n const headerBeginIndex = 0;\n const headerDelimiterIndex = this._buffer.indexOf(HEADER_DELIMITER, headerBeginIndex);\n\n // Check explicitly for -1 (not found) rather than using falsy check (!headerDelimiterIndex)\n // because indexOf() returns 0 when the delimiter is at position 0, which is a valid buffer index.\n // Using !0 would incorrectly treat position 0 as an error.\n if (headerDelimiterIndex === -1) {\n throw new QvdCorruptedError(\n 'The XML header section does not exist or is not properly delimited from the binary data.',\n {\n file: this._path,\n stage: 'parseHeader',\n },\n );\n }\n\n const headerEndIndex = headerDelimiterIndex + HEADER_DELIMITER.length;\n const headerBuffer = this._buffer.subarray(headerBeginIndex, headerEndIndex);\n\n /*\n * The following instruction parses the XML header into a JSON object. It is important to\n * note that the object is a plain JavaScript object and not an instance of representative\n * class. Hence, types are not casted, therefore all raw values are strings, and child nodes\n * that contain an array of objects are not represented directly as an array but as an object\n * with a property, named like the array item tag, that is an array of the actual objects. The\n * same applies to child nodes that contain a single object and the root node.\n *\n * The following XML representation of the QVD header for example...\n *\n * <QvdTableHeader>\n * ...\n * <Fields>\n * <QvdFieldHeader>\n * <FieldName>Field1</FieldName>\n * ...\n * </QvdFieldHeader>\n * <QvdFieldHeader>\n * <FieldName>Field1</FieldName>\n * ...\n * </QvdFieldHeader>\n * </Fields>\n * </QvdTableHeader>\n *\n * ...is parsed into the following object:\n *\n * {\n * QvdTableHeader: {\n * ...,\n * Fields: {\n * QvdFieldHeader: [\n * { FieldName: 'Field1', ...},\n * { FieldName: 'Field2', ...}\n * ]\n * }\n * }\n * }\n */\n\n // Note: xml2js (via sax-js) does not support external entity resolution\n // by default, providing inherent protection against XXE attacks.\n this._header = await xml.parseStringPromise(headerBuffer.toString(), {explicitArray: false});\n\n if (!this._header) {\n throw new QvdParseError('The XML header could not be parsed.', {\n file: this._path,\n stage: 'parseHeader',\n });\n }\n\n /*\n * Because the three parts of the QVD file, header, symbol and index table, are seamlessly concatenated,\n * the end of the respective previous part is the beginning of the next part.\n */\n\n this._headerOffset = headerBeginIndex;\n this._symbolTableOffset = headerEndIndex;\n this._indexTableOffset = this._symbolTableOffset + parseInt(this._header['QvdTableHeader']['Offset'], 10);\n }\n\n /**\n * Estimates the memory usage for loading a QVD file with given parameters.\n * Takes into account Phase 2.5 optimization which skips parsing unused symbols.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n * @returns {number} Estimated memory usage in bytes\n * @private\n */\n _estimateMemoryUsage(symbolTableSize, maxRows, totalRows) {\n return estimateMemoryUsage(symbolTableSize, maxRows, totalRows);\n }\n\n /**\n * Analyzes the index table to determine which symbols are actually needed.\n * This is used for two-pass symbol filtering optimization.\n *\n * @param {number} maxRows The maximum number of rows to analyze.\n * @returns {Promise<Map<string, Set<number>>>} Map of field names to Set of needed symbol indices.\n * @private\n */\n async _analyzeIndexTableSymbolUsage(maxRows) {\n if (!this._buffer || !this._header || !this._indexTableOffset) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'analyzeIndexTableSymbolUsage',\n },\n );\n }\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n const recordSize = parseInt(this._header['QvdTableHeader']['RecordByteSize'], 10);\n const totalRows = parseInt(this._header['QvdTableHeader']['NoOfRecords'], 10);\n const rowsToAnalyze = Math.min(maxRows, totalRows);\n const indexTableLength = parseInt(this._header['QvdTableHeader']['Length'], 10);\n\n const indexBuffer = this._buffer.subarray(this._indexTableOffset, this._indexTableOffset + indexTableLength + 1);\n\n // Map of field name -> Set of symbol indices needed\n /** @type {Map<string, Set<number>>} */\n const symbolUsage = new Map();\n\n // Initialize sets for each field\n fields.forEach((field) => {\n symbolUsage.set(field['FieldName'], new Set());\n });\n\n // Parse rows to collect symbol indices\n for (\n let pointer = 0, rowCount = 0;\n pointer < indexBuffer.length && rowCount < rowsToAnalyze;\n pointer += recordSize, rowCount++\n ) {\n const bytes = new Int32Array(indexBuffer.subarray(pointer, pointer + recordSize));\n bytes.reverse();\n\n const mask = bytes\n .reduce((bits, byte) => bits + ('00000000' + byte.toString(2)).slice(-8), '')\n .split('')\n .reverse()\n .map((bit) => parseInt(bit));\n\n // Extract symbol index for each field\n fields.forEach((field) => {\n const bitOffset = parseInt(field['BitOffset'], 10);\n const bitWidth = parseInt(field['BitWidth'], 10);\n const bias = parseInt(field['Bias'], 10);\n\n let symbolIndex;\n\n if (bitWidth === 0) {\n symbolIndex = 0;\n } else {\n symbolIndex = this._convertBitsToInt32(mask.slice(bitOffset, bitOffset + bitWidth));\n }\n\n // Apply bias\n symbolIndex -= bias;\n\n // Add to the set of needed symbols for this field\n const fieldName = field['FieldName'];\n symbolUsage.get(fieldName)?.add(symbolIndex);\n });\n }\n\n return symbolUsage;\n }\n\n /**\n * Parses the symbol table of the QVD file. This method is part of the parsing process\n * and should not be called directly.\n *\n * @param {Map<string, Set<number>>|null} symbolsToKeep Optional map of field names to symbol indices to keep.\n * If provided, only these symbols will be parsed (two-pass filtering optimization).\n * @param {number|null} maxRows Optional maximum number of rows being loaded (for memory estimation).\n */\n async _parseSymbolTable(symbolsToKeep = null, maxRows = null) {\n if (!this._buffer || !this._header || !this._symbolTableOffset || !this._indexTableOffset) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'parseSymbolTable',\n },\n );\n }\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n const symbolBuffer = this._buffer.subarray(this._symbolTableOffset, this._indexTableOffset);\n const symbolTableSize = symbolBuffer.length;\n const totalRows = parseInt(this._header['QvdTableHeader']['NoOfRecords'], 10);\n\n // SAFETY CHECK 1: Absolute ceiling to prevent pathological cases\n // Phase 2.5 optimization allows much larger symbol tables when using maxRows,\n // but we still need an absolute maximum to prevent truly extreme cases\n validateSymbolTableSize(symbolTableSize, this._path, totalRows);\n\n // SAFETY CHECK 2: Dynamic memory validation\n // Check if we have enough available memory to load this file safely\n validateMemoryAvailability(symbolTableSize, maxRows, totalRows, this._path);\n\n // WARNING ZONE: Large files without maxRows parameter\n // Educate users about best practices but don't block\n warnLargeSymbolTable(symbolTableSize, maxRows, totalRows);\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n /*\n * The symbol table is a contiguous byte array that contains all possible symbols/values of all fields/columns.\n * The symbols/values of one field are stored consecutively in the same order as the fields/columns are defined\n * in the header. The length of the symbol area as well as it's offset, relativ to the begin of the symbol\n * table, are also defined in the header.\n */\n\n // Validate all field metadata before processing to prevent buffer overflow attacks\n for (const field of fields) {\n validateFieldMetadata(field, symbolBuffer.length, this._path);\n }\n\n // Parse all possible symbols of each field/column\n // Phase 2.5 optimization: Skip parsing entirely for symbols we don't need\n this._symbolTable = fields.map((/** @type {any} */ field) => {\n const symbolsOffset = parseInt(field['Offset'], 10); // Offset of the column's symbol area in the symbol table\n const symbolsLength = parseInt(field['Length'], 10); // Length of the column's symbol area in the symbol table\n\n const fieldName = field['FieldName'];\n const neededSymbols = symbolsToKeep ? symbolsToKeep.get(fieldName) : null;\n const filteringEnabled = neededSymbols !== null;\n\n const symbols = [];\n let symbolIndex = 0; // Track current symbol index as we parse\n\n // Parse all possible values of the current field/column\n for (let pointer = symbolsOffset; pointer < symbolsOffset + symbolsLength; pointer++) {\n // Each stored symbol consists of a type byte and the actual value, which length depends on the type\n const typeByte = symbolBuffer[pointer++];\n\n // Check if we should keep this symbol (filtering mode)\n const shouldKeepSymbol = !filteringEnabled || !!(neededSymbols && neededSymbols.has(symbolIndex));\n\n // Use utility function to parse or skip symbol\n const {symbol, bytesRead} = parseSymbol(\n typeByte,\n symbolBuffer,\n pointer,\n symbolBuffer.length,\n fieldName,\n this._path,\n shouldKeepSymbol,\n );\n\n symbols.push(symbol);\n pointer += bytesRead - 1; // -1 because the loop will increment\n symbolIndex++;\n }\n\n return symbols;\n // @ts-ignore - Symbol table type assignment\n });\n }\n\n /**\n * Utility method to convert a bit array to an integer value.\n *\n * @param {Array<number>} bits The bit array\n * @return {Number} The integer value\n */\n _convertBitsToInt32(bits) {\n return convertBitsToInt32(bits);\n }\n\n /**\n * Parses the bit stuffed index table of the QVD file. This method is part of the parsing process\n * and should not be called directly.\n *\n * @param {number|null} maxRows The maximum number of rows to parse. If null, all rows are parsed.\n */\n async _parseIndexTable(maxRows = null) {\n if (!this._buffer || !this._header || !this._indexTableOffset) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'parseIndexTable',\n },\n );\n }\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n // Size of a single row of the index table in bytes\n const recordSize = parseInt(this._header['QvdTableHeader']['RecordByteSize'], 10);\n const totalRows = parseInt(this._header['QvdTableHeader']['NoOfRecords'], 10);\n const rowsToLoad = maxRows !== null ? Math.min(maxRows, totalRows) : totalRows;\n const indexTableLength = parseInt(this._header['QvdTableHeader']['Length'], 10);\n\n // Validate all index table metadata\n validateIndexTableMetadata(\n recordSize,\n totalRows,\n indexTableLength,\n this._indexTableOffset,\n this._buffer.length,\n rowsToLoad,\n this._path,\n );\n\n const indexBuffer = this._buffer.subarray(this._indexTableOffset, this._indexTableOffset + indexTableLength + 1);\n\n // Validate BitOffset and BitWidth for all fields before processing\n for (const field of fields) {\n validateFieldBitMetadata(field, recordSize, this._path);\n }\n\n this._indexTable = [];\n\n // Parse rows of the index table, each row contains the indices of the symbol table for each field/column\n for (\n let pointer = 0, rowCount = 0;\n pointer < indexBuffer.length && rowCount < rowsToLoad;\n pointer += recordSize, rowCount++\n ) {\n // Validate we have enough bytes for this record\n if (pointer + recordSize > indexBuffer.length) {\n throw new QvdCorruptedError('Buffer overflow reading index table record', {\n pointer,\n recordSize,\n bufferSize: indexBuffer.length,\n file: this._path,\n stage: 'parseIndexTable',\n });\n }\n\n const bytes = new Int32Array(indexBuffer.subarray(pointer, pointer + recordSize));\n bytes.reverse();\n\n // The bit mask contains the bit stuffed indices of the symbol table of the current row\n const mask = bytes\n .reduce((bits, byte) => bits + ('00000000' + byte.toString(2)).slice(-8), '')\n .split('')\n .reverse()\n .map((bit) => parseInt(bit));\n\n /** @type {number[]} */\n const symbolIndices = [];\n\n // Extract the index from the current row's bit mask for each field/column\n fields.forEach((/** @type {any} */ field) => {\n const bitOffset = parseInt(field['BitOffset'], 10);\n const bitWidth = parseInt(field['BitWidth'], 10);\n const bias = parseInt(field['Bias'], 10);\n\n let symbolIndex;\n\n if (bitWidth === 0) {\n symbolIndex = 0;\n } else {\n symbolIndex = this._convertBitsToInt32(mask.slice(bitOffset, bitOffset + bitWidth));\n }\n\n symbolIndex += bias;\n symbolIndices.push(symbolIndex);\n });\n\n this._indexTable.push(symbolIndices);\n }\n }\n\n /**\n * Loads the QVD file into memory and parses it.\n *\n * @param {number|null} maxRows The maximum number of rows to load. If null, all rows are loaded.\n * @return {Promise<QvdDataFrame>} The loaded QVD file.\n */\n async load(maxRows = null) {\n await this._readData(maxRows);\n await this._parseHeader();\n\n // Determine if we should use two-pass symbol filtering\n // This optimization is beneficial for large symbol tables with limited row access\n let symbolsToKeep = null;\n\n if (maxRows !== null && this._header) {\n const symbolTableLength = parseInt(this._header['QvdTableHeader']['Offset'], 10);\n const SYMBOL_FILTERING_THRESHOLD = 50 * 1024 * 1024; // 50MB\n\n // Use two-pass filtering for symbol tables > 50MB when loading limited rows\n if (symbolTableLength > SYMBOL_FILTERING_THRESHOLD) {\n // Pass 1: Analyze which symbols are actually needed\n symbolsToKeep = await this._analyzeIndexTableSymbolUsage(maxRows);\n\n // Log the optimization for visibility\n const totalSymbols = Array.from(symbolsToKeep.values()).reduce((sum, set) => sum + set.size, 0);\n console.log(\n `[Phase 2.5 Optimization] Using stream-and-skip parsing: keeping ${totalSymbols} symbols from ${(symbolTableLength / 1024 / 1024).toFixed(1)}MB symbol table`,\n );\n }\n }\n\n // Pass 2: Parse symbol table (with filtering if enabled)\n await this._parseSymbolTable(symbolsToKeep, maxRows);\n await this._parseIndexTable(maxRows);\n\n assert(this._header, 'The QVD file header has not been parsed.');\n assert(this._symbolTable, 'The QVD file symbol table has not been parsed.');\n assert(this._indexTable, 'The QVD file index table has not been parsed.');\n\n /**\n * Retrieves the values of a specific row of the QVD file. Values are in the same order\n * as the field names.\n *\n * @param {number} index The index of the row.\n * @return {Array<any>} The values of the row.\n */\n const getRow = (index) => {\n if (!this._indexTable || index >= this._indexTable.length) {\n throw new QvdValidationError('Row index out of bounds', {\n index,\n max: this._indexTable ? this._indexTable.length - 1 : -1,\n file: this._path,\n });\n }\n\n return this._indexTable?.[index].map((/** @type {number} */ symbolIndex, /** @type {number} */ fieldIndex) => {\n if (symbolIndex < 0) {\n return null;\n }\n\n const symbol = this._symbolTable?.[fieldIndex]?.[symbolIndex];\n const value = symbol?.toPrimaryValue();\n\n if (typeof value === 'string') {\n if (!isNaN(Number(value))) {\n return Number(value);\n }\n }\n\n return value;\n });\n };\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n const columns = fields.map((/** @type {any} */ field) => field['FieldName']);\n const data = this._indexTable.map((_, index) => getRow(index));\n\n // Pass the complete header metadata to the data frame\n const metadata = this._header['QvdTableHeader'];\n\n return new QvdDataFrame(data, columns, metadata);\n }\n}\n","// @ts-check\n\nimport {QvdValidationError} from './QvdErrors.js';\n\n/**\n * @typedef {Object} QvdNumberFormat\n * @property {string} Type - Number format type\n * @property {string} nDec - Number of decimals\n * @property {string} UseThou - Use thousands separator\n * @property {string} Fmt - Format string\n * @property {string} Dec - Decimal separator\n * @property {string} Thou - Thousands separator\n */\n\n/**\n * @typedef {Object} QvdFieldHeader\n * @property {string} FieldName - The name of the field\n * @property {string|number} [BitOffset] - The bit offset\n * @property {string|number} [BitWidth] - The bit width\n * @property {string|number} [Bias] - The bias value\n * @property {string|number} [NoOfSymbols] - Number of symbols\n * @property {string|number} [Offset] - The offset\n * @property {string|number} [Length] - The length\n * @property {string} [Comment] - Field comment\n * @property {QvdNumberFormat|string} [NumberFormat] - Number format\n * @property {Object|string} [Tags] - Field tags\n */\n\n/**\n * @typedef {Object} QvdFields\n * @property {QvdFieldHeader|QvdFieldHeader[]} QvdFieldHeader - Field header(s)\n */\n\n/**\n * @typedef {Object} QvdMetadata\n * @property {string|number} [QvBuildNo] - QlikView build number\n * @property {string} [CreatorDoc] - Creator document\n * @property {string} [CreateUtcTime] - Creation UTC time\n * @property {string} [SourceCreateUtcTime] - Source creation UTC time\n * @property {string} [SourceFileUtcTime] - Source file UTC time\n * @property {string|number} [SourceFileSize] - Source file size\n * @property {string} [StaleUtcTime] - Stale UTC time\n * @property {string} [TableName] - Table name\n * @property {string|number} [NoOfRecords] - Number of records\n * @property {string|number} [RecordByteSize] - Record byte size\n * @property {string|number} [Offset] - Offset\n * @property {string|number} [Length] - Length\n * @property {string} [Compression] - Compression type\n * @property {string} [Comment] - Comment\n * @property {string} [EncryptionInfo] - Encryption info\n * @property {string} [TableTags] - Table tags\n * @property {string} [ProfilingData] - Profiling data\n * @property {Object|string} [Lineage] - Lineage\n * @property {QvdFields} [Fields] - Fields information\n */\n\n/**\n * Represents a loaded QVD file.\n */\nexport class QvdDataFrame {\n /**\n * Represents the data frame stored inside a QVD file.\n * @param {Array<Array<any>>} data The data of the data frame.\n * @param {Array<string>} columns The columns of the data frame.\n * @param {QvdMetadata|null} metadata The metadata from the QVD file header (optional).\n */\n constructor(data, columns, metadata = null) {\n this._data = data;\n this._columns = columns;\n this._metadata = metadata;\n }\n\n /**\n * Returns the data of the data frame.\n */\n get data() {\n return this._data;\n }\n\n /**\n * Returns the columns of the data frame.\n */\n get columns() {\n return this._columns;\n }\n\n /**\n * Returns the shape of the data frame.\n */\n get shape() {\n return [this._data.length, this._columns.length];\n }\n\n /**\n * Returns the complete metadata object from the QVD file header.\n * @return {Object|null} The complete metadata object or null if not available.\n */\n get metadata() {\n return this._metadata;\n }\n\n /**\n * Returns file-level metadata from the QVD header.\n * @return {Object} File-level metadata properties.\n */\n get fileMetadata() {\n if (!this._metadata) {\n return {};\n }\n\n const header = this._metadata;\n return {\n qvBuildNo: header.QvBuildNo,\n creatorDoc: header.CreatorDoc,\n createUtcTime: header.CreateUtcTime,\n sourceCreateUtcTime: header.SourceCreateUtcTime,\n sourceFileUtcTime: header.SourceFileUtcTime,\n sourceFileSize: header.SourceFileSize,\n staleUtcTime: header.StaleUtcTime,\n tableName: header.TableName,\n noOfRecords: header.NoOfRecords,\n recordByteSize: header.RecordByteSize,\n offset: header.Offset,\n length: header.Length,\n compression: header.Compression,\n comment: header.Comment,\n encryptionInfo: header.EncryptionInfo,\n tableTags: header.TableTags,\n profilingData: header.ProfilingData,\n lineage: header.Lineage,\n };\n }\n\n /**\n * Returns field-level metadata for a specific field/column.\n * @param {string} fieldName The name of the field.\n * @return {Object|null} Field metadata or null if field not found.\n */\n getFieldMetadata(fieldName) {\n if (!this._metadata || !this._metadata.Fields || !this._metadata.Fields.QvdFieldHeader) {\n return null;\n }\n\n let fields = this._metadata.Fields.QvdFieldHeader;\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n const field = fields.find((f) => f.FieldName === fieldName);\n if (!field) {\n return null;\n }\n\n return {\n fieldName: field.FieldName,\n bitOffset: field.BitOffset,\n bitWidth: field.BitWidth,\n bias: field.Bias,\n noOfSymbols: field.NoOfSymbols,\n offset: field.Offset,\n length: field.Length,\n comment: field.Comment,\n numberFormat: field.NumberFormat,\n tags: field.Tags,\n };\n }\n\n /**\n * Returns field-level metadata for all fields.\n * @return {Array<Object>} Array of field metadata objects.\n */\n getAllFieldMetadata() {\n if (!this._metadata || !this._metadata.Fields || !this._metadata.Fields.QvdFieldHeader) {\n return [];\n }\n\n let fields = this._metadata.Fields.QvdFieldHeader;\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n return fields.map((field) => ({\n fieldName: field.FieldName,\n bitOffset: field.BitOffset,\n bitWidth: field.BitWidth,\n bias: field.Bias,\n noOfSymbols: field.NoOfSymbols,\n offset: field.Offset,\n length: field.Length,\n comment: field.Comment,\n numberFormat: field.NumberFormat,\n tags: field.Tags,\n }));\n }\n\n /**\n * @typedef {Object} FileMetadataUpdate\n * @property {string|number} [qvBuildNo] - QlikView build number\n * @property {string} [creatorDoc] - Creator document\n * @property {string} [createUtcTime] - Creation UTC time\n * @property {string} [sourceCreateUtcTime] - Source creation UTC time\n * @property {string} [sourceFileUtcTime] - Source file UTC time\n * @property {string|number} [sourceFileSize] - Source file size\n * @property {string} [staleUtcTime] - Stale UTC time\n * @property {string} [tableName] - Table name\n * @property {string} [compression] - Compression type\n * @property {string} [comment] - Comment\n * @property {string} [encryptionInfo] - Encryption info\n * @property {string} [tableTags] - Table tags\n * @property {string} [profilingData] - Profiling data\n * @property {Object|string} [lineage] - Lineage\n */\n\n /**\n * Sets modifiable file-level metadata. Immutable properties related to data storage are ignored.\n * @param {FileMetadataUpdate} metadata Object containing metadata properties to update.\n */\n setFileMetadata(metadata) {\n if (!this._metadata) {\n // Initialize metadata structure if it doesn't exist\n this._metadata = {\n QvBuildNo: 50667,\n CreatorDoc: '',\n CreateUtcTime: '',\n SourceCreateUtcTime: '',\n SourceFileUtcTime: '',\n SourceFileSize: -1,\n StaleUtcTime: '',\n TableName: '',\n Fields: {\n QvdFieldHeader: this._columns.map((column) => ({\n FieldName: column,\n BitOffset: 0,\n BitWidth: 0,\n Bias: 0,\n NoOfSymbols: 0,\n Offset: 0,\n Length: 0,\n Comment: '',\n NumberFormat: {\n Type: 'UNKNOWN',\n nDec: '0',\n UseThou: '0',\n Fmt: '',\n Dec: '',\n Thou: '',\n },\n Tags: {},\n })),\n },\n NoOfRecords: 0,\n RecordByteSize: 0,\n Offset: 0,\n Length: 0,\n Compression: '',\n Comment: '',\n EncryptionInfo: '',\n TableTags: '',\n ProfilingData: '',\n Lineage: {},\n };\n }\n\n // Only allow modification of certain fields (not Offset, Length, NoOfRecords, RecordByteSize)\n const modifiableFields = [\n 'qvBuildNo',\n 'creatorDoc',\n 'createUtcTime',\n 'sourceCreateUtcTime',\n 'sourceFileUtcTime',\n 'sourceFileSize',\n 'staleUtcTime',\n 'tableName',\n 'compression',\n 'comment',\n 'encryptionInfo',\n 'tableTags',\n 'profilingData',\n 'lineage',\n ];\n\n // Map camelCase to XML property names\n const fieldMapping = {\n qvBuildNo: 'QvBuildNo',\n creatorDoc: 'CreatorDoc',\n createUtcTime: 'CreateUtcTime',\n sourceCreateUtcTime: 'SourceCreateUtcTime',\n sourceFileUtcTime: 'SourceFileUtcTime',\n sourceFileSize: 'SourceFileSize',\n staleUtcTime: 'StaleUtcTime',\n tableName: 'TableName',\n compression: 'Compression',\n comment: 'Comment',\n encryptionInfo: 'EncryptionInfo',\n tableTags: 'TableTags',\n profilingData: 'ProfilingData',\n lineage: 'Lineage',\n };\n\n modifiableFields.forEach((field) => {\n // @ts-ignore - Dynamic property access for metadata mapping\n if (metadata[field] !== undefined) {\n // @ts-ignore - Dynamic property access for metadata mapping\n this._metadata[fieldMapping[field]] = metadata[field];\n }\n });\n }\n\n /**\n * @typedef {Object} FieldMetadataUpdate\n * @property {string} [comment] - Field comment\n * @property {QvdNumberFormat|string} [numberFormat] - Number format\n * @property {Object|string} [tags] - Field tags\n */\n\n /**\n * Sets modifiable field-level metadata for a specific field.\n * Immutable properties related to data storage (Offset, Length, BitOffset, etc.) are ignored.\n * @param {string} fieldName The name of the field.\n * @param {FieldMetadataUpdate} metadata Object containing field metadata properties to update.\n */\n setFieldMetadata(fieldName, metadata) {\n if (!this._metadata || !this._metadata.Fields || !this._metadata.Fields.QvdFieldHeader) {\n return;\n }\n\n let fields = this._metadata.Fields.QvdFieldHeader;\n if (!Array.isArray(fields)) {\n fields = [fields];\n this._metadata.Fields.QvdFieldHeader = fields;\n }\n\n const fieldIndex = fields.findIndex((f) => f.FieldName === fieldName);\n if (fieldIndex === -1) {\n return;\n }\n\n // Only allow modification of Comment, NumberFormat, and Tags (not Offset, Length, BitOffset, etc.)\n if (metadata.comment !== undefined) {\n fields[fieldIndex].Comment = metadata.comment;\n }\n if (metadata.numberFormat !== undefined) {\n fields[fieldIndex].NumberFormat = metadata.numberFormat;\n }\n if (metadata.tags !== undefined) {\n fields[fieldIndex].Tags = metadata.tags;\n }\n }\n\n /**\n * Returns the first n rows of the data frame.\n *\n * @param {number} n The number of rows to return.\n * @return {QvdDataFrame} The first n rows of the data frame.\n * @throws {QvdValidationError} If n is not a non-negative integer.\n */\n head(n = 5) {\n if (typeof n !== 'number' || !Number.isInteger(n) || n < 0) {\n throw new QvdValidationError('head() requires a non-negative integer', {\n provided: n,\n type: typeof n,\n });\n }\n return new QvdDataFrame(this._data.slice(0, n), this._columns, this._metadata);\n }\n\n /**\n * Returns the last n rows of the data frame.\n *\n * @param {number} n The number of rows to return.\n * @return {QvdDataFrame} The first n rows of the data frame.\n * @throws {QvdValidationError} If n is not a non-negative integer.\n */\n tail(n = 5) {\n if (typeof n !== 'number' || !Number.isInteger(n) || n < 0) {\n throw new QvdValidationError('tail() requires a non-negative integer', {\n provided: n,\n type: typeof n,\n });\n }\n return new QvdDataFrame(n === 0 ? [] : this._data.slice(-n), this._columns, this._metadata);\n }\n\n /**\n * Returns the selected rows of the data frame.\n *\n * @param {...number} args The indices of the rows to return.\n * @return {QvdDataFrame} The selected rows of the data frame.\n * @throws {QvdValidationError} If any index is not an integer or is out of bounds.\n */\n rows(...args) {\n for (const index of args) {\n if (typeof index !== 'number' || !Number.isInteger(index)) {\n throw new QvdValidationError('rows() requires integer indices', {\n provided: index,\n type: typeof index,\n });\n }\n if (index < 0 || index >= this._data.length) {\n throw new QvdValidationError(`Row index ${index} out of bounds`, {\n index,\n validRange: [0, this._data.length - 1],\n dataLength: this._data.length,\n });\n }\n }\n return new QvdDataFrame(\n args.map((index) => this._data[index]),\n this._columns,\n this._metadata,\n );\n }\n\n /**\n * Returns the value at the specified row and column.\n *\n * @param {number} row The index of the row.\n * @param {string} column The name of the column.\n * @return {any} The value at the specified row and column.\n * @throws {QvdValidationError} If row is not an integer, out of bounds, or column does not exist.\n */\n at(row, column) {\n if (typeof row !== 'number' || !Number.isInteger(row)) {\n throw new QvdValidationError('Row index must be an integer', {\n provided: row,\n type: typeof row,\n });\n }\n if (row < 0 || row >= this._data.length) {\n throw new QvdValidationError(`Row index ${row} out of bounds`, {\n index: row,\n validRange: [0, this._data.length - 1],\n dataLength: this._data.length,\n });\n }\n if (!this._columns.includes(column)) {\n throw new QvdValidationError(`Column '${column}' does not exist`, {\n column,\n availableColumns: this._columns,\n });\n }\n return this._data[row][this._columns.indexOf(column)];\n }\n\n /**\n * Selects the specified columns from the data frame.\n *\n * @param {...string} args The names of the columns to select.\n * @return {QvdDataFrame} The selected columns of the data frame.\n * @throws {QvdValidationError} If any column name does not exist.\n */\n select(...args) {\n for (const column of args) {\n if (!this._columns.includes(column)) {\n throw new QvdValidationError(`Column '${column}' does not exist`, {\n column,\n availableColumns: this._columns,\n });\n }\n }\n const indices = args.map((arg) => this._columns.indexOf(arg));\n const data = this._data.map((row) => indices.map((index) => row[index]));\n const columns = indices.map((index) => this._columns[index]);\n return new QvdDataFrame(data, columns, this._metadata);\n }\n\n /**\n * Returns the data frame as a dictionary.\n *\n * @return {Promise<{columns: Array<string>, data: Array<Array<any>>}>} The data frame as a dictionary.\n */\n async toDict() {\n return {columns: this._columns, data: this._data};\n }\n\n /**\n * Persists the data frame to a QVD file.\n *\n * @param {string} path The path to the QVD file.\n * @param {Object} [options] Optional writing options.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file path must be within this directory.\n * @param {Function} [options.onProgress] Optional progress callback function that receives progress updates during write operations.\n */\n async toQvd(path, options = {}) {\n const {QvdFileWriter} = await import('./QvdFileWriter.js');\n const writerOptions = {\n allowedDir: options.allowedDir,\n onProgress: options.onProgress,\n };\n await new QvdFileWriter(path, this, writerOptions).save();\n }\n\n /**\n * Loads a QVD file and returns its data frame.\n *\n * @param {string} path The path to the QVD file.\n * @param {Object} [options] Optional loading options.\n * @param {number|null} [options.maxRows] The maximum number of rows to load. If not specified, all rows are loaded.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file path must be within this directory.\n * @return {Promise<QvdDataFrame>} The data frame of the QVD file.\n */\n static async fromQvd(path, options = {}) {\n const {QvdFileReader} = await import('./QvdFileReader.js');\n const readerOptions = {allowedDir: options.allowedDir};\n return await new QvdFileReader(path, readerOptions).load(options.maxRows !== undefined ? options.maxRows : null);\n }\n\n /**\n * Constructs a data frame from a dictionary.\n *\n * @param {{columns: Array<string>, data: Array<Array<any>>}} data The dictionary to construct the data frame from.\n * @return {Promise<QvdDataFrame>} The constructed data frame.\n */\n static async fromDict(data) {\n if (!data.columns) {\n throw new QvdValidationError('The dictionary to construct the data frame from does not contain any columns.', {\n data,\n });\n }\n if (!data.data) {\n throw new QvdValidationError('The dictionary to construct the data frame from does not contain any data.', {\n data,\n });\n }\n\n return new QvdDataFrame(data.data, data.columns);\n }\n}\n","// @ts-check\n\nexport {QvdSymbol} from './QvdSymbol.js';\nexport {QvdDataFrame} from './QvdDataFrame.js';\nexport {QvdFileReader} from './QvdFileReader.js';\nexport {QvdFileWriter} from './QvdFileWriter.js';\nexport {\n QvdError,\n QvdParseError,\n QvdValidationError,\n QvdIOError,\n QvdCorruptedError,\n QvdSecurityError,\n} from './QvdErrors.js';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/QvdErrors.js","../src/QvdSymbol.js","../src/util/validatePath.js","../src/QvdFileWriter.js","../src/util/bitUtils.js","../src/util/memoryUtils.js","../src/util/validationUtils.js","../src/util/symbolParser.js","../src/QvdFileReader.js","../src/QvdDataFrame.js","../src/index.js"],"names":["path","fs","xml","assert","QvdFileWriter","QvdFileReader"],"mappings":"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","file":"index.js","sourcesContent":["// @ts-check\n\n/**\n * Base error class for all QVD-related errors.\n * Provides structured error information with error codes and context.\n */\nexport class QvdError extends Error {\n /**\n * Constructs a new QVD error.\n *\n * @param {string} message The error message.\n * @param {string} code The error code.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, code, context = {}) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.context = context;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when parsing a QVD file fails.\n * Used for issues during XML header parsing, symbol table parsing, or index table parsing.\n */\nexport class QvdParseError extends QvdError {\n /**\n * Constructs a new QVD parse error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_PARSE_ERROR', context);\n }\n}\n\n/**\n * Error thrown when input validation fails.\n * Used for invalid parameters, out of bounds access, or missing required data.\n */\nexport class QvdValidationError extends QvdError {\n /**\n * Constructs a new QVD validation error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_VALIDATION_ERROR', context);\n }\n}\n\n/**\n * Error thrown when file system operations fail.\n * Used for issues reading or writing QVD files.\n */\nexport class QvdIOError extends QvdError {\n /**\n * Constructs a new QVD IO error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_IO_ERROR', context);\n }\n}\n\n/**\n * Error thrown when a QVD file is corrupted or malformed.\n * Used for missing headers, invalid data structures, or corrupted data.\n */\nexport class QvdCorruptedError extends QvdError {\n /**\n * Constructs a new QVD corrupted error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_CORRUPTED_ERROR', context);\n }\n}\n\n/**\n * Error thrown when security violations occur.\n * Used for path traversal attempts, XXE attacks, or other security issues.\n */\nexport class QvdSecurityError extends QvdError {\n /**\n * Constructs a new QVD security error.\n *\n * @param {string} message The error message.\n * @param {Object} [context={}] Additional context about the error.\n */\n constructor(message, context = {}) {\n super(message, 'QVD_SECURITY_ERROR', context);\n }\n}\n","// @ts-check\n\nimport {QvdValidationError} from './QvdErrors.js';\n\n/**\n * Represents a Qlik symbol/value, stored in a QVD file.\n */\nexport class QvdSymbol {\n /**\n * Constructs a new QVD symbol.\n *\n * @param {number|null} intValue The integer value.\n * @param {number|null} doubleValue The double value.\n * @param {string|null} stringValue The string value.\n */\n constructor(intValue, doubleValue, stringValue) {\n this._intValue = intValue;\n\n this._doubleValue = doubleValue;\n\n this._stringValue = stringValue;\n }\n\n /**\n * Returns the integer value of this symbol.\n *\n * @return {number|null} The integer value.\n */\n get intValue() {\n return this._intValue;\n }\n\n /**\n * Returns the double value of this symbol.\n *\n * @return {number|null} The double value.\n */\n get doubleValue() {\n return this._doubleValue;\n }\n\n /**\n * Returns the string value of this symbol.\n *\n * @return {string|null} The string value.\n */\n get stringValue() {\n return this._stringValue;\n }\n\n /**\n * Retrieves the primary value of this symbol. The primary value is descriptive raw value.\n * It is either the string value, the integer value or the double value, prioritized in this order.\n *\n * @return {number|string|null} The primary value.\n */\n toPrimaryValue() {\n if (null != this._stringValue) {\n return this._stringValue;\n } else if (null != this._intValue) {\n return this._intValue;\n } else if (null != this._doubleValue) {\n return this._doubleValue;\n } else {\n return null;\n }\n }\n\n /**\n * Converts the symbol to its byte representation.\n *\n * @return {Buffer} The byte representation of the symbol.\n */\n toByteRepresentation() {\n if (this._intValue !== null && this._stringValue !== null) {\n const intBuffer = Buffer.alloc(4);\n intBuffer.writeInt32LE(this._intValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n const stringBuffer = Buffer.concat([Buffer.from(this._stringValue, 'utf-8'), Buffer.from([0])]);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([5]), intBuffer, stringBuffer]);\n } else if (this._doubleValue !== null && this._stringValue !== null) {\n const floatBuffer = Buffer.alloc(8);\n floatBuffer.writeDoubleLE(this._doubleValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n const stringBuffer = Buffer.concat([Buffer.from(this._stringValue, 'utf-8'), Buffer.from([0])]);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([6]), floatBuffer, stringBuffer]);\n } else if (this._intValue !== null) {\n const buffer = Buffer.alloc(4);\n buffer.writeInt32LE(this._intValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([1]), buffer]);\n } else if (this._doubleValue !== null) {\n const buffer = Buffer.alloc(8);\n buffer.writeDoubleLE(this._doubleValue);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([2]), buffer]);\n } else if (this._stringValue !== null) {\n // @ts-ignore - Buffer.concat type compatibility\n const buffer = Buffer.concat([Buffer.from(this._stringValue, 'utf-8'), Buffer.from([0])]);\n\n // @ts-ignore - Buffer.concat type compatibility\n return Buffer.concat([Buffer.from([4]), buffer]);\n } else {\n throw new QvdValidationError('The symbol does not contain any value.', {\n intValue: this._intValue,\n doubleValue: this._doubleValue,\n stringValue: this._stringValue,\n });\n }\n }\n\n /**\n * Checks if this symbol is equal to another symbol.\n *\n * @param {*} value The object to compare with.\n * @return {boolean} True if the objects are equal, false otherwise.\n */\n equals(value) {\n if (!(value instanceof QvdSymbol)) {\n return false;\n }\n\n return (\n this._intValue === value.intValue &&\n this._doubleValue === value.doubleValue &&\n this._stringValue === value.stringValue\n );\n }\n\n /**\n * Constructs a pure integer value symbol.\n *\n * @param {number} intValue The integer value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromIntValue(intValue) {\n return new QvdSymbol(intValue, null, null);\n }\n\n /**\n * Constructs a pure double value symbol.\n *\n * @param {number} doubleValue The double value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromDoubleValue(doubleValue) {\n return new QvdSymbol(null, doubleValue, null);\n }\n\n /**\n * Constructs a pure string value symbol.\n *\n * @param {string} stringValue The string value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromStringValue(stringValue) {\n return new QvdSymbol(null, null, stringValue);\n }\n\n /**\n * Constructs a dual value symbol from an integer and a string value.\n *\n * @param {number} intValue The integer value.\n * @param {string} stringValue The string value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromDualIntValue(intValue, stringValue) {\n return new QvdSymbol(intValue, null, stringValue);\n }\n\n /**\n * Constructs a dual value symbol from a double and a string value.\n *\n * @param {number} doubleValue The double value.\n * @param {string} stringValue The string value.\n * @return {QvdSymbol} The constructed value symbol.\n */\n static fromDualDoubleValue(doubleValue, stringValue) {\n return new QvdSymbol(null, doubleValue, stringValue);\n }\n}\n","// @ts-check\n\nimport path from 'path';\nimport {QvdSecurityError} from '../QvdErrors.js';\n\n/**\n * Validates that a file path does not contain path traversal sequences.\n *\n * @param {string} filePath The path to validate.\n * @param {string} [allowedDir] Optional allowed directory path. If not provided, defaults to the\n * current working directory to prevent path traversal attacks.\n * @throws {QvdSecurityError} If path traversal is detected.\n * @return {string} The resolved absolute path.\n */\nexport function validatePath(filePath, allowedDir) {\n // Check for null bytes which can be used in path traversal attacks\n if (filePath.includes('\\0')) {\n throw new QvdSecurityError('Path traversal detected: Null byte in path', {\n path: filePath,\n reason: 'null_byte',\n });\n }\n\n // Default to current working directory if no allowed directory is specified\n // This prevents path traversal attacks by ensuring files can only be accessed\n // within the CWD or a more restrictive allowed directory\n const baseDir = allowedDir || process.cwd();\n const resolvedBaseDir = path.resolve(baseDir);\n const resolvedPath = path.resolve(filePath);\n\n // Ensure the resolved path is within the allowed directory\n // Use path.sep to ensure proper directory boundary checking across platforms\n // On Windows and macOS (default APFS), file systems are case-insensitive,\n // so we need case-insensitive comparison. On Linux, use case-sensitive comparison.\n const isCaseInsensitiveFS = process.platform === 'win32' || process.platform === 'darwin';\n const baseForComparison = isCaseInsensitiveFS ? resolvedBaseDir.toLowerCase() : resolvedBaseDir;\n const pathForComparison = isCaseInsensitiveFS ? resolvedPath.toLowerCase() : resolvedPath;\n\n if (!pathForComparison.startsWith(baseForComparison + path.sep) && pathForComparison !== baseForComparison) {\n throw new QvdSecurityError('Path traversal detected: Access denied', {\n path: filePath,\n resolvedPath,\n allowedDir: resolvedBaseDir,\n reason: 'outside_allowed_directory',\n });\n }\n\n return resolvedPath;\n}\n","// @ts-check\n\nimport fs from 'fs';\nimport path from 'path';\nimport crypto from 'crypto';\nimport xml from 'xml2js';\nimport assert from 'assert';\nimport {QvdSymbol} from './QvdSymbol.js';\nimport {validatePath} from './util/validatePath.js';\n\n/**\n * @typedef {import('./QvdDataFrame.js').QvdDataFrame} QvdDataFrame\n */\n\n/**\n * Persists a QVD file to disk.\n */\nexport class QvdFileWriter {\n /**\n * Constructs a new QVD file writer.\n *\n * @param {string} filePath The path to the QVD file to write.\n * @param {QvdDataFrame} df The data frame to write to the QVD file.\n * @param {Object} [options={}] Options for the writer.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file\n * path must be within this directory. Defaults to current working directory.\n * @param {Function} [options.onProgress] Optional progress callback function.\n */\n constructor(filePath, df, options = {}) {\n const {allowedDir, onProgress} = options;\n this._path = validatePath(filePath, allowedDir);\n this._df = df;\n this._onProgress = onProgress;\n this._header = null;\n this._symbolBuffer = null;\n /** @type {Array<Array<import('./QvdSymbol.js').QvdSymbol>>|null} */\n this._symbolTable = null;\n /** @type {Array<any>|null} */\n this._symbolTableMetadata = null;\n this._indexBuffer = null;\n /** @type {Array<any>|null} */\n this._indexTable = null;\n /** @type {Array<any>|null} */\n this._indexTableMetadata = null;\n this._recordByteSize = null;\n }\n\n /**\n * Emits a progress event if a callback is registered.\n *\n * @param {string} stage The current stage of the operation.\n * @param {number} current The current progress value.\n * @param {number} total The total progress value.\n */\n _emitProgress(stage, current, total) {\n if (this._onProgress) {\n const percent = total > 0 ? Math.round((current / total) * 100) : 100;\n this._onProgress({\n stage,\n current,\n total,\n percent,\n });\n }\n }\n\n /**\n * Writes the data to the QVD file.\n */\n async _writeData() {\n assert(this._header, 'The QVD file header has not been parsed.');\n assert(this._symbolBuffer, 'The QVD file symbol table has not been parsed.');\n assert(this._indexBuffer, 'The QVD file index table has not been parsed.');\n\n this._emitProgress('write', 0, 1);\n\n // @ts-ignore - Buffer.concat type compatibility\n const headerBuffer = Buffer.concat([Buffer.from(this._header, 'utf-8'), Buffer.from([0])]);\n\n let fd;\n try {\n fd = await fs.promises.open(this._path, 'w');\n await fd.write(headerBuffer, 0, headerBuffer.length, 0);\n await fd.write(this._symbolBuffer, 0, this._symbolBuffer.length, headerBuffer.length);\n await fd.write(this._indexBuffer, 0, this._indexBuffer.length, headerBuffer.length + this._symbolBuffer.length);\n this._emitProgress('write', 1, 1);\n } finally {\n if (fd) {\n await fd.close();\n }\n }\n }\n\n /**\n * Builds the XML header of the QVD file.\n */\n _buildHeader() {\n this._emitProgress('header', 0, 1);\n const creationDate = new Date().toISOString().replace(/T/, ' ').replace(/\\..+/, '');\n /** @type {import('./QvdDataFrame.js').QvdMetadata|null} */\n const existingMetadata = this._df.metadata;\n\n // Use existing metadata if available, otherwise create default values\n const baseMetadata = existingMetadata\n ? {\n QvBuildNo: existingMetadata.QvBuildNo || 50667,\n CreatorDoc: existingMetadata.CreatorDoc || crypto.randomUUID(),\n CreateUtcTime: existingMetadata.CreateUtcTime || creationDate,\n SourceCreateUtcTime: existingMetadata.SourceCreateUtcTime || '',\n SourceFileUtcTime: existingMetadata.SourceFileUtcTime || '',\n SourceFileSize: existingMetadata.SourceFileSize || -1,\n StaleUtcTime: existingMetadata.StaleUtcTime || '',\n TableName: existingMetadata.TableName || path.basename(this._path, path.extname(this._path)),\n Compression: existingMetadata.Compression || '',\n Comment: existingMetadata.Comment || '',\n EncryptionInfo: existingMetadata.EncryptionInfo || '',\n TableTags: existingMetadata.TableTags || '',\n ProfilingData: existingMetadata.ProfilingData || '',\n Lineage: existingMetadata.Lineage || {\n LineageInfo: {\n Discriminator: 'INLINE;',\n Statement: '',\n },\n },\n }\n : {\n QvBuildNo: 50667,\n CreatorDoc: crypto.randomUUID(),\n CreateUtcTime: creationDate,\n SourceCreateUtcTime: '',\n SourceFileUtcTime: '',\n SourceFileSize: -1,\n StaleUtcTime: '',\n TableName: path.basename(this._path, path.extname(this._path)),\n Compression: '',\n Comment: '',\n EncryptionInfo: '',\n TableTags: '',\n ProfilingData: '',\n Lineage: {\n LineageInfo: {\n Discriminator: 'INLINE;',\n Statement: '',\n },\n },\n };\n\n // Get existing field metadata if available\n /** @type {any[]} */\n let existingFields = [];\n if (existingMetadata && existingMetadata.Fields && existingMetadata.Fields.QvdFieldHeader) {\n existingFields = Array.isArray(existingMetadata.Fields.QvdFieldHeader)\n ? existingMetadata.Fields.QvdFieldHeader\n : [existingMetadata.Fields.QvdFieldHeader];\n }\n\n const xmlObject = {\n QvdTableHeader: {\n ...baseMetadata,\n Fields: {\n QvdFieldHeader: this._df.columns.map((/** @type {any} */ column, /** @type {number} */ index) => {\n // Find existing field metadata for this column\n const existingField = existingFields.find((/** @type {any} */ f) => f.FieldName === column);\n\n return {\n FieldName: column,\n BitOffset: this._indexTableMetadata?.[index][0],\n BitWidth: this._indexTableMetadata?.[index][1],\n Bias: this._indexTableMetadata?.[index][2],\n NoOfSymbols: this._symbolTable?.[index].length,\n Offset: this._symbolTableMetadata?.[index][0],\n Length: this._symbolTableMetadata?.[index][1],\n Comment: existingField?.Comment || '',\n NumberFormat: existingField?.NumberFormat || {\n Type: 'UNKNOWN',\n nDec: '0',\n UseThou: '0',\n Fmt: '',\n Dec: '',\n Thou: '',\n },\n Tags: existingField?.Tags || {},\n };\n }),\n },\n NoOfRecords: this._indexTable?.length,\n RecordByteSize: this._recordByteSize,\n Offset:\n this._symbolTableMetadata && this._symbolTableMetadata.length > 0\n ? this._symbolTableMetadata[this._symbolTableMetadata.length - 1][0] +\n this._symbolTableMetadata[this._symbolTableMetadata.length - 1][1]\n : 0,\n Length: this._indexBuffer?.length,\n },\n };\n\n const builder = new xml.Builder({\n renderOpts: {\n pretty: true,\n newline: '\\r\\n',\n indent: ' ',\n },\n });\n this._header = builder.buildObject(xmlObject) + '\\r\\n';\n this._emitProgress('header', 1, 1);\n }\n\n /**\n * Builds the symbol table of the QVD file.\n *\n * PERFORMANCE OPTIMIZATION: This method uses a single-pass algorithm to build\n * symbol tables for all columns simultaneously. This reduces time complexity from\n * O(n×m×s) to O(n×m) where n=rows, m=columns, s=symbols per column.\n *\n * Algorithm:\n * 1. Initialize a Set for each column to collect unique values\n * 2. Single pass through all data rows, adding values to corresponding Sets\n * 3. Convert Sets to arrays and create QvdSymbol instances\n * 4. Serialize symbols to binary format and update metadata\n *\n * This approach provides:\n * - 80-90% performance improvement for large datasets (100K+ rows)\n * - Better cache locality (process all columns in one data traversal)\n * - Lower memory pressure (no intermediate arrays per column)\n *\n * @private\n */\n _buildSymbolTable() {\n this._symbolTable = [];\n this._symbolTableMetadata = [];\n this._symbolBuffer = Buffer.alloc(0);\n\n const numColumns = this._df.columns.length;\n\n this._emitProgress('symbol-table', 0, numColumns);\n\n // Initialize a Set for each column to track unique values\n // Sets provide O(1) add and automatic deduplication\n const uniqueValuesSets = this._df.columns.map(() => new Set());\n\n // Single pass through all data to collect unique values for all columns\n // This is the key optimization: process all columns together instead of\n // iterating through data once per column\n this._df.data.forEach((row) => {\n this._df.columns.forEach((column, columnIndex) => {\n const value = row[columnIndex];\n uniqueValuesSets[columnIndex].add(value);\n });\n });\n\n // Process each column's unique values\n this._df.columns.forEach((column, columnIndex) => {\n const uniqueValuesSet = uniqueValuesSets[columnIndex];\n const uniqueValues = Array.from(uniqueValuesSet);\n const containsNull = uniqueValues.includes(null) || uniqueValues.includes(undefined);\n const symbols = uniqueValues\n .filter((value) => value !== null && value !== undefined)\n .map((value) => QvdFileWriter._convertRawToSymbol(value));\n\n // @ts-ignore:next-line sd\n const currentSymbolBuffer = Buffer.concat(symbols.map((symbol) => symbol.toByteRepresentation()));\n this._symbolBuffer = this._symbolBuffer\n ? Buffer.concat([this._symbolBuffer, currentSymbolBuffer])\n : currentSymbolBuffer;\n\n const symbolsLength = currentSymbolBuffer.length;\n const symbolsOffset = this._symbolBuffer.length - symbolsLength;\n\n this._symbolTableMetadata?.push([symbolsOffset, symbolsLength, containsNull]);\n // @ts-ignore - Symbol array type compatibility\n this._symbolTable?.push(symbols);\n\n this._emitProgress('symbol-table', columnIndex + 1, numColumns);\n });\n }\n\n /**\n * Builds the index table of the QVD file.\n *\n * PERFORMANCE OPTIMIZATION: Uses Map-based lookups for O(1) symbol index retrieval\n * instead of Array.findIndex() which is O(n). For columns with many unique values,\n * this provides significant performance improvements.\n *\n * Algorithm:\n * 1. Build Map<symbol, index> for each column (O(m) where m=unique values)\n * 2. For each data row, lookup indices in maps (O(1) per value)\n * 3. Convert indices to bit-packed binary format\n *\n * Bit Packing:\n * - Calculates minimum bits needed: ceil(log2(numSymbols))\n * - Packs indices into binary string, then converts to bytes\n * - Reduces file size significantly for columns with few unique values\n *\n * Example: Column with 10 unique values needs only 4 bits per value\n * instead of 32 bits (full integer), saving 87.5% space.\n *\n * @private\n */\n _buildIndexTable() {\n this._indexTable = [];\n this._indexTableMetadata = [];\n this._indexBuffer = Buffer.alloc(0);\n\n const numRows = this._df.data.length;\n this._emitProgress('index-table', 0, numRows);\n\n // Build symbol-to-index lookup maps for O(1) lookups\n // This is crucial for performance: findIndex() on large arrays is O(n)\n // while Map.get() is O(1)\n // This converts the O(n×m×s) findIndex operations to O(n×m)\n const symbolIndexMaps = this._symbolTable?.map((symbols) => {\n const map = new Map();\n symbols.forEach((symbol, idx) => {\n // Create a unique key for each symbol based on its values\n const key = `${symbol.intValue}|${symbol.doubleValue}|${symbol.stringValue}`;\n map.set(key, idx);\n });\n return map;\n });\n\n let processedRows = 0;\n const progressInterval = Math.max(1, Math.floor(numRows / 100)); // Report progress every 1%\n\n this._df.data.forEach((/** @type {any} */ row) => {\n // Convert the raw values to indices referring to the symbol table\n const indices = this._df.columns.map((/** @type {any} */ column, columnIndex) => {\n const value = row[columnIndex];\n const symbol = QvdFileWriter._convertRawToSymbol(value);\n const fieldContainsNull = this._symbolTableMetadata?.[columnIndex][2];\n\n // None values are represented by bias shifted negative indices\n if (symbol === null) {\n return 0;\n } else {\n // Use the Map for O(1) lookup instead of findIndex\n const key = `${symbol.intValue}|${symbol.doubleValue}|${symbol.stringValue}`;\n const symbolIndex = symbolIndexMaps?.[columnIndex].get(key);\n // In order to represent None values, the indices are shifted by the bias value of the column\n return fieldContainsNull ? (symbolIndex ?? 0) + 2 : (symbolIndex ?? 0);\n }\n });\n\n // Convert the integer indices to binary representation\n /** @type {string[]} */\n const stringIndices = indices.map((/** @type {number} */ index) => {\n const bits = QvdFileWriter._convertInt32ToBits(index, 32);\n let bitString = bits.join('');\n bitString = bitString.replace(/^0+/, '') || '0';\n return bitString;\n });\n\n // @ts-ignore - Index array type compatibility\n this._indexTable?.push(stringIndices);\n\n // Report progress periodically\n processedRows++;\n if (processedRows % progressInterval === 0 || processedRows === numRows) {\n this._emitProgress('index-table', processedRows, numRows);\n }\n });\n\n // Normalize the bit representation of the indices by padding with zeros\n this._df.columns.forEach((column) => {\n // Bit offset is the sum of the bit widths of all previous columns\n const bitOffset = this._indexTableMetadata\n ?.slice(0, this._df.columns.indexOf(column))\n .reduce((sum, metadata) => sum + metadata[1], 0);\n\n assert(this._indexTable, 'The QVD file header has not been parsed.');\n\n // Bit width is the maximum bit width of all indices of the column\n // For empty data, default to 0 bit width\n const bitWidth =\n this._indexTable.length > 0\n ? Math.max(\n ...this._indexTable.map(\n (/** @type{string[]} */ indices) => indices[this._df.columns.indexOf(column)].length,\n ),\n )\n : 0;\n\n const fieldContainsNull = this._symbolTableMetadata?.[this._df.columns.indexOf(column)][2];\n const bias = fieldContainsNull ? -2 : 0;\n\n this._indexTableMetadata?.push([bitOffset, bitWidth, bias]);\n\n // Pad the bit representation of the indices with zeros to match the bit width\n this._indexTable.forEach((/** @type{string[]} */ indices) => {\n const bitString = indices[this._df.columns.indexOf(column)];\n const paddedBitString = bitString.padStart(bitWidth, '0');\n indices[this._df.columns.indexOf(column)] = paddedBitString;\n });\n });\n\n // Concatenate the bit representation of the indices of each row to a single binary string per row\n // @ts-ignore - Buffer.concat type compatibility\n this._indexBuffer = Buffer.concat(\n // @ts-ignore - Buffer array type compatibility\n this._indexTable.map((/** @type{string[]} */ indices) => {\n indices.reverse();\n const bits = indices.join('');\n const paddingWidth = (8 - (bits.length % 8)) % 8;\n const paddedBits = bits.padStart(bits.length + paddingWidth, '0');\n const bytes = paddedBits.match(/.{1,8}/g)?.map((byte) => parseInt(byte, 2));\n bytes?.reverse();\n\n assert(bytes, 'Byte conversion of bit indices failed.');\n\n return Buffer.from(Uint8Array.from(bytes));\n }),\n );\n\n // For empty data, set record byte size to 1 (matching Qlik Sense behavior)\n // instead of 0 or NaN/Infinity\n this._recordByteSize = this._indexTable.length > 0 ? this._indexBuffer.length / this._indexTable.length : 1;\n }\n\n /**\n * Converts a raw value/literal to a QVD symbol.\n *\n * @param {any} raw The raw value/literal to convert.\n * @return {QvdSymbol|null} The converted QVD symbol.\n */\n static _convertRawToSymbol(raw) {\n if (raw === null || raw === undefined) {\n return null;\n }\n\n const INT32_MIN = -2147483648;\n const INT32_MAX = 2147483647;\n\n const isInteger = typeof raw === 'number' && Number.isInteger(raw);\n const isFloat = typeof raw === 'number' && !Number.isInteger(raw);\n const isWithinInt32Range = typeof raw === 'number' && raw >= INT32_MIN && raw <= INT32_MAX;\n\n if (isInteger && isWithinInt32Range) {\n return QvdSymbol.fromDualIntValue(raw, raw.toString());\n } else if (isFloat || (isInteger && !isWithinInt32Range)) {\n return QvdSymbol.fromDualDoubleValue(raw, raw.toString());\n } else {\n return QvdSymbol.fromStringValue(raw);\n }\n }\n\n /**\n * Converts an integer to a list of bits.\n *\n * @param {number} value The integer value to convert.\n * @param {number} width The width of the bit list.\n * @return {Array<number>} The list of bits.\n */\n static _convertInt32ToBits(value, width) {\n return value\n .toString(2)\n .split('')\n .map((bit) => parseInt(bit))\n .reverse()\n .concat(new Array(width).fill(0))\n .slice(0, width)\n .reverse();\n }\n\n /**\n * Persists the data frame to a QVD file.\n */\n async save() {\n this._buildSymbolTable();\n this._buildIndexTable();\n this._buildHeader();\n await this._writeData();\n }\n}\n","// @ts-check\n\n/**\n * Converts a bit array to an integer value.\n *\n * @param {Array<number>} bits The bit array\n * @return {number} The integer value\n */\nexport function convertBitsToInt32(bits) {\n if (bits.length === 0) {\n return 0;\n }\n\n return bits.reduce((value, bit, index) => (value += bit * Math.pow(2, index)), 0);\n}\n","// @ts-check\n\nimport os from 'os';\nimport v8 from 'v8';\nimport {QvdValidationError} from '../QvdErrors.js';\n\n/**\n * Gets the configured V8 heap size limit for the current Node.js process.\n * This respects the --max-old-space-size flag if set.\n *\n * @returns {number} Heap size limit in bytes\n */\nexport function getHeapLimit() {\n return v8.getHeapStatistics().heap_size_limit;\n}\n\n/**\n * Estimates the memory usage for loading a QVD file with given parameters.\n * Takes into account Phase 2.5 optimization which skips parsing unused symbols.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n * @returns {number} Estimated memory usage in bytes\n */\nexport function estimateMemoryUsage(symbolTableSize, maxRows, totalRows) {\n // Memory overhead multipliers based on empirical testing\n const FULL_PARSE_OVERHEAD = 6.0; // Baseline: JavaScript objects have 6x overhead\n const MINIMAL_OVERHEAD = 0.01; // Skipped symbols: minimal null placeholder overhead\n\n if (maxRows === null || maxRows >= totalRows) {\n // Loading all rows - need all symbols, no filtering benefit\n return symbolTableSize * FULL_PARSE_OVERHEAD;\n }\n\n // Estimate what percentage of symbols we'll need\n // Symbol usage grows slower than linear (diminishing returns as you add rows)\n // Use square root scaling as empirical approximation\n const rowPercentage = maxRows / totalRows;\n const symbolPercentage = Math.sqrt(rowPercentage);\n\n // Calculate memory for kept symbols (full overhead) + skipped symbols (minimal overhead)\n const keptSymbolsMemory = symbolTableSize * symbolPercentage * FULL_PARSE_OVERHEAD;\n const skippedSymbolsMemory = symbolTableSize * (1 - symbolPercentage) * MINIMAL_OVERHEAD;\n\n return keptSymbolsMemory + skippedSymbolsMemory;\n}\n\n/**\n * Validates that there is sufficient memory available to load a QVD file safely.\n * Considers both available system RAM and the configured V8 heap limit.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n * @param {string} filePath Path to the QVD file (for error messages)\n * @param {number} [safetyFactor=0.3] Percentage of available memory to use (0.0-1.0)\n * @throws {QvdValidationError} If insufficient memory is available\n */\nexport function validateMemoryAvailability(symbolTableSize, maxRows, totalRows, filePath, safetyFactor = 0.3) {\n const availableMemory = os.freemem();\n const heapLimit = getHeapLimit();\n const estimatedMemory = estimateMemoryUsage(symbolTableSize, maxRows, totalRows);\n\n // Use the smaller of available RAM or heap limit to determine max allowed memory\n // This ensures we don't try to allocate more than V8 can handle\n const effectiveLimit = Math.min(availableMemory, heapLimit);\n const maxAllowedMemory = effectiveLimit * safetyFactor;\n\n if (estimatedMemory > maxAllowedMemory) {\n // Calculate how many rows would be safe to load\n // Reverse the square root formula: symbolPercentage = sqrt(rowPercentage)\n const safeSymbolPercentage = maxAllowedMemory / (symbolTableSize * 6.0);\n const safeRowPercentage = Math.pow(safeSymbolPercentage, 2);\n const recommendedMaxRows = Math.max(1, Math.floor(totalRows * safeRowPercentage));\n\n const sizeMB = Math.round(symbolTableSize / 1024 / 1024);\n const estimatedMB = Math.round(estimatedMemory / 1024 / 1024);\n const availableMB = Math.round(maxAllowedMemory / 1024 / 1024);\n const heapLimitMB = Math.round(heapLimit / 1024 / 1024);\n const availableRamMB = Math.round(availableMemory / 1024 / 1024);\n\n // Determine which limit was hit\n const limitingFactor = heapLimit < availableMemory ? 'V8 heap limit' : 'available RAM';\n\n throw new QvdValidationError(\n `Insufficient memory to load file safely. ` +\n `Symbol table: ${sizeMB}MB, Estimated memory needed: ${estimatedMB}MB, Available: ${availableMB}MB (limited by ${limitingFactor}: ${heapLimitMB}MB heap / ${availableRamMB}MB RAM). ` +\n `Try loading fewer rows using the maxRows parameter (recommended: ${recommendedMaxRows.toLocaleString()} rows or less).`,\n {\n file: filePath,\n symbolTableSize,\n symbolTableSizeMB: sizeMB,\n estimatedMemoryMB: estimatedMB,\n availableMemoryMB: availableMB,\n heapLimitMB,\n availableRamMB,\n limitingFactor,\n totalRows,\n maxRows,\n recommendedMaxRows,\n },\n );\n }\n}\n\n/**\n * Emits a warning for large symbol tables when loading all rows.\n * Warning threshold scales with configured heap size (12.5% of heap).\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n */\nexport function warnLargeSymbolTable(symbolTableSize, maxRows, totalRows) {\n // Dynamic warning threshold: 12.5% of configured heap size\n // Examples: 4GB heap = 512MB, 8GB heap = 1GB, 16GB heap = 2GB\n const heapLimit = getHeapLimit();\n const LARGE_SYMBOL_TABLE_WARNING = heapLimit * 0.125;\n\n if (symbolTableSize > LARGE_SYMBOL_TABLE_WARNING && (maxRows === null || maxRows >= totalRows)) {\n const sizeMB = Math.round(symbolTableSize / 1024 / 1024);\n const estimatedMemory = estimateMemoryUsage(symbolTableSize, maxRows, totalRows);\n const estimatedMB = Math.round(estimatedMemory / 1024 / 1024);\n const warnMB = Math.round(LARGE_SYMBOL_TABLE_WARNING / 1024 / 1024);\n\n console.warn(\n `⚠️ Large symbol table detected (${sizeMB}MB > ${warnMB}MB threshold). Loading all ${totalRows.toLocaleString()} rows will use ~${estimatedMB}MB RAM. ` +\n `Consider using the maxRows parameter for better performance and lower memory usage.`,\n );\n }\n}\n","// @ts-check\n\nimport {QvdCorruptedError, QvdValidationError} from '../QvdErrors.js';\nimport {getHeapLimit} from './memoryUtils.js';\n\n/**\n * Validates symbol table size during initial file read (early check).\n * This is the first-pass validation in _readData for lazy loading.\n * Limit scales with configured heap size (12.5% of heap).\n *\n * @param {number} symbolTableLength Size of symbol table in bytes\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdValidationError} If symbol table exceeds dynamic limit\n */\nexport function validateSymbolTableSizeEarly(symbolTableLength, filePath) {\n // Dynamic limit: 12.5% of configured heap size\n // Examples: 4GB heap = 512MB, 8GB heap = 1GB, 16GB heap = 2GB\n const heapLimit = getHeapLimit();\n const MAX_SYMBOL_TABLE_SIZE = heapLimit * 0.125;\n\n if (symbolTableLength > MAX_SYMBOL_TABLE_SIZE) {\n const sizeMB = Math.round(symbolTableLength / 1024 / 1024);\n const maxMB = Math.round(MAX_SYMBOL_TABLE_SIZE / 1024 / 1024);\n const heapMB = Math.round(heapLimit / 1024 / 1024);\n\n throw new QvdValidationError(\n `Symbol table too large (${sizeMB}MB exceeds ${maxMB}MB limit for lazy loading). ` +\n `This QVD file contains extremely high-cardinality fields. ` +\n `Limit scales with heap size (current: ${heapMB}MB, limit: 12.5% = ${maxMB}MB). ` +\n `Consider: (1) loading the full file without maxRows, (2) increasing heap size with --max-old-space-size, or (3) aggregating high-cardinality fields.`,\n {\n file: filePath,\n symbolTableSize: symbolTableLength,\n symbolTableSizeMB: sizeMB,\n maxAllowed: MAX_SYMBOL_TABLE_SIZE,\n maxAllowedMB: maxMB,\n heapLimitMB: heapMB,\n limitPercentage: 12.5,\n },\n );\n }\n}\n\n/**\n * Validates symbol table size limits to prevent out-of-memory conditions.\n * This is the comprehensive validation in _parseSymbolTable.\n * Absolute ceiling scales with configured heap size (50% of heap).\n *\n * @param {number} symbolTableLength Size of symbol table in bytes\n * @param {string} filePath Path to the QVD file (for error messages)\n * @param {number} totalRows Total number of rows in the file\n * @throws {QvdValidationError} If symbol table exceeds safety limits\n */\nexport function validateSymbolTableSize(symbolTableLength, filePath, totalRows) {\n // Dynamic absolute ceiling: 50% of configured heap size\n // Examples: 4GB heap = 2GB, 8GB heap = 4GB, 16GB heap = 8GB, 32GB heap = 16GB\n const heapLimit = getHeapLimit();\n const ABSOLUTE_MAX_SYMBOL_TABLE = heapLimit * 0.5;\n\n if (symbolTableLength > ABSOLUTE_MAX_SYMBOL_TABLE) {\n const sizeMB = Math.round(symbolTableLength / 1024 / 1024);\n const maxMB = Math.round(ABSOLUTE_MAX_SYMBOL_TABLE / 1024 / 1024);\n const heapMB = Math.round(heapLimit / 1024 / 1024);\n\n throw new QvdValidationError(\n `Symbol table exceeds absolute maximum size (${sizeMB}MB > ${maxMB}MB). ` +\n `This QVD file has pathological cardinality (likely a data modeling issue). ` +\n `Limit scales with heap size (current: ${heapMB}MB, limit: 50% = ${maxMB}MB). ` +\n `Consider: (1) increasing heap size with --max-old-space-size, (2) aggregating high-cardinality fields, (3) splitting the data, or (4) using a different format.`,\n {\n file: filePath,\n symbolTableSize: symbolTableLength,\n symbolTableSizeMB: sizeMB,\n maxAllowed: ABSOLUTE_MAX_SYMBOL_TABLE,\n maxAllowedMB: maxMB,\n heapLimitMB: heapMB,\n limitPercentage: 50,\n totalRows,\n },\n );\n }\n}\n\n/**\n * Validates field metadata before processing to prevent buffer overflow attacks.\n *\n * @param {any} field Field metadata object\n * @param {number} symbolBufferLength Length of the symbol buffer\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdCorruptedError} If field metadata is invalid\n */\nexport function validateFieldMetadata(field, symbolBufferLength, filePath) {\n const symbolsOffset = parseInt(field['Offset'], 10);\n const symbolsLength = parseInt(field['Length'], 10);\n\n // Validate offset is a valid number and within bounds\n if (isNaN(symbolsOffset) || !Number.isSafeInteger(symbolsOffset) || symbolsOffset < 0) {\n throw new QvdCorruptedError('Invalid symbol offset', {\n field: field['FieldName'],\n offset: symbolsOffset,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n // Validate length is a valid number and non-negative\n if (isNaN(symbolsLength) || !Number.isSafeInteger(symbolsLength) || symbolsLength < 0) {\n throw new QvdCorruptedError('Invalid symbol length', {\n field: field['FieldName'],\n length: symbolsLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n // Validate that offset + length doesn't exceed buffer size\n if (symbolsOffset + symbolsLength > symbolBufferLength) {\n throw new QvdCorruptedError('Symbol data extends beyond buffer', {\n field: field['FieldName'],\n offset: symbolsOffset,\n length: symbolsLength,\n bufferSize: symbolBufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n}\n\n/**\n * Validates index table metadata and bounds.\n *\n * @param {number} recordSize Size of a single record in bytes\n * @param {number} totalRows Total number of rows\n * @param {number} indexTableLength Length of the index table\n * @param {number} indexTableOffset Offset to the index table\n * @param {number} bufferLength Length of the buffer\n * @param {number} rowsToLoad Number of rows to load\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdCorruptedError} If index table metadata is invalid\n */\nexport function validateIndexTableMetadata(\n recordSize,\n totalRows,\n indexTableLength,\n indexTableOffset,\n bufferLength,\n rowsToLoad,\n filePath,\n) {\n // Validate recordSize\n if (isNaN(recordSize) || !Number.isSafeInteger(recordSize) || recordSize < 0) {\n throw new QvdCorruptedError('Invalid record byte size', {\n recordSize,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate totalRows\n if (isNaN(totalRows) || !Number.isSafeInteger(totalRows) || totalRows < 0) {\n throw new QvdCorruptedError('Invalid number of records', {\n totalRows,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Allow recordSize of 0 or 1 only when there are no records (empty QVD)\n // Qlik Sense uses recordSize=1 for empty QVDs\n if (recordSize === 0 && totalRows > 0) {\n throw new QvdCorruptedError('Record byte size cannot be zero when records exist', {\n recordSize,\n totalRows,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate recordSize is reasonable (max 1MB per record)\n if (recordSize > 1048576) {\n throw new QvdCorruptedError('Record byte size exceeds maximum', {\n recordSize,\n maxSize: 1048576,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate index table length\n if (isNaN(indexTableLength) || !Number.isSafeInteger(indexTableLength) || indexTableLength < 0) {\n throw new QvdCorruptedError('Invalid index table length', {\n length: indexTableLength,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate index table start offset doesn't extend beyond buffer\n if (indexTableOffset > bufferLength) {\n throw new QvdCorruptedError('Index table offset beyond buffer', {\n indexTableOffset,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate that the claimed index table length isn't excessively large\n const maxReasonableOverage = 100 * 1024 * 1024;\n if (indexTableLength > bufferLength + maxReasonableOverage) {\n throw new QvdCorruptedError('Index table length unreasonably large', {\n indexTableLength,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Ensure the index table length is sufficient for the number of rows to load\n const requiredIndexBytes = rowsToLoad * recordSize;\n if (indexTableLength < requiredIndexBytes) {\n throw new QvdCorruptedError('Index table length smaller than required', {\n indexTableLength,\n requiredBytes: requiredIndexBytes,\n rowsToLoad,\n recordSize,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n}\n\n/**\n * Validates field bit offset and bit width for index table parsing.\n *\n * @param {any} field Field metadata object\n * @param {number} recordSize Size of a single record in bytes\n * @param {string} filePath Path to the QVD file (for error messages)\n * @throws {QvdCorruptedError} If field bit metadata is invalid\n */\nexport function validateFieldBitMetadata(field, recordSize, filePath) {\n const bitOffset = parseInt(field['BitOffset'], 10);\n const bitWidth = parseInt(field['BitWidth'], 10);\n\n // Validate bitOffset\n if (isNaN(bitOffset) || !Number.isSafeInteger(bitOffset) || bitOffset < 0) {\n throw new QvdCorruptedError('Invalid bit offset', {\n field: field['FieldName'],\n bitOffset,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate bitWidth\n if (isNaN(bitWidth) || !Number.isSafeInteger(bitWidth) || bitWidth < 0) {\n throw new QvdCorruptedError('Invalid bit width', {\n field: field['FieldName'],\n bitWidth,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n\n // Validate bitOffset + bitWidth doesn't exceed record size in bits\n const recordSizeInBits = recordSize * 8;\n if (bitOffset + bitWidth > recordSizeInBits) {\n throw new QvdCorruptedError('Bit field extends beyond record size', {\n field: field['FieldName'],\n bitOffset,\n bitWidth,\n recordSizeInBits,\n file: filePath,\n stage: 'parseIndexTable',\n });\n }\n}\n","// @ts-check\n\nimport {QvdSymbol} from '../QvdSymbol.js';\nimport {QvdCorruptedError, QvdParseError} from '../QvdErrors.js';\n\n/**\n * Parses an integer symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for an integer\n if (pointer + 4 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading integer symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const byteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 4));\n const value = Buffer.from(byteData).readIntLE(0, byteData.length);\n return {symbol: QvdSymbol.fromIntValue(value), bytesRead: 4};\n}\n\n/**\n * Parses a double symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for a double\n if (pointer + 8 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading double symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const byteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 8));\n const value = Buffer.from(byteData).readDoubleLE(0);\n return {symbol: QvdSymbol.fromDoubleValue(value), bytesRead: 8};\n}\n\n/**\n * Parses a string symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n const startPointer = pointer;\n const maxStringLength = 1048576; // 1MB max string size to prevent memory exhaustion\n let stringLength = 0;\n\n // Find the null terminator\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('String symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n // Ensure we found the null terminator\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('String symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const value = symbolBuffer.subarray(startPointer, pointer).toString('utf-8');\n return {symbol: QvdSymbol.fromStringValue(value), bytesRead: pointer - startPointer + 1};\n}\n\n/**\n * Skips a string symbol in the buffer without parsing it.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {number} Bytes to skip\n */\nexport function skipStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n const startPointer = pointer;\n const maxStringLength = 1048576;\n let stringLength = 0;\n\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('String symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('String symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n return pointer - startPointer + 1;\n}\n\n/**\n * Parses a dual integer symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseDualIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for an integer\n if (pointer + 4 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading dual integer symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const intByteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 4));\n const intValue = Buffer.from(intByteData).readIntLE(0, intByteData.length);\n pointer += 4;\n\n // Parse the string portion\n const stringStart = pointer;\n const maxStringLength = 1048576;\n let stringLength = 0;\n\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('Dual string symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('Dual string symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const stringValue = symbolBuffer.subarray(stringStart, pointer).toString('utf-8');\n return {symbol: QvdSymbol.fromDualIntValue(intValue, stringValue), bytesRead: pointer - (stringStart - 4) + 1};\n}\n\n/**\n * Parses a dual double symbol from the buffer.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol and bytes read\n */\nexport function parseDualDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath) {\n // Validate we have enough bytes for a double\n if (pointer + 8 > bufferLength) {\n throw new QvdCorruptedError('Buffer overflow reading dual double symbol', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const doubleByteData = new Int32Array(symbolBuffer.subarray(pointer, pointer + 8));\n const doubleValue = Buffer.from(doubleByteData).readDoubleLE(0);\n pointer += 8;\n\n // Parse the string portion\n const stringStart = pointer;\n const maxStringLength = 1048576;\n let stringLength = 0;\n\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('Dual string symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('Dual string symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const stringValue = symbolBuffer.subarray(stringStart, pointer).toString('utf-8');\n return {\n symbol: QvdSymbol.fromDualDoubleValue(doubleValue, stringValue),\n bytesRead: pointer - (stringStart - 8) + 1,\n };\n}\n\n/**\n * Skips a dual symbol (integer or double) in the buffer without parsing it.\n *\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position\n * @param {number} bufferLength Length of the buffer\n * @param {number} numericBytes Number of bytes for the numeric portion (4 for int, 8 for double)\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @returns {number} Bytes to skip\n */\nexport function skipDualSymbol(symbolBuffer, pointer, bufferLength, numericBytes, fieldName, filePath) {\n if (pointer + numericBytes > bufferLength) {\n throw new QvdCorruptedError(`Buffer overflow reading dual symbol`, {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n const startPointer = pointer;\n pointer += numericBytes;\n\n // Skip the string portion\n const maxStringLength = 1048576;\n let stringLength = 0;\n while (pointer < bufferLength && symbolBuffer[pointer] !== 0) {\n if (stringLength >= maxStringLength) {\n throw new QvdCorruptedError('Dual string symbol exceeds maximum length', {\n field: fieldName,\n maxLength: maxStringLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n pointer++;\n stringLength++;\n }\n\n if (pointer >= bufferLength) {\n throw new QvdCorruptedError('Dual string symbol not null-terminated', {\n field: fieldName,\n pointer,\n bufferSize: bufferLength,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n\n return pointer - startPointer + 1;\n}\n\n/**\n * Parses a symbol based on the type byte.\n *\n * @param {number} typeByte The type byte\n * @param {Buffer} symbolBuffer The symbol buffer\n * @param {number} pointer Current pointer position (after type byte)\n * @param {number} bufferLength Length of the buffer\n * @param {string} fieldName Name of the field being parsed\n * @param {string} filePath Path to the QVD file (for error messages)\n * @param {boolean} shouldParse Whether to parse the symbol (true) or skip it (false)\n * @returns {{symbol: import('../QvdSymbol.js').QvdSymbol | null, bytesRead: number}} Parsed symbol (or null if skipped) and bytes read\n */\nexport function parseSymbol(typeByte, symbolBuffer, pointer, bufferLength, fieldName, filePath, shouldParse) {\n switch (typeByte) {\n case 1: {\n // Integer value (4 Bytes)\n if (shouldParse) {\n return parseIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n return {symbol: null, bytesRead: 4};\n }\n case 2: {\n // Double value (8 Bytes)\n if (shouldParse) {\n return parseDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n return {symbol: null, bytesRead: 8};\n }\n case 4: {\n // String value (0 terminated)\n if (shouldParse) {\n return parseStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n const bytesRead = skipStringSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n return {symbol: null, bytesRead};\n }\n case 5: {\n // Dual (Integer format) value (4 bytes), followed by string format\n if (shouldParse) {\n return parseDualIntegerSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n const bytesRead = skipDualSymbol(symbolBuffer, pointer, bufferLength, 4, fieldName, filePath);\n return {symbol: null, bytesRead};\n }\n case 6: {\n // Dual (Double format) value (8 bytes), followed by string format\n if (shouldParse) {\n return parseDualDoubleSymbol(symbolBuffer, pointer, bufferLength, fieldName, filePath);\n }\n const bytesRead = skipDualSymbol(symbolBuffer, pointer, bufferLength, 8, fieldName, filePath);\n return {symbol: null, bytesRead};\n }\n default: {\n throw new QvdParseError('Unknown symbol type byte', {\n typeByte: typeByte.toString(16),\n offset: pointer - 1,\n file: filePath,\n stage: 'parseSymbolTable',\n });\n }\n }\n}\n","// @ts-check\n\nimport fs from 'fs';\nimport xml from 'xml2js';\nimport assert from 'assert';\nimport {QvdDataFrame} from './QvdDataFrame.js';\nimport {QvdParseError, QvdValidationError, QvdCorruptedError} from './QvdErrors.js';\nimport {validatePath} from './util/validatePath.js';\nimport {convertBitsToInt32} from './util/bitUtils.js';\nimport {estimateMemoryUsage, validateMemoryAvailability, warnLargeSymbolTable} from './util/memoryUtils.js';\nimport {\n validateSymbolTableSize,\n validateSymbolTableSizeEarly,\n validateFieldMetadata,\n validateIndexTableMetadata,\n validateFieldBitMetadata,\n} from './util/validationUtils.js';\nimport {parseSymbol} from './util/symbolParser.js';\n\n/**\n * Parses a QVD file and loads it into memory.\n */\nexport class QvdFileReader {\n /**\n * Constructs a new QVD file parser.\n *\n * @param {string} filePath The path to the QVD file to load.\n * @param {Object} [options={}] Options for the reader.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file\n * path must be within this directory. Defaults to current working directory.\n * @param {number} [options.memorySafetyFactor=0.3] Memory safety factor (0.0-1.0). Determines\n * what percentage of available memory (or V8 heap limit, whichever is smaller) can be used\n * for loading QVD files. Default is 0.3 (30%). Increase for larger heap configurations.\n */\n constructor(filePath, options = {}) {\n const {allowedDir, memorySafetyFactor = 0.3} = options;\n this._path = validatePath(filePath, allowedDir);\n this._memorySafetyFactor = memorySafetyFactor;\n this._buffer = null;\n this._headerOffset = null;\n this._symbolTableOffset = null;\n this._indexTableOffset = null;\n this._header = null;\n /** @type {Array<Array<import('./QvdSymbol.js').QvdSymbol>>|null} */\n this._symbolTable = null;\n /** @type {Array<Array<number>>|null} */\n this._indexTable = null;\n }\n\n /**\n * Reads the binary data of the QVD file.\n *\n * LAZY LOADING OPTIMIZATION: When maxRows is specified, this method implements\n * true lazy loading by reading only the necessary portions of the file from disk.\n *\n * For large files (e.g., 5GB), loading only the first 1000 rows can save significant\n * memory and time:\n * - Full load: 5GB in memory, ~30-60s load time\n * - Lazy load (maxRows=1000): ~1.75-2GB in memory, ~2-5s load time\n *\n * Algorithm for Lazy Loading:\n * 1. Stream-read the file until XML header delimiter is found\n * 2. Parse header to determine symbol table and index table locations\n * 3. Calculate bytes needed: header + full symbol table + partial index table\n * 4. Read only those calculated bytes using fs.open/read\n * 5. Rest of parsing proceeds normally with limited data\n *\n * WHY THIS APPROACH:\n * - Symbol table must be fully loaded (contains all unique values)\n * - Index table can be partially loaded (only rows we need)\n * - Streaming for header finding is efficient for unknown header sizes\n * - Direct byte-range reading for remaining data is fastest\n *\n * @param {number|null} maxRows The maximum number of rows to load. If null, all data is loaded.\n * @private\n */\n async _readData(maxRows = null) {\n if (maxRows === null) {\n // Load entire file into memory (original behavior)\n // This is simple and fast for small to medium files\n this._buffer = await fs.promises.readFile(this._path);\n return;\n }\n\n const HEADER_DELIMITER = '\\r\\n\\0';\n const CHUNK_SIZE = 64 * 1024; // 64KB chunks - balance between memory and I/O efficiency\n\n // Use streaming to find the header delimiter dynamically\n // We don't know header size in advance, so we must stream-read\n const stream = fs.createReadStream(this._path, {\n highWaterMark: CHUNK_SIZE,\n });\n\n let headerBuffer = Buffer.alloc(0);\n let headerDelimiterIndex = -1;\n\n try {\n // Read chunks until we find the delimiter\n for await (const chunk of stream) {\n headerBuffer = Buffer.concat([headerBuffer, chunk]);\n headerDelimiterIndex = headerBuffer.indexOf(HEADER_DELIMITER);\n\n if (headerDelimiterIndex !== -1) {\n // Found the delimiter, stop streaming\n stream.destroy();\n break;\n }\n }\n } catch (error) {\n // Ignore destroy errors (expected when we stop the stream early)\n if (error && typeof error === 'object' && 'code' in error && error.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n throw error;\n }\n }\n\n if (headerDelimiterIndex === -1) {\n throw new QvdCorruptedError(\n 'The XML header section does not exist or is not properly delimited from the binary data.',\n {\n file: this._path,\n stage: 'readData',\n },\n );\n }\n\n const headerEndIndex = headerDelimiterIndex + HEADER_DELIMITER.length;\n\n // Parse header to get metadata about symbol and index table locations\n const headerXml = headerBuffer.subarray(0, headerEndIndex).toString();\n const headerObj = await xml.parseStringPromise(headerXml, {explicitArray: false});\n\n if (!headerObj) {\n throw new QvdParseError('The XML header could not be parsed.', {\n file: this._path,\n stage: 'readData',\n });\n }\n\n const symbolTableOffset = headerEndIndex;\n const symbolTableLength = parseInt(headerObj['QvdTableHeader']['Offset'], 10);\n const indexTableOffset = symbolTableOffset + symbolTableLength;\n const recordSize = parseInt(headerObj['QvdTableHeader']['RecordByteSize'], 10);\n const totalRows = parseInt(headerObj['QvdTableHeader']['NoOfRecords'], 10);\n const rowsToLoad = Math.min(maxRows, totalRows);\n\n // SAFETY CHECK: Very large symbol tables (>500MB) are still blocked to prevent OOM\n // Phase 2 filtering can handle up to ~500MB symbol tables efficiently\n validateSymbolTableSizeEarly(symbolTableLength, this._path);\n\n // Calculate how much of the index table we need to read\n const indexTableBytesToRead = rowsToLoad * recordSize;\n\n // Calculate total bytes needed: header + symbol table + partial index table\n const totalBytesToRead = indexTableOffset + indexTableBytesToRead;\n\n // Now read the exact portion we need from the file\n const fd = await fs.promises.open(this._path, 'r');\n try {\n this._buffer = Buffer.allocUnsafe(totalBytesToRead);\n // @ts-ignore - Buffer type compatibility\n await fd.read(this._buffer, 0, totalBytesToRead, 0);\n } finally {\n await fd.close();\n }\n }\n\n /**\n * Parses the XML header of the QVD file. This method is part of the parsing process\n * and should not be called directly.\n */\n async _parseHeader() {\n if (!this._buffer) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'parseHeader',\n },\n );\n }\n\n const HEADER_DELIMITER = '\\r\\n\\0';\n\n const headerBeginIndex = 0;\n const headerDelimiterIndex = this._buffer.indexOf(HEADER_DELIMITER, headerBeginIndex);\n\n // Check explicitly for -1 (not found) rather than using falsy check (!headerDelimiterIndex)\n // because indexOf() returns 0 when the delimiter is at position 0, which is a valid buffer index.\n // Using !0 would incorrectly treat position 0 as an error.\n if (headerDelimiterIndex === -1) {\n throw new QvdCorruptedError(\n 'The XML header section does not exist or is not properly delimited from the binary data.',\n {\n file: this._path,\n stage: 'parseHeader',\n },\n );\n }\n\n const headerEndIndex = headerDelimiterIndex + HEADER_DELIMITER.length;\n const headerBuffer = this._buffer.subarray(headerBeginIndex, headerEndIndex);\n\n /*\n * The following instruction parses the XML header into a JSON object. It is important to\n * note that the object is a plain JavaScript object and not an instance of representative\n * class. Hence, types are not casted, therefore all raw values are strings, and child nodes\n * that contain an array of objects are not represented directly as an array but as an object\n * with a property, named like the array item tag, that is an array of the actual objects. The\n * same applies to child nodes that contain a single object and the root node.\n *\n * The following XML representation of the QVD header for example...\n *\n * <QvdTableHeader>\n * ...\n * <Fields>\n * <QvdFieldHeader>\n * <FieldName>Field1</FieldName>\n * ...\n * </QvdFieldHeader>\n * <QvdFieldHeader>\n * <FieldName>Field1</FieldName>\n * ...\n * </QvdFieldHeader>\n * </Fields>\n * </QvdTableHeader>\n *\n * ...is parsed into the following object:\n *\n * {\n * QvdTableHeader: {\n * ...,\n * Fields: {\n * QvdFieldHeader: [\n * { FieldName: 'Field1', ...},\n * { FieldName: 'Field2', ...}\n * ]\n * }\n * }\n * }\n */\n\n // Note: xml2js (via sax-js) does not support external entity resolution\n // by default, providing inherent protection against XXE attacks.\n this._header = await xml.parseStringPromise(headerBuffer.toString(), {explicitArray: false});\n\n if (!this._header) {\n throw new QvdParseError('The XML header could not be parsed.', {\n file: this._path,\n stage: 'parseHeader',\n });\n }\n\n /*\n * Because the three parts of the QVD file, header, symbol and index table, are seamlessly concatenated,\n * the end of the respective previous part is the beginning of the next part.\n */\n\n this._headerOffset = headerBeginIndex;\n this._symbolTableOffset = headerEndIndex;\n this._indexTableOffset = this._symbolTableOffset + parseInt(this._header['QvdTableHeader']['Offset'], 10);\n }\n\n /**\n * Estimates the memory usage for loading a QVD file with given parameters.\n * Takes into account Phase 2.5 optimization which skips parsing unused symbols.\n *\n * @param {number} symbolTableSize Size of symbol table in bytes\n * @param {number|null} maxRows Maximum number of rows to load (null = all rows)\n * @param {number} totalRows Total number of rows in the file\n * @returns {number} Estimated memory usage in bytes\n * @private\n */\n _estimateMemoryUsage(symbolTableSize, maxRows, totalRows) {\n return estimateMemoryUsage(symbolTableSize, maxRows, totalRows);\n }\n\n /**\n * Analyzes the index table to determine which symbols are actually needed.\n * This is used for two-pass symbol filtering optimization.\n *\n * @param {number} maxRows The maximum number of rows to analyze.\n * @returns {Promise<Map<string, Set<number>>>} Map of field names to Set of needed symbol indices.\n * @private\n */\n async _analyzeIndexTableSymbolUsage(maxRows) {\n if (!this._buffer || !this._header || !this._indexTableOffset) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'analyzeIndexTableSymbolUsage',\n },\n );\n }\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n const recordSize = parseInt(this._header['QvdTableHeader']['RecordByteSize'], 10);\n const totalRows = parseInt(this._header['QvdTableHeader']['NoOfRecords'], 10);\n const rowsToAnalyze = Math.min(maxRows, totalRows);\n const indexTableLength = parseInt(this._header['QvdTableHeader']['Length'], 10);\n\n const indexBuffer = this._buffer.subarray(this._indexTableOffset, this._indexTableOffset + indexTableLength + 1);\n\n // Map of field name -> Set of symbol indices needed\n /** @type {Map<string, Set<number>>} */\n const symbolUsage = new Map();\n\n // Initialize sets for each field\n fields.forEach((field) => {\n symbolUsage.set(field['FieldName'], new Set());\n });\n\n // Parse rows to collect symbol indices\n for (\n let pointer = 0, rowCount = 0;\n pointer < indexBuffer.length && rowCount < rowsToAnalyze;\n pointer += recordSize, rowCount++\n ) {\n const bytes = new Int32Array(indexBuffer.subarray(pointer, pointer + recordSize));\n bytes.reverse();\n\n const mask = bytes\n .reduce((bits, byte) => bits + ('00000000' + byte.toString(2)).slice(-8), '')\n .split('')\n .reverse()\n .map((bit) => parseInt(bit));\n\n // Extract symbol index for each field\n fields.forEach((field) => {\n const bitOffset = parseInt(field['BitOffset'], 10);\n const bitWidth = parseInt(field['BitWidth'], 10);\n const bias = parseInt(field['Bias'], 10);\n\n let symbolIndex;\n\n if (bitWidth === 0) {\n symbolIndex = 0;\n } else {\n symbolIndex = this._convertBitsToInt32(mask.slice(bitOffset, bitOffset + bitWidth));\n }\n\n // Apply bias\n symbolIndex -= bias;\n\n // Add to the set of needed symbols for this field\n const fieldName = field['FieldName'];\n symbolUsage.get(fieldName)?.add(symbolIndex);\n });\n }\n\n return symbolUsage;\n }\n\n /**\n * Parses the symbol table of the QVD file. This method is part of the parsing process\n * and should not be called directly.\n *\n * @param {Map<string, Set<number>>|null} symbolsToKeep Optional map of field names to symbol indices to keep.\n * If provided, only these symbols will be parsed (two-pass filtering optimization).\n * @param {number|null} maxRows Optional maximum number of rows being loaded (for memory estimation).\n */\n async _parseSymbolTable(symbolsToKeep = null, maxRows = null) {\n if (!this._buffer || !this._header || !this._symbolTableOffset || !this._indexTableOffset) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'parseSymbolTable',\n },\n );\n }\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n const symbolBuffer = this._buffer.subarray(this._symbolTableOffset, this._indexTableOffset);\n const symbolTableSize = symbolBuffer.length;\n const totalRows = parseInt(this._header['QvdTableHeader']['NoOfRecords'], 10);\n\n // SAFETY CHECK 1: Absolute ceiling to prevent pathological cases\n // Phase 2.5 optimization allows much larger symbol tables when using maxRows,\n // but we still need an absolute maximum to prevent truly extreme cases\n validateSymbolTableSize(symbolTableSize, this._path, totalRows);\n\n // SAFETY CHECK 2: Dynamic memory validation\n // Check if we have enough available memory to load this file safely\n validateMemoryAvailability(symbolTableSize, maxRows, totalRows, this._path, this._memorySafetyFactor);\n\n // WARNING ZONE: Large files without maxRows parameter\n // Educate users about best practices but don't block\n warnLargeSymbolTable(symbolTableSize, maxRows, totalRows);\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n /*\n * The symbol table is a contiguous byte array that contains all possible symbols/values of all fields/columns.\n * The symbols/values of one field are stored consecutively in the same order as the fields/columns are defined\n * in the header. The length of the symbol area as well as it's offset, relativ to the begin of the symbol\n * table, are also defined in the header.\n */\n\n // Validate all field metadata before processing to prevent buffer overflow attacks\n for (const field of fields) {\n validateFieldMetadata(field, symbolBuffer.length, this._path);\n }\n\n // Parse all possible symbols of each field/column\n // Phase 2.5 optimization: Skip parsing entirely for symbols we don't need\n this._symbolTable = fields.map((/** @type {any} */ field) => {\n const symbolsOffset = parseInt(field['Offset'], 10); // Offset of the column's symbol area in the symbol table\n const symbolsLength = parseInt(field['Length'], 10); // Length of the column's symbol area in the symbol table\n\n const fieldName = field['FieldName'];\n const neededSymbols = symbolsToKeep ? symbolsToKeep.get(fieldName) : null;\n const filteringEnabled = neededSymbols !== null;\n\n const symbols = [];\n let symbolIndex = 0; // Track current symbol index as we parse\n\n // Parse all possible values of the current field/column\n for (let pointer = symbolsOffset; pointer < symbolsOffset + symbolsLength; pointer++) {\n // Each stored symbol consists of a type byte and the actual value, which length depends on the type\n const typeByte = symbolBuffer[pointer++];\n\n // Check if we should keep this symbol (filtering mode)\n const shouldKeepSymbol = !filteringEnabled || !!(neededSymbols && neededSymbols.has(symbolIndex));\n\n // Use utility function to parse or skip symbol\n const {symbol, bytesRead} = parseSymbol(\n typeByte,\n symbolBuffer,\n pointer,\n symbolBuffer.length,\n fieldName,\n this._path,\n shouldKeepSymbol,\n );\n\n symbols.push(symbol);\n pointer += bytesRead - 1; // -1 because the loop will increment\n symbolIndex++;\n }\n\n return symbols;\n // @ts-ignore - Symbol table type assignment\n });\n }\n\n /**\n * Utility method to convert a bit array to an integer value.\n *\n * @param {Array<number>} bits The bit array\n * @return {Number} The integer value\n */\n _convertBitsToInt32(bits) {\n return convertBitsToInt32(bits);\n }\n\n /**\n * Parses the bit stuffed index table of the QVD file. This method is part of the parsing process\n * and should not be called directly.\n *\n * @param {number|null} maxRows The maximum number of rows to parse. If null, all rows are parsed.\n */\n async _parseIndexTable(maxRows = null) {\n if (!this._buffer || !this._header || !this._indexTableOffset) {\n throw new QvdCorruptedError(\n 'The QVD file has not been loaded in the proper order or has not been loaded at all.',\n {\n file: this._path,\n stage: 'parseIndexTable',\n },\n );\n }\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n // Size of a single row of the index table in bytes\n const recordSize = parseInt(this._header['QvdTableHeader']['RecordByteSize'], 10);\n const totalRows = parseInt(this._header['QvdTableHeader']['NoOfRecords'], 10);\n const rowsToLoad = maxRows !== null ? Math.min(maxRows, totalRows) : totalRows;\n const indexTableLength = parseInt(this._header['QvdTableHeader']['Length'], 10);\n\n // Validate all index table metadata\n validateIndexTableMetadata(\n recordSize,\n totalRows,\n indexTableLength,\n this._indexTableOffset,\n this._buffer.length,\n rowsToLoad,\n this._path,\n );\n\n const indexBuffer = this._buffer.subarray(this._indexTableOffset, this._indexTableOffset + indexTableLength + 1);\n\n // Validate BitOffset and BitWidth for all fields before processing\n for (const field of fields) {\n validateFieldBitMetadata(field, recordSize, this._path);\n }\n\n this._indexTable = [];\n\n // Parse rows of the index table, each row contains the indices of the symbol table for each field/column\n for (\n let pointer = 0, rowCount = 0;\n pointer < indexBuffer.length && rowCount < rowsToLoad;\n pointer += recordSize, rowCount++\n ) {\n // Validate we have enough bytes for this record\n if (pointer + recordSize > indexBuffer.length) {\n throw new QvdCorruptedError('Buffer overflow reading index table record', {\n pointer,\n recordSize,\n bufferSize: indexBuffer.length,\n file: this._path,\n stage: 'parseIndexTable',\n });\n }\n\n const bytes = new Int32Array(indexBuffer.subarray(pointer, pointer + recordSize));\n bytes.reverse();\n\n // The bit mask contains the bit stuffed indices of the symbol table of the current row\n const mask = bytes\n .reduce((bits, byte) => bits + ('00000000' + byte.toString(2)).slice(-8), '')\n .split('')\n .reverse()\n .map((bit) => parseInt(bit));\n\n /** @type {number[]} */\n const symbolIndices = [];\n\n // Extract the index from the current row's bit mask for each field/column\n fields.forEach((/** @type {any} */ field) => {\n const bitOffset = parseInt(field['BitOffset'], 10);\n const bitWidth = parseInt(field['BitWidth'], 10);\n const bias = parseInt(field['Bias'], 10);\n\n let symbolIndex;\n\n if (bitWidth === 0) {\n symbolIndex = 0;\n } else {\n symbolIndex = this._convertBitsToInt32(mask.slice(bitOffset, bitOffset + bitWidth));\n }\n\n symbolIndex += bias;\n symbolIndices.push(symbolIndex);\n });\n\n this._indexTable.push(symbolIndices);\n }\n }\n\n /**\n * Loads the QVD file into memory and parses it.\n *\n * @param {number|null} maxRows The maximum number of rows to load. If null, all rows are loaded.\n * @return {Promise<QvdDataFrame>} The loaded QVD file.\n */\n async load(maxRows = null) {\n await this._readData(maxRows);\n await this._parseHeader();\n\n // Determine if we should use two-pass symbol filtering\n // This optimization is beneficial for large symbol tables with limited row access\n let symbolsToKeep = null;\n\n if (maxRows !== null && this._header) {\n const symbolTableLength = parseInt(this._header['QvdTableHeader']['Offset'], 10);\n const SYMBOL_FILTERING_THRESHOLD = 50 * 1024 * 1024; // 50MB\n\n // Use two-pass filtering for symbol tables > 50MB when loading limited rows\n if (symbolTableLength > SYMBOL_FILTERING_THRESHOLD) {\n // Pass 1: Analyze which symbols are actually needed\n symbolsToKeep = await this._analyzeIndexTableSymbolUsage(maxRows);\n\n // Log the optimization for visibility\n const totalSymbols = Array.from(symbolsToKeep.values()).reduce((sum, set) => sum + set.size, 0);\n console.log(\n `[Phase 2.5 Optimization] Using stream-and-skip parsing: keeping ${totalSymbols} symbols from ${(symbolTableLength / 1024 / 1024).toFixed(1)}MB symbol table`,\n );\n }\n }\n\n // Pass 2: Parse symbol table (with filtering if enabled)\n await this._parseSymbolTable(symbolsToKeep, maxRows);\n await this._parseIndexTable(maxRows);\n\n assert(this._header, 'The QVD file header has not been parsed.');\n assert(this._symbolTable, 'The QVD file symbol table has not been parsed.');\n assert(this._indexTable, 'The QVD file index table has not been parsed.');\n\n /**\n * Retrieves the values of a specific row of the QVD file. Values are in the same order\n * as the field names.\n *\n * @param {number} index The index of the row.\n * @return {Array<any>} The values of the row.\n */\n const getRow = (index) => {\n if (!this._indexTable || index >= this._indexTable.length) {\n throw new QvdValidationError('Row index out of bounds', {\n index,\n max: this._indexTable ? this._indexTable.length - 1 : -1,\n file: this._path,\n });\n }\n\n return this._indexTable?.[index].map((/** @type {number} */ symbolIndex, /** @type {number} */ fieldIndex) => {\n if (symbolIndex < 0) {\n return null;\n }\n\n const symbol = this._symbolTable?.[fieldIndex]?.[symbolIndex];\n const value = symbol?.toPrimaryValue();\n\n if (typeof value === 'string') {\n if (!isNaN(Number(value))) {\n return Number(value);\n }\n }\n\n return value;\n });\n };\n\n let fields = this._header['QvdTableHeader']['Fields']['QvdFieldHeader'];\n\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n const columns = fields.map((/** @type {any} */ field) => field['FieldName']);\n const data = this._indexTable.map((_, index) => getRow(index));\n\n // Pass the complete header metadata to the data frame\n const metadata = this._header['QvdTableHeader'];\n\n return new QvdDataFrame(data, columns, metadata);\n }\n}\n","// @ts-check\n\nimport {QvdValidationError} from './QvdErrors.js';\n\n/**\n * @typedef {Object} QvdNumberFormat\n * @property {string} Type - Number format type\n * @property {string} nDec - Number of decimals\n * @property {string} UseThou - Use thousands separator\n * @property {string} Fmt - Format string\n * @property {string} Dec - Decimal separator\n * @property {string} Thou - Thousands separator\n */\n\n/**\n * @typedef {Object} QvdFieldHeader\n * @property {string} FieldName - The name of the field\n * @property {string|number} [BitOffset] - The bit offset\n * @property {string|number} [BitWidth] - The bit width\n * @property {string|number} [Bias] - The bias value\n * @property {string|number} [NoOfSymbols] - Number of symbols\n * @property {string|number} [Offset] - The offset\n * @property {string|number} [Length] - The length\n * @property {string} [Comment] - Field comment\n * @property {QvdNumberFormat|string} [NumberFormat] - Number format\n * @property {Object|string} [Tags] - Field tags\n */\n\n/**\n * @typedef {Object} QvdFields\n * @property {QvdFieldHeader|QvdFieldHeader[]} QvdFieldHeader - Field header(s)\n */\n\n/**\n * @typedef {Object} QvdMetadata\n * @property {string|number} [QvBuildNo] - QlikView build number\n * @property {string} [CreatorDoc] - Creator document\n * @property {string} [CreateUtcTime] - Creation UTC time\n * @property {string} [SourceCreateUtcTime] - Source creation UTC time\n * @property {string} [SourceFileUtcTime] - Source file UTC time\n * @property {string|number} [SourceFileSize] - Source file size\n * @property {string} [StaleUtcTime] - Stale UTC time\n * @property {string} [TableName] - Table name\n * @property {string|number} [NoOfRecords] - Number of records\n * @property {string|number} [RecordByteSize] - Record byte size\n * @property {string|number} [Offset] - Offset\n * @property {string|number} [Length] - Length\n * @property {string} [Compression] - Compression type\n * @property {string} [Comment] - Comment\n * @property {string} [EncryptionInfo] - Encryption info\n * @property {string} [TableTags] - Table tags\n * @property {string} [ProfilingData] - Profiling data\n * @property {Object|string} [Lineage] - Lineage\n * @property {QvdFields} [Fields] - Fields information\n */\n\n/**\n * Represents a loaded QVD file.\n */\nexport class QvdDataFrame {\n /**\n * Represents the data frame stored inside a QVD file.\n * @param {Array<Array<any>>} data The data of the data frame.\n * @param {Array<string>} columns The columns of the data frame.\n * @param {QvdMetadata|null} metadata The metadata from the QVD file header (optional).\n */\n constructor(data, columns, metadata = null) {\n this._data = data;\n this._columns = columns;\n this._metadata = metadata;\n }\n\n /**\n * Returns the data of the data frame.\n */\n get data() {\n return this._data;\n }\n\n /**\n * Returns the columns of the data frame.\n */\n get columns() {\n return this._columns;\n }\n\n /**\n * Returns the shape of the data frame.\n */\n get shape() {\n return [this._data.length, this._columns.length];\n }\n\n /**\n * Returns the complete metadata object from the QVD file header.\n * @return {Object|null} The complete metadata object or null if not available.\n */\n get metadata() {\n return this._metadata;\n }\n\n /**\n * Returns file-level metadata from the QVD header.\n * @return {Object} File-level metadata properties.\n */\n get fileMetadata() {\n if (!this._metadata) {\n return {};\n }\n\n const header = this._metadata;\n return {\n qvBuildNo: header.QvBuildNo,\n creatorDoc: header.CreatorDoc,\n createUtcTime: header.CreateUtcTime,\n sourceCreateUtcTime: header.SourceCreateUtcTime,\n sourceFileUtcTime: header.SourceFileUtcTime,\n sourceFileSize: header.SourceFileSize,\n staleUtcTime: header.StaleUtcTime,\n tableName: header.TableName,\n noOfRecords: header.NoOfRecords,\n recordByteSize: header.RecordByteSize,\n offset: header.Offset,\n length: header.Length,\n compression: header.Compression,\n comment: header.Comment,\n encryptionInfo: header.EncryptionInfo,\n tableTags: header.TableTags,\n profilingData: header.ProfilingData,\n lineage: header.Lineage,\n };\n }\n\n /**\n * Returns field-level metadata for a specific field/column.\n * @param {string} fieldName The name of the field.\n * @return {Object|null} Field metadata or null if field not found.\n */\n getFieldMetadata(fieldName) {\n if (!this._metadata || !this._metadata.Fields || !this._metadata.Fields.QvdFieldHeader) {\n return null;\n }\n\n let fields = this._metadata.Fields.QvdFieldHeader;\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n const field = fields.find((f) => f.FieldName === fieldName);\n if (!field) {\n return null;\n }\n\n return {\n fieldName: field.FieldName,\n bitOffset: field.BitOffset,\n bitWidth: field.BitWidth,\n bias: field.Bias,\n noOfSymbols: field.NoOfSymbols,\n offset: field.Offset,\n length: field.Length,\n comment: field.Comment,\n numberFormat: field.NumberFormat,\n tags: field.Tags,\n };\n }\n\n /**\n * Returns field-level metadata for all fields.\n * @return {Array<Object>} Array of field metadata objects.\n */\n getAllFieldMetadata() {\n if (!this._metadata || !this._metadata.Fields || !this._metadata.Fields.QvdFieldHeader) {\n return [];\n }\n\n let fields = this._metadata.Fields.QvdFieldHeader;\n if (!Array.isArray(fields)) {\n fields = [fields];\n }\n\n return fields.map((field) => ({\n fieldName: field.FieldName,\n bitOffset: field.BitOffset,\n bitWidth: field.BitWidth,\n bias: field.Bias,\n noOfSymbols: field.NoOfSymbols,\n offset: field.Offset,\n length: field.Length,\n comment: field.Comment,\n numberFormat: field.NumberFormat,\n tags: field.Tags,\n }));\n }\n\n /**\n * @typedef {Object} FileMetadataUpdate\n * @property {string|number} [qvBuildNo] - QlikView build number\n * @property {string} [creatorDoc] - Creator document\n * @property {string} [createUtcTime] - Creation UTC time\n * @property {string} [sourceCreateUtcTime] - Source creation UTC time\n * @property {string} [sourceFileUtcTime] - Source file UTC time\n * @property {string|number} [sourceFileSize] - Source file size\n * @property {string} [staleUtcTime] - Stale UTC time\n * @property {string} [tableName] - Table name\n * @property {string} [compression] - Compression type\n * @property {string} [comment] - Comment\n * @property {string} [encryptionInfo] - Encryption info\n * @property {string} [tableTags] - Table tags\n * @property {string} [profilingData] - Profiling data\n * @property {Object|string} [lineage] - Lineage\n */\n\n /**\n * Sets modifiable file-level metadata. Immutable properties related to data storage are ignored.\n * @param {FileMetadataUpdate} metadata Object containing metadata properties to update.\n */\n setFileMetadata(metadata) {\n if (!this._metadata) {\n // Initialize metadata structure if it doesn't exist\n this._metadata = {\n QvBuildNo: 50667,\n CreatorDoc: '',\n CreateUtcTime: '',\n SourceCreateUtcTime: '',\n SourceFileUtcTime: '',\n SourceFileSize: -1,\n StaleUtcTime: '',\n TableName: '',\n Fields: {\n QvdFieldHeader: this._columns.map((column) => ({\n FieldName: column,\n BitOffset: 0,\n BitWidth: 0,\n Bias: 0,\n NoOfSymbols: 0,\n Offset: 0,\n Length: 0,\n Comment: '',\n NumberFormat: {\n Type: 'UNKNOWN',\n nDec: '0',\n UseThou: '0',\n Fmt: '',\n Dec: '',\n Thou: '',\n },\n Tags: {},\n })),\n },\n NoOfRecords: 0,\n RecordByteSize: 0,\n Offset: 0,\n Length: 0,\n Compression: '',\n Comment: '',\n EncryptionInfo: '',\n TableTags: '',\n ProfilingData: '',\n Lineage: {},\n };\n }\n\n // Only allow modification of certain fields (not Offset, Length, NoOfRecords, RecordByteSize)\n const modifiableFields = [\n 'qvBuildNo',\n 'creatorDoc',\n 'createUtcTime',\n 'sourceCreateUtcTime',\n 'sourceFileUtcTime',\n 'sourceFileSize',\n 'staleUtcTime',\n 'tableName',\n 'compression',\n 'comment',\n 'encryptionInfo',\n 'tableTags',\n 'profilingData',\n 'lineage',\n ];\n\n // Map camelCase to XML property names\n const fieldMapping = {\n qvBuildNo: 'QvBuildNo',\n creatorDoc: 'CreatorDoc',\n createUtcTime: 'CreateUtcTime',\n sourceCreateUtcTime: 'SourceCreateUtcTime',\n sourceFileUtcTime: 'SourceFileUtcTime',\n sourceFileSize: 'SourceFileSize',\n staleUtcTime: 'StaleUtcTime',\n tableName: 'TableName',\n compression: 'Compression',\n comment: 'Comment',\n encryptionInfo: 'EncryptionInfo',\n tableTags: 'TableTags',\n profilingData: 'ProfilingData',\n lineage: 'Lineage',\n };\n\n modifiableFields.forEach((field) => {\n // @ts-ignore - Dynamic property access for metadata mapping\n if (metadata[field] !== undefined) {\n // @ts-ignore - Dynamic property access for metadata mapping\n this._metadata[fieldMapping[field]] = metadata[field];\n }\n });\n }\n\n /**\n * @typedef {Object} FieldMetadataUpdate\n * @property {string} [comment] - Field comment\n * @property {QvdNumberFormat|string} [numberFormat] - Number format\n * @property {Object|string} [tags] - Field tags\n */\n\n /**\n * Sets modifiable field-level metadata for a specific field.\n * Immutable properties related to data storage (Offset, Length, BitOffset, etc.) are ignored.\n * @param {string} fieldName The name of the field.\n * @param {FieldMetadataUpdate} metadata Object containing field metadata properties to update.\n */\n setFieldMetadata(fieldName, metadata) {\n if (!this._metadata || !this._metadata.Fields || !this._metadata.Fields.QvdFieldHeader) {\n return;\n }\n\n let fields = this._metadata.Fields.QvdFieldHeader;\n if (!Array.isArray(fields)) {\n fields = [fields];\n this._metadata.Fields.QvdFieldHeader = fields;\n }\n\n const fieldIndex = fields.findIndex((f) => f.FieldName === fieldName);\n if (fieldIndex === -1) {\n return;\n }\n\n // Only allow modification of Comment, NumberFormat, and Tags (not Offset, Length, BitOffset, etc.)\n if (metadata.comment !== undefined) {\n fields[fieldIndex].Comment = metadata.comment;\n }\n if (metadata.numberFormat !== undefined) {\n fields[fieldIndex].NumberFormat = metadata.numberFormat;\n }\n if (metadata.tags !== undefined) {\n fields[fieldIndex].Tags = metadata.tags;\n }\n }\n\n /**\n * Returns the first n rows of the data frame.\n *\n * @param {number} n The number of rows to return.\n * @return {QvdDataFrame} The first n rows of the data frame.\n * @throws {QvdValidationError} If n is not a non-negative integer.\n */\n head(n = 5) {\n if (typeof n !== 'number' || !Number.isInteger(n) || n < 0) {\n throw new QvdValidationError('head() requires a non-negative integer', {\n provided: n,\n type: typeof n,\n });\n }\n return new QvdDataFrame(this._data.slice(0, n), this._columns, this._metadata);\n }\n\n /**\n * Returns the last n rows of the data frame.\n *\n * @param {number} n The number of rows to return.\n * @return {QvdDataFrame} The first n rows of the data frame.\n * @throws {QvdValidationError} If n is not a non-negative integer.\n */\n tail(n = 5) {\n if (typeof n !== 'number' || !Number.isInteger(n) || n < 0) {\n throw new QvdValidationError('tail() requires a non-negative integer', {\n provided: n,\n type: typeof n,\n });\n }\n return new QvdDataFrame(n === 0 ? [] : this._data.slice(-n), this._columns, this._metadata);\n }\n\n /**\n * Returns the selected rows of the data frame.\n *\n * @param {...number} args The indices of the rows to return.\n * @return {QvdDataFrame} The selected rows of the data frame.\n * @throws {QvdValidationError} If any index is not an integer or is out of bounds.\n */\n rows(...args) {\n for (const index of args) {\n if (typeof index !== 'number' || !Number.isInteger(index)) {\n throw new QvdValidationError('rows() requires integer indices', {\n provided: index,\n type: typeof index,\n });\n }\n if (index < 0 || index >= this._data.length) {\n throw new QvdValidationError(`Row index ${index} out of bounds`, {\n index,\n validRange: [0, this._data.length - 1],\n dataLength: this._data.length,\n });\n }\n }\n return new QvdDataFrame(\n args.map((index) => this._data[index]),\n this._columns,\n this._metadata,\n );\n }\n\n /**\n * Returns the value at the specified row and column.\n *\n * @param {number} row The index of the row.\n * @param {string} column The name of the column.\n * @return {any} The value at the specified row and column.\n * @throws {QvdValidationError} If row is not an integer, out of bounds, or column does not exist.\n */\n at(row, column) {\n if (typeof row !== 'number' || !Number.isInteger(row)) {\n throw new QvdValidationError('Row index must be an integer', {\n provided: row,\n type: typeof row,\n });\n }\n if (row < 0 || row >= this._data.length) {\n throw new QvdValidationError(`Row index ${row} out of bounds`, {\n index: row,\n validRange: [0, this._data.length - 1],\n dataLength: this._data.length,\n });\n }\n if (!this._columns.includes(column)) {\n throw new QvdValidationError(`Column '${column}' does not exist`, {\n column,\n availableColumns: this._columns,\n });\n }\n return this._data[row][this._columns.indexOf(column)];\n }\n\n /**\n * Selects the specified columns from the data frame.\n *\n * @param {...string} args The names of the columns to select.\n * @return {QvdDataFrame} The selected columns of the data frame.\n * @throws {QvdValidationError} If any column name does not exist.\n */\n select(...args) {\n for (const column of args) {\n if (!this._columns.includes(column)) {\n throw new QvdValidationError(`Column '${column}' does not exist`, {\n column,\n availableColumns: this._columns,\n });\n }\n }\n const indices = args.map((arg) => this._columns.indexOf(arg));\n const data = this._data.map((row) => indices.map((index) => row[index]));\n const columns = indices.map((index) => this._columns[index]);\n return new QvdDataFrame(data, columns, this._metadata);\n }\n\n /**\n * Returns the data frame as a dictionary.\n *\n * @return {Promise<{columns: Array<string>, data: Array<Array<any>>}>} The data frame as a dictionary.\n */\n async toDict() {\n return {columns: this._columns, data: this._data};\n }\n\n /**\n * Persists the data frame to a QVD file.\n *\n * @param {string} path The path to the QVD file.\n * @param {Object} [options] Optional writing options.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file path must be within this directory.\n * @param {Function} [options.onProgress] Optional progress callback function that receives progress updates during write operations.\n */\n async toQvd(path, options = {}) {\n const {QvdFileWriter} = await import('./QvdFileWriter.js');\n const writerOptions = {\n allowedDir: options.allowedDir,\n onProgress: options.onProgress,\n };\n await new QvdFileWriter(path, this, writerOptions).save();\n }\n\n /**\n * Loads a QVD file and returns its data frame.\n *\n * @param {string} path The path to the QVD file.\n * @param {Object} [options] Optional loading options.\n * @param {number|null} [options.maxRows] The maximum number of rows to load. If not specified, all rows are loaded.\n * @param {string} [options.allowedDir] Optional allowed directory path. If provided, the file path must be within this directory.\n * @param {number} [options.memorySafetyFactor=0.3] Memory safety factor (0.0-1.0). Determines what percentage\n * of available memory (or V8 heap limit, whichever is smaller) can be used. Default is 0.3 (30%).\n * Increase this (e.g., to 0.5 or 0.7) when running with larger heap sizes via --max-old-space-size.\n * @return {Promise<QvdDataFrame>} The data frame of the QVD file.\n */\n static async fromQvd(path, options = {}) {\n const {QvdFileReader} = await import('./QvdFileReader.js');\n const readerOptions = {\n allowedDir: options.allowedDir,\n memorySafetyFactor: options.memorySafetyFactor,\n };\n return await new QvdFileReader(path, readerOptions).load(options.maxRows !== undefined ? options.maxRows : null);\n }\n\n /**\n * Constructs a data frame from a dictionary.\n *\n * @param {{columns: Array<string>, data: Array<Array<any>>}} data The dictionary to construct the data frame from.\n * @return {Promise<QvdDataFrame>} The constructed data frame.\n */\n static async fromDict(data) {\n if (!data.columns) {\n throw new QvdValidationError('The dictionary to construct the data frame from does not contain any columns.', {\n data,\n });\n }\n if (!data.data) {\n throw new QvdValidationError('The dictionary to construct the data frame from does not contain any data.', {\n data,\n });\n }\n\n return new QvdDataFrame(data.data, data.columns);\n }\n}\n","// @ts-check\n\nexport {QvdSymbol} from './QvdSymbol.js';\nexport {QvdDataFrame} from './QvdDataFrame.js';\nexport {QvdFileReader} from './QvdFileReader.js';\nexport {QvdFileWriter} from './QvdFileWriter.js';\nexport {\n QvdError,\n QvdParseError,\n QvdValidationError,\n QvdIOError,\n QvdCorruptedError,\n QvdSecurityError,\n} from './QvdErrors.js';\n"]}
|