molstar
Version:
A comprehensive macromolecular library.
163 lines (162 loc) • 5.51 kB
JavaScript
/**
* Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*
* based in part on https://github.com/dsehnal/CIFTools.js
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNumberType = exports.parseFloat = exports.parseFloatSkipLeadingWhitespace = exports.parseInt = exports.parseIntSkipLeadingWhitespace = void 0;
/**
* Efficient integer and float parsers.
*
* For the purposes of parsing numbers from the mmCIF data representations,
* up to 4 times faster than JS parseInt/parseFloat.
*/
function parseIntSkipLeadingWhitespace(str, start, end) {
while (start < end && str.charCodeAt(start) === 32)
start++;
return parseInt(str, start, end);
}
exports.parseIntSkipLeadingWhitespace = parseIntSkipLeadingWhitespace;
function parseInt(str, start, end) {
var _start = start, ret = 0, neg = 1;
if (str.charCodeAt(_start) === 45 /* - */) {
neg = -1;
++_start;
}
else if (str.charCodeAt(_start) === 43 /* + */) {
++_start;
}
for (; _start < end; _start++) {
var c = str.charCodeAt(_start) - 48;
if (c > 9 || c < 0)
return (neg * ret) | 0;
else
ret = (10 * ret + c) | 0;
}
return neg * ret;
}
exports.parseInt = parseInt;
function parseScientific(main, str, start, end) {
// handle + in '1e+1' separately.
if (str.charCodeAt(start) === 43 /* + */)
start++;
return main * Math.pow(10.0, parseInt(str, start, end));
}
function parseFloatSkipLeadingWhitespace(str, start, end) {
while (start < end && str.charCodeAt(start) === 32)
start++;
return parseFloat(str, start, end);
}
exports.parseFloatSkipLeadingWhitespace = parseFloatSkipLeadingWhitespace;
function parseFloat(str, start, end) {
var _start = start, neg = 1.0, ret = 0.0, point = 0.0, div = 1.0;
if (str.charCodeAt(_start) === 45 /* - */) {
neg = -1;
++_start;
}
else if (str.charCodeAt(_start) === 43 /* + */) {
++_start;
}
while (_start < end) {
var c = str.charCodeAt(_start) - 48;
if (c >= 0 && c < 10) {
ret = ret * 10 + c;
++_start;
}
else if (c === -2) { // .
++_start;
while (_start < end) {
c = str.charCodeAt(_start) - 48;
if (c >= 0 && c < 10) {
point = 10.0 * point + c;
div = 10.0 * div;
++_start;
}
else if (c === 53 || c === 21) { // 'e'/'E'
return parseScientific(neg * (ret + point / div), str, _start + 1, end);
}
else {
return neg * (ret + point / div);
}
}
return neg * (ret + point / div);
}
else if (c === 53 || c === 21) { // 'e'/'E'
return parseScientific(neg * ret, str, _start + 1, end);
}
else {
break;
}
}
return neg * ret;
}
exports.parseFloat = parseFloat;
function isInt(str, start, end) {
if (str.charCodeAt(start) === 45 /* - */) {
start++;
}
for (; start < end; start++) {
var c = str.charCodeAt(start) - 48;
if (c > 9 || c < 0)
return false;
}
return true;
}
// TODO: check for "scientific integers?"
function getNumberTypeScientific(str, start, end) {
// handle + in '1e+1' separately.
if (str.charCodeAt(start) === 43 /* + */)
start++;
return isInt(str, start, end) ? 2 /* NumberType.Scientific */ : 3 /* NumberType.NaN */;
}
/** The whole range must match, otherwise returns NaN */
function getNumberType(str) {
var start = 0;
var end = str.length;
if (str.charCodeAt(start) === 45) { // -
++start;
}
// string is . or -.
if (str.charCodeAt(start) === 46 && end - start === 1) {
return 3 /* NumberType.NaN */;
}
while (start < end) {
var c = str.charCodeAt(start) - 48;
if (c >= 0 && c < 10) {
++start;
}
else if (c === -2) { // .
++start;
var hasDigit = false;
while (start < end) {
c = str.charCodeAt(start) - 48;
if (c >= 0 && c < 10) {
hasDigit = true;
++start;
}
else if (c === 53 || c === 21) { // 'e'/'E'
return getNumberTypeScientific(str, start + 1, end);
}
else {
return 3 /* NumberType.NaN */;
}
}
return hasDigit ? 1 /* NumberType.Float */ : 0 /* NumberType.Int */;
}
else if (c === 53 || c === 21) { // 'e'/'E'
if (start === 0 || start === 1 && str.charCodeAt(0) === 45) {
return 3 /* NumberType.NaN */; // string starts with e/E or -e/-E
}
return getNumberTypeScientific(str, start + 1, end);
}
else {
break;
}
}
return start === end ? 0 /* NumberType.Int */ : 3 /* NumberType.NaN */;
}
exports.getNumberType = getNumberType;
;