diff --git a/src/cdbToSql.ts b/src/cdbToSql.ts index 7c9a081..e86f6ff 100644 --- a/src/cdbToSql.ts +++ b/src/cdbToSql.ts @@ -8,7 +8,7 @@ import { inferKeys } from "./keyInference"; import type { TableKeys } from "./keyInference"; import { CDBReader } from "./reader"; import { escapeSqlIdentifier } from "./sqlUtils"; -import { CHUNK_TYPE, DATA_TYPE } from "./tableMetadata"; +import { ChunkType, DataType } from "./types"; import type { CdbToSqlOptions, SqlDatabase, @@ -126,7 +126,7 @@ export function cdbToSql( } const tables = - (wrapperChildren[CHUNK_TYPE.DATABASE_TABLES] as TableInfo[] | undefined) ?? + (wrapperChildren[ChunkType.DATABASE_TABLES] as TableInfo[] | undefined) ?? []; // DB_STRUCTURE mirrors the PCM convention used by sqlToCdb: TableName keeps the @@ -188,33 +188,33 @@ export function cdbToSql( let baseType: string; let encodedType: number; switch (col.type) { - case DATA_TYPE.FLOAT: + case DataType.FLOAT: baseType = "REAL"; encodedType = col.type; break; - case DATA_TYPE.STRING: - case DATA_TYPE.INTEGER_LIST: - case DATA_TYPE.FLOAT_LIST: + case DataType.STRING: + case DataType.INTEGER_LIST: + case DataType.FLOAT_LIST: baseType = "TEXT"; encodedType = col.type; break; - case DATA_TYPE.BOOLEAN: + case DataType.BOOLEAN: // `SQLiteExporter` (the official PCM tool) has no case for BOOLEAN, // INTEGER_BYTE or INTEGER_SHORT: they all fall into its default // branch and get encoded as plain INTEGER. Match that by default so // our output stays importable there; preciseTypes opts back into // preserving the exact CDB type for our own round-trip. baseType = options?.preciseTypes ? "NUMERIC" : "INTEGER"; - encodedType = options?.preciseTypes ? col.type : DATA_TYPE.INTEGER; + encodedType = options?.preciseTypes ? col.type : DataType.INTEGER; break; - case DATA_TYPE.INTEGER_BYTE: - case DATA_TYPE.INTEGER_SHORT: + case DataType.INTEGER_BYTE: + case DataType.INTEGER_SHORT: baseType = "INTEGER"; - encodedType = options?.preciseTypes ? col.type : DATA_TYPE.INTEGER; + encodedType = options?.preciseTypes ? col.type : DataType.INTEGER; break; default: baseType = "INTEGER"; - encodedType = DATA_TYPE.INTEGER; + encodedType = DataType.INTEGER; break; } diff --git a/src/compression.ts b/src/compression.ts index 5036713..e6ce278 100644 --- a/src/compression.ts +++ b/src/compression.ts @@ -3,7 +3,7 @@ */ import { deflate, inflate } from "pako"; -import { MAGIC } from "./tableMetadata"; +import { Magic } from "./types"; function toUint8Array(data: ArrayBuffer | Uint8Array): Uint8Array { return data instanceof Uint8Array ? data : new Uint8Array(data); @@ -25,7 +25,7 @@ export function decompressCdb(data: ArrayBuffer | Uint8Array): ArrayBuffer { const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); // Check if data is compressed (magic header) - if (view.getUint32(0, true) !== MAGIC.COMPRESSION_MAGIC) { + if (view.getUint32(0, true) !== Magic.COMPRESSION_MAGIC) { return bytes.slice().buffer; } @@ -78,7 +78,7 @@ export function compressCdb(data: ArrayBuffer | Uint8Array): ArrayBuffer { const result = new Uint8Array(12 + compressed.length); const view = new DataView(result.buffer); - view.setUint32(0, MAGIC.COMPRESSION_MAGIC, true); + view.setUint32(0, Magic.COMPRESSION_MAGIC, true); view.setUint32(4, uncompressedData.length, true); view.setUint32(8, compressed.length, true); result.set(compressed, 12); diff --git a/src/index.ts b/src/index.ts index a49fe70..102958e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,9 +24,4 @@ export type { } from "./types"; export { ChunkType, DataType, Magic } from "./types"; -export { - CHUNK_TYPE, - DATA_TYPE, - MAGIC, - TABLE_FLAGS_BY_ID, -} from "./tableMetadata"; +export { TABLE_FLAGS_BY_ID } from "./tableMetadata"; diff --git a/src/reader.ts b/src/reader.ts index 6e22f85..5b36322 100644 --- a/src/reader.ts +++ b/src/reader.ts @@ -3,14 +3,8 @@ * Handles parsing of chunk hierarchy, data types, and value unpacking */ -import type { - ChunkHeader, - CDBChunk, - ColumnData, - DataType, - ColumnInfo, -} from "./types"; -import { CHUNK_TYPE, DATA_TYPE, MAGIC } from "./tableMetadata"; +import type { ChunkHeader, CDBChunk, ColumnData, ColumnInfo } from "./types"; +import { ChunkType, DataType, Magic } from "./types"; type ColumnDefinition = Omit & { data?: ColumnData; @@ -106,7 +100,7 @@ export class CDBReader { } private readChunkHeader(): ChunkHeader { - this.readMagic(MAGIC.CHUNK_BEGIN, "CHUNK_BEGIN"); + this.readMagic(Magic.CHUNK_BEGIN, "CHUNK_BEGIN"); const chunkSize = this.read32(); const chunkType = this.read32(); const flags = this.read32(); @@ -121,7 +115,7 @@ export class CDBReader { } this.readPadding(); - this.readMagic(MAGIC.CHUNK_SEPARATOR, "CHUNK_SEPARATOR"); + this.readMagic(Magic.CHUNK_SEPARATOR, "CHUNK_SEPARATOR"); return { chunkSize, chunkType, flags, description }; } @@ -134,16 +128,16 @@ export class CDBReader { let result: CDBChunk; switch (header.chunkType) { - case CHUNK_TYPE.ROW_COUNT: - case CHUNK_TYPE.TABLE_ID: - case CHUNK_TYPE.TABLE_FLAGS: - case CHUNK_TYPE.DATABASE_FLAGS: - case CHUNK_TYPE.COLUMN_INDEX: - case CHUNK_TYPE.COLUMN_DATA_TYPE: + case ChunkType.ROW_COUNT: + case ChunkType.TABLE_ID: + case ChunkType.TABLE_FLAGS: + case ChunkType.DATABASE_FLAGS: + case ChunkType.COLUMN_INDEX: + case ChunkType.COLUMN_DATA_TYPE: result = { type: header.chunkType, value: this.read32() }; break; - case CHUNK_TYPE.COLUMN_VALUES: + case ChunkType.COLUMN_VALUES: { const dataBytes = chunkEndPos - this.pos - 4; const values: number[] = []; @@ -154,7 +148,7 @@ export class CDBReader { } break; - case CHUNK_TYPE.COLUMN_BLOB_DATA: + case ChunkType.COLUMN_BLOB_DATA: { const sizedDataBytes = chunkEndPos - this.pos - 4; result = { @@ -164,16 +158,16 @@ export class CDBReader { } break; - case CHUNK_TYPE.DATABASE_TABLES: + case ChunkType.DATABASE_TABLES: { const tables = this.readArray(() => { const tableChunk = this.readChunk(); const rowCount = - this.getRequiredChild(tableChunk, CHUNK_TYPE.ROW_COUNT) || + this.getRequiredChild(tableChunk, ChunkType.ROW_COUNT) || 0; const columnDefinitions = this.getRequiredChild( tableChunk, - CHUNK_TYPE.COLUMN_DEFINITIONS, + ChunkType.COLUMN_DEFINITIONS, ); const columns: ColumnInfo[] = columnDefinitions.map((column) => ({ name: column.name, @@ -192,11 +186,11 @@ export class CDBReader { columns, tableId: this.getRequiredChild( tableChunk, - CHUNK_TYPE.TABLE_ID, + ChunkType.TABLE_ID, ), tableFlags: this.getRequiredChild( tableChunk, - CHUNK_TYPE.TABLE_FLAGS, + ChunkType.TABLE_FLAGS, ), }; }); @@ -204,7 +198,7 @@ export class CDBReader { } break; - case CHUNK_TYPE.COLUMN_DEFINITIONS: + case ChunkType.COLUMN_DEFINITIONS: { const columns = this.readArray(() => { const columnChunk = this.readChunk(); @@ -214,11 +208,11 @@ export class CDBReader { name: colName, type: this.getRequiredChild( columnChunk, - CHUNK_TYPE.COLUMN_DATA_TYPE, + ChunkType.COLUMN_DATA_TYPE, ), columnIndex: this.getRequiredChild( columnChunk, - CHUNK_TYPE.COLUMN_INDEX, + ChunkType.COLUMN_INDEX, ), columnChunk: columnChunk, // Store for later conversion }; @@ -227,9 +221,9 @@ export class CDBReader { } break; - case CHUNK_TYPE.WRAPPER: - case CHUNK_TYPE.TABLE: - case CHUNK_TYPE.COLUMN: + case ChunkType.WRAPPER: + case ChunkType.TABLE: + case ChunkType.COLUMN: { const children: Record = {}; while (this.pos < chunkEndPos) { @@ -269,12 +263,12 @@ export class CDBReader { } this.readPadding(); - this.readMagic(MAGIC.CHUNK_END, "CHUNK_END"); + this.readMagic(Magic.CHUNK_END, "CHUNK_END"); return result; } private readArray(itemReader: () => T): T[] { - this.readMagic(MAGIC.ARRAY_BEGIN, "ARRAY_BEGIN"); + this.readMagic(Magic.ARRAY_BEGIN, "ARRAY_BEGIN"); const count = this.read32(); const items: T[] = []; @@ -282,7 +276,7 @@ export class CDBReader { items.push(itemReader()); } - this.readMagic(MAGIC.ARRAY_END, "ARRAY_END"); + this.readMagic(Magic.ARRAY_END, "ARRAY_END"); return items; } @@ -292,26 +286,26 @@ export class CDBReader { ): ColumnData { const dataType = this.getRequiredChild( columnChunk, - CHUNK_TYPE.COLUMN_DATA_TYPE, + ChunkType.COLUMN_DATA_TYPE, ); const rawData = - (this.getChunkChildren(columnChunk)[CHUNK_TYPE.COLUMN_VALUES] as + (this.getChunkChildren(columnChunk)[ChunkType.COLUMN_VALUES] as | number[] | undefined) ?? []; const sizedData = - (this.getChunkChildren(columnChunk)[CHUNK_TYPE.COLUMN_BLOB_DATA] as + (this.getChunkChildren(columnChunk)[ChunkType.COLUMN_BLOB_DATA] as | Uint8Array | undefined) ?? new Uint8Array([0, 0, 0, 0]); // If no data, return array of zeros/empty strings based on type if (rawData.length === 0 && rowCount !== undefined) { switch (dataType) { - case DATA_TYPE.STRING: + case DataType.STRING: return Array(rowCount).fill(""); - case DATA_TYPE.FLOAT: + case DataType.FLOAT: return Array(rowCount).fill(0.0); - case DATA_TYPE.FLOAT_LIST: - case DATA_TYPE.INTEGER_LIST: + case DataType.FLOAT_LIST: + case DataType.INTEGER_LIST: return Array(rowCount).fill("()"); default: return Array(rowCount).fill(0); @@ -319,10 +313,10 @@ export class CDBReader { } switch (dataType) { - case DATA_TYPE.INTEGER: + case DataType.INTEGER: return rawData.map((value) => value | 0); - case DATA_TYPE.BOOLEAN: { + case DataType.BOOLEAN: { if (rowCount === undefined) { throw new Error("Row count required for boolean type"); } @@ -336,7 +330,7 @@ export class CDBReader { return boolValues; } - case DATA_TYPE.INTEGER_BYTE: { + case DataType.INTEGER_BYTE: { const bytes = new Uint8Array(new Uint32Array(rawData).buffer).slice( 0, rowCount, @@ -344,7 +338,7 @@ export class CDBReader { return Array.from(bytes, (b) => (b > 127 ? b - 256 : b)); } - case DATA_TYPE.INTEGER_SHORT: { + case DataType.INTEGER_SHORT: { const bytes = new Uint8Array(new Uint32Array(rawData).buffer); const int16Values: number[] = []; for (let i = 0; i < rowCount; i++) { @@ -354,7 +348,7 @@ export class CDBReader { return int16Values; } - case DATA_TYPE.FLOAT: { + case DataType.FLOAT: { const view = new DataView(new ArrayBuffer(4)); return rawData.map((intValue) => { view.setUint32(0, intValue, true); @@ -362,15 +356,15 @@ export class CDBReader { }); } - case DATA_TYPE.STRING: + case DataType.STRING: return this.parseStrings(sizedData, rawData); - case DATA_TYPE.INTEGER_LIST: + case DataType.INTEGER_LIST: return this.parseNumericLists(sizedData, rawData, (view, offset) => { return view.getUint32(offset, true) | 0; }); - case DATA_TYPE.FLOAT_LIST: + case DataType.FLOAT_LIST: return this.parseNumericLists( sizedData, rawData, diff --git a/src/sqlToCdb.ts b/src/sqlToCdb.ts index 89a6c83..3cde61e 100644 --- a/src/sqlToCdb.ts +++ b/src/sqlToCdb.ts @@ -5,24 +5,20 @@ import { compressCdb } from "./compression"; import { escapeSqlIdentifier } from "./sqlUtils"; import { CDBWriter } from "./writer"; -import { - CHUNK_TYPE, - DATA_TYPE, - MAGIC, - TABLE_FLAGS_BY_ID, -} from "./tableMetadata"; -import type { ColumnMetadata, DataType, SqlDatabase } from "./types"; +import { TABLE_FLAGS_BY_ID } from "./tableMetadata"; +import { ChunkType, DataType, Magic } from "./types"; +import type { ColumnMetadata, SqlDatabase } from "./types"; function toDataType(value: number): DataType { switch (value) { - case DATA_TYPE.INTEGER: - case DATA_TYPE.FLOAT: - case DATA_TYPE.STRING: - case DATA_TYPE.BOOLEAN: - case DATA_TYPE.INTEGER_BYTE: - case DATA_TYPE.INTEGER_SHORT: - case DATA_TYPE.FLOAT_LIST: - case DATA_TYPE.INTEGER_LIST: + case DataType.INTEGER: + case DataType.FLOAT: + case DataType.STRING: + case DataType.BOOLEAN: + case DataType.INTEGER_BYTE: + case DataType.INTEGER_SHORT: + case DataType.FLOAT_LIST: + case DataType.INTEGER_LIST: return value; default: throw new Error(`Unsupported CDB data type: ${value}`); @@ -86,13 +82,13 @@ export function sqlToCdb(db: SqlDatabase): ArrayBuffer { ? new CDBWriter(estimatedSize) : new CDBWriter(); - writer.writeChunkOpen(CHUNK_TYPE.WRAPPER, "cyanide database"); - writer.writeChunkOpen(CHUNK_TYPE.DATABASE_FLAGS); + writer.writeChunkOpen(ChunkType.WRAPPER, "cyanide database"); + writer.writeChunkOpen(ChunkType.DATABASE_FLAGS); writer.write32(274); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.DATABASE_TABLES); - writer.write32(MAGIC.ARRAY_BEGIN); + writer.writeChunkOpen(ChunkType.DATABASE_TABLES); + writer.write32(Magic.ARRAY_BEGIN); writer.write32(tables.length); tables.forEach((tableInfo) => { @@ -116,23 +112,23 @@ export function sqlToCdb(db: SqlDatabase): ArrayBuffer { const dataResult = db.exec(`SELECT * FROM "${escapedTableName}"`); const rows = dataResult.length > 0 ? dataResult[0].values : []; - writer.writeChunkOpen(CHUNK_TYPE.TABLE, tableInfo.name); + writer.writeChunkOpen(ChunkType.TABLE, tableInfo.name); - writer.writeChunkOpen(CHUNK_TYPE.TABLE_ID); + writer.writeChunkOpen(ChunkType.TABLE_ID); writer.write32(tableInfo.id); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.ROW_COUNT); + writer.writeChunkOpen(ChunkType.ROW_COUNT); writer.write32(rows.length); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.TABLE_FLAGS); + writer.writeChunkOpen(ChunkType.TABLE_FLAGS); const tableFlags = tableInfo.flags ?? TABLE_FLAGS_BY_ID[tableInfo.id] ?? 0; writer.write32(tableFlags); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_DEFINITIONS); - writer.write32(MAGIC.ARRAY_BEGIN); + writer.writeChunkOpen(ChunkType.COLUMN_DEFINITIONS); + writer.write32(Magic.ARRAY_BEGIN); writer.write32(Object.keys(columnInfo).length); // Transpose row data to column data in single pass @@ -145,15 +141,15 @@ export function sqlToCdb(db: SqlDatabase): ArrayBuffer { }); columnNames.forEach((columnName, colIdx) => { - writer.writeChunkOpen(CHUNK_TYPE.COLUMN, columnName); + writer.writeChunkOpen(ChunkType.COLUMN, columnName); const info = columnInfo[columnName]; - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_INDEX); + writer.writeChunkOpen(ChunkType.COLUMN_INDEX); writer.write32(info.cdbColumnIndex); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_DATA_TYPE, columnName); + writer.writeChunkOpen(ChunkType.COLUMN_DATA_TYPE, columnName); writer.write32(info.cdbDataType); writer.writeChunkClose(); @@ -178,13 +174,13 @@ export function sqlToCdb(db: SqlDatabase): ArrayBuffer { writer.writeChunkClose(); }); - writer.write32(MAGIC.ARRAY_END); + writer.write32(Magic.ARRAY_END); writer.writeChunkClose(); writer.writeChunkClose(); }); - writer.write32(MAGIC.ARRAY_END); + writer.write32(Magic.ARRAY_END); writer.writeChunkClose(); writer.writeChunkClose(); diff --git a/src/tableMetadata.ts b/src/tableMetadata.ts index 22d5463..eb5e464 100644 --- a/src/tableMetadata.ts +++ b/src/tableMetadata.ts @@ -2,12 +2,6 @@ * CDB table metadata and constants */ -import { ChunkType, DataType, Magic } from "./types"; - -export const CHUNK_TYPE = ChunkType; -export const DATA_TYPE = DataType; -export const MAGIC = Magic; - /** * TABLE_FLAGS values by table ID (extracted from PCM save files) * Meaning is unknown but must be preserved for round-trip conversion diff --git a/src/writer.ts b/src/writer.ts index 4b14f34..ac645b9 100644 --- a/src/writer.ts +++ b/src/writer.ts @@ -3,8 +3,7 @@ * Handles writing of chunk hierarchy and data type encoding */ -import type { ChunkType, DataType } from "./types"; -import { CHUNK_TYPE, DATA_TYPE, MAGIC } from "./tableMetadata"; +import { ChunkType, DataType, Magic } from "./types"; interface ChunkInfo { type: ChunkType; @@ -66,7 +65,7 @@ export class CDBWriter { ): void { const chunkStart = this.pos; - this.write32(MAGIC.CHUNK_BEGIN); + this.write32(Magic.CHUNK_BEGIN); this.write32(0); // placeholder for chunk size this.write32(chunkType); this.write32(0); // flags @@ -82,7 +81,7 @@ export class CDBWriter { } this.writePadding(); - this.write32(MAGIC.CHUNK_SEPARATOR); + this.write32(Magic.CHUNK_SEPARATOR); this.chunkStack.push({ type: chunkType, startPos: chunkStart }); } @@ -94,7 +93,7 @@ export class CDBWriter { } this.writePadding(); - this.write32(MAGIC.CHUNK_END); + this.write32(Magic.CHUNK_END); chunk.size = this.pos - chunk.startPos; this.closedChunks.push(chunk); @@ -120,16 +119,16 @@ export class CDBWriter { const buffer = new ArrayBuffer(4); const view = new DataView(buffer); - this.writeChunkOpen(CHUNK_TYPE.COLUMN_VALUES); + this.writeChunkOpen(ChunkType.COLUMN_VALUES); switch (dataType) { - case DATA_TYPE.INTEGER: + case DataType.INTEGER: for (const value of values as number[]) { this.write32(value); } break; - case DATA_TYPE.BOOLEAN: + case DataType.BOOLEAN: { const numBytes = Math.ceil(values.length / 8); for (let byteIdx = 0; byteIdx < numBytes; byteIdx++) { @@ -146,7 +145,7 @@ export class CDBWriter { } break; - case DATA_TYPE.INTEGER_BYTE: + case DataType.INTEGER_BYTE: { (values as number[]).forEach((value) => { this.ensureCapacity(1); @@ -156,7 +155,7 @@ export class CDBWriter { } break; - case DATA_TYPE.INTEGER_SHORT: + case DataType.INTEGER_SHORT: { (values as number[]).forEach((value) => { this.ensureCapacity(2); @@ -166,7 +165,7 @@ export class CDBWriter { } break; - case DATA_TYPE.FLOAT: + case DataType.FLOAT: { (values as number[]).forEach((value) => { view.setFloat32(0, parseFloat(String(value)), true); @@ -175,12 +174,12 @@ export class CDBWriter { } break; - case DATA_TYPE.STRING: + case DataType.STRING: this.writeStringData(values as string[]); break; - case DATA_TYPE.INTEGER_LIST: - case DATA_TYPE.FLOAT_LIST: + case DataType.INTEGER_LIST: + case DataType.FLOAT_LIST: this.writeListData(dataType, values as string[]); break; } @@ -205,7 +204,7 @@ export class CDBWriter { if (stringData.length > 0) { this.writeChunkClose(); - this.writeChunkOpen(CHUNK_TYPE.COLUMN_BLOB_DATA); + this.writeChunkOpen(ChunkType.COLUMN_BLOB_DATA); this.write32(stringData.length); this.writeBytes(new Uint8Array(stringData)); } @@ -226,7 +225,7 @@ export class CDBWriter { counts.push(elements.length); elements.forEach((elem) => { - if (dataType === DATA_TYPE.INTEGER_LIST) { + if (dataType === DataType.INTEGER_LIST) { listData.push(parseInt(elem, 10)); } else { // FLOAT_LIST - store as uint32 bits @@ -243,7 +242,7 @@ export class CDBWriter { if (listData.length > 0) { this.writeChunkClose(); - this.writeChunkOpen(CHUNK_TYPE.COLUMN_BLOB_DATA); + this.writeChunkOpen(ChunkType.COLUMN_BLOB_DATA); this.write32(listData.length * 4); for (const value of listData) { this.write32(value); diff --git a/test/compression.test.ts b/test/compression.test.ts index b336149..5a9d780 100644 --- a/test/compression.test.ts +++ b/test/compression.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import { compressCdb, decompressCdb } from "../src/compression"; import { CDBReader } from "../src/reader"; -import { MAGIC } from "../src/tableMetadata"; +import { Magic } from "../src/types"; import { CDBWriter } from "../src/writer"; // Uncompressed passthrough test data @@ -47,7 +47,7 @@ describe("compression", () => { const compressed = compressCdb(cdbPayload.buffer); const view = new DataView(compressed); - expect(view.getUint32(0, true)).toBe(MAGIC.COMPRESSION_MAGIC); + expect(view.getUint32(0, true)).toBe(Magic.COMPRESSION_MAGIC); const decompressed = decompressCdb(compressed); const originalBytes = new Uint8Array(cdbPayload.buffer); @@ -69,7 +69,7 @@ describe("compression", () => { const compressed = compressCdb(cdbPayload.buffer); const view = new DataView(compressed); - expect(view.getUint32(0, true)).toBe(MAGIC.COMPRESSION_MAGIC); + expect(view.getUint32(0, true)).toBe(Magic.COMPRESSION_MAGIC); const uncompressedSize = view.getUint32(4, true); expect(uncompressedSize).toBe(cdbPayload.length); @@ -83,7 +83,7 @@ describe("compression", () => { const malformed = new Uint8Array(8); const view = new DataView(malformed.buffer); - view.setUint32(0, MAGIC.COMPRESSION_MAGIC, true); + view.setUint32(0, Magic.COMPRESSION_MAGIC, true); expect(() => decompressCdb(malformed)).toThrowError( "Malformed compressed CDB: incomplete compression header", @@ -94,7 +94,7 @@ describe("compression", () => { const malformed = new Uint8Array(15); const view = new DataView(malformed.buffer); - view.setUint32(0, MAGIC.COMPRESSION_MAGIC, true); + view.setUint32(0, Magic.COMPRESSION_MAGIC, true); view.setUint32(4, cdbPayload.length, true); view.setUint32(8, 8, true); @@ -107,7 +107,7 @@ describe("compression", () => { const malformed = new Uint8Array(16); const view = new DataView(malformed.buffer); - view.setUint32(0, MAGIC.COMPRESSION_MAGIC, true); + view.setUint32(0, Magic.COMPRESSION_MAGIC, true); view.setUint32(4, cdbPayload.length, true); view.setUint32(8, 4, true); malformed.set([0xde, 0xad, 0xbe, 0xef], 12); diff --git a/test/reader.test.ts b/test/reader.test.ts index 9e1322e..0a3e421 100644 --- a/test/reader.test.ts +++ b/test/reader.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; import { CDBReader } from "../src/reader"; -import { CHUNK_TYPE, DATA_TYPE, MAGIC } from "../src/tableMetadata"; +import { ChunkType, DataType, Magic } from "../src/types"; import { CDBWriter } from "../src/writer"; function createChunkBuffer(overrides?: { @@ -10,13 +10,13 @@ function createChunkBuffer(overrides?: { const buffer = new ArrayBuffer(28); const view = new DataView(buffer); - view.setUint32(0, overrides?.chunkBegin ?? MAGIC.CHUNK_BEGIN, true); + view.setUint32(0, overrides?.chunkBegin ?? Magic.CHUNK_BEGIN, true); view.setUint32(4, 28, true); - view.setUint32(8, CHUNK_TYPE.WRAPPER, true); + view.setUint32(8, ChunkType.WRAPPER, true); view.setUint32(12, 0, true); view.setUint32(16, 0, true); - view.setUint32(20, overrides?.chunkSeparator ?? MAGIC.CHUNK_SEPARATOR, true); - view.setUint32(24, MAGIC.CHUNK_END, true); + view.setUint32(20, overrides?.chunkSeparator ?? Magic.CHUNK_SEPARATOR, true); + view.setUint32(24, Magic.CHUNK_END, true); return new Uint8Array(buffer); } @@ -24,35 +24,35 @@ function createChunkBuffer(overrides?: { function createWrapperWithMissingColumnDescription(): Uint8Array { const writer = new CDBWriter(); - writer.writeChunkOpen(CHUNK_TYPE.WRAPPER); - writer.writeChunkOpen(CHUNK_TYPE.DATABASE_TABLES); - writer.write32(MAGIC.ARRAY_BEGIN); + writer.writeChunkOpen(ChunkType.WRAPPER); + writer.writeChunkOpen(ChunkType.DATABASE_TABLES); + writer.write32(Magic.ARRAY_BEGIN); writer.write32(1); - writer.writeChunkOpen(CHUNK_TYPE.TABLE, "TestTable"); - writer.writeChunkOpen(CHUNK_TYPE.ROW_COUNT); + writer.writeChunkOpen(ChunkType.TABLE, "TestTable"); + writer.writeChunkOpen(ChunkType.ROW_COUNT); writer.write32(0); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.TABLE_ID); + writer.writeChunkOpen(ChunkType.TABLE_ID); writer.write32(1); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.TABLE_FLAGS); + writer.writeChunkOpen(ChunkType.TABLE_FLAGS); writer.write32(0); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_DEFINITIONS); - writer.write32(MAGIC.ARRAY_BEGIN); + writer.writeChunkOpen(ChunkType.COLUMN_DEFINITIONS); + writer.write32(Magic.ARRAY_BEGIN); writer.write32(1); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_DATA_TYPE); - writer.write32(DATA_TYPE.INTEGER); + writer.writeChunkOpen(ChunkType.COLUMN); + writer.writeChunkOpen(ChunkType.COLUMN_DATA_TYPE); + writer.write32(DataType.INTEGER); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_INDEX); + writer.writeChunkOpen(ChunkType.COLUMN_INDEX); writer.write32(0); writer.writeChunkClose(); writer.writeChunkClose(); - writer.write32(MAGIC.ARRAY_END); + writer.write32(Magic.ARRAY_END); writer.writeChunkClose(); writer.writeChunkClose(); - writer.write32(MAGIC.ARRAY_END); + writer.write32(Magic.ARRAY_END); writer.writeChunkClose(); writer.writeChunkClose(); @@ -64,13 +64,13 @@ function createUnknownChunkBuffer(payloadLength: number): Uint8Array { const buffer = new ArrayBuffer(chunkSize); const view = new DataView(buffer); - view.setUint32(0, MAGIC.CHUNK_BEGIN, true); + view.setUint32(0, Magic.CHUNK_BEGIN, true); view.setUint32(4, chunkSize, true); view.setUint32(8, 0x99, true); // unknown chunk type view.setUint32(12, 0, true); view.setUint32(16, 0, true); - view.setUint32(20, MAGIC.CHUNK_SEPARATOR, true); - view.setUint32(24 + payloadLength, MAGIC.CHUNK_END, true); + view.setUint32(20, Magic.CHUNK_SEPARATOR, true); + view.setUint32(24 + payloadLength, Magic.CHUNK_END, true); return new Uint8Array(buffer); } @@ -78,36 +78,36 @@ function createUnknownChunkBuffer(payloadLength: number): Uint8Array { function createFloatListTable(rows: string[]): Uint8Array { const writer = new CDBWriter(); - writer.writeChunkOpen(CHUNK_TYPE.WRAPPER); - writer.writeChunkOpen(CHUNK_TYPE.DATABASE_TABLES); - writer.write32(MAGIC.ARRAY_BEGIN); + writer.writeChunkOpen(ChunkType.WRAPPER); + writer.writeChunkOpen(ChunkType.DATABASE_TABLES); + writer.write32(Magic.ARRAY_BEGIN); writer.write32(1); - writer.writeChunkOpen(CHUNK_TYPE.TABLE, "TestTable"); - writer.writeChunkOpen(CHUNK_TYPE.ROW_COUNT); + writer.writeChunkOpen(ChunkType.TABLE, "TestTable"); + writer.writeChunkOpen(ChunkType.ROW_COUNT); writer.write32(rows.length); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.TABLE_ID); + writer.writeChunkOpen(ChunkType.TABLE_ID); writer.write32(1); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.TABLE_FLAGS); + writer.writeChunkOpen(ChunkType.TABLE_FLAGS); writer.write32(0); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_DEFINITIONS); - writer.write32(MAGIC.ARRAY_BEGIN); + writer.writeChunkOpen(ChunkType.COLUMN_DEFINITIONS); + writer.write32(Magic.ARRAY_BEGIN); writer.write32(1); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN, "values"); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_DATA_TYPE); - writer.write32(DATA_TYPE.FLOAT_LIST); + writer.writeChunkOpen(ChunkType.COLUMN, "values"); + writer.writeChunkOpen(ChunkType.COLUMN_DATA_TYPE); + writer.write32(DataType.FLOAT_LIST); writer.writeChunkClose(); - writer.writeChunkOpen(CHUNK_TYPE.COLUMN_INDEX); + writer.writeChunkOpen(ChunkType.COLUMN_INDEX); writer.write32(0); writer.writeChunkClose(); - writer.writeColumnData(DATA_TYPE.FLOAT_LIST, rows); + writer.writeColumnData(DataType.FLOAT_LIST, rows); writer.writeChunkClose(); - writer.write32(MAGIC.ARRAY_END); + writer.write32(Magic.ARRAY_END); writer.writeChunkClose(); writer.writeChunkClose(); - writer.write32(MAGIC.ARRAY_END); + writer.write32(Magic.ARRAY_END); writer.writeChunkClose(); writer.writeChunkClose(); @@ -119,7 +119,7 @@ function readFloatListColumn(rows: string[]): unknown[] { const chunk = reader.readChunk(); const tables = ( chunk.children as Record - )[CHUNK_TYPE.DATABASE_TABLES]; + )[ChunkType.DATABASE_TABLES]; return tables[0].columns[0].data; } diff --git a/test/writer.test.ts b/test/writer.test.ts index a280441..50b4520 100644 --- a/test/writer.test.ts +++ b/test/writer.test.ts @@ -1,12 +1,12 @@ import { describe, expect, it } from "vitest"; -import { CHUNK_TYPE } from "../src/tableMetadata"; +import { ChunkType } from "../src/types"; import { CDBWriter } from "../src/writer"; describe("CDBWriter", () => { it("throws when getData is called with open chunks", () => { const writer = new CDBWriter(); - writer.writeChunkOpen(CHUNK_TYPE.WRAPPER); + writer.writeChunkOpen(ChunkType.WRAPPER); expect(() => writer.getData()).toThrowError( "Cannot get CDB data with 1 open chunk",