This tries to determine whether a file is binary or not, i.e. whether it
can be displayed in a sensible way.
PBGitTree is extended with the method isBinary, which first checks the
output of "git check-attr binary <file>" to see if the user set/unset
the binary attribute manually. Then it checks for common binary
file-extensions, and finally it uses Unix "file" on the first 100 bytes
of the file to make a decision.

Signed-off-by: Johannes Gilger <[email protected]>
---
This is the second try. I followed Pieters advice. The list of "common binary 
filename-extensions" is still something up for discuission.
The binary-file detection is always overriden by gitattributes, so noone can 
complain we broke any crucial functioanlity.
I thought about making a wrapper-method "isBinary" without any arguments, but 
atm it seems to be overkill. The fileHeader argument can be NULL

Comments appreciated!

 PBGitTree.m |   40 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/PBGitTree.m b/PBGitTree.m
index 51fadd2..9ffe235 100644
--- a/PBGitTree.m
+++ b/PBGitTree.m
@@ -63,6 +63,40 @@ - (BOOL) isLocallyCached
        return NO;
 }
 
+- (BOOL)isBinary:(NSString *)fileHeader
+{
+       NSFileHandle* handle = [repository handleInWorkDirForArguments:[NSArray 
arrayWithObjects:@"check-attr", @"binary", [self fullPath], nil]];
+       NSData* data = [handle readDataToEndOfFile];
+       NSString* string = [[NSString alloc] initWithData:data 
encoding:NSUTF8StringEncoding];
+       if (!string)
+               string = [[NSString alloc] initWithData:data 
encoding:NSISOLatin1StringEncoding];
+
+       if(string) {
+               string = [string 
stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
+               NSLog(string);
+               if([string hasSuffix:@"binary: set"]) {
+                       return YES;
+               } else if([string hasSuffix:@"binary: unset"]) {
+                       return NO;
+               } else if([string hasSuffix:@"binary: unspecified"] && 
fileHeader) {
+                       // no gitattribute "binary" set, we try to determine 
whether it's binary ourselves
+                       // first try common filename-extensions
+                       for (NSString* extension in [NSArray 
arrayWithObjects:@".pdf", @".jpg", @".jpeg", @".png", @".bmp", @".gif", @".o", 
nil]) {
+                               if([[self fullPath] hasSuffix:extension])
+                                       return YES;
+                       }
+                       // invoke "file"
+                       NSString* filetype = [PBEasyPipe 
outputForCommand:@"/usr/bin/file" withArgs:[NSArray arrayWithObjects:@"-b", 
@"-N", @"-", nil] inDir:[repository workingDirectory] inputString:fileHeader 
retValue:nil];
+                       if([filetype rangeOfString:@"text"].location == 
NSNotFound)
+                               return YES;
+                       else
+                               return NO;
+               }
+       }
+
+       return NO;
+}
+
 - (NSString*) contents
 {
        if (!leaf)
@@ -81,6 +115,12 @@ - (NSString*) contents
        if (!string) {
                string = [[NSString alloc] initWithData:data 
encoding:NSISOLatin1StringEncoding];
        }
+
+       if (string) {
+               if([self isBinary:([string length] > 100) ? [string 
substringToIndex:100] : string])
+                       return [NSString stringWithFormat:@"%@ appears to be a 
binary file", [self fullPath]];
+       }
+
        return string;
 }
 
-- 
1.6.4.2.236.gf324c

Reply via email to