diff --git a/src/vs/base/node/mime.ts b/src/vs/base/node/mime.ts index 92549a81b0e9357ef7a1ccd239f2d5a9dee200a5..94f9c7def7039afd121f52973da1891c9206c72c 100644 --- a/src/vs/base/node/mime.ts +++ b/src/vs/base/node/mime.ts @@ -8,6 +8,7 @@ import streams = require('stream'); import mime = require('vs/base/common/mime'); +import { TPromise } from 'vs/base/common/winjs.base'; import stream = require('vs/base/node/stream'); import encoding = require('vs/base/node/encoding'); @@ -57,27 +58,38 @@ export interface IMimeAndEncoding { mimes: string[]; } -function doDetectMimesFromStream(instream: streams.Readable, callback: (error: Error, result: IMimeAndEncoding) => void): void { - stream.readExactlyByStream(instream, BUFFER_READ_MAX_LEN, (err, buffer, bytesRead) => { - handleReadResult(err, buffer, bytesRead, callback); - }); +function doDetectMimesFromStream(instream: streams.Readable): TPromise { + return new TPromise((complete, error) => + stream.readExactlyByStream(instream, BUFFER_READ_MAX_LEN, (err, buffer, bytesRead) => { + if (err) { + error(error); + } else { + complete(detectMimeAndEncodingFromBuffer({ buffer, bytesRead })); + } + }) + ); } -function doDetectMimesFromFile(absolutePath: string, callback: (error: Error, result: IMimeAndEncoding) => void): void { - stream.readExactlyByFile(absolutePath, BUFFER_READ_MAX_LEN, (err, buffer, bytesRead) => { - handleReadResult(err, buffer, bytesRead, callback); - }); +function doDetectMimesFromFile(absolutePath: string): TPromise { + return new TPromise((complete, error) => + stream.readExactlyByFile(absolutePath, BUFFER_READ_MAX_LEN, (err, buffer, bytesRead) => { + if (err) { + error(error); + } else { + complete(detectMimeAndEncodingFromBuffer({ buffer, bytesRead })); + } + }) + ); } -function handleReadResult(err: Error, buffer: NodeBuffer, bytesRead: number, callback: (error: Error, result: IMimeAndEncoding) => void): void { - if (err) { - return callback(err, null); - } - return callback(null, detectMimeAndEncodingFromBuffer(buffer, bytesRead)); + +export interface ReadResult { + buffer: NodeBuffer; + bytesRead: number; } -export function detectMimeAndEncodingFromBuffer(buffer: NodeBuffer, bytesRead: number): IMimeAndEncoding { +export function detectMimeAndEncodingFromBuffer({buffer, bytesRead}: ReadResult): IMimeAndEncoding { let enc = encoding.detectEncodingByBOMFromBuffer(buffer, bytesRead); // Detect 0 bytes to see if file is binary (ignore for UTF 16 though) @@ -127,29 +139,26 @@ function filterAndSortMimes(detectedMimes: string[], guessedMimes: string[]): st * @param instream the readable stream to detect the mime types from. * @param nameHint an additional hint that can be used to detect a mime from a file extension. */ -export function detectMimesFromStream(instream: streams.Readable, nameHint: string, callback: (error: Error, result: IMimeAndEncoding) => void): void { - doDetectMimesFromStream(instream, (error: Error, result: IMimeAndEncoding) => { - handleMimeResult(nameHint, error, result, callback); - }); +export function detectMimesFromStream(instream: streams.Readable, nameHint: string): TPromise { + return doDetectMimesFromStream(instream).then(encoding => + handleMimeResult(nameHint, encoding) + ); } /** * Opens the given file to detect its mime type. Returns an array of mime types sorted from most specific to unspecific. * @param absolutePath the absolute path of the file. */ -export function detectMimesFromFile(absolutePath: string, callback: (error: Error, result: IMimeAndEncoding) => void): void { - doDetectMimesFromFile(absolutePath, (error: Error, result: IMimeAndEncoding) => { - handleMimeResult(absolutePath, error, result, callback); - }); +export function detectMimesFromFile(absolutePath: string): TPromise { + return doDetectMimesFromFile(absolutePath).then(encoding => + handleMimeResult(absolutePath, encoding) + ); } -function handleMimeResult(nameHint: string, error: Error, result: IMimeAndEncoding, callback: (error: Error, result: IMimeAndEncoding) => void): void { - if (error) { - return callback(error, null); - } +function handleMimeResult(nameHint: string, result: IMimeAndEncoding): IMimeAndEncoding { let filterAndSortedMimes = filterAndSortMimes(result.mimes, mime.guessMimeTypes(nameHint)); result.mimes = filterAndSortedMimes; - callback(null, result); + return result; } \ No newline at end of file diff --git a/src/vs/base/test/node/mime/mime.test.ts b/src/vs/base/test/node/mime/mime.test.ts index cc1c44b485625bc3f50f47353a8a48553fbbaefb..9abd262a724a85ac765aa1082d97298b2ea5d778 100644 --- a/src/vs/base/test/node/mime/mime.test.ts +++ b/src/vs/base/test/node/mime/mime.test.ts @@ -12,64 +12,52 @@ import mime = require('vs/base/node/mime'); suite('Mime', () => { - test('detectMimesFromFile (JSON saved as PNG)', function (done: () => void) { + test('detectMimesFromFile (JSON saved as PNG)', function (done: (err?: any) => void) { const file = require.toUrl('./fixtures/some.json.png'); - mime.detectMimesFromFile(file, (error, mimes) => { - assert.equal(error, null); + mime.detectMimesFromFile(file).then(mimes => { assert.deepEqual(mimes.mimes, ['text/plain']); - done(); - }); + }, done); }); - test('detectMimesFromFile (PNG saved as TXT)', function (done: () => void) { + test('detectMimesFromFile (PNG saved as TXT)', function (done: (err?: any) => void) { mimeCommon.registerTextMime({ id: 'text', mime: 'text/plain', extension: '.txt' }); const file = require.toUrl('./fixtures/some.png.txt'); - mime.detectMimesFromFile(file, (error, mimes) => { - assert.equal(error, null); + mime.detectMimesFromFile(file).then(mimes => { assert.deepEqual(mimes.mimes, ['text/plain', 'application/octet-stream']); - done(); - }); + }, done); }); - test('detectMimesFromFile (XML saved as PNG)', function (done: () => void) { + test('detectMimesFromFile (XML saved as PNG)', function (done: (err?: any) => void) { const file = require.toUrl('./fixtures/some.xml.png'); - mime.detectMimesFromFile(file, (error, mimes) => { - assert.equal(error, null); + mime.detectMimesFromFile(file).then(mimes => { assert.deepEqual(mimes.mimes, ['text/plain']); - done(); - }); + }, done); }); - test('detectMimesFromFile (QWOFF saved as TXT)', function (done: () => void) { + test('detectMimesFromFile (QWOFF saved as TXT)', function (done: (err?: any) => void) { const file = require.toUrl('./fixtures/some.qwoff.txt'); - mime.detectMimesFromFile(file, (error, mimes) => { - assert.equal(error, null); + mime.detectMimesFromFile(file).then(mimes => { assert.deepEqual(mimes.mimes, ['text/plain', 'application/octet-stream']); - done(); - }); + }, done); }); - test('detectMimesFromFile (CSS saved as QWOFF)', function (done: () => void) { + test('detectMimesFromFile (CSS saved as QWOFF)', function (done: (err?: any) => void) { const file = require.toUrl('./fixtures/some.css.qwoff'); - mime.detectMimesFromFile(file, (error, mimes) => { - assert.equal(error, null); + mime.detectMimesFromFile(file).then(mimes => { assert.deepEqual(mimes.mimes, ['text/plain']); - done(); - }); + }, done); }); test('detectMimesFromFile (PDF)', function (done: () => void) { const file = require.toUrl('./fixtures/some.pdf'); - mime.detectMimesFromFile(file, (error, mimes) => { - assert.equal(error, null); + mime.detectMimesFromFile(file).then(mimes => { assert.deepEqual(mimes.mimes, ['application/octet-stream']); - done(); - }); + }, done); }); }); diff --git a/src/vs/workbench/parts/git/node/git.lib.ts b/src/vs/workbench/parts/git/node/git.lib.ts index e78f0edf160d677aba901caafd420ad682a90493..96850b60380e07b68e2231a7b2ddc83df8f435d5 100644 --- a/src/vs/workbench/parts/git/node/git.lib.ts +++ b/src/vs/workbench/parts/git/node/git.lib.ts @@ -327,20 +327,14 @@ export class Repository { return TPromise.wrapError(localize('errorBuffer', "Can't open file from git")); } - return new Promise((c, e) => { - detectMimesFromStream(child.stdout, null, (err, result) => { - if (err) { - e(err); - } else if (isBinaryMime(result.mimes)) { - e({ - message: localize('fileBinaryError', "File seems to be binary and cannot be opened as text"), - fileOperationResult: FileOperationResult.FILE_IS_BINARY - }); - } else { - c(this.doBuffer(object)); - } - }); - }); + return detectMimesFromStream(child.stdout, null).then(result => + isBinaryMime(result.mimes) ? + TPromise.wrapError({ + message: localize('fileBinaryError', "File seems to be binary and cannot be opened as text"), + fileOperationResult: FileOperationResult.FILE_IS_BINARY + }) : + this.doBuffer(object) + ); } private doBuffer(object: string): TPromise { diff --git a/src/vs/workbench/parts/git/node/rawGitService.ts b/src/vs/workbench/parts/git/node/rawGitService.ts index 9e9acca621ae7329b9a9b1f85072ce2944a08f3c..1127fc6daefe53c1c70856b1a0f64d1d3e5f2b1a 100644 --- a/src/vs/workbench/parts/git/node/rawGitService.ts +++ b/src/vs/workbench/parts/git/node/rawGitService.ts @@ -165,22 +165,16 @@ export class RawGitService implements IRawGitService { detectMimetypes(filePath: string, treeish?: string): TPromise { return exists(join(this.repo.path, filePath)).then((exists) => { if (exists) { - return new TPromise((c, e) => { - detectMimesFromFile(join(this.repo.path, filePath), (err, result) => { - if (err) { e(err); } - else { c(result.mimes); } - }); - }); + return detectMimesFromFile(join(this.repo.path, filePath)) + .then(result => result.mimes); } const child = this.repo.show(treeish + ':' + filePath); - return new TPromise((c, e) => { - detectMimesFromStream(child.stdout, filePath, (err, result) => { - if (err) { e(err); } - else { c(result.mimes); } - }); - }); + return new TPromise((c, e) => + detectMimesFromStream(child.stdout, filePath) + .then(result => result.mimes) + ); }); } diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index 70ad2f3a4fce7bac29b6d06918dee9d49a17aede..1d69548dad4b037d2b7dedf269117d6f2fc7d5bf 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -205,7 +205,7 @@ export class FileService implements IFileService { } // 2.) detect mimes - return nfcall(mime.detectMimesFromFile, absolutePath).then((detected: mime.IMimeAndEncoding): TPromise => { + return mime.detectMimesFromFile(absolutePath).then((detected: mime.IMimeAndEncoding) => { const isText = detected.mimes.indexOf(baseMime.MIME_BINARY) === -1; // Return error early if client only accepts text and this is not text diff --git a/src/vs/workbench/services/search/node/worker/searchWorker.ts b/src/vs/workbench/services/search/node/worker/searchWorker.ts index b9fdcbd2b96e6d46ce4cc35e68b638b98ea69aea..220ec72eb0cc7d943613eeb63f94a921b391657f 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorker.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorker.ts @@ -209,7 +209,7 @@ export class SearchWorkerEngine { // Detect encoding and mime when this is the beginning of the file if (isFirstRead) { - const mimeAndEncoding = detectMimeAndEncodingFromBuffer(buffer, bytesRead); + const mimeAndEncoding = detectMimeAndEncodingFromBuffer({buffer, bytesRead}); if (mimeAndEncoding.mimes[mimeAndEncoding.mimes.length - 1] !== baseMime.MIME_TEXT) { return clb(null); // skip files that seem binary }