diff --git a/demo/node/rntuple_test.js b/demo/node/rntuple_test.js index 01993a23d..77d451d47 100644 --- a/demo/node/rntuple_test.js +++ b/demo/node/rntuple_test.js @@ -43,3 +43,19 @@ else { console.log(`OK: Field ${i}: ${field.fieldName} (${field.typeName})`); } } + +// Column Check + +if (!rntuple.builder?.columnDescriptors?.length) + console.error('FAILURE: No columns deserialized'); +else { + console.log(`OK: ${rntuple.builder.columnDescriptors.length} column(s) deserialized`); + for (let i = 0; i < rntuple.builder.columnDescriptors.length; ++i) { + const column = rntuple.builder.columnDescriptors[i]; + if (!column.fieldId) + console.error(`FAILURE: Column ${i} is missing fieldId`); + else + console.log(`OK: Column ${i} fieldId: ${column.fieldId} `); + } +} + diff --git a/modules/rntuple.mjs b/modules/rntuple.mjs index abf87a004..5492b0d2e 100644 --- a/modules/rntuple.mjs +++ b/modules/rntuple.mjs @@ -127,6 +127,9 @@ deserializeHeader(header_blob) { // List frame: list of field record frames this._readFieldDescriptors(reader); + + // List frame: list of column record frames + this._readColumnDescriptors(reader); } deserializeFooter(footer_blob) { @@ -219,6 +222,52 @@ fieldListIsList = fieldListSize < 0; this.fieldDescriptors = fieldDescriptors; } +_readColumnDescriptors(reader) { + const columnListSize = reader.readS64(), + columnListIsList = columnListSize < 0; + if (!columnListIsList) + throw new Error('Column list frame is not a list frame, which is required.'); + const columnListCount = reader.readU32(); // number of column entries + console.log('Column List Count:', columnListCount); + const columnDescriptors = []; + for (let i = 0; i < columnListCount; ++i) { + const columnRecordSize = reader.readS64(), + coltype = reader.readU16(), + bitsOnStorage = reader.readU16(), + fieldId = reader.readU32(), + flags = reader.readU16(), + representationIndex = reader.readU16(); + console.log(`Column Record Size: ${columnRecordSize}`); + let firstElementIndex = null, minValue = null, maxValue = null; + if (flags & 0x1) firstElementIndex = reader.readU64(); + if (flags & 0x2){ + minValue = reader.readF64(); + maxValue = reader.readF64(); + } + + + const column = { + coltype, + bitsOnStorage, + fieldId, + flags, + representationIndex, + firstElementIndex, + minValue, + maxValue + }; + column.isDeferred = function() { + return (this.flags & 0x01) !== 0; + }; + column.isSuppressed = function() { + return this.firstElementIndex !== null && this.firstElementIndex < 0; + }; + + columnDescriptors.push(column); + } + this.columnDescriptors = columnDescriptors; +} + } /** @summary Very preliminary function to read header/footer from RNTuple