Skip to content

Commit

Permalink
added writing unpacked objects to disk, sha calculations, sha packing…
Browse files Browse the repository at this point in the history
… and unpacking
  • Loading branch information
schacon committed Sep 23, 2008
1 parent 949b98f commit 9c45b41
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 5 deletions.
8 changes: 6 additions & 2 deletions Git.h
Expand Up @@ -19,9 +19,13 @@
- (BOOL) ensureGitPath;
- (void) initGitRepo;

- (void) writeObject:(NSData *)objectData withType:(int)type withSize:(int)size;
- (NSString *) writeObject:(NSData *)objectData withType:(NSString *)type withSize:(int)size;

- (NSMutableArray *) getCommitsFromSha:(NSString *)shaValue withLimit:(int)commitSize;
- (NSString *) getLooseObjectPathBySha:(NSString *)shaValue;

@end
+ (int) isAlpha:(unsigned char)n ;
+ (int) gitUnpackHex:(const unsigned char *)rawsha fillSha:(char *)sha1;
+ (int) gitPackHex:(const char *)sha1 fillRawSha:(unsigned char *)rawsha;

@end
94 changes: 92 additions & 2 deletions Git.m
Expand Up @@ -8,6 +8,8 @@
#import "GitCommit.h"
#import "GitServerHandler.h"

#include <CommonCrypto/CommonDigest.h>

@implementation Git

@synthesize gitDirectory;
Expand Down Expand Up @@ -55,12 +57,33 @@ - (void) initGitRepo {
[fm createDirectoryAtPath:[gitDirectory stringByAppendingPathComponent:@"info"] attributes:nil];
}

- (void) writeObject:(NSData *)objectData withType:(int)type withSize:(int)size
- (NSString *) writeObject:(NSData *)objectData withType:(NSString *)type withSize:(int)size
{
NSLog(@"WRITE OBJECT");
NSMutableData *object;
NSString *header, *path, *shaStr;
unsigned char rawsha[20];
char sha1[41];

header = [NSString stringWithFormat:@"%@ %d", type, size];
NSLog(@"header: %@", header);

const char *headerBytes = [header cStringUsingEncoding:NSASCIIStringEncoding];

object = [NSMutableData dataWithBytes:headerBytes length:([header length] + 1)];
[object appendData:objectData];

CC_SHA1([object bytes], [object length], rawsha);
[Git gitUnpackHex:rawsha fillSha:sha1];
NSLog(@"SHAR: %s", sha1);

// write object to file
shaStr = [NSString stringWithCString:sha1 encoding:NSASCIIStringEncoding];
path = [self getLooseObjectPathBySha:shaStr];
[object writeToFile:path atomically:YES];
return shaStr;
}


- (BOOL) openRepo:(NSString *)dirPath
{
gitDirectory = dirPath;
Expand Down Expand Up @@ -99,8 +122,75 @@ - (NSString *) getLooseObjectPathBySha: (NSString *)shaValue
NSString *looseSubDir = [shaValue substringWithRange:NSMakeRange(0, 2)];
NSString *looseFileName = [shaValue substringWithRange:NSMakeRange(2, 38)];

NSString *dir = [NSString stringWithFormat: @"%@/objects/%@", gitDirectory, looseSubDir];

BOOL isDir;
NSFileManager *fm = [NSFileManager defaultManager];
if (!([fm fileExistsAtPath:dir isDirectory:&isDir] && isDir)) {
[fm createDirectoryAtPath:dir attributes:nil];
}

return [NSString stringWithFormat: @"%@/objects/%@/%@", \
gitDirectory, looseSubDir, looseFileName];
}


/*
* returns 1 if the char is alphanumeric, 0 if not
*/
+ (int) isAlpha:(unsigned char)n
{
if(n <= 102 && n >= 97) {
return 1;
}
return 0;
}

/*
* fills a 40-char string with a readable hex version of 20-char sha binary
*/
+ (int) gitUnpackHex:(const unsigned char *)rawsha fillSha:(char *)sha1
{
static const char hex[] = "0123456789abcdef";
int i;

for (i = 0; i < 20; i++) {
unsigned char n = rawsha[i];
sha1[i * 2] = hex[((n >> 4) & 15)];
n <<= 4;
sha1[(i * 2) + 1] = hex[((n >> 4) & 15)];
}
sha1[40] = 0;

return 1;
}

/*
* fills 20-char sha from 40-char hex version
*/
+ (int) gitPackHex:(const char *)sha1 fillRawSha:(unsigned char *)rawsha
{
unsigned char byte = 0;
int i, j = 0;

for (i = 1; i <= 40; i++) {
unsigned char n = sha1[i - 1];

if([Git isAlpha:n]) {
byte |= ((n & 15) + 9) & 15;
} else {
byte |= (n & 15);
}
if(i & 1) {
byte <<= 4;
} else {
rawsha[j] = (byte & 0xff);
j++;
byte = 0;
}
}
return 1;
}

@end

1 change: 1 addition & 0 deletions GitServerHandler.h
Expand Up @@ -33,6 +33,7 @@
- (void) readPack;
- (void) writeRefs;
- (NSData *) readData:(int)size;
- (NSString *) typeString:(int)type;

- (int) readPackHeader;
- (void) unpackObject;
Expand Down
14 changes: 13 additions & 1 deletion GitServerHandler.m
Expand Up @@ -171,7 +171,7 @@ - (void) unpackObject {
if((type == OBJ_COMMIT) || (type == OBJ_TREE) || (type == OBJ_BLOB) || (type == OBJ_TAG)) {
NSData *objectData;
objectData = [self readData:size];
[gitRepo writeObject:objectData withType:type withSize:size];
[gitRepo writeObject:objectData withType:[self typeString:type] withSize:size];
// TODO : check saved delta objects
} else if ((type == OBJ_REF_DELTA) || (type == OBJ_OFS_DELTA)) {
NSLog(@"NO SUPPORT FOR DELTAS YET");
Expand All @@ -180,6 +180,18 @@ - (void) unpackObject {
}
}

- (NSString *) typeString:(int)type {
if (type == OBJ_COMMIT)
return @"commit";
if (type == OBJ_TREE)
return @"tree";
if (type == OBJ_BLOB)
return @"blob";
if (type == OBJ_TAG)
return @"tag";
return @"";
}

- (NSData *) readData:(int)size {
// read in the data
NSMutableData *decompressed = [NSMutableData dataWithLength: size];
Expand Down

0 comments on commit 9c45b41

Please sign in to comment.