Revision: 2861
http://skim-app.svn.sourceforge.net/skim-app/?rev=2861&view=rev
Author: hofman
Date: 2007-09-09 10:32:04 -0700 (Sun, 09 Sep 2007)
Log Message:
-----------
Rewrite scanning to use a parser instance, so we don't need to pass the
dictionary everywhere.
Modified Paths:
--------------
trunk/SKDocument.m
trunk/SKFDFParser.h
trunk/SKFDFParser.m
Modified: trunk/SKDocument.m
===================================================================
--- trunk/SKDocument.m 2007-09-09 16:54:30 UTC (rev 2860)
+++ trunk/SKDocument.m 2007-09-09 17:32:04 UTC (rev 2861)
@@ -684,7 +684,7 @@
} else {
NSString *fdfString = [NSString stringWithContentsOfURL:notesURL
encoding:NSISOLatin1StringEncoding error:NULL];
if (fdfString)
- array = [SKFDFParser notesDictionariesFromFDFString:fdfString];
+ array = [SKFDFParser noteDictionariesFromFDFString:fdfString];
}
if (array) {
Modified: trunk/SKFDFParser.h
===================================================================
--- trunk/SKFDFParser.h 2007-09-09 16:54:30 UTC (rev 2860)
+++ trunk/SKFDFParser.h 2007-09-09 17:32:04 UTC (rev 2861)
@@ -39,7 +39,9 @@
#import <Cocoa/Cocoa.h>
[EMAIL PROTECTED] SKFDFParser : NSObject
-+ (NSArray *)notesDictionariesFromFDFString:(NSString *)string;
-+ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string;
[EMAIL PROTECTED] SKFDFParser : NSObject {
+ NSDictionary *fdfDictionary;
+ NSString *fdfString;
+}
++ (NSArray *)noteDictionariesFromFDFString:(NSString *)string;
@end
Modified: trunk/SKFDFParser.m
===================================================================
--- trunk/SKFDFParser.m 2007-09-09 16:54:30 UTC (rev 2860)
+++ trunk/SKFDFParser.m 2007-09-09 17:32:04 UTC (rev 2861)
@@ -41,6 +41,20 @@
#import "NSScanner_SKExtensions.h"
#import "NSCharacterSet_SKExtensions.h"
+
[EMAIL PROTECTED] SKFDFParser (SKPrivate)
+- (id)initWithString:(NSString *)aString;
+- (BOOL)parseFDFString;
+- (NSArray *)noteDictionaries;
+- (NSDictionary *)noteDictionary:(NSDictionary *)dict;
+- (id)value:(id)value ofClass:(Class)aClass;
+- (NSString *)stringValue:(id)value;
+- (NSNumber *)numberValue:(id)value;
+- (NSArray *)arrayValue:(id)value;
+- (NSDictionary *)dictionaryValue:(id)value;
[EMAIL PROTECTED]
+
+
@interface NSScanner (SKFDFParserExtensions)
- (BOOL)scanFDFObject:(id *)object;
- (BOOL)scanFDFArray:(NSArray **)array;
@@ -70,13 +84,166 @@
@implementation SKFDFParser
-+ (id)value:(id)value ofClass:(Class)aClass lookup:(NSDictionary *)lookup {
++ (NSArray *)noteDictionariesFromFDFString:(NSString *)string {
+ NSArray *notes = nil;
+ SKFDFParser *parser = [[self alloc] initWithString:string];
+
+ if ([parser parseFDFString])
+ notes = [parser noteDictionaries];
+ [parser release];
+
+ return notes;
+}
+
+- (id)initWithString:(NSString *)string {
+ if (self = [super init]) {
+ fdfString = [string retain];
+ fdfDictionary = nil;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [fdfString release];
+ [fdfDictionary release];
+ [super dealloc];
+}
+
+- (BOOL)parseFDFString {
+ NSMutableDictionary *fdfDict = [[NSMutableDictionary alloc] init];
+
+ NSDictionary *dictionary;
+ int objNumber, genNumber;
+ id object;
+ BOOL success = YES;
+
+ NSScanner *scanner = [[NSScanner alloc] initWithString:fdfString];
+
+ // Scan the FDF header
+ [scanner scanString:@"%FDF-1.2" intoString:NULL];
+ while ([scanner scanFDFComment:NULL]);
+
+ // Scan the FDF body
+ while (success && [scanner scanInt:&objNumber]) {
+ while ([scanner scanFDFComment:NULL]);
+ if (success = [scanner scanInt:&genNumber]) {
+ while ([scanner scanFDFComment:NULL]);
+ if ([scanner scanString:@"obj" intoString:NULL]) {
+ if (success = [scanner scanFDFObject:&object]) {
+ if ([object isKindOfClass:[NSDictionary class]]) {
+ while ([scanner scanFDFComment:NULL]);
+ if ([scanner scanString:@"stream" intoString:NULL]) {
+ object = @"";
+ [scanner scanString:@"\n" intoString:NULL] ||
[scanner scanString:@"\r\n" intoString:NULL];
+
+ if ([scanner scanUpToString:@"endstream"
intoString:&object]) {
+ int end = [object length];
+ unichar ch = end ? [object
characterAtIndex:end - 1] : 0;
+ if ([[NSCharacterSet newlineCharacterSet]
characterIsMember:ch]) {
+ end--;
+ if (end && ch == '\n' && [object
characterAtIndex:end - 1] == '\r')
+ end--;
+ object = [object substringToIndex:end];
+ }
+ }
+ [scanner scanString:@"endstream" intoString:NULL];
+ }
+ [fdfDict setObject:object forKey:[SKIndirectObject
indirectObjectWithNumber:objNumber generation:genNumber]];
+ while ([scanner scanFDFComment:NULL]);
+ success = [scanner scanString:@"endobj"
intoString:NULL];
+ while ([scanner scanFDFComment:NULL]);
+ }
+ }
+ }
+ }
+ }
+
+ // Scan the FDF cross reference table, if present
+ if (success) {
+ while ([scanner scanString:@"xref" intoString:NULL]) {
+ while ([scanner scanFDFComment:NULL]);
+ while ([scanner scanInt:NULL]) {
+ while ([scanner scanFDFComment:NULL]);
+ }
+ }
+ }
+
+ // Scan the FDF trailer
+ if (success = success && [scanner scanString:@"trailer" intoString:NULL]) {
+ while ([scanner scanFDFComment:NULL]);
+ if (success = [scanner scanFDFDictionary:&dictionary]) {
+ while ([scanner scanFDFComment:NULL]);
+ [fdfDict setObject:dictionary forKey:@"trailer"];
+ [scanner scanString:@"%%EOF" intoString:NULL];
+ }
+ }
+
+ [scanner release];
+
+ if (success)
+ fdfDictionary = fdfDict;
+ else
+ [fdfDict release];
+
+ return success;
+}
+
+- (NSArray *)noteDictionaries {
+ NSMutableArray *array = nil;
+ NSDictionary *trailer;
+ SKIndirectObject *root;
+ NSDictionary *rootDict;
+ NSDictionary *fdfDict;
+ NSArray *annots;
+
+ if ((trailer = [fdfDictionary objectForKey:@"trailer"]) &&
+ ([trailer isKindOfClass:[NSDictionary class]]) &&
+ (root = [trailer objectForKey:@"Root"]) &&
+ ([root isKindOfClass:[SKIndirectObject class]]) &&
+ (rootDict = [fdfDictionary objectForKey:root]) &&
+ ([rootDict isKindOfClass:[NSDictionary class]]) &&
+ (fdfDict = [rootDict objectForKey:@"FDF"]) &&
+ ([fdfDict isKindOfClass:[NSDictionary class]]) &&
+ (annots = [fdfDict objectForKey:@"Annots"]) &&
+ ([annots isKindOfClass:[NSArray class]])) {
+
+ NSEnumerator *annotEnum = [annots objectEnumerator];
+ NSDictionary *dict;
+
+ array = [NSMutableArray array];
+ while (dict = [annotEnum nextObject]) {
+ if ((dict = [self dictionaryValue:dict]) &&
+ (dict = [self noteDictionary:dict]))
+ [array addObject:dict];
+ }
+ }
+
+ return array;
+}
+
+- (id)value:(id)value ofClass:(Class)aClass {
while ([value isKindOfClass:[SKIndirectObject class]])
- value = [lookup objectForKey:value];
- return ([value isKindOfClass:aClass]) ? value : nil;
+ value = [fdfDictionary objectForKey:value];
+ return (aClass == Nil || [value isKindOfClass:aClass]) ? value : nil;
}
-+ (NSDictionary *)noteDictionary:(NSDictionary *)dict lookup:(NSDictionary
*)lookup {
+- (NSString *)stringValue:(id)value {
+ return [self value:value ofClass:[NSString class]];
+}
+
+- (NSNumber *)numberValue:(id)value {
+ return [self value:value ofClass:[NSNumber class]];
+}
+
+- (NSArray *)arrayValue:(id)value {
+ return [self value:value ofClass:[NSArray class]];
+}
+
+- (NSDictionary *)dictionaryValue:(id)value {
+ return [self value:value ofClass:[NSDictionary class]];
+}
+
+- (NSDictionary *)noteDictionary:(NSDictionary *)dict {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSSet *validTypes = [NSSet setWithObjects:@"FreeText", @"Note", @"Circle",
@"Square", @"Highlight", @"Underline", @"StrikeOut", @"Line", nil];
NSEnumerator *keyEnum = [dict keyEnumerator];
@@ -87,7 +254,7 @@
id value = [dict valueForKey:key];
if ([key isEqualToString:@"Type"]) {
- if (value = [self value:value ofClass:[NSString class]
lookup:lookup]) {
+ if (value = [self stringValue:value]) {
if ([value isEqualToString:@"Annot"] == NO) {
success = NO;
}
@@ -95,7 +262,7 @@
success = NO;
}
} else if ([key isEqualToString:@"Subtype"]) {
- if (value = [self value:value ofClass:[NSString class]
lookup:lookup]) {
+ if (value = [self stringValue:value]) {
if ([value isEqualToString:@"Text"])
value = @"Note";
if ([validTypes containsObject:value]) {
@@ -107,17 +274,17 @@
success = NO;
}
} else if ([key isEqualToString:@"Contents"]) {
- if (value = [self value:value ofClass:[NSString class]
lookup:lookup]) {
+ if (value = [self stringValue:value]) {
[dictionary setObject:value forKey:@"contents"];
} else {
success = NO;
}
} else if ([key isEqualToString:@"Rect"]) {
- if ((value = [self value:value ofClass:[NSArray class]
lookup:lookup]) && [value count] == 4) {
- NSNumber *l = [self value:[value objectAtIndex:0]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *b = [self value:[value objectAtIndex:1]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *r = [self value:[value objectAtIndex:2]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *t = [self value:[value objectAtIndex:3]
ofClass:[NSNumber class] lookup:lookup];
+ if ((value = [self arrayValue:value]) && [value count] == 4) {
+ NSNumber *l = [self numberValue:[value objectAtIndex:0]];
+ NSNumber *b = [self numberValue:[value objectAtIndex:1]];
+ NSNumber *r = [self numberValue:[value objectAtIndex:2]];
+ NSNumber *t = [self numberValue:[value objectAtIndex:3]];
if (l && b && r && t) {
NSRect rect;
rect.origin.x = [l floatValue];
@@ -132,16 +299,16 @@
success = NO;
}
} else if ([key isEqualToString:@"Page"]) {
- if (value = [self value:value ofClass:[NSNumber class]
lookup:lookup]) {
+ if (value = [self numberValue:value]) {
[dictionary setObject:value forKey:@"pageIndex"];
} else {
success = NO;
}
} else if ([key isEqualToString:@"C"]) {
- if ((value = [self value:value ofClass:[NSArray class]
lookup:lookup]) && [value count] == 3) {
- NSNumber *r = [self value:[value objectAtIndex:0]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *g = [self value:[value objectAtIndex:1]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *b = [self value:[value objectAtIndex:2]
ofClass:[NSNumber class] lookup:lookup];
+ if ((value = [self arrayValue:value]) && [value count] == 3) {
+ NSNumber *r = [self numberValue:[value objectAtIndex:0]];
+ NSNumber *g = [self numberValue:[value objectAtIndex:1]];
+ NSNumber *b = [self numberValue:[value objectAtIndex:2]];
if (r && g && b) {
[dictionary setObject:[NSColor colorWithCalibratedRed:[r
floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0]
forKey:@"color"];
} else {
@@ -151,10 +318,10 @@
success = NO;
}
} else if ([key isEqualToString:@"BS"]) {
- if (value = [self value:value ofClass:[NSDictionary class]
lookup:lookup]) {
- NSNumber *width = [self value:[value objectForKey:@"W"]
ofClass:[NSNumber class] lookup:lookup];
- NSString *s = [self value:[value objectForKey:@"S"]
ofClass:[NSString class] lookup:lookup];
- NSArray *dashPattern = [self value:[value objectForKey:@"D"]
ofClass:[NSArray class] lookup:lookup];
+ if (value = [self dictionaryValue:value]) {
+ NSNumber *width = [self numberValue:[value objectForKey:@"W"]];
+ NSString *s = [self stringValue:[value objectForKey:@"S"]];
+ NSArray *dashPattern = [self arrayValue:[value
objectForKey:@"D"]];
int style = kPDFBorderStyleSolid;
if ([s isEqualToString:@"S"])
style = kPDFBorderStyleSolid;
@@ -180,8 +347,8 @@
success = NO;
break;
}
- NSNumber *width = [value count] > 2 ? [self value:[value
objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup] : nil;
- NSArray *dashPattern = [value count] > 3 ? [self value:[value
objectAtIndex:2] ofClass:[NSArray class] lookup:lookup] : nil;
+ NSNumber *width = [value count] > 2 ? [self numberValue:[value
objectAtIndex:2]] : nil;
+ NSArray *dashPattern = [value count] > 3 ? [self arrayValue:[value
objectAtIndex:2]] : nil;
if (width && [width floatValue] > 0.0) {
[dictionary setObject:width forKey:@"lineWidth"];
[dictionary setObject:[NSNumber numberWithInt:dashPattern ?
kPDFBorderStyleDashed : kPDFBorderStyleSolid] forKey:@"borderStyle"];
@@ -189,7 +356,7 @@
[dictionary setObject:dashPattern forKey:@"dashPattern"];
}
} else if ([key isEqualToString:@"Name"]) {
- if (value = [self value:value ofClass:[NSString class]
lookup:lookup]) {
+ if (value = [self stringValue:value]) {
int icon = kPDFTextAnnotationIconNote;
if ([value isEqualToString:@"Comment"])
icon = kPDFTextAnnotationIconComment;
@@ -208,10 +375,10 @@
success = NO;
}
} else if ([key isEqualToString:@"IC"]) {
- if ((value = [self value:value ofClass:[NSArray class]
lookup:lookup]) && [value count] == 3) {
- NSNumber *r = [self value:[value objectAtIndex:0]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *g = [self value:[value objectAtIndex:1]
ofClass:[NSNumber class] lookup:lookup];
- NSNumber *b = [self value:[value objectAtIndex:2]
ofClass:[NSNumber class] lookup:lookup];
+ if ((value = [self arrayValue:value]) && [value count] == 3) {
+ NSNumber *r = [self numberValue:[value objectAtIndex:0]];
+ NSNumber *g = [self numberValue:[value objectAtIndex:1]];
+ NSNumber *b = [self numberValue:[value objectAtIndex:2]];
if (r && g && b) {
[dictionary setObject:[NSColor colorWithCalibratedRed:[r
floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0]
forKey:@"interiorColor"];
} else {
@@ -221,9 +388,9 @@
success = NO;
}
} else if ([key isEqualToString:@"LE"]) {
- if ((value = [self value:value ofClass:[NSArray class]
lookup:lookup]) && [value count] == 2) {
- NSString *start = [self value:[value objectAtIndex:0]
ofClass:[NSNumber class] lookup:lookup];
- NSString *end = [self value:[value objectAtIndex:1]
ofClass:[NSNumber class] lookup:lookup];
+ if ((value = [self arrayValue:value]) && [value count] == 2) {
+ NSString *start = [self stringValue:[value objectAtIndex:0]];
+ NSString *end = [self stringValue:[value objectAtIndex:1]];
int startStyle = kPDFLineStyleNone;
int endStyle = kPDFLineStyleNone;
if ([start isEqualToString:@"None"])
@@ -256,7 +423,7 @@
success = NO;
}
} else if ([key isEqualToString:@"QuadPoints"]) {
- if ((value = [self value:value ofClass:[NSArray class]
lookup:lookup]) && [value count] % 8 == 0) {
+ if ((value = [self arrayValue:value]) && [value count] % 8 == 0) {
NSMutableArray *quadPoints = [NSMutableArray array];
int i, count = [value count];
for (i = 0; i < count; i++) {
@@ -274,116 +441,6 @@
return success ? dictionary : nil;
}
-+ (NSArray *)notesDictionariesFromFDFString:(NSString *)string {
- NSMutableArray *array = nil;
- NSDictionary *fdfDict;
- NSDictionary *trailer;
- SKIndirectObject *root;
- NSDictionary *rootDict;
- NSDictionary *rootFDFDict;
- NSArray *annots;
-
- if ((fdfDict = [self fdfObjectsFromFDFString:string]) &&
- (trailer = [fdfDict objectForKey:@"trailer"]) &&
- ([trailer isKindOfClass:[NSDictionary class]]) &&
- (root = [trailer objectForKey:@"Root"]) &&
- ([root isKindOfClass:[SKIndirectObject class]]) &&
- (rootDict = [fdfDict objectForKey:root]) &&
- ([rootDict isKindOfClass:[NSDictionary class]]) &&
- (rootFDFDict = [rootDict objectForKey:@"FDF"]) &&
- ([rootFDFDict isKindOfClass:[NSDictionary class]]) &&
- (annots = [rootFDFDict objectForKey:@"Annots"]) &&
- ([annots isKindOfClass:[NSArray class]])) {
-
- NSEnumerator *annotEnum = [annots objectEnumerator];
- NSDictionary *dict;
-
- array = [NSMutableArray array];
- while (dict = [annotEnum nextObject]) {
- while ([dict isKindOfClass:[SKIndirectObject class]])
- dict = [fdfDict objectForKey:dict];
- if ([dict isKindOfClass:[NSDictionary class]] == NO)
- return nil;
- if (dict = [self noteDictionary:dict lookup:fdfDict])
- [array addObject:dict];
- }
- }
-
- return array;
-}
-
-+ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string {
- NSMutableDictionary *fdfDict = [NSMutableDictionary dictionary];
-
- NSDictionary *dictionary;
- int objNumber, genNumber;
- id object;
- BOOL success = YES;
-
- NSScanner *scanner = [NSScanner scannerWithString:string];
-
- // Scan the FDF header
- [scanner scanString:@"%FDF-1.2" intoString:NULL];
- while ([scanner scanFDFComment:NULL]);
-
- // Scan the FDF body
- while (success && [scanner scanInt:&objNumber]) {
- while ([scanner scanFDFComment:NULL]);
- if (success = [scanner scanInt:&genNumber]) {
- while ([scanner scanFDFComment:NULL]);
- if ([scanner scanString:@"obj" intoString:NULL]) {
- if (success = [scanner scanFDFObject:&object]) {
- if ([object isKindOfClass:[NSDictionary class]]) {
- while ([scanner scanFDFComment:NULL]);
- if ([scanner scanString:@"stream" intoString:NULL]) {
- object = @"";
- [scanner scanString:@"\n" intoString:NULL] ||
[scanner scanString:@"\r\n" intoString:NULL];
-
- if ([scanner scanUpToString:@"endstream"
intoString:&object]) {
- int end = [object length];
- unichar ch = end ? [object
characterAtIndex:end - 1] : 0;
- if ([[NSCharacterSet newlineCharacterSet]
characterIsMember:ch]) {
- end--;
- if (end && ch == '\n' && [object
characterAtIndex:end - 1] == '\r')
- end--;
- object = [object substringToIndex:end];
- }
- }
- [scanner scanString:@"endstream" intoString:NULL];
- }
- [fdfDict setObject:object forKey:[SKIndirectObject
indirectObjectWithNumber:objNumber generation:genNumber]];
- while ([scanner scanFDFComment:NULL]);
- success = [scanner scanString:@"endobj"
intoString:NULL];
- while ([scanner scanFDFComment:NULL]);
- }
- }
- }
- }
- }
-
- // Scan the FDF cross reference table, if present
- if (success) {
- while ([scanner scanString:@"xref" intoString:NULL]) {
- while ([scanner scanFDFComment:NULL]);
- while ([scanner scanInt:NULL]) {
- while ([scanner scanFDFComment:NULL]);
- }
- }
- }
-
- // Scan the FDF trailer
- if (success = success && [scanner scanString:@"trailer" intoString:NULL]) {
- while ([scanner scanFDFComment:NULL]);
- if (success = [scanner scanFDFDictionary:&dictionary]) {
- while ([scanner scanFDFComment:NULL]);
- [fdfDict setObject:dictionary forKey:@"trailer"];
- [scanner scanString:@"%%EOF" intoString:NULL];
- }
- }
-
- return success ? fdfDict : nil;
-}
-
@end
#pragma mark -
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit