1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.CodePointBuffer = void 0;
|
8 | const assert = require("assert");
|
9 | const Character = require("./misc/Character");
|
10 |
|
11 |
|
12 |
|
13 | class 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 | }
|
44 | exports.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 ;
|
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 :
|
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 :
|
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 :
|
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 :
|
101 | this.appendArrayByte(utf16In);
|
102 | break;
|
103 | case 1 :
|
104 | this.appendArrayChar(utf16In);
|
105 | break;
|
106 | case 2 :
|
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 |
|
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 |
|
205 | outInt[outOffset] = this.prevHighSurrogate;
|
206 | outOffset++;
|
207 | }
|
208 | this.position = outOffset;
|
209 | }
|
210 | byteToCharBuffer(toAppend) {
|
211 |
|
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 ;
|
215 | this.buffer = newBuffer;
|
216 | }
|
217 | byteToIntBuffer(toAppend) {
|
218 |
|
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 ;
|
222 | this.buffer = newBuffer;
|
223 | }
|
224 | charToIntBuffer(toAppend) {
|
225 |
|
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 ;
|
229 | this.buffer = newBuffer;
|
230 | }
|
231 | }
|
232 | CodePointBuffer.Builder = Builder;
|
233 | })(CodePointBuffer = exports.CodePointBuffer || (exports.CodePointBuffer = {}));
|
234 |
|
\ | No newline at end of file |