This uses the same mechanisms as git to determine whether a file is
binary: By simply searching the first 8000 bytes for a 0-byte. This
gets rid of the call to "file" and is a much cleaner and shorter
implementation.

Signed-off-by: Johannes Gilger <[email protected]>
---
Hi folks,

I had that on my TODO and it turns out that git uses a dead-simple (yet 
seemingly very effective) mechanisms to determine binary-files (see commit 
message).

I thought about using memchr like git does, but then again were coding 
Objective-C and I don't think using the rangeOfString method here creates too 
much overhead. If you're wondering why the check for binaryAttributes and for 
binaryHeader isn't done in the same line: Searching the header (which means 
invoking "git show" on a possbily large file) is the last resort, and is only 
done if the other ifs didn't yield anything (like binary attributes or "file 
too big"). With this patch "git show" is only invoked once (max) per time you 
select the file.

This one is up for discussion, since it can be performance-critical.

Greetings,
Jojo

 PBGitTree.m |   23 ++++++++---------------
 1 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/PBGitTree.m b/PBGitTree.m
index 21c91f8..c8003d1 100644
--- a/PBGitTree.m
+++ b/PBGitTree.m
@@ -63,18 +63,12 @@ - (BOOL) isLocallyCached
        return NO;
 }
 
-- (BOOL)hasBinaryHeader:(NSString *)fileHeader
+- (BOOL)hasBinaryHeader:(NSString*)contents
 {
-       if (!fileHeader)
+       if(!contents)
                return NO;
 
-       NSString *filetype = [PBEasyPipe outputForCommand:@"/usr/bin/file"
-                                                                               
         withArgs:[NSArray arrayWithObjects:@"-b", @"-N", @"-", nil]
-                                                                               
                inDir:[repository workingDirectory]
-                                                                               
  inputString:fileHeader
-                                                                               
         retValue:nil];
-
-       return [filetype rangeOfString:@"text"].location == NSNotFound;
+       return [contents rangeOfString:@"\0" options:0 range:NSMakeRange(0, 
([contents length] >= 8000) ? 7999 : [contents length])].location != NSNotFound;
 }
 
 - (BOOL)hasBinaryAttributes
@@ -143,14 +137,13 @@ - (NSString *)textContents
        if ([self hasBinaryAttributes])
                return [NSString stringWithFormat:@"%@ appears to be a binary 
file of %d bytes", [self fullPath], [self fileSize]];
 
-       long long fileSize = [self fileSize];
-       if (fileSize > 52428800) // ~50MB
-               return [NSString stringWithFormat:@"%@ is too big to be 
displayed (%d bytes)", [self fullPath], fileSize];
+       if ([self fileSize] > 52428800) // ~50MB
+               return [NSString stringWithFormat:@"%@ is too big to be 
displayed (%d bytes)", [self fullPath], [self fileSize]];
 
-       NSString *contents = [self contents];
+       NSString* contents = [self contents];
 
-       if ([self hasBinaryHeader:([contents length] >= 100) ? [contents 
substringToIndex:99] : contents])
-               return [NSString stringWithFormat:@"%@ appears to be a binary 
file of %d bytes", [self fullPath], fileSize];
+       if ([self hasBinaryHeader:contents])
+               return [NSString stringWithFormat:@"%@ appears to be a binary 
file of %d bytes", [self fullPath], [self fileSize]];
 
        return contents;
 }
-- 
1.6.4.2.236.gf324c

Reply via email to