提交 5b8482eb 编写于 作者: S Sandeep Somavarapu

- use buffered output channel service for nodeless

上级 04dbcafd
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { isString } from 'vs/base/common/types';
import { toUint8ArrayBuffer } from 'vs/base/common/uint';
/**
* Return a hash value for an object.
......@@ -76,7 +77,7 @@ export class Hasher {
//#region SHA1
export function computeSHA1Hash(value: string): string {
const data = encodeToArrayBuffer(value);
const data = toUint8ArrayBuffer(value);
const hash = new SHA1();
if (data.byteLength) {
......@@ -137,7 +138,7 @@ class SHA1 {
let data: Uint8Array;
if (isString(arg)) {
data = new Uint8Array(encodeToArrayBuffer(<string>arg));
data = new Uint8Array(toUint8ArrayBuffer(<string>arg));
} else if (arg instanceof ArrayBuffer) {
data = new Uint8Array(arg);
} else if (arg instanceof DataView) {
......@@ -301,101 +302,6 @@ function multiply64(a: number, b: number): number[] {
return [(c3 << 16 | c2) >>> 0, (c1 << 16 | c0) >>> 0];
}
function encodeToArrayBuffer(str: string): ArrayBuffer {
let i: number, len: number, length = 0, charCode = 0, trailCharCode = 0, codepoint = 0;
// First pass, for the size
for (i = 0, len = str.length; i < len; i++) {
charCode = str.charCodeAt(i);
// Surrogate pair
if (charCode >= 0xD800 && charCode < 0xDC00) {
trailCharCode = str.charCodeAt(++i);
if (!(trailCharCode >= 0xDC00 && trailCharCode < 0xE000)) {
throw new Error('Invalid char code');
}
// Code point can be obtained by subtracting 0xD800 and 0xDC00 from both char codes respectively
// and joining the 10 least significant bits from each, finally adding 0x10000.
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
} else {
codepoint = charCode;
}
length += byteSizeInUTF8(codepoint);
}
let result = new ArrayBuffer(length);
let view = new Uint8Array(result);
let pos = 0;
// Second pass, for the data
for (i = 0, len = str.length; i < len; i++) {
charCode = str.charCodeAt(i);
if (charCode >= 0xD800 && charCode < 0xDC00) {
trailCharCode = str.charCodeAt(++i);
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
} else {
codepoint = charCode;
}
pos += writeUTF8(codepoint, view, pos);
}
return result;
}
function byteSizeInUTF8(codePoint: number): number {
codePoint = codePoint >>> 0;
if (codePoint < 0x80) {
return 1;
} else if (codePoint < 0x800) {
return 2;
} else if (codePoint < 0x10000) {
return 3;
} else if (codePoint < 0x200000) {
return 4;
} else if (codePoint < 0x4000000) {
return 5;
} else if (codePoint < 0x80000000) {
return 6;
} else {
throw new Error('Code point 0x' + toHexString(codePoint) + ' not encodable in UTF8.');
}
}
function writeUTF8(codePoint: number, buffer: Uint8Array, pos: number): number {
// How many bits needed for codePoint
let byteSize = byteSizeInUTF8(codePoint);
// 0xxxxxxx
if (byteSize === 1) {
buffer[pos] = codePoint;
return 1;
}
// 110xxxxx 10xxxxxx
// 1110xxxx 10xxxxxx 10xxxxxx
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// first byte
buffer[pos] = ((0xFC << (6 - byteSize)) | (codePoint >>> (6 * (byteSize - 1)))) & 0xFF;
// successive bytes
for (let i = 1; i < byteSize; i++) {
buffer[pos + i] = (0x80 | (0x3F & (codePoint >>> (6 * (byteSize - i - 1))))) & 0xFF;
}
return byteSize;
}
function copy(dest: Uint8Array, destIndex: number, src: Uint8Array, srcIndex: number, count: number): number {
const len = Math.min(dest.byteLength - destIndex, src.byteLength - srcIndex, count);
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export function toUint8ArrayBuffer(str: string): ArrayBuffer {
let i: number, len: number, length = 0, charCode = 0, trailCharCode = 0, codepoint = 0;
// First pass, for the size
for (i = 0, len = str.length; i < len; i++) {
charCode = str.charCodeAt(i);
// Surrogate pair
if (charCode >= 0xD800 && charCode < 0xDC00) {
trailCharCode = str.charCodeAt(++i);
if (!(trailCharCode >= 0xDC00 && trailCharCode < 0xE000)) {
throw new Error('Invalid char code');
}
// Code point can be obtained by subtracting 0xD800 and 0xDC00 from both char codes respectively
// and joining the 10 least significant bits from each, finally adding 0x10000.
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
} else {
codepoint = charCode;
}
length += byteSizeInUTF8(codepoint);
}
let result = new ArrayBuffer(length);
let view = new Uint8Array(result);
let pos = 0;
// Second pass, for the data
for (i = 0, len = str.length; i < len; i++) {
charCode = str.charCodeAt(i);
if (charCode >= 0xD800 && charCode < 0xDC00) {
trailCharCode = str.charCodeAt(++i);
codepoint = ((((charCode - 0xD800) & 0x3FF) << 10) | ((trailCharCode - 0xDC00) & 0x3FF)) + 0x10000;
} else {
codepoint = charCode;
}
pos += writeUTF8(codepoint, view, pos);
}
return result;
}
function byteSizeInUTF8(codePoint: number): number {
codePoint = codePoint >>> 0;
if (codePoint < 0x80) {
return 1;
} else if (codePoint < 0x800) {
return 2;
} else if (codePoint < 0x10000) {
return 3;
} else if (codePoint < 0x200000) {
return 4;
} else if (codePoint < 0x4000000) {
return 5;
} else if (codePoint < 0x80000000) {
return 6;
} else {
throw new Error('Code point 0x' + toHexString(codePoint) + ' not encodable in UTF8.');
}
}
function writeUTF8(codePoint: number, buffer: Uint8Array, pos: number): number {
// How many bits needed for codePoint
let byteSize = byteSizeInUTF8(codePoint);
// 0xxxxxxx
if (byteSize === 1) {
buffer[pos] = codePoint;
return 1;
}
// 110xxxxx 10xxxxxx
// 1110xxxx 10xxxxxx 10xxxxxx
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
// first byte
buffer[pos] = ((0xFC << (6 - byteSize)) | (codePoint >>> (6 * (byteSize - 1)))) & 0xFF;
// successive bytes
for (let i = 1; i < byteSize; i++) {
buffer[pos + i] = (0x80 | (0x3F & (codePoint >>> (6 * (byteSize - i - 1))))) & 0xFF;
}
return byteSize;
}
function leftPad(value: string, length: number, char: string = '0'): string {
return new Array(length - value.length + 1).join(char) + value;
}
function toHexString(value: number, bitsize: number = 32): string {
return leftPad((value >>> 0).toString(16), bitsize / 4);
}
......@@ -259,7 +259,7 @@ export class SimpleEnvironmentService implements IEnvironmentService {
wait: boolean;
status: boolean;
log?: string;
logsPath: string;
logsPath: string = '/nodeless/logs';
verbose: boolean;
skipGettingStarted: boolean;
skipReleaseNotes: boolean;
......
......@@ -155,33 +155,30 @@ export class SwitchOutputActionItem extends SelectActionItem {
}
private updateOtions(): void {
const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => {
if (!c1.log && c2.log) {
return -1;
}
if (c1.log && !c2.log) {
return 1;
}
return 0;
});
this.outputChannels = groups[0] || [];
this.logChannels = groups[1] || [];
const showSeparator = this.outputChannels.length && this.logChannels.length;
const separatorIndex = showSeparator ? this.outputChannels.length : -1;
const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))];
let selected = 0;
const activeChannel = this.outputService.getActiveChannel();
if (activeChannel) {
const selectedChannel = activeChannel.id;
const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => {
if (!c1.log && c2.log) {
return -1;
}
if (c1.log && !c2.log) {
return 1;
}
return 0;
});
this.outputChannels = groups[0] || [];
this.logChannels = groups[1] || [];
const showSeparator = this.outputChannels.length && this.logChannels.length;
const separatorIndex = showSeparator ? this.outputChannels.length : -1;
const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))];
let selected = 0;
if (selectedChannel) {
selected = this.outputChannels.map(c => c.id).indexOf(selectedChannel);
if (selected === -1) {
const logChannelIndex = this.logChannels.map(c => c.id).indexOf(selectedChannel);
selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0;
}
selected = this.outputChannels.map(c => c.id).indexOf(activeChannel.id);
if (selected === -1) {
const logChannelIndex = this.logChannels.map(c => c.id).indexOf(activeChannel.id);
selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0;
}
this.setOptions(options.map((label, index) => <ISelectOptionItem>{ text: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected));
}
this.setOptions(options.map((label, index) => <ISelectOptionItem>{ text: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected));
}
}
......
......@@ -155,7 +155,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo
private onDidRegisterChannel(channelId: string): void {
const channel = this.createChannel(channelId);
this.channels.set(channelId, channel);
if (this.activeChannelIdInStorage === channelId) {
if (!this.activeChannel || this.activeChannelIdInStorage === channelId) {
this.activeChannel = channel;
this.onDidPanelOpen(this.panelService.getActivePanel(), true)
.then(() => this._onActiveOutputChannel.fire(channelId));
......
......@@ -17,6 +17,7 @@ import { isNumber } from 'vs/base/common/types';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { Position } from 'vs/editor/common/core/position';
import { binarySearch } from 'vs/base/common/arrays';
import { toUint8ArrayBuffer } from 'vs/base/common/uint';
export interface IOutputChannelModel extends IDisposable {
readonly onDidAppendedContent: Event<void>;
......@@ -184,7 +185,7 @@ class OutputFileListener extends Disposable {
/**
* An output channel driven by a file and does not support appending messages.
*/
export class FileOutputChannelModel extends AbstractFileOutputChannelModel implements IOutputChannelModel {
class FileOutputChannelModel extends AbstractFileOutputChannelModel implements IOutputChannelModel {
private readonly fileHandler: OutputFileListener;
......@@ -210,7 +211,7 @@ export class FileOutputChannelModel extends AbstractFileOutputChannelModel imple
loadModel(): Promise<ITextModel> {
this.loadModelPromise = this.fileService.resolveContent(this.file, { position: this.startOffset, encoding: 'utf8' })
.then(content => {
this.endOffset = this.startOffset + Buffer.from(content.value).byteLength;
this.endOffset = this.startOffset + this.getByteLength(content.value);
this.etag = content.etag;
return this.createModel(content.value);
});
......@@ -235,7 +236,7 @@ export class FileOutputChannelModel extends AbstractFileOutputChannelModel imple
.then(content => {
this.etag = content.etag;
if (content.value) {
this.endOffset = this.endOffset + Buffer.from(content.value).byteLength;
this.endOffset = this.endOffset + this.getByteLength(content.value);
this.appendToModel(content.value);
}
this.updateInProgress = false;
......@@ -257,6 +258,13 @@ export class FileOutputChannelModel extends AbstractFileOutputChannelModel imple
this.updateInProgress = false;
}
protected getByteLength(str: string): number {
if (typeof Buffer !== undefined) {
return Buffer.from(str).byteLength;
}
return toUint8ArrayBuffer(str).byteLength;
}
update(size?: number): void {
if (this.model) {
if (!this.updateInProgress) {
......
......@@ -110,7 +110,7 @@ import 'vs/workbench/services/progress/browser/progressService2';
import 'vs/workbench/services/editor/browser/codeEditorService';
// import 'vs/workbench/services/broadcast/electron-browser/broadcastService';
import 'vs/workbench/services/preferences/browser/preferencesService';
// import 'vs/workbench/services/output/node/outputChannelModelService';
import 'vs/workbench/services/output/common/outputChannelModelService';
// import 'vs/workbench/services/configuration/node/jsonEditingService';
import 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import 'vs/workbench/services/textfile/common/textFileService';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册