Skip to content

Commit 5b8482e

Browse files
committed
- use buffered output channel service for nodeless
1 parent 04dbcaf commit 5b8482e

7 files changed

Lines changed: 145 additions & 126 deletions

File tree

src/vs/base/common/hash.ts

Lines changed: 3 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { isString } from 'vs/base/common/types';
7+
import { toUint8ArrayBuffer } from 'vs/base/common/uint';
78

89
/**
910
* Return a hash value for an object.
@@ -76,7 +77,7 @@ export class Hasher {
7677
//#region SHA1
7778

7879
export function computeSHA1Hash(value: string): string {
79-
const data = encodeToArrayBuffer(value);
80+
const data = toUint8ArrayBuffer(value);
8081
const hash = new SHA1();
8182

8283
if (data.byteLength) {
@@ -137,7 +138,7 @@ class SHA1 {
137138
let data: Uint8Array;
138139

139140
if (isString(arg)) {
140-
data = new Uint8Array(encodeToArrayBuffer(<string>arg));
141+
data = new Uint8Array(toUint8ArrayBuffer(<string>arg));
141142
} else if (arg instanceof ArrayBuffer) {
142143
data = new Uint8Array(arg);
143144
} else if (arg instanceof DataView) {
@@ -301,101 +302,6 @@ function multiply64(a: number, b: number): number[] {
301302
return [(c3 << 16 | c2) >>> 0, (c1 << 16 | c0) >>> 0];
302303
}
303304

304-
function encodeToArrayBuffer(str: string): ArrayBuffer {
305-
let i: number, len: number, length = 0, charCode = 0, trailCharCode = 0, codepoint = 0;
306-
307-
// First pass, for the size
308-
for (i = 0, len = str.length; i < len; i++) {
309-
charCode = str.charCodeAt(i);
310-
311-
// Surrogate pair
312-
if (charCode >= 0xD800 && charCode < 0xDC00) {
313-
trailCharCode = str.charCodeAt(++i);
314-
315-
if (!(trailCharCode >= 0xDC00 && trailCharCode < 0xE000)) {
316-
throw new Error('Invalid char code');
317-
}
318-
319-
// Code point can be obtained by subtracting 0xD800 and 0xDC00 from both char codes respectively
320-
// and joining the 10 least significant bits from each, finally adding 0x10000.
321-
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
322-
323-
} else {
324-
codepoint = charCode;
325-
}
326-
327-
length += byteSizeInUTF8(codepoint);
328-
}
329-
330-
let result = new ArrayBuffer(length);
331-
let view = new Uint8Array(result);
332-
let pos = 0;
333-
334-
// Second pass, for the data
335-
for (i = 0, len = str.length; i < len; i++) {
336-
charCode = str.charCodeAt(i);
337-
338-
if (charCode >= 0xD800 && charCode < 0xDC00) {
339-
trailCharCode = str.charCodeAt(++i);
340-
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
341-
} else {
342-
codepoint = charCode;
343-
}
344-
345-
pos += writeUTF8(codepoint, view, pos);
346-
}
347-
348-
return result;
349-
}
350-
351-
function byteSizeInUTF8(codePoint: number): number {
352-
codePoint = codePoint >>> 0;
353-
354-
if (codePoint < 0x80) {
355-
return 1;
356-
} else if (codePoint < 0x800) {
357-
return 2;
358-
} else if (codePoint < 0x10000) {
359-
return 3;
360-
} else if (codePoint < 0x200000) {
361-
return 4;
362-
} else if (codePoint < 0x4000000) {
363-
return 5;
364-
} else if (codePoint < 0x80000000) {
365-
return 6;
366-
} else {
367-
throw new Error('Code point 0x' + toHexString(codePoint) + ' not encodable in UTF8.');
368-
}
369-
}
370-
371-
function writeUTF8(codePoint: number, buffer: Uint8Array, pos: number): number {
372-
373-
// How many bits needed for codePoint
374-
let byteSize = byteSizeInUTF8(codePoint);
375-
376-
// 0xxxxxxx
377-
if (byteSize === 1) {
378-
buffer[pos] = codePoint;
379-
return 1;
380-
}
381-
382-
// 110xxxxx 10xxxxxx
383-
// 1110xxxx 10xxxxxx 10xxxxxx
384-
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
385-
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
386-
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
387-
388-
// first byte
389-
buffer[pos] = ((0xFC << (6 - byteSize)) | (codePoint >>> (6 * (byteSize - 1)))) & 0xFF;
390-
391-
// successive bytes
392-
for (let i = 1; i < byteSize; i++) {
393-
buffer[pos + i] = (0x80 | (0x3F & (codePoint >>> (6 * (byteSize - i - 1))))) & 0xFF;
394-
}
395-
396-
return byteSize;
397-
}
398-
399305
function copy(dest: Uint8Array, destIndex: number, src: Uint8Array, srcIndex: number, count: number): number {
400306
const len = Math.min(dest.byteLength - destIndex, src.byteLength - srcIndex, count);
401307

src/vs/base/common/uint.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
export function toUint8ArrayBuffer(str: string): ArrayBuffer {
7+
8+
let i: number, len: number, length = 0, charCode = 0, trailCharCode = 0, codepoint = 0;
9+
10+
// First pass, for the size
11+
for (i = 0, len = str.length; i < len; i++) {
12+
charCode = str.charCodeAt(i);
13+
14+
// Surrogate pair
15+
if (charCode >= 0xD800 && charCode < 0xDC00) {
16+
trailCharCode = str.charCodeAt(++i);
17+
18+
if (!(trailCharCode >= 0xDC00 && trailCharCode < 0xE000)) {
19+
throw new Error('Invalid char code');
20+
}
21+
22+
// Code point can be obtained by subtracting 0xD800 and 0xDC00 from both char codes respectively
23+
// and joining the 10 least significant bits from each, finally adding 0x10000.
24+
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
25+
26+
} else {
27+
codepoint = charCode;
28+
}
29+
30+
length += byteSizeInUTF8(codepoint);
31+
}
32+
33+
let result = new ArrayBuffer(length);
34+
let view = new Uint8Array(result);
35+
let pos = 0;
36+
37+
// Second pass, for the data
38+
for (i = 0, len = str.length; i < len; i++) {
39+
charCode = str.charCodeAt(i);
40+
41+
if (charCode >= 0xD800 && charCode < 0xDC00) {
42+
trailCharCode = str.charCodeAt(++i);
43+
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
44+
} else {
45+
codepoint = charCode;
46+
}
47+
48+
pos += writeUTF8(codepoint, view, pos);
49+
}
50+
51+
return result;
52+
}
53+
54+
function byteSizeInUTF8(codePoint: number): number {
55+
codePoint = codePoint >>> 0;
56+
57+
if (codePoint < 0x80) {
58+
return 1;
59+
} else if (codePoint < 0x800) {
60+
return 2;
61+
} else if (codePoint < 0x10000) {
62+
return 3;
63+
} else if (codePoint < 0x200000) {
64+
return 4;
65+
} else if (codePoint < 0x4000000) {
66+
return 5;
67+
} else if (codePoint < 0x80000000) {
68+
return 6;
69+
} else {
70+
throw new Error('Code point 0x' + toHexString(codePoint) + ' not encodable in UTF8.');
71+
}
72+
}
73+
74+
function writeUTF8(codePoint: number, buffer: Uint8Array, pos: number): number {
75+
76+
// How many bits needed for codePoint
77+
let byteSize = byteSizeInUTF8(codePoint);
78+
79+
// 0xxxxxxx
80+
if (byteSize === 1) {
81+
buffer[pos] = codePoint;
82+
return 1;
83+
}
84+
85+
// 110xxxxx 10xxxxxx
86+
// 1110xxxx 10xxxxxx 10xxxxxx
87+
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
88+
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
89+
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
90+
91+
// first byte
92+
buffer[pos] = ((0xFC << (6 - byteSize)) | (codePoint >>> (6 * (byteSize - 1)))) & 0xFF;
93+
94+
// successive bytes
95+
for (let i = 1; i < byteSize; i++) {
96+
buffer[pos + i] = (0x80 | (0x3F & (codePoint >>> (6 * (byteSize - i - 1))))) & 0xFF;
97+
}
98+
99+
return byteSize;
100+
}
101+
102+
function leftPad(value: string, length: number, char: string = '0'): string {
103+
return new Array(length - value.length + 1).join(char) + value;
104+
}
105+
106+
function toHexString(value: number, bitsize: number = 32): string {
107+
return leftPad((value >>> 0).toString(16), bitsize / 4);
108+
}

src/vs/workbench/browser/nodeless.simpleservices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ export class SimpleEnvironmentService implements IEnvironmentService {
259259
wait: boolean;
260260
status: boolean;
261261
log?: string;
262-
logsPath: string;
262+
logsPath: string = '/nodeless/logs';
263263
verbose: boolean;
264264
skipGettingStarted: boolean;
265265
skipReleaseNotes: boolean;

src/vs/workbench/contrib/output/browser/outputActions.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -155,33 +155,30 @@ export class SwitchOutputActionItem extends SelectActionItem {
155155
}
156156

157157
private updateOtions(): void {
158+
const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => {
159+
if (!c1.log && c2.log) {
160+
return -1;
161+
}
162+
if (c1.log && !c2.log) {
163+
return 1;
164+
}
165+
return 0;
166+
});
167+
this.outputChannels = groups[0] || [];
168+
this.logChannels = groups[1] || [];
169+
const showSeparator = this.outputChannels.length && this.logChannels.length;
170+
const separatorIndex = showSeparator ? this.outputChannels.length : -1;
171+
const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))];
172+
let selected = 0;
158173
const activeChannel = this.outputService.getActiveChannel();
159174
if (activeChannel) {
160-
const selectedChannel = activeChannel.id;
161-
const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => {
162-
if (!c1.log && c2.log) {
163-
return -1;
164-
}
165-
if (c1.log && !c2.log) {
166-
return 1;
167-
}
168-
return 0;
169-
});
170-
this.outputChannels = groups[0] || [];
171-
this.logChannels = groups[1] || [];
172-
const showSeparator = this.outputChannels.length && this.logChannels.length;
173-
const separatorIndex = showSeparator ? this.outputChannels.length : -1;
174-
const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))];
175-
let selected = 0;
176-
if (selectedChannel) {
177-
selected = this.outputChannels.map(c => c.id).indexOf(selectedChannel);
178-
if (selected === -1) {
179-
const logChannelIndex = this.logChannels.map(c => c.id).indexOf(selectedChannel);
180-
selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0;
181-
}
175+
selected = this.outputChannels.map(c => c.id).indexOf(activeChannel.id);
176+
if (selected === -1) {
177+
const logChannelIndex = this.logChannels.map(c => c.id).indexOf(activeChannel.id);
178+
selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0;
182179
}
183-
this.setOptions(options.map((label, index) => <ISelectOptionItem>{ text: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected));
184180
}
181+
this.setOptions(options.map((label, index) => <ISelectOptionItem>{ text: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected));
185182
}
186183
}
187184

src/vs/workbench/contrib/output/browser/outputServices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo
155155
private onDidRegisterChannel(channelId: string): void {
156156
const channel = this.createChannel(channelId);
157157
this.channels.set(channelId, channel);
158-
if (this.activeChannelIdInStorage === channelId) {
158+
if (!this.activeChannel || this.activeChannelIdInStorage === channelId) {
159159
this.activeChannel = channel;
160160
this.onDidPanelOpen(this.panelService.getActivePanel(), true)
161161
.then(() => this._onActiveOutputChannel.fire(channelId));

src/vs/workbench/services/output/common/outputChannelModel.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { isNumber } from 'vs/base/common/types';
1717
import { EditOperation } from 'vs/editor/common/core/editOperation';
1818
import { Position } from 'vs/editor/common/core/position';
1919
import { binarySearch } from 'vs/base/common/arrays';
20+
import { toUint8ArrayBuffer } from 'vs/base/common/uint';
2021

2122
export interface IOutputChannelModel extends IDisposable {
2223
readonly onDidAppendedContent: Event<void>;
@@ -184,7 +185,7 @@ class OutputFileListener extends Disposable {
184185
/**
185186
* An output channel driven by a file and does not support appending messages.
186187
*/
187-
export class FileOutputChannelModel extends AbstractFileOutputChannelModel implements IOutputChannelModel {
188+
class FileOutputChannelModel extends AbstractFileOutputChannelModel implements IOutputChannelModel {
188189

189190
private readonly fileHandler: OutputFileListener;
190191

@@ -210,7 +211,7 @@ export class FileOutputChannelModel extends AbstractFileOutputChannelModel imple
210211
loadModel(): Promise<ITextModel> {
211212
this.loadModelPromise = this.fileService.resolveContent(this.file, { position: this.startOffset, encoding: 'utf8' })
212213
.then(content => {
213-
this.endOffset = this.startOffset + Buffer.from(content.value).byteLength;
214+
this.endOffset = this.startOffset + this.getByteLength(content.value);
214215
this.etag = content.etag;
215216
return this.createModel(content.value);
216217
});
@@ -235,7 +236,7 @@ export class FileOutputChannelModel extends AbstractFileOutputChannelModel imple
235236
.then(content => {
236237
this.etag = content.etag;
237238
if (content.value) {
238-
this.endOffset = this.endOffset + Buffer.from(content.value).byteLength;
239+
this.endOffset = this.endOffset + this.getByteLength(content.value);
239240
this.appendToModel(content.value);
240241
}
241242
this.updateInProgress = false;
@@ -257,6 +258,13 @@ export class FileOutputChannelModel extends AbstractFileOutputChannelModel imple
257258
this.updateInProgress = false;
258259
}
259260

261+
protected getByteLength(str: string): number {
262+
if (typeof Buffer !== undefined) {
263+
return Buffer.from(str).byteLength;
264+
}
265+
return toUint8ArrayBuffer(str).byteLength;
266+
}
267+
260268
update(size?: number): void {
261269
if (this.model) {
262270
if (!this.updateInProgress) {

src/vs/workbench/workbench.nodeless.main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ import 'vs/workbench/services/progress/browser/progressService2';
110110
import 'vs/workbench/services/editor/browser/codeEditorService';
111111
// import 'vs/workbench/services/broadcast/electron-browser/broadcastService';
112112
import 'vs/workbench/services/preferences/browser/preferencesService';
113-
// import 'vs/workbench/services/output/node/outputChannelModelService';
113+
import 'vs/workbench/services/output/common/outputChannelModelService';
114114
// import 'vs/workbench/services/configuration/node/jsonEditingService';
115115
import 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
116116
import 'vs/workbench/services/textfile/common/textFileService';

0 commit comments

Comments
 (0)