UNPKG

diffusion

Version:

Diffusion JavaScript client

134 lines (133 loc) 5.08 kB
"use strict"; /** * @module diffusion.datatypes.RecordV2 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.parse = void 0; var recordv2_utils_1 = require("./../../data/record/recordv2-utils"); var uint8array_1 = require("./../../util/uint8array"); /** * Parse a buffer of Record V2 data and split it into records and fields * * @param bytes the buffer to parse * @param offset the starting position in the buffer * @param length the number of bytes to convert * @return an array of records, each containing an array of fields */ function parse(bytes, offset, length) { if (offset === void 0) { offset = 0; } if (length === void 0) { length = bytes.length; } // empty bytes returns empty record list if (length === 0) { return []; } // record MU returns single empty record if (length === 1 && bytes[offset] === recordv2_utils_1.RECORD_MU) { return [[]]; } // process all records var records = []; var fields = []; var pos = offset; for (var i = offset; i < length; ++i) { if (bytes[i] === recordv2_utils_1.RECORD_DELIMITER) { processRecordDelimiter(bytes, records, pos, i, fields); pos = i + 1; } else if (bytes[i] === recordv2_utils_1.FIELD_DELIMITER) { addField(bytes, records, pos, i, fields); pos = i + 1; } } processEnd(bytes, records, pos, length, fields); return records; } exports.parse = parse; /** * Process a record delimiter * * @param bytes the buffer to parse * @param records a reference to the records that will be constructed. A * new record will be added to this array. * @param startPos the start position in the buffer of the last field * @param endPos the end position in the buffer of the last field * @param field a reference to the fields that are being constructed for * this record. A new field will be added to this array before * this array will be added to the records. */ function processRecordDelimiter(bytes, records, startPos, endPos, fields) { var written = false; // if we have a field add it to list if (startPos < endPos) { written = addField(bytes, records, startPos, endPos, fields); } else { // buf if we're not at the start of content && the last delimiter was for a field // it implies an empty field if (startPos > 0 && bytes[startPos - 1] === recordv2_utils_1.FIELD_DELIMITER) { fields.push(''); } } if (!written) { records.push(Array.from(fields)); } // clear fields array fields.length = 0; } /** * Process the end of the record data * * @param bytes the buffer to parse * @param records a reference to the records that will be constructed. A * new record will be added to this array. * @param startPos the start position in the buffer of the last field * @param endPos the end position in the buffer of the last field * @param field a reference to the fields that are being constructed for * this record. A new field will be added to this array before * this array will be added to the records. */ function processEnd(bytes, records, startPos, endPos, fields) { // if we have read something then add to fields if (endPos > startPos) { addField(bytes, records, startPos, endPos, fields); } else { // nothing at end so process possible final delimiter var endByte = bytes[endPos - 1]; if (endByte === recordv2_utils_1.RECORD_DELIMITER) { // a record delimiter at the end implies a final empty record records.push([]); } else if (endByte === recordv2_utils_1.FIELD_DELIMITER) { // a field delimiter implies an empty field fields.push(''); } } // if we have some fields add record. This is not the case if // the last thing read was a record delimiter or start of content if (fields.length) { records.push(Array.from(fields)); } } /** * Add a field to the array of fields * * @param bytes the buffer to parse * @param records a reference to the records that will be constructed. * @param startPos the start position in the buffer of the last field * @param endPos the end position in the buffer of the last field * @param field a reference to the fields that are being constructed for * this record. A new field will be added to this array. * @return `true` if the fields have been added to the records. */ function addField(bytes, records, startPos, endPos, fields) { var len = endPos - startPos; if (fields.length === 0 && len === 1 && bytes[startPos] === recordv2_utils_1.FIELD_MU) { records.push(['']); return true; } else { fields.push(uint8array_1.uint8toUtf8(bytes, startPos, endPos)); } return false; }