cog/Plugins/FileSource/FileSource.m

149 lines
2.2 KiB
Objective-C

//
// FileSource.m
// FileSource
//
// Created by Vincent Spader on 3/1/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "FileSource.h"
@implementation FileSource
+ (void)initialize {
fex_init();
}
- (id)init {
self = [super init];
if(self) {
fex = NULL;
_fd = NULL;
}
return self;
}
- (BOOL)open:(NSURL *)url {
[self setURL:url];
NSString *path = [url path];
fex_type_t type;
fex_err_t error = fex_identify_file(&type, [path UTF8String]);
if(!error && type && strcmp(fex_type_name(type), "file")) {
error = fex_open_type(&fex, [path UTF8String], type);
if(!error) {
while(!fex_done(fex)) {
NSString *name = [[NSString stringWithUTF8String:fex_name(fex)] lowercaseString];
if([name hasSuffix:@".diz"] || [name hasSuffix:@".txt"] || [name hasSuffix:@".nfo"]) {
error = fex_next(fex);
if(error)
return NO;
continue;
}
break;
}
if(fex_done(fex))
return NO;
error = fex_data(fex, &data);
if(error)
return NO;
size = fex_size(fex);
offset = 0;
return YES;
} else
return NO;
}
_fd = fopen([path UTF8String], "r");
return (_fd != NULL);
}
- (BOOL)seekable {
return YES;
}
- (BOOL)seek:(long)position whence:(int)whence {
if(fex) {
switch(whence) {
case SEEK_CUR:
position += offset;
break;
case SEEK_END:
position += size;
break;
}
offset = position;
return (position >= 0) && (position < size);
}
if(_fd == NULL) {
offset = 0;
size = 0;
return NO;
}
return (fseek(_fd, position, whence) == 0);
}
- (long)tell {
if(fex)
return offset;
else
return ftell(_fd);
}
- (long)read:(void *)buffer amount:(long)amount {
if(fex) {
if(amount + offset > size)
amount = size - offset;
memcpy(buffer, (const char *)data + offset, amount);
offset += amount;
return amount;
} else {
return fread(buffer, 1, amount, _fd);
}
}
- (void)close {
if(_fd) {
fclose(_fd);
_fd = NULL;
}
if(fex) {
fex_close(fex);
fex = NULL;
}
}
- (NSURL *)url {
return _url;
}
- (NSString *)mimeType {
return nil;
}
- (void)setURL:(NSURL *)url {
_url = url;
}
+ (NSArray *)schemes {
return @[@"file"];
}
- (void)dealloc {
[self close];
}
@end