UNPKG

9.44 kBJavaScriptView Raw
1"use strict";
2/*!
3 * Copyright 2016 The ANTLR Project. All rights reserved.
4 * Licensed under the BSD-3-Clause license. See LICENSE file in the project root for license information.
5 */
6Object.defineProperty(exports, "__esModule", { value: true });
7exports.CodePointBuffer = void 0;
8const assert = require("assert");
9const Character = require("./misc/Character");
10/**
11 * Wrapper for `Uint8Array` / `Uint16Array` / `Int32Array`.
12 */
13class CodePointBuffer {
14 constructor(buffer, size) {
15 this.buffer = buffer;
16 this._position = 0;
17 this._size = size;
18 }
19 static withArray(buffer) {
20 return new CodePointBuffer(buffer, buffer.length);
21 }
22 get position() {
23 return this._position;
24 }
25 set position(newPosition) {
26 if (newPosition < 0 || newPosition > this._size) {
27 throw new RangeError();
28 }
29 this._position = newPosition;
30 }
31 get remaining() {
32 return this._size - this.position;
33 }
34 get(offset) {
35 return this.buffer[offset];
36 }
37 array() {
38 return this.buffer.slice(0, this._size);
39 }
40 static builder(initialBufferSize) {
41 return new CodePointBuffer.Builder(initialBufferSize);
42 }
43}
44exports.CodePointBuffer = CodePointBuffer;
45(function (CodePointBuffer) {
46 let Type;
47 (function (Type) {
48 Type[Type["BYTE"] = 0] = "BYTE";
49 Type[Type["CHAR"] = 1] = "CHAR";
50 Type[Type["INT"] = 2] = "INT";
51 })(Type || (Type = {}));
52 class Builder {
53 constructor(initialBufferSize) {
54 this.type = 0 /* BYTE */;
55 this.buffer = new Uint8Array(initialBufferSize);
56 this.prevHighSurrogate = -1;
57 this.position = 0;
58 }
59 build() {
60 return new CodePointBuffer(this.buffer, this.position);
61 }
62 static roundUpToNextPowerOfTwo(i) {
63 let nextPowerOfTwo = 32 - Math.clz32(i - 1);
64 return Math.pow(2, nextPowerOfTwo);
65 }
66 ensureRemaining(remainingNeeded) {
67 switch (this.type) {
68 case 0 /* BYTE */:
69 if (this.buffer.length - this.position < remainingNeeded) {
70 let newCapacity = Builder.roundUpToNextPowerOfTwo(this.buffer.length + remainingNeeded);
71 let newBuffer = new Uint8Array(newCapacity);
72 newBuffer.set(this.buffer.subarray(0, this.position), 0);
73 this.buffer = newBuffer;
74 }
75 break;
76 case 1 /* CHAR */:
77 if (this.buffer.length - this.position < remainingNeeded) {
78 let newCapacity = Builder.roundUpToNextPowerOfTwo(this.buffer.length + remainingNeeded);
79 let newBuffer = new Uint16Array(newCapacity);
80 newBuffer.set(this.buffer.subarray(0, this.position), 0);
81 this.buffer = newBuffer;
82 }
83 break;
84 case 2 /* INT */:
85 if (this.buffer.length - this.position < remainingNeeded) {
86 let newCapacity = Builder.roundUpToNextPowerOfTwo(this.buffer.length + remainingNeeded);
87 let newBuffer = new Int32Array(newCapacity);
88 newBuffer.set(this.buffer.subarray(0, this.position), 0);
89 this.buffer = newBuffer;
90 }
91 break;
92 }
93 }
94 append(utf16In) {
95 this.ensureRemaining(utf16In.length);
96 this.appendArray(utf16In);
97 }
98 appendArray(utf16In) {
99 switch (this.type) {
100 case 0 /* BYTE */:
101 this.appendArrayByte(utf16In);
102 break;
103 case 1 /* CHAR */:
104 this.appendArrayChar(utf16In);
105 break;
106 case 2 /* INT */:
107 this.appendArrayInt(utf16In);
108 break;
109 }
110 }
111 appendArrayByte(utf16In) {
112 assert(this.prevHighSurrogate === -1);
113 let input = utf16In;
114 let inOffset = 0;
115 let inLimit = utf16In.length;
116 let outByte = this.buffer;
117 let outOffset = this.position;
118 while (inOffset < inLimit) {
119 let c = input[inOffset];
120 if (c <= 0xFF) {
121 outByte[outOffset] = c;
122 }
123 else {
124 utf16In = utf16In.subarray(inOffset, inLimit);
125 this.position = outOffset;
126 if (!Character.isHighSurrogate(c)) {
127 this.byteToCharBuffer(utf16In.length);
128 this.appendArrayChar(utf16In);
129 return;
130 }
131 else {
132 this.byteToIntBuffer(utf16In.length);
133 this.appendArrayInt(utf16In);
134 return;
135 }
136 }
137 inOffset++;
138 outOffset++;
139 }
140 this.position = outOffset;
141 }
142 appendArrayChar(utf16In) {
143 assert(this.prevHighSurrogate === -1);
144 let input = utf16In;
145 let inOffset = 0;
146 let inLimit = utf16In.length;
147 let outChar = this.buffer;
148 let outOffset = this.position;
149 while (inOffset < inLimit) {
150 let c = input[inOffset];
151 if (!Character.isHighSurrogate(c)) {
152 outChar[outOffset] = c;
153 }
154 else {
155 utf16In = utf16In.subarray(inOffset, inLimit);
156 this.position = outOffset;
157 this.charToIntBuffer(utf16In.length);
158 this.appendArrayInt(utf16In);
159 return;
160 }
161 inOffset++;
162 outOffset++;
163 }
164 this.position = outOffset;
165 }
166 appendArrayInt(utf16In) {
167 let input = utf16In;
168 let inOffset = 0;
169 let inLimit = utf16In.length;
170 let outInt = this.buffer;
171 let outOffset = this.position;
172 while (inOffset < inLimit) {
173 let c = input[inOffset];
174 inOffset++;
175 if (this.prevHighSurrogate !== -1) {
176 if (Character.isLowSurrogate(c)) {
177 outInt[outOffset] = String.fromCharCode(this.prevHighSurrogate, c).codePointAt(0);
178 outOffset++;
179 this.prevHighSurrogate = -1;
180 }
181 else {
182 // Dangling high surrogate
183 outInt[outOffset] = this.prevHighSurrogate;
184 outOffset++;
185 if (Character.isHighSurrogate(c)) {
186 this.prevHighSurrogate = c;
187 }
188 else {
189 outInt[outOffset] = c;
190 outOffset++;
191 this.prevHighSurrogate = -1;
192 }
193 }
194 }
195 else if (Character.isHighSurrogate(c)) {
196 this.prevHighSurrogate = c;
197 }
198 else {
199 outInt[outOffset] = c;
200 outOffset++;
201 }
202 }
203 if (this.prevHighSurrogate !== -1) {
204 // Dangling high surrogate
205 outInt[outOffset] = this.prevHighSurrogate;
206 outOffset++;
207 }
208 this.position = outOffset;
209 }
210 byteToCharBuffer(toAppend) {
211 // CharBuffers hold twice as much per unit as ByteBuffers, so start with half the capacity.
212 let newBuffer = new Uint16Array(Math.max(this.position + toAppend, this.buffer.length >> 1));
213 newBuffer.set(this.buffer.subarray(0, this.position), 0);
214 this.type = 1 /* CHAR */;
215 this.buffer = newBuffer;
216 }
217 byteToIntBuffer(toAppend) {
218 // IntBuffers hold four times as much per unit as ByteBuffers, so start with one quarter the capacity.
219 let newBuffer = new Int32Array(Math.max(this.position + toAppend, this.buffer.length >> 2));
220 newBuffer.set(this.buffer.subarray(0, this.position), 0);
221 this.type = 2 /* INT */;
222 this.buffer = newBuffer;
223 }
224 charToIntBuffer(toAppend) {
225 // IntBuffers hold two times as much per unit as ByteBuffers, so start with one half the capacity.
226 let newBuffer = new Int32Array(Math.max(this.position + toAppend, this.buffer.length >> 1));
227 newBuffer.set(this.buffer.subarray(0, this.position), 0);
228 this.type = 2 /* INT */;
229 this.buffer = newBuffer;
230 }
231 }
232 CodePointBuffer.Builder = Builder;
233})(CodePointBuffer = exports.CodePointBuffer || (exports.CodePointBuffer = {}));
234//# sourceMappingURL=CodePointBuffer.js.map
\No newline at end of file