Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/extension-editing/src/jsonReconstruct.ts
3291 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
/**
7
* This class has a very specific purpose:
8
*
9
* It can return convert offset within a decoded JSON string to offset within the encoded JSON string.
10
*/
11
export class JsonStringScanner {
12
private resultChars = 0;
13
private pos = 0;
14
15
/**
16
*
17
* @param text the encoded JSON string
18
* @param pos must not include ", ie must be `stringJSONNode.offset + 1`
19
*/
20
constructor(private readonly text: string, initialPos: number /* offset within `text` */) {
21
this.pos = initialPos;
22
}
23
24
// note that we don't do bound checks here, because we know that the offset is within the string
25
getOffsetInEncoded(offsetDecoded: number) {
26
27
let start = this.pos;
28
29
while (true) {
30
if (this.resultChars > offsetDecoded) {
31
return start;
32
}
33
34
const ch = this.text.charCodeAt(this.pos);
35
36
if (ch === CharacterCodes.backslash) {
37
start = this.pos;
38
this.pos++;
39
40
const ch2 = this.text.charCodeAt(this.pos++);
41
switch (ch2) {
42
case CharacterCodes.doubleQuote:
43
case CharacterCodes.backslash:
44
case CharacterCodes.slash:
45
case CharacterCodes.b:
46
case CharacterCodes.f:
47
case CharacterCodes.n:
48
case CharacterCodes.r:
49
case CharacterCodes.t:
50
this.resultChars += 1;
51
break;
52
case CharacterCodes.u: {
53
const ch3 = this.scanHexDigits(4, true);
54
if (ch3 >= 0) {
55
this.resultChars += String.fromCharCode(ch3).length;
56
}
57
break;
58
}
59
}
60
continue;
61
}
62
start = this.pos;
63
this.pos++;
64
this.resultChars++;
65
}
66
}
67
68
scanHexDigits(count: number, exact?: boolean): number {
69
let digits = 0;
70
let value = 0;
71
while (digits < count || !exact) {
72
const ch = this.text.charCodeAt(this.pos);
73
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
74
value = value * 16 + ch - CharacterCodes._0;
75
}
76
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
77
value = value * 16 + ch - CharacterCodes.A + 10;
78
}
79
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) {
80
value = value * 16 + ch - CharacterCodes.a + 10;
81
}
82
else {
83
break;
84
}
85
this.pos++;
86
digits++;
87
}
88
if (digits < count) {
89
value = -1;
90
}
91
return value;
92
}
93
}
94
95
96
const enum CharacterCodes {
97
lineFeed = 0x0A, // \n
98
carriageReturn = 0x0D, // \r
99
100
space = 0x0020, // " "
101
102
_0 = 0x30,
103
_1 = 0x31,
104
_2 = 0x32,
105
_3 = 0x33,
106
_4 = 0x34,
107
_5 = 0x35,
108
_6 = 0x36,
109
_7 = 0x37,
110
_8 = 0x38,
111
_9 = 0x39,
112
113
a = 0x61,
114
b = 0x62,
115
c = 0x63,
116
d = 0x64,
117
e = 0x65,
118
f = 0x66,
119
g = 0x67,
120
h = 0x68,
121
i = 0x69,
122
j = 0x6A,
123
k = 0x6B,
124
l = 0x6C,
125
m = 0x6D,
126
n = 0x6E,
127
o = 0x6F,
128
p = 0x70,
129
q = 0x71,
130
r = 0x72,
131
s = 0x73,
132
t = 0x74,
133
u = 0x75,
134
v = 0x76,
135
w = 0x77,
136
x = 0x78,
137
y = 0x79,
138
z = 0x7A,
139
140
A = 0x41,
141
B = 0x42,
142
C = 0x43,
143
D = 0x44,
144
E = 0x45,
145
F = 0x46,
146
G = 0x47,
147
H = 0x48,
148
I = 0x49,
149
J = 0x4A,
150
K = 0x4B,
151
L = 0x4C,
152
M = 0x4D,
153
N = 0x4E,
154
O = 0x4F,
155
P = 0x50,
156
Q = 0x51,
157
R = 0x52,
158
S = 0x53,
159
T = 0x54,
160
U = 0x55,
161
V = 0x56,
162
W = 0x57,
163
X = 0x58,
164
Y = 0x59,
165
Z = 0x5a,
166
167
asterisk = 0x2A, // *
168
backslash = 0x5C, // \
169
closeBrace = 0x7D, // }
170
closeBracket = 0x5D, // ]
171
colon = 0x3A, // :
172
comma = 0x2C, // ,
173
dot = 0x2E, // .
174
doubleQuote = 0x22, // "
175
minus = 0x2D, // -
176
openBrace = 0x7B, // {
177
openBracket = 0x5B, // [
178
plus = 0x2B, // +
179
slash = 0x2F, // /
180
181
formFeed = 0x0C, // \f
182
tab = 0x09, // \t
183
}
184
185