read-gedcom
Version:
Gedcom file reader
114 lines • 5.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeUtfBOM = exports.decodeUtf16le = exports.decodeUtf16be = exports.decodeUtf8 = exports.decodeUtf = exports.DECODE_UTF16_LE = exports.DECODE_UTF16_BE = exports.DECODE_UTF8 = exports.BOM_UTF32_LE = exports.BOM_UTF32_BE = exports.BOM_UTF16_LE = exports.BOM_UTF16_BE = exports.BOM_UTF8 = void 0;
const error_1 = require("../error");
const common_1 = require("./common");
exports.BOM_UTF8 = [0xef, 0xbb, 0xbf];
exports.BOM_UTF16_BE = [0xfe, 0xff];
exports.BOM_UTF16_LE = exports.BOM_UTF16_BE.slice().reverse();
// These are not part of the specification
exports.BOM_UTF32_BE = [0x00, 0x00, 0xfe, 0xff];
exports.BOM_UTF32_LE = exports.BOM_UTF32_BE.slice().reverse();
exports.DECODE_UTF8 = 'utf-8';
exports.DECODE_UTF16_BE = 'utf-16be';
exports.DECODE_UTF16_LE = 'utf-16le';
const decodeUtf = (buffer, progressCallback) => {
const { output } = (0, exports.decodeUtfBOM)(buffer, progressCallback);
return output;
};
exports.decodeUtf = decodeUtf;
const decodeUtf8 = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
let outputView = '';
const byteBuffer = new Uint8Array(buffer);
let nIdx = 0;
for (let nPart, nLen = byteBuffer.length; nIdx < nLen; nIdx++) {
nPart = byteBuffer[nIdx];
outputView += String.fromCharCode(nPart > 251 && nPart < 254 && nIdx + 5 < nLen /* six bytes */
/* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */
? (nPart - 252) * 1073741824 + (byteBuffer[++nIdx] - 128 << 24) + (byteBuffer[++nIdx] - 128 << 18) + (byteBuffer[++nIdx] - 128 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 247 && nPart < 252 && nIdx + 4 < nLen /* five bytes */
? (nPart - 248 << 24) + (byteBuffer[++nIdx] - 128 << 18) + (byteBuffer[++nIdx] - 128 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 239 && nPart < 248 && nIdx + 3 < nLen /* four bytes */
? (nPart - 240 << 18) + (byteBuffer[++nIdx] - 128 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 223 && nPart < 240 && nIdx + 2 < nLen /* three bytes */
? (nPart - 224 << 12) + (byteBuffer[++nIdx] - 128 << 6) + byteBuffer[++nIdx] - 128
: nPart > 191 && nPart < 224 && nIdx + 1 < nLen /* two bytes */
? (nPart - 192 << 6) + byteBuffer[++nIdx] - 128
: /* nPart < 127 ? */ /* one byte */ nPart);
if (progressCallback && nIdx % common_1.BYTES_INTERVAL === 0) {
progressCallback(nIdx);
}
}
if (progressCallback) {
progressCallback(nIdx);
}
return outputView;
};
exports.decodeUtf8 = decodeUtf8;
const decodeUtf16 = (buffer, isBe, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
let outputView = '';
const byteBuffer = new Uint8Array(buffer);
for (let i = 0; i < byteBuffer.length; i += 2) {
const a = byteBuffer[i], b = byteBuffer[i + 1];
const code = isBe ? a * 16 + b : b * 16 + a;
outputView += String.fromCharCode(code);
if (progressCallback && ((i + 1) / 2) % common_1.BYTES_INTERVAL === 0) {
progressCallback(i);
}
}
return outputView;
};
const decodeUtf16be = (buffer, progressCallback) => decodeUtf16(buffer, true, progressCallback);
exports.decodeUtf16be = decodeUtf16be;
const decodeUtf16le = (buffer, progressCallback) => decodeUtf16(buffer, false, progressCallback);
exports.decodeUtf16le = decodeUtf16le;
const decodeUtfBOM = (buffer, progressCallback) => {
if (progressCallback) {
progressCallback(0);
}
const byteBuffer = new Uint8Array(buffer);
const startsWith = (bom) => {
if (byteBuffer.length < bom.length) {
return false;
}
for (let i = 0; i < bom.length; i++) {
if (byteBuffer[i] !== bom[i]) {
return false;
}
}
return true;
};
const boms = [[exports.DECODE_UTF8, exports.BOM_UTF8], [exports.DECODE_UTF16_BE, exports.BOM_UTF16_BE], [exports.DECODE_UTF16_LE, exports.BOM_UTF16_LE]];
const optional = boms.map(([charset, bom]) => ({ charset, bom })).find(({ bom }) => startsWith(bom));
if ([exports.BOM_UTF32_BE, exports.BOM_UTF32_LE].some(bom => startsWith(bom))) {
throw new error_1.ErrorUnsupportedCharset(`Unsupported charset detected from BOM: 'utf-32'`, 'utf-32');
}
const bomCharset = optional !== undefined ? optional.charset : null;
const byteBufferWithoutBOM = optional !== undefined ? byteBuffer.slice(optional.bom.length) : byteBuffer;
const charset = bomCharset !== null ? bomCharset : exports.DECODE_UTF8; // No BOM = defaults to UTF-8
let output;
if (charset === exports.DECODE_UTF8) {
output = (0, exports.decodeUtf8)(byteBufferWithoutBOM);
}
else if (charset === exports.DECODE_UTF16_BE) {
output = (0, exports.decodeUtf16be)(byteBufferWithoutBOM);
}
else if (charset === exports.DECODE_UTF16_LE) {
output = (0, exports.decodeUtf16le)(byteBufferWithoutBOM);
}
else {
throw new Error();
}
if (progressCallback) {
progressCallback(byteBuffer.length);
}
return { output, bomCharset };
};
exports.decodeUtfBOM = decodeUtfBOM;
//# sourceMappingURL=utf.js.map