diff --git a/Atom/src/native_handler.mm b/Atom/src/native_handler.mm index 2fc653aed..68e8a687e 100644 --- a/Atom/src/native_handler.mm +++ b/Atom/src/native_handler.mm @@ -4,6 +4,8 @@ #import "AtomController.h" #import "client_handler.h" #import "PathWatcher.h" +#import +#import #define MY_EXCEPTION_TRY @try { #define MY_EXCEPTION_HANDLE } @catch (NSException *localException) {} @@ -16,7 +18,7 @@ NSString *stringFromCefV8Value(const CefRefPtr& value) { NativeHandler::NativeHandler() : CefV8Handler() { std::string extensionCode = "var $native = {}; (function() {"; - const char *functionNames[] = {"exists", "alert", "read", "write", "absolute", "list", "isFile", "isDirectory", "remove", "asyncList", "open", "openDialog", "quit", "writeToPasteboard", "readFromPasteboard", "showDevTools", "toggleDevTools", "newWindow", "saveDialog", "exit", "watchPath", "unwatchPath", "makeDirectory", "move", "moveToTrash", "reload", "lastModified"}; + const char *functionNames[] = {"exists", "alert", "read", "write", "absolute", "list", "isFile", "isDirectory", "remove", "asyncList", "open", "openDialog", "quit", "writeToPasteboard", "readFromPasteboard", "showDevTools", "toggleDevTools", "newWindow", "saveDialog", "exit", "watchPath", "unwatchPath", "makeDirectory", "move", "moveToTrash", "reload", "lastModified", "md5ForPath"}; NSUInteger arrayLength = sizeof(functionNames) / sizeof(const char *); for (NSUInteger i = 0; i < arrayLength; i++) { std::string functionName = std::string(functionNames[i]); @@ -403,6 +405,23 @@ bool NativeHandler::Execute(const CefString& name, NSDate *lastModified = [attributes objectForKey:NSFileModificationDate]; retval = CefV8Value::CreateDate(CefTime([lastModified timeIntervalSince1970])); return true; + } + else if (name == "md5ForPath") { + NSString *path = stringFromCefV8Value(arguments[0]); + unsigned char outputData[CC_MD5_DIGEST_LENGTH]; + + NSData *inputData = [[NSData alloc] initWithContentsOfFile:path]; + CC_MD5([inputData bytes], [inputData length], outputData); + [inputData release]; + + NSMutableString *hash = [[NSMutableString alloc] init]; + + for (NSUInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { + [hash appendFormat:@"%02x", outputData[i]]; + } + + retval = CefV8Value::CreateString([hash UTF8String]); + return true; } return false; }; \ No newline at end of file diff --git a/spec/stdlib/fs-spec.coffee b/spec/stdlib/fs-spec.coffee index 1e39bf08b..ad7c29bd9 100644 --- a/spec/stdlib/fs-spec.coffee +++ b/spec/stdlib/fs-spec.coffee @@ -80,6 +80,10 @@ describe "fs", -> expect(lastModified instanceof Date).toBeTruthy() expect(lastModified.getTime()).toBeGreaterThan(beforeWrite.getTime() - 1000) + describe ".md5ForPath(path)", -> + it "returns the MD5 hash of the file at the given path", -> + expect(fs.md5ForPath(require.resolve('fixtures/sample.js'))).toBe 'dd38087d0d7e3e4802a6d3f9b9745f2b' + describe ".async", -> directoryPath = null beforeEach -> diff --git a/src/stdlib/fs.coffee b/src/stdlib/fs.coffee index 8e0e0fc2f..b873e453f 100644 --- a/src/stdlib/fs.coffee +++ b/src/stdlib/fs.coffee @@ -94,6 +94,9 @@ module.exports = lastModified: (path) -> $native.lastModified(path) + md5ForPath: (path) -> + $native.md5ForPath(path) + async: list: (path) -> deferred = $.Deferred()