@@ -12,7 +12,7 @@ import { posix } from 'path';
1212import { IDisposable } from 'vs/base/common/lifecycle' ;
1313import { isFalsyOrEmpty , distinct } from 'vs/base/common/arrays' ;
1414import { Schemas } from 'vs/base/common/network' ;
15- import { decodeStream , encode , UTF8 , UTF8_with_bom , detectEncodingFromBuffer , maxEncodingDetectionBufferLen } from 'vs/base/node/encoding' ;
15+ import { encode , UTF8 , UTF8_with_bom , toDecodeStream } from 'vs/base/node/encoding' ;
1616import { TernarySearchTree } from 'vs/base/common/map' ;
1717import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
1818import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace' ;
@@ -23,6 +23,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res
2323import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions' ;
2424import { localize } from 'vs/nls' ;
2525import { INotificationService } from 'vs/platform/notification/common/notification' ;
26+ import { Readable } from 'stream' ;
2627
2728function toIFileStat ( provider : IFileSystemProvider , tuple : [ URI , IStat ] , recurse ?: ( tuple : [ URI , IStat ] ) => boolean ) : TPromise < IFileStat > {
2829 const [ resource , stat ] = tuple ;
@@ -220,6 +221,25 @@ export class RemoteFileService extends FileService {
220221 }
221222 }
222223
224+ private _createReadStream ( provider : IFileSystemProvider , resource : URI ) : Readable {
225+ return new class extends Readable {
226+ _done : boolean = false ;
227+ _read ( size ?: number ) : void {
228+ if ( this . _done ) {
229+ this . push ( null ) ;
230+ return ;
231+ }
232+ provider . readFile ( resource ) . then ( data => {
233+ this . _done = true ;
234+ this . push ( data ) ;
235+ } , err => {
236+ this . _done = true ;
237+ this . emit ( 'error' , err ) ;
238+ } ) ;
239+ }
240+ } ;
241+ }
242+
223243 private _readFile ( resource : URI , options : IResolveContentOptions = Object . create ( null ) ) : TPromise < IStreamContent > {
224244 return this . _withProvider ( resource ) . then ( provider => {
225245
@@ -242,49 +262,44 @@ export class RemoteFileService extends FileService {
242262 ) ;
243263 }
244264
245- const guessEncoding = options . autoGuessEncoding ;
246- const count = maxEncodingDetectionBufferLen ( options ) ;
247- let buffer : Buffer ;
265+ return toDecodeStream ( this . _createReadStream ( provider , resource ) , {
266+ guessEncoding : options . autoGuessEncoding ,
267+ overwriteEncoding : detected => {
268+ let preferredEncoding : string ;
269+ if ( options && options . encoding ) {
270+ if ( detected === UTF8 && options . encoding === UTF8 ) {
271+ preferredEncoding = UTF8_with_bom ; // indicate the file has BOM if we are to resolve with UTF 8
272+ } else {
273+ preferredEncoding = options . encoding ; // give passed in encoding highest priority
274+ }
275+ } else if ( detected ) {
276+ if ( detected === UTF8 ) {
277+ preferredEncoding = UTF8_with_bom ; // if we detected UTF-8, it can only be because of a BOM
278+ } else {
279+ preferredEncoding = detected ;
280+ }
281+ // todo@remote - encoding logic should not be kept
282+ // hostage inside the node file service
283+ // } else if (super.configuredEncoding(resource) === UTF8_with_bom) {
284+ } else {
285+ preferredEncoding = UTF8 ; // if we did not detect UTF 8 BOM before, this can only be UTF 8 then
286+ }
287+ return preferredEncoding ;
288+ }
248289
249- return provider . readFile ( resource ) . then ( data => {
250- buffer = Buffer . from ( data ) ;
251- return detectEncodingFromBuffer ( { bytesRead : Math . min ( count , buffer . length ) , buffer } , guessEncoding ) ;
252- } ) . then ( detected => {
253- if ( options . acceptTextOnly && detected . seemsBinary ) {
290+ } ) . then ( data => {
291+
292+ if ( options . acceptTextOnly && data . detected . seemsBinary ) {
254293 return TPromise . wrapError < IStreamContent > ( new FileOperationError (
255294 localize ( 'fileBinaryError' , "File seems to be binary and cannot be opened as text" ) ,
256295 FileOperationResult . FILE_IS_BINARY ,
257296 options
258297 ) ) ;
259298 }
260299
261- let preferredEncoding : string ;
262- if ( options && options . encoding ) {
263- if ( detected . encoding === UTF8 && options . encoding === UTF8 ) {
264- preferredEncoding = UTF8_with_bom ; // indicate the file has BOM if we are to resolve with UTF 8
265- } else {
266- preferredEncoding = options . encoding ; // give passed in encoding highest priority
267- }
268- } else if ( detected . encoding ) {
269- if ( detected . encoding === UTF8 ) {
270- preferredEncoding = UTF8_with_bom ; // if we detected UTF-8, it can only be because of a BOM
271- } else {
272- preferredEncoding = detected . encoding ;
273- }
274- // todo@remote - encoding logic should not be kept
275- // hostage inside the node file service
276- // } else if (super.configuredEncoding(resource) === UTF8_with_bom) {
277- } else {
278- preferredEncoding = UTF8 ; // if we did not detect UTF 8 BOM before, this can only be UTF 8 then
279- }
280-
281- // const encoding = this.getEncoding(resource);
282- const stream = decodeStream ( preferredEncoding ) ;
283- stream . end ( buffer ) ;
284-
285- return {
286- encoding : preferredEncoding ,
287- value : stream ,
300+ return < IStreamContent > {
301+ encoding : data . detected . encoding ,
302+ value : data . stream ,
288303 resource : fileStat . resource ,
289304 name : fileStat . name ,
290305 etag : fileStat . etag ,
0 commit comments