UNPKG

molstar

Version:

A comprehensive macromolecular library.

181 lines 6.97 kB
/** * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info. * * Adapted from CIFTools.js (https://github.com/dsehnal/CIFTools.js) * * @author David Sehnal <david.sehnal@gmail.com> */ import { encodeMsgPack } from '../../../common/msgpack/encode'; import { ArrayEncoder, ArrayEncoding as E, VERSION } from '../../../common/binary-cif'; import { Category } from '../encoder'; import { getIncludedFields, getCategoryInstanceData } from './util'; import { classifyIntArray, classifyFloatArray } from '../../../common/binary-cif/classifier'; var BinaryEncoder = /** @class */ (function () { function BinaryEncoder(encoder, encodingProvider, autoClassify) { this.autoClassify = autoClassify; this.dataBlocks = []; this.filter = Category.DefaultFilter; this.formatter = Category.DefaultFormatter; this.isBinary = true; this.binaryEncodingProvider = void 0; this.binaryEncodingProvider = encodingProvider; this.data = { encoder: encoder, version: VERSION, dataBlocks: this.dataBlocks }; } BinaryEncoder.prototype.setFilter = function (filter) { this.filter = filter || Category.DefaultFilter; }; BinaryEncoder.prototype.isCategoryIncluded = function (name) { return this.filter.includeCategory(name); }; BinaryEncoder.prototype.setFormatter = function (formatter) { this.formatter = formatter || Category.DefaultFormatter; }; BinaryEncoder.prototype.startDataBlock = function (header) { this.dataBlocks.push({ header: (header || '').replace(/[ \n\t]/g, '').toUpperCase(), categories: [] }); }; BinaryEncoder.prototype.writeCategory = function (category, context, options) { if (!this.data) { throw new Error('The writer contents have already been encoded, no more writing.'); } if (!this.dataBlocks.length) { throw new Error('No data block created.'); } if (!(options === null || options === void 0 ? void 0 : options.ignoreFilter) && !this.filter.includeCategory(category.name)) return; var _a = getCategoryInstanceData(category, context), instance = _a.instance, rowCount = _a.rowCount, source = _a.source; if (!rowCount) return; var cat = { name: '_' + category.name, columns: [], rowCount: rowCount }; var fields = getIncludedFields(instance); for (var _i = 0, fields_1 = fields; _i < fields_1.length; _i++) { var f = fields_1[_i]; if (!this.filter.includeField(category.name, f.name)) continue; var format = this.formatter.getFormat(category.name, f.name); cat.columns.push(encodeField(category.name, f, source, rowCount, format, this.binaryEncodingProvider, this.autoClassify)); } // no columns included. if (!cat.columns.length) return; this.dataBlocks[this.dataBlocks.length - 1].categories.push(cat); }; BinaryEncoder.prototype.encode = function () { if (this.encodedData) return; this.encodedData = encodeMsgPack(this.data); this.data = null; this.dataBlocks = null; }; BinaryEncoder.prototype.writeTo = function (writer) { writer.writeBinary(this.encodedData); }; BinaryEncoder.prototype.getData = function () { this.encode(); return this.encodedData; }; BinaryEncoder.prototype.getSize = function () { return this.encodedData.length; }; return BinaryEncoder; }()); export { BinaryEncoder }; function getArrayCtor(field, format) { if (format && format.typedArray) return format.typedArray; if (field.defaultFormat && field.defaultFormat.typedArray) return field.defaultFormat.typedArray; if (field.type === 0 /* Str */) return Array; if (field.type === 1 /* Int */) return Int32Array; return Float64Array; } function getDefaultEncoder(type) { if (type === 0 /* Str */) return ArrayEncoder.by(E.stringArray); return ArrayEncoder.by(E.byteArray); } function tryGetEncoder(categoryName, field, format, provider) { if (format && format.encoder) { return format.encoder; } else if (field.defaultFormat && field.defaultFormat.encoder) { return field.defaultFormat.encoder; } else if (provider) { return provider.get(categoryName, field.name); } else { return void 0; } } function classify(type, data) { if (type === 0 /* Str */) return ArrayEncoder.by(E.stringArray); if (type === 1 /* Int */) return classifyIntArray(data); return classifyFloatArray(data); } function encodeField(categoryName, field, data, totalCount, format, encoderProvider, autoClassify) { var _a = getFieldData(field, getArrayCtor(field, format), totalCount, data), array = _a.array, allPresent = _a.allPresent, mask = _a.mask; var encoder = tryGetEncoder(categoryName, field, format, encoderProvider); if (!encoder) { if (autoClassify) encoder = classify(field.type, array); else encoder = getDefaultEncoder(field.type); } var encoded = encoder.encode(array); var maskData = void 0; if (!allPresent) { var maskRLE = ArrayEncoder.by(E.runLength).and(E.byteArray).encode(mask); if (maskRLE.data.length < mask.length) { maskData = maskRLE; } else { maskData = ArrayEncoder.by(E.byteArray).encode(mask); } } return { name: field.name, data: encoded, mask: maskData }; } function getFieldData(field, arrayCtor, totalCount, data) { var isStr = field.type === 0 /* Str */; var array = new arrayCtor(totalCount); var mask = new Uint8Array(totalCount); var valueKind = field.valueKind; var getter = field.value; var allPresent = true; var offset = 0; for (var _d = 0; _d < data.length; _d++) { var d = data[_d].data; var keys = data[_d].keys(); while (keys.hasNext) { var key = keys.move(); var p = valueKind ? valueKind(key, d) : 0 /* Present */; if (p !== 0 /* Present */) { mask[offset] = p; if (isStr) array[offset] = ''; allPresent = false; } else { mask[offset] = 0 /* Present */; array[offset] = getter(key, d, offset); } offset++; } } return { array: array, allPresent: allPresent, mask: mask }; } //# sourceMappingURL=binary.js.map