123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- #import "ReaderDocument.h"
- #import "CGPDFDocument.h"
- #import <fcntl.h>
- @interface ReaderDocument ()
- @property (nonatomic, strong, readwrite) NSString *password;
- @property (nonatomic, strong, readwrite) NSString *filePath;
- @end
- @implementation ReaderDocument
- {
- NSString *_guid;
- NSDate *_fileDate;
- NSDate *_lastOpen;
- NSNumber *_fileSize;
- NSNumber *_pageCount;
- NSNumber *_pageNumber;
- NSMutableIndexSet *_bookmarks;
- NSString *_password;
- NSString *_fileName;
- NSString *_filePath;
- NSURL *_fileURL;
- }
- #pragma mark - Properties
- @synthesize guid = _guid;
- @synthesize fileDate = _fileDate;
- @synthesize lastOpen = _lastOpen;
- @synthesize fileSize = _fileSize;
- @synthesize pageCount = _pageCount;
- @synthesize pageNumber = _pageNumber;
- @synthesize bookmarks = _bookmarks;
- @synthesize password = _password;
- @synthesize filePath = _filePath;
- @dynamic fileName, fileURL;
- @dynamic canEmail, canExport, canPrint;
- #pragma mark - ReaderDocument class methods
- + (NSString *)GUID
- {
- CFUUIDRef theUUID = CFUUIDCreate(NULL);
- CFStringRef theString = CFUUIDCreateString(NULL, theUUID);
- NSString *unique = [NSString stringWithString:(__bridge id)theString];
- CFRelease(theString); CFRelease(theUUID);
- return unique;
- }
- + (NSString *)documentsPath
- {
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSURL *pathURL = [fileManager URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
- return [pathURL path];
- }
- + (NSString *)applicationSupportPath
- {
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSURL *pathURL = [fileManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
- return [pathURL path];
- }
- + (NSString *)archiveFilePath:(NSString *)fileName
- {
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSString *applicationSupportPath = [ReaderDocument applicationSupportPath];
- NSString *archivePath = [applicationSupportPath stringByAppendingPathComponent:@"Reader Metadata"];
- [fileManager createDirectoryAtPath:archivePath withIntermediateDirectories:NO attributes:nil error:NULL];
- NSString *archiveName = [[fileName stringByDeletingPathExtension] stringByAppendingPathExtension:@"plist"];
- return [archivePath stringByAppendingPathComponent:archiveName];
- }
- + (ReaderDocument *)unarchiveFromFileName:(NSString *)filePath password:(NSString *)phrase
- {
- ReaderDocument *document = nil;
- NSString *fileName = [filePath lastPathComponent];
- NSString *archiveFilePath = [ReaderDocument archiveFilePath:fileName];
- @try
- {
- document = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
- if (document != nil)
- {
- document.filePath = [filePath copy]; document.password = [phrase copy];
- }
- }
- @catch (NSException *exception)
- {
- #ifdef DEBUG
- NSLog(@"%s Caught %@: %@", __FUNCTION__, [exception name], [exception reason]);
- #endif
- }
- return document;
- }
- + (ReaderDocument *)withDocumentFilePath:(NSString *)filePath password:(NSString *)phrase
- {
- ReaderDocument *document = nil;
- document = [ReaderDocument unarchiveFromFileName:filePath password:phrase];
- if (document == nil)
- {
- document = [[ReaderDocument alloc] initWithFilePath:filePath password:phrase];
- }
- return document;
- }
- + (BOOL)isPDF:(NSString *)filePath
- {
- BOOL state = NO;
- if (filePath != nil)
- {
- const char *path = [filePath fileSystemRepresentation];
- int fd = open(path, O_RDONLY);
- if (fd > 0)
- {
- const char sig[1024];
- ssize_t len = read(fd, (void *)&sig, sizeof(sig));
- state = (strnstr(sig, "%PDF", len) != NULL);
- close(fd);
- }
- }
- return state;
- }
- #pragma mark - ReaderDocument instance methods
- - (instancetype)initWithFilePath:(NSString *)filePath password:(NSString *)phrase
- {
- if ((self = [super init]))
- {
- if ([ReaderDocument isPDF:filePath] == YES)
- {
- _guid = [ReaderDocument GUID];
- _password = [phrase copy];
- _filePath = [filePath copy];
- _pageNumber = [NSNumber numberWithInteger:1];
- _bookmarks = [NSMutableIndexSet new];
- CFURLRef docURLRef = (__bridge CFURLRef)[self fileURL];
- CGPDFDocumentRef thePDFDocRef = CGPDFDocumentCreateUsingUrl(docURLRef, _password);
- if (thePDFDocRef != NULL)
- {
- NSInteger pageCount = CGPDFDocumentGetNumberOfPages(thePDFDocRef);
- _pageCount = [NSNumber numberWithInteger:pageCount];
- CGPDFDocumentRelease(thePDFDocRef);
- }
- else
- {
- NSAssert(NO, @"CGPDFDocumentRef == NULL");
- }
- _lastOpen = [NSDate dateWithTimeIntervalSinceReferenceDate:0.0];
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:_filePath error:NULL];
- _fileDate = [fileAttributes objectForKey:NSFileModificationDate];
- _fileSize = [fileAttributes objectForKey:NSFileSize];
- [self archiveDocumentProperties];
- }
- else
- {
- self = nil;
- }
- }
- return self;
- }
- - (NSString *)fileName
- {
- if (_fileName == nil) _fileName = [_filePath lastPathComponent];
- return _fileName;
- }
- - (NSURL *)fileURL
- {
- if (_fileURL == nil) _fileURL = [[NSURL alloc] initFileURLWithPath:_filePath isDirectory:NO];
- return _fileURL;
- }
- - (BOOL)canEmail
- {
- return YES;
- }
- - (BOOL)canExport
- {
- return YES;
- }
- - (BOOL)canPrint
- {
- return YES;
- }
- - (BOOL)archiveDocumentProperties
- {
- NSString *archiveFilePath = [ReaderDocument archiveFilePath:[self fileName]];
- return [NSKeyedArchiver archiveRootObject:self toFile:archiveFilePath];
- }
- - (void)updateDocumentProperties
- {
- CFURLRef docURLRef = (__bridge CFURLRef)[self fileURL];
- CGPDFDocumentRef thePDFDocRef = CGPDFDocumentCreateUsingUrl(docURLRef, _password);
- if (thePDFDocRef != NULL)
- {
- NSInteger pageCount = CGPDFDocumentGetNumberOfPages(thePDFDocRef);
- _pageCount = [NSNumber numberWithInteger:pageCount];
- CGPDFDocumentRelease(thePDFDocRef);
- }
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:_filePath error:NULL];
- _fileDate = [fileAttributes objectForKey:NSFileModificationDate];
- _fileSize = [fileAttributes objectForKey:NSFileSize];
- }
- #pragma mark - NSCoding protocol methods
- - (void)encodeWithCoder:(NSCoder *)encoder
- {
- [encoder encodeObject:_guid forKey:@"FileGUID"];
- [encoder encodeObject:_fileDate forKey:@"FileDate"];
- [encoder encodeObject:_pageCount forKey:@"PageCount"];
- [encoder encodeObject:_pageNumber forKey:@"PageNumber"];
- [encoder encodeObject:_bookmarks forKey:@"Bookmarks"];
- [encoder encodeObject:_fileSize forKey:@"FileSize"];
- [encoder encodeObject:_lastOpen forKey:@"LastOpen"];
- }
- - (instancetype)initWithCoder:(NSCoder *)decoder
- {
- if ((self = [super init]))
- {
- _guid = [decoder decodeObjectForKey:@"FileGUID"];
- _fileDate = [decoder decodeObjectForKey:@"FileDate"];
- _pageCount = [decoder decodeObjectForKey:@"PageCount"];
- _pageNumber = [decoder decodeObjectForKey:@"PageNumber"];
- _bookmarks = [decoder decodeObjectForKey:@"Bookmarks"];
- _fileSize = [decoder decodeObjectForKey:@"FileSize"];
- _lastOpen = [decoder decodeObjectForKey:@"LastOpen"];
- if (_guid == nil) _guid = [ReaderDocument GUID];
- if (_bookmarks != nil)
- _bookmarks = [_bookmarks mutableCopy];
- else
- _bookmarks = [NSMutableIndexSet new];
- }
- return self;
- }
- @end
|