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

Reply via email to