| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import * as strings from '../../../base/common/strings.js';
- import * as platform from '../../../base/common/platform.js';
- import * as buffer from '../../../base/common/buffer.js';
- let _utf16LE_TextDecoder;
- function getUTF16LE_TextDecoder() {
- if (!_utf16LE_TextDecoder) {
- _utf16LE_TextDecoder = new TextDecoder('UTF-16LE');
- }
- return _utf16LE_TextDecoder;
- }
- let _utf16BE_TextDecoder;
- function getUTF16BE_TextDecoder() {
- if (!_utf16BE_TextDecoder) {
- _utf16BE_TextDecoder = new TextDecoder('UTF-16BE');
- }
- return _utf16BE_TextDecoder;
- }
- let _platformTextDecoder;
- export function getPlatformTextDecoder() {
- if (!_platformTextDecoder) {
- _platformTextDecoder = platform.isLittleEndian() ? getUTF16LE_TextDecoder() : getUTF16BE_TextDecoder();
- }
- return _platformTextDecoder;
- }
- export const hasTextDecoder = (typeof TextDecoder !== 'undefined');
- export let createStringBuilder;
- export let decodeUTF16LE;
- if (hasTextDecoder) {
- createStringBuilder = (capacity) => new StringBuilder(capacity);
- decodeUTF16LE = standardDecodeUTF16LE;
- }
- else {
- createStringBuilder = (capacity) => new CompatStringBuilder();
- decodeUTF16LE = compatDecodeUTF16LE;
- }
- function standardDecodeUTF16LE(source, offset, len) {
- const view = new Uint16Array(source.buffer, offset, len);
- if (len > 0 && (view[0] === 0xFEFF || view[0] === 0xFFFE)) {
- // UTF16 sometimes starts with a BOM https://de.wikipedia.org/wiki/Byte_Order_Mark
- // It looks like TextDecoder.decode will eat up a leading BOM (0xFEFF or 0xFFFE)
- // We don't want that behavior because we know the string is UTF16LE and the BOM should be maintained
- // So we use the manual decoder
- return compatDecodeUTF16LE(source, offset, len);
- }
- return getUTF16LE_TextDecoder().decode(view);
- }
- function compatDecodeUTF16LE(source, offset, len) {
- const result = [];
- let resultLen = 0;
- for (let i = 0; i < len; i++) {
- const charCode = buffer.readUInt16LE(source, offset);
- offset += 2;
- result[resultLen++] = String.fromCharCode(charCode);
- }
- return result.join('');
- }
- class StringBuilder {
- constructor(capacity) {
- this._capacity = capacity | 0;
- this._buffer = new Uint16Array(this._capacity);
- this._completedStrings = null;
- this._bufferLength = 0;
- }
- reset() {
- this._completedStrings = null;
- this._bufferLength = 0;
- }
- build() {
- if (this._completedStrings !== null) {
- this._flushBuffer();
- return this._completedStrings.join('');
- }
- return this._buildBuffer();
- }
- _buildBuffer() {
- if (this._bufferLength === 0) {
- return '';
- }
- const view = new Uint16Array(this._buffer.buffer, 0, this._bufferLength);
- return getPlatformTextDecoder().decode(view);
- }
- _flushBuffer() {
- const bufferString = this._buildBuffer();
- this._bufferLength = 0;
- if (this._completedStrings === null) {
- this._completedStrings = [bufferString];
- }
- else {
- this._completedStrings[this._completedStrings.length] = bufferString;
- }
- }
- write1(charCode) {
- const remainingSpace = this._capacity - this._bufferLength;
- if (remainingSpace <= 1) {
- if (remainingSpace === 0 || strings.isHighSurrogate(charCode)) {
- this._flushBuffer();
- }
- }
- this._buffer[this._bufferLength++] = charCode;
- }
- appendASCII(charCode) {
- if (this._bufferLength === this._capacity) {
- // buffer is full
- this._flushBuffer();
- }
- this._buffer[this._bufferLength++] = charCode;
- }
- appendASCIIString(str) {
- const strLen = str.length;
- if (this._bufferLength + strLen >= this._capacity) {
- // This string does not fit in the remaining buffer space
- this._flushBuffer();
- this._completedStrings[this._completedStrings.length] = str;
- return;
- }
- for (let i = 0; i < strLen; i++) {
- this._buffer[this._bufferLength++] = str.charCodeAt(i);
- }
- }
- }
- class CompatStringBuilder {
- constructor() {
- this._pieces = [];
- this._piecesLen = 0;
- }
- reset() {
- this._pieces = [];
- this._piecesLen = 0;
- }
- build() {
- return this._pieces.join('');
- }
- write1(charCode) {
- this._pieces[this._piecesLen++] = String.fromCharCode(charCode);
- }
- appendASCII(charCode) {
- this._pieces[this._piecesLen++] = String.fromCharCode(charCode);
- }
- appendASCIIString(str) {
- this._pieces[this._piecesLen++] = str;
- }
- }
|