Skip to content

Commit 153a1ba

Browse files
committed
Simplify encoding / decoding code
1 parent c0f2ad1 commit 153a1ba

1 file changed

Lines changed: 69 additions & 67 deletions

File tree

src/vs/workbench/api/common/shared/semanticTokensDto.ts

Lines changed: 69 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -25,113 +25,115 @@ const enum EncodedSemanticTokensType {
2525
Delta = 2
2626
}
2727

28-
function toUint8Array(arr: Uint32Array): Uint8Array {
29-
return new Uint8Array(arr.buffer, arr.byteOffset, arr.length * 4);
28+
function reverseEndianness(arr: Uint8Array): void {
29+
for (let i = 0, len = arr.length; i < len; i += 4) {
30+
// flip bytes 0<->3 and 1<->2
31+
const b0 = arr[i + 0];
32+
const b1 = arr[i + 1];
33+
const b2 = arr[i + 2];
34+
const b3 = arr[i + 3];
35+
arr[i + 0] = b3;
36+
arr[i + 1] = b2;
37+
arr[i + 2] = b1;
38+
arr[i + 3] = b0;
39+
}
40+
}
41+
42+
function toLittleEndianBuffer(arr: Uint32Array): VSBuffer {
43+
const uint8Arr = new Uint8Array(arr.buffer, arr.byteOffset, arr.length * 4);
44+
if (!platform.isLittleEndian()) {
45+
// the byte order must be changed
46+
reverseEndianness(uint8Arr);
47+
}
48+
return VSBuffer.wrap(uint8Arr);
3049
}
3150

32-
function toUint32Array(arr: Uint8Array, byteOffset: number, length: number): Uint32Array {
33-
return new Uint32Array(arr.buffer, arr.byteOffset + byteOffset, length);
51+
function fromLittleEndianBuffer(buff: VSBuffer): Uint32Array {
52+
const uint8Arr = buff.buffer;
53+
if (!platform.isLittleEndian()) {
54+
// the byte order must be changed
55+
reverseEndianness(uint8Arr);
56+
}
57+
return new Uint32Array(uint8Arr.buffer, uint8Arr.byteOffset);
3458
}
3559

3660
export function encodeSemanticTokensDto(semanticTokens: ISemanticTokensDto): VSBuffer {
37-
const isLittleEndian = platform.isLittleEndian();
38-
const buff = VSBuffer.alloc(encodeSemanticTokensDtoSize(semanticTokens));
61+
const dest = new Uint32Array(encodeSemanticTokensDtoSize(semanticTokens));
3962
let offset = 0;
40-
buff.writeUInt32LE(semanticTokens.id, offset); offset += 4;
63+
dest[offset++] = semanticTokens.id;
4164
if (semanticTokens.type === 'full') {
42-
buff.writeUInt32LE(EncodedSemanticTokensType.Full, offset); offset += 4;
43-
buff.writeUInt32LE(semanticTokens.data.length, offset); offset += 4;
44-
if (isLittleEndian) {
45-
const uint8Arr = toUint8Array(semanticTokens.data);
46-
buff.set(uint8Arr, offset); offset += uint8Arr.length;
47-
} else {
48-
for (const uint of semanticTokens.data) {
49-
buff.writeUInt32LE(uint, offset); offset += 4;
50-
}
51-
}
65+
dest[offset++] = EncodedSemanticTokensType.Full;
66+
dest[offset++] = semanticTokens.data.length;
67+
dest.set(semanticTokens.data, offset); offset += semanticTokens.data.length;
5268
} else {
53-
buff.writeUInt32LE(EncodedSemanticTokensType.Delta, offset); offset += 4;
54-
buff.writeUInt32LE(semanticTokens.deltas.length, offset); offset += 4;
69+
dest[offset++] = EncodedSemanticTokensType.Delta;
70+
dest[offset++] = semanticTokens.deltas.length;
5571
for (const delta of semanticTokens.deltas) {
56-
buff.writeUInt32LE(delta.start, offset); offset += 4;
57-
buff.writeUInt32LE(delta.deleteCount, offset); offset += 4;
72+
dest[offset++] = delta.start;
73+
dest[offset++] = delta.deleteCount;
5874
if (delta.data) {
59-
buff.writeUInt32LE(delta.data.length, offset); offset += 4;
60-
if (isLittleEndian) {
61-
const uint8Arr = toUint8Array(delta.data);
62-
buff.set(uint8Arr, offset); offset += uint8Arr.length;
63-
} else {
64-
for (const uint of delta.data) {
65-
buff.writeUInt32LE(uint, offset); offset += 4;
66-
}
67-
}
75+
dest[offset++] = delta.data.length;
76+
dest.set(delta.data, offset); offset += delta.data.length;
6877
} else {
69-
buff.writeUInt32LE(0, offset); offset += 4;
78+
dest[offset++] = 0;
7079
}
7180
}
7281
}
73-
return buff;
82+
return toLittleEndianBuffer(dest);
7483
}
7584

7685
function encodeSemanticTokensDtoSize(semanticTokens: ISemanticTokensDto): number {
7786
let result = 0;
78-
result += 4; // id
79-
result += 4; // type
87+
result += (
88+
+ 1 // id
89+
+ 1 // type
90+
);
8091
if (semanticTokens.type === 'full') {
81-
result += 4; // data length
82-
result += semanticTokens.data.byteLength;
92+
result += (
93+
+ 1 // data length
94+
+ semanticTokens.data.length
95+
);
8396
} else {
84-
result += 4; // delta count
97+
result += (
98+
+ 1 // delta count
99+
);
100+
result += (
101+
+ 1 // start
102+
+ 1 // deleteCount
103+
+ 1 // data length
104+
) * semanticTokens.deltas.length;
85105
for (const delta of semanticTokens.deltas) {
86-
result += 4; // start
87-
result += 4; // deleteCount
88-
result += 4; // data length
89106
if (delta.data) {
90-
result += delta.data.byteLength;
107+
result += delta.data.length;
91108
}
92109
}
93110
}
94111
return result;
95112
}
96113

97-
export function decodeSemanticTokensDto(buff: VSBuffer): ISemanticTokensDto {
98-
const isLittleEndian = platform.isLittleEndian();
114+
export function decodeSemanticTokensDto(_buff: VSBuffer): ISemanticTokensDto {
115+
const src = fromLittleEndianBuffer(_buff);
99116
let offset = 0;
100-
const id = buff.readUInt32LE(offset); offset += 4;
101-
const type: EncodedSemanticTokensType = buff.readUInt32LE(offset); offset += 4;
117+
const id = src[offset++];
118+
const type: EncodedSemanticTokensType = src[offset++];
102119
if (type === EncodedSemanticTokensType.Full) {
103-
const length = buff.readUInt32LE(offset); offset += 4;
104-
let data: Uint32Array;
105-
if (isLittleEndian) {
106-
data = toUint32Array(buff.buffer, offset, length); offset += 4 * length;
107-
} else {
108-
data = new Uint32Array(length);
109-
for (let j = 0; j < length; j++) {
110-
data[j] = buff.readUInt32LE(offset); offset += 4;
111-
}
112-
}
120+
const length = src[offset++];
121+
const data = src.subarray(offset, offset + length); offset += length;
113122
return {
114123
id: id,
115124
type: 'full',
116125
data: data
117126
};
118127
}
119-
const deltaCount = buff.readUInt32LE(offset); offset += 4;
128+
const deltaCount = src[offset++];
120129
let deltas: { start: number; deleteCount: number; data?: Uint32Array; }[] = [];
121130
for (let i = 0; i < deltaCount; i++) {
122-
const start = buff.readUInt32LE(offset); offset += 4;
123-
const deleteCount = buff.readUInt32LE(offset); offset += 4;
124-
const length = buff.readUInt32LE(offset); offset += 4;
131+
const start = src[offset++];
132+
const deleteCount = src[offset++];
133+
const length = src[offset++];
125134
let data: Uint32Array | undefined;
126135
if (length > 0) {
127-
if (isLittleEndian) {
128-
data = toUint32Array(buff.buffer, offset, length); offset += 4 * length;
129-
} else {
130-
data = new Uint32Array(length);
131-
for (let j = 0; j < length; j++) {
132-
data[j] = buff.readUInt32LE(offset); offset += 4;
133-
}
134-
}
136+
data = src.subarray(offset, offset + length); offset += length;
135137
}
136138
deltas[i] = { start, deleteCount, data };
137139
}

0 commit comments

Comments
 (0)