提交 9ee29afe 编写于 作者: K katainaka0503

Refactor mime.ts

上级 d86affcd
......@@ -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<IMimeAndEncoding> {
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<IMimeAndEncoding> {
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<IMimeAndEncoding> {
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<IMimeAndEncoding> {
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
......@@ -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);
});
});
......@@ -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(<IFileOperationResult>{
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<string>(<IFileOperationResult>{
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<string> {
......
......@@ -165,22 +165,16 @@ export class RawGitService implements IRawGitService {
detectMimetypes(filePath: string, treeish?: string): TPromise<string[]> {
return exists(join(this.repo.path, filePath)).then((exists) => {
if (exists) {
return new TPromise<string[]>((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<string[]>((c, e) => {
detectMimesFromStream(child.stdout, filePath, (err, result) => {
if (err) { e(err); }
else { c(result.mimes); }
});
});
return new TPromise<string[]>((c, e) =>
detectMimesFromStream(child.stdout, filePath)
.then(result => result.mimes)
);
});
}
......
......@@ -205,7 +205,7 @@ export class FileService implements IFileService {
}
// 2.) detect mimes
return nfcall(mime.detectMimesFromFile, absolutePath).then((detected: mime.IMimeAndEncoding): TPromise<IStreamContent> => {
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
......
......@@ -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
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册