mainThreadFileSystem.ts 4.7 KB
Newer Older
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

7
import { Emitter, Event } from 'vs/base/common/event';
8
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
9 10
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
11
import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions } from 'vs/platform/files/common/files';
12
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
13
import { ExtHostContext, ExtHostFileSystemShape, IExtHostContext, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../node/extHost.protocol';
14
import { LabelRules, ILabelService } from 'vs/platform/label/common/label';
15 16 17 18 19

@extHostNamedCustomer(MainContext.MainThreadFileSystem)
export class MainThreadFileSystem implements MainThreadFileSystemShape {

	private readonly _proxy: ExtHostFileSystemShape;
20
	private readonly _fileProvider = new Map<number, RemoteFileSystemProvider>();
21 22 23

	constructor(
		extHostContext: IExtHostContext,
A
Tweaks  
Alex Dima 已提交
24
		@IFileService private readonly _fileService: IFileService,
I
isidor 已提交
25
		@ILabelService private readonly _labelService: ILabelService
26
	) {
27
		this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostFileSystem);
28 29 30
	}

	dispose(): void {
J
Johannes Rieken 已提交
31
		this._fileProvider.forEach(value => value.dispose());
32
		this._fileProvider.clear();
33 34
	}

35 36
	$registerFileSystemProvider(handle: number, scheme: string, capabilities: FileSystemProviderCapabilities): void {
		this._fileProvider.set(handle, new RemoteFileSystemProvider(this._fileService, scheme, capabilities, handle, this._proxy));
37
	}
38

39 40 41
	$unregisterProvider(handle: number): void {
		dispose(this._fileProvider.get(handle));
		this._fileProvider.delete(handle);
42 43
	}

44 45
	$setUriFormatter(scheme: string, formatter: LabelRules): void {
		this._labelService.registerFormatter(scheme, formatter);
A
Tweaks  
Alex Dima 已提交
46 47
	}

J
Johannes Rieken 已提交
48
	$onFileSystemChange(handle: number, changes: IFileChangeDto[]): void {
49
		this._fileProvider.get(handle).$onFileSystemChange(changes);
50 51 52
	}
}

53
class RemoteFileSystemProvider implements IFileSystemProvider {
54 55

	private readonly _onDidChange = new Emitter<IFileChange[]>();
J
Johannes Rieken 已提交
56
	private readonly _registrations: IDisposable[];
57

58
	readonly onDidChangeFile: Event<IFileChange[]> = this._onDidChange.event;
59
	readonly capabilities: FileSystemProviderCapabilities;
60 61

	constructor(
J
Johannes Rieken 已提交
62
		fileService: IFileService,
63
		scheme: string,
64
		capabilities: FileSystemProviderCapabilities,
65 66 67
		private readonly _handle: number,
		private readonly _proxy: ExtHostFileSystemShape
	) {
68
		this.capabilities = capabilities;
69
		this._registrations = [fileService.registerProvider(scheme, this)];
70 71 72
	}

	dispose(): void {
J
Johannes Rieken 已提交
73
		dispose(this._registrations);
74 75 76
		this._onDidChange.dispose();
	}

77 78 79
	watch(resource: URI, opts: IWatchOptions) {
		const session = Math.random();
		this._proxy.$watch(this._handle, session, resource, opts);
80 81 82
		return toDisposable(() => {
			this._proxy.$unwatch(this._handle, session);
		});
83 84
	}

J
Johannes Rieken 已提交
85 86 87 88 89 90
	$onFileSystemChange(changes: IFileChangeDto[]): void {
		this._onDidChange.fire(changes.map(RemoteFileSystemProvider._createFileChange));
	}

	private static _createFileChange(dto: IFileChangeDto): IFileChange {
		return { resource: URI.revive(dto.resource), type: dto.type };
91 92 93 94
	}

	// --- forwarding calls

J
Johannes Rieken 已提交
95
	stat(resource: URI): TPromise<IStat> {
96 97 98
		return this._proxy.$stat(this._handle, resource).then(undefined, err => {
			throw err;
		});
99
	}
100

J
Joao Moreno 已提交
101
	readFile(resource: URI): TPromise<Uint8Array> {
102
		return this._proxy.$readFile(this._handle, resource);
103
	}
104

J
Joao Moreno 已提交
105
	writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): TPromise<void> {
J
Johannes Rieken 已提交
106
		let encoded = Buffer.isBuffer(content)
107 108
			? content
			: Buffer.from(content.buffer, content.byteOffset, content.byteLength);
109
		return this._proxy.$writeFile(this._handle, resource, encoded, opts);
110
	}
111

J
Joao Moreno 已提交
112
	delete(resource: URI, opts: FileDeleteOptions): TPromise<void> {
113
		return this._proxy.$delete(this._handle, resource, opts);
114
	}
115

J
Joao Moreno 已提交
116
	mkdir(resource: URI): TPromise<void> {
117 118
		return this._proxy.$mkdir(this._handle, resource);
	}
119

J
Joao Moreno 已提交
120
	readdir(resource: URI): TPromise<[string, FileType][]> {
121
		return this._proxy.$readdir(this._handle, resource);
122
	}
123

J
Joao Moreno 已提交
124
	rename(resource: URI, target: URI, opts: FileOverwriteOptions): TPromise<void> {
125
		return this._proxy.$rename(this._handle, resource, target, opts);
126
	}
127

J
Joao Moreno 已提交
128
	copy(resource: URI, target: URI, opts: FileOverwriteOptions): TPromise<void> {
129
		return this._proxy.$copy(this._handle, resource, target, opts);
130
	}
131
}