molstar
Version:
A comprehensive macromolecular library.
257 lines • 10.4 kB
JavaScript
/**
* Copyright (c) 2017-2021 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>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TextEncoder = void 0;
var string_builder_1 = require("../../../../mol-util/string-builder");
var encoder_1 = require("../encoder");
var util_1 = require("./util");
var TextEncoder = /** @class */ (function () {
function TextEncoder() {
this.builder = string_builder_1.StringBuilder.create();
this.encoded = false;
this.dataBlockCreated = false;
this.filter = encoder_1.Category.DefaultFilter;
this.formatter = encoder_1.Category.DefaultFormatter;
this.isBinary = false;
this.binaryEncodingProvider = void 0;
}
TextEncoder.prototype.setFilter = function (filter) {
this.filter = filter || encoder_1.Category.DefaultFilter;
};
TextEncoder.prototype.isCategoryIncluded = function (name) {
return this.filter.includeCategory(name);
};
TextEncoder.prototype.setFormatter = function (formatter) {
this.formatter = formatter || encoder_1.Category.DefaultFormatter;
};
TextEncoder.prototype.startDataBlock = function (header) {
this.dataBlockCreated = true;
string_builder_1.StringBuilder.write(this.builder, "data_" + (header || '').replace(/[ \n\t]/g, '').toUpperCase() + "\n#\n");
};
TextEncoder.prototype.writeCategory = function (category, context, options) {
if (this.encoded) {
throw new Error('The writer contents have already been encoded, no more writing.');
}
if (!this.dataBlockCreated) {
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 = (0, util_1.getCategoryInstanceData)(category, context), instance = _a.instance, rowCount = _a.rowCount, source = _a.source;
if (!rowCount)
return;
if (rowCount === 1) {
writeCifSingleRecord(category, instance, source, this.builder, this.filter, this.formatter);
}
else {
writeCifLoop(category, instance, source, this.builder, this.filter, this.formatter);
}
};
TextEncoder.prototype.encode = function () {
this.encoded = true;
};
TextEncoder.prototype.writeTo = function (stream) {
var chunks = string_builder_1.StringBuilder.getChunks(this.builder);
for (var i = 0, _i = chunks.length; i < _i; i++) {
stream.writeString(chunks[i]);
}
};
TextEncoder.prototype.getSize = function () {
return string_builder_1.StringBuilder.getSize(this.builder);
};
TextEncoder.prototype.getData = function () {
return string_builder_1.StringBuilder.getString(this.builder);
};
return TextEncoder;
}());
exports.TextEncoder = TextEncoder;
function writeValue(builder, data, key, f, floatPrecision, index) {
var kind = f.valueKind;
var p = kind ? kind(key, data) : 0 /* Present */;
if (p !== 0 /* Present */) {
if (p === 1 /* NotPresent */)
writeNotPresent(builder);
else
writeUnknown(builder);
}
else {
var val = f.value(key, data, index);
var t = f.type;
if (t === 0 /* Str */) {
if (isMultiline(val)) {
writeMultiline(builder, val);
return true;
}
else {
return writeChecked(builder, val);
}
}
else if (t === 1 /* Int */) {
writeInteger(builder, val);
}
else {
writeFloat(builder, val, floatPrecision);
}
}
return false;
}
function getFloatPrecisions(categoryName, fields, formatter) {
var ret = [];
for (var _a = 0, fields_1 = fields; _a < fields_1.length; _a++) {
var f = fields_1[_a];
var format = formatter.getFormat(categoryName, f.name);
if (format && typeof format.digitCount !== 'undefined')
ret[ret.length] = f.type === 2 /* Float */ ? Math.pow(10, Math.max(0, Math.min(format.digitCount, 15))) : 0;
else
ret[ret.length] = f.type === 2 /* Float */ ? Math.pow(10, (0, util_1.getFieldDigitCount)(f)) : 0;
}
return ret;
}
function writeCifSingleRecord(category, instance, source, builder, filter, formatter) {
var fields = (0, util_1.getIncludedFields)(instance);
var src = source[0];
var data = src.data;
var width = fields.reduce(function (w, f) { return filter.includeField(category.name, f.name) ? Math.max(w, f.name.length) : 0; }, 0);
// this means no field from this category is included.
if (width === 0)
return;
width += category.name.length + 6;
var it = src.keys();
var key = it.move();
var precisions = getFloatPrecisions(category.name, instance.fields, formatter);
for (var _f = 0; _f < fields.length; _f++) {
var f = fields[_f];
if (!filter.includeField(category.name, f.name))
continue;
string_builder_1.StringBuilder.writePadRight(builder, "_" + category.name + "." + f.name, width);
var multiline = writeValue(builder, data, key, f, precisions[_f], 0);
if (!multiline)
string_builder_1.StringBuilder.newline(builder);
}
string_builder_1.StringBuilder.write(builder, '#\n');
}
function writeCifLoop(category, instance, source, builder, filter, formatter) {
var fieldSource = (0, util_1.getIncludedFields)(instance);
var fields = filter === encoder_1.Category.DefaultFilter ? fieldSource : fieldSource.filter(function (f) { return filter.includeField(category.name, f.name); });
var fieldCount = fields.length;
if (fieldCount === 0)
return;
var precisions = getFloatPrecisions(category.name, fields, formatter);
writeLine(builder, 'loop_');
for (var i = 0; i < fieldCount; i++) {
writeLine(builder, "_" + category.name + "." + fields[i].name);
}
var index = 0;
for (var _c = 0; _c < source.length; _c++) {
var src = source[_c];
var data = src.data;
if (src.rowCount === 0)
continue;
var it_1 = src.keys();
while (it_1.hasNext) {
var key = it_1.move();
var multiline = false;
for (var _f = 0; _f < fieldCount; _f++) {
multiline = writeValue(builder, data, key, fields[_f], precisions[_f], index);
}
if (!multiline)
string_builder_1.StringBuilder.newline(builder);
index++;
}
}
string_builder_1.StringBuilder.write(builder, '#\n');
}
function isMultiline(value) {
return typeof value === 'string' && value.indexOf('\n') >= 0;
}
function writeLine(builder, val) {
string_builder_1.StringBuilder.write(builder, val);
string_builder_1.StringBuilder.newline(builder);
}
function writeInteger(builder, val) {
string_builder_1.StringBuilder.writeInteger(builder, val);
string_builder_1.StringBuilder.whitespace1(builder);
}
function writeFloat(builder, val, precisionMultiplier) {
string_builder_1.StringBuilder.writeFloat(builder, val, precisionMultiplier);
string_builder_1.StringBuilder.whitespace1(builder);
}
function writeNotPresent(builder) {
string_builder_1.StringBuilder.writeSafe(builder, '. ');
}
function writeUnknown(builder) {
string_builder_1.StringBuilder.writeSafe(builder, '? ');
}
function writeChecked(builder, val) {
if (!val) {
string_builder_1.StringBuilder.writeSafe(builder, '. ');
return false;
}
var fst = val.charCodeAt(0);
var escape = false;
var escapeKind = 0; // 0 => ', 1 => "
var hasSingleQuote = false, hasDoubleQuote = false;
for (var i = 0, _l = val.length - 1; i <= _l; i++) {
var c = val.charCodeAt(i);
switch (c) {
case 9: // \t
escape = true;
break;
case 10: // \n
writeMultiline(builder, val);
return true;
case 32: // ' '
escape = true;
break;
case 34: // "
// no need to escape quote if it's the last char and the length is > 1
if (i && i === _l)
break;
if (hasSingleQuote) {
// the string already has a " => use multiline value
writeMultiline(builder, val);
return true;
}
hasDoubleQuote = true;
escape = true;
escapeKind = 0;
break;
case 39: // '
// no need to escape quote if it's the last char and the length is > 1
if (i && i === _l)
break;
if (hasDoubleQuote) {
writeMultiline(builder, val);
return true;
}
hasSingleQuote = true;
escape = true;
escapeKind = 1;
break;
}
}
if (!escape && (fst === 35 /* # */ || fst === 36 /* $ */ || fst === 59 /* ; */ || fst === 91 /* [ */ || fst === 93 /* ] */ || fst === 95 /* _ */)) {
escape = true;
}
if (escape) {
string_builder_1.StringBuilder.writeSafe(builder, escapeKind ? '"' : '\'');
string_builder_1.StringBuilder.writeSafe(builder, val);
string_builder_1.StringBuilder.writeSafe(builder, escapeKind ? '" ' : '\' ');
}
else {
string_builder_1.StringBuilder.writeSafe(builder, val);
string_builder_1.StringBuilder.writeSafe(builder, ' ');
}
return false;
}
function writeMultiline(builder, val) {
string_builder_1.StringBuilder.writeSafe(builder, '\n;' + val);
string_builder_1.StringBuilder.writeSafe(builder, '\n;\n');
}
//# sourceMappingURL=text.js.map
;