Revision: 4340
          http://skim-app.svn.sourceforge.net/skim-app/?rev=4340&view=rev
Author:   hofman
Date:     2008-08-03 10:17:53 +0000 (Sun, 03 Aug 2008)

Log Message:
-----------
Make dictionaries to lookup tex files case insensitive. Borrow code for case 
insensitive callbacks from BibDesk.

Modified Paths:
--------------
    trunk/SKCFCallBacks.h
    trunk/SKCFCallBacks.m
    trunk/SKPDFSynchronizer.m

Modified: trunk/SKCFCallBacks.h
===================================================================
--- trunk/SKCFCallBacks.h       2008-08-02 23:55:43 UTC (rev 4339)
+++ trunk/SKCFCallBacks.h       2008-08-03 10:17:53 UTC (rev 4340)
@@ -45,6 +45,11 @@
 extern CFStringRef SKNSObjectCopyDescription(const void *value);
 
 
+extern Boolean SKCaseInsensitiveStringEqual(const void *value1, const void 
*value2);
+
+extern CFHashCode SKCaseInsensitiveStringHash(const void *value);
+
+
 extern const void *SKFloatRetain(CFAllocatorRef allocator, const void *value);
 
 extern void SKFloatRelease(CFAllocatorRef allocator, const void *value);
@@ -65,8 +70,12 @@
 
 extern const CFDictionaryKeyCallBacks 
SKPointerEqualObjectDictionaryKeyCallbacks;
 
+extern const CFDictionaryKeyCallBacks SKCaseInsensitiveDictionaryKeyCallbacks;
+
 extern const CFDictionaryValueCallBacks SKFloatDictionaryValueCallbacks;
 
+extern const CFDictionaryValueCallBacks SKFloatDictionaryValueCallbacks;
+
 extern const CFDictionaryValueCallBacks SKNSRectDictionaryValueCallbacks;
 
 

Modified: trunk/SKCFCallBacks.m
===================================================================
--- trunk/SKCFCallBacks.m       2008-08-02 23:55:43 UTC (rev 4339)
+++ trunk/SKCFCallBacks.m       2008-08-03 10:17:53 UTC (rev 4340)
@@ -38,6 +38,7 @@
 
 #import "SKCFCallBacks.h"
 
+#define STACK_BUFFER_SIZE 256
 
 const void *SKNSObjectRetain(CFAllocatorRef allocator, const void *value) {
     return [(id)value retain];
@@ -51,6 +52,97 @@
     return (CFStringRef)[[(id)value description] retain];
 }
 
+Boolean SKCaseInsensitiveStringEqual(const void *value1, const void *value2) {
+    return (CFStringCompareWithOptions(value1, value2, CFRangeMake(0, 
CFStringGetLength(value1)), kCFCompareCaseInsensitive) == kCFCompareEqualTo);
+}
+
+CFHashCode SKCaseInsensitiveStringHash(const void *value)
+{
+    if(value == NULL) return 0;
+    
+    CFAllocatorRef allocator = CFGetAllocator(value);
+    CFIndex len = CFStringGetLength(value);
+    
+    // use a generous length, in case the lowercase changes the number of 
characters
+    UniChar *buffer, stackBuffer[STACK_BUFFER_SIZE];
+    if(len + 10 >= STACK_BUFFER_SIZE) {
+        buffer = (UniChar *)CFAllocatorAllocate(allocator, (len + 10) * 
sizeof(UniChar), 0);
+    } else {
+        buffer = stackBuffer;
+    }
+    CFStringGetCharacters(value, CFRangeMake(0, len), buffer);
+    
+    // If we create the string with external characters, 
CFStringGetCharactersPtr is guaranteed to succeed; since we're going to call 
CFStringGetCharacters anyway in fastHash if CFStringGetCharactsPtr fails, let's 
do it now when we lowercase the string
+    CFMutableStringRef mutableString = 
CFStringCreateMutableWithExternalCharactersNoCopy(allocator, buffer, len, len + 
10, (buffer != stackBuffer ? allocator : kCFAllocatorNull));
+    CFStringLowercase(mutableString, NULL);
+    
+    // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+    // or anything like that.
+    static const uint32_t PHI = 0x9e3779b9U;
+    
+    // Paul Hsieh's SuperFastHash
+    // http://www.azillionmonkeys.com/qed/hash.html
+    // Implementation from Apple's WebCore/khtml/xml/dom_stringimpl.cpp, 
designed
+    // to hash UTF-16 characters.
+    
+    unsigned l = CFStringGetLength(mutableString);
+    uint32_t hash = PHI;
+    uint32_t tmp;
+    
+    const UniChar *s = CFStringGetCharactersPtr(mutableString);
+    UniChar *buf = NULL, stackBuf[STACK_BUFFER_SIZE];
+    
+    if (s == NULL) {
+        
+        if (l > STACK_BUFFER_SIZE) {
+            buf = (UniChar *)CFAllocatorAllocate(allocator, l * 
sizeof(UniChar), 0);
+            NSCAssert(buf != NULL, @"unable to allocate memory");
+        } else {
+            buf = stackBuf;
+        }
+        CFStringGetCharacters(mutableString, CFRangeMake(0, l), buf);
+        s = buf;
+    }
+    
+    int rem = l & 1;
+    l >>= 1;
+    
+    // Main loop
+    for (; l > 0; l--) {
+        hash += s[0];
+        tmp = (s[1] << 11) ^ hash;
+        hash = (hash << 16) ^ tmp;
+        s += 2;
+        hash += hash >> 11;
+    }
+    
+    // Handle end case
+    if (rem) {
+        hash += s[0];
+        hash ^= hash << 11;
+        hash += hash >> 17;
+    }
+    
+    if (buf != stackBuf) CFAllocatorDeallocate(allocator, buf);
+    
+    // Force "avalanching" of final 127 bits
+    hash ^= hash << 3;
+    hash += hash >> 5;
+    hash ^= hash << 2;
+    hash += hash >> 15;
+    hash ^= hash << 10;
+    
+    // this avoids ever returning a hash code of 0, since that is used to
+    // signal "hash not computed yet", using a value that is likely to be
+    // effectively the same as 0 when the low bits are masked
+    if (hash == 0)
+        hash = 0x80000000;
+    
+    // if we used the allocator, this should free the buffer for us
+    CFRelease(mutableString);
+    return hash;
+}
+    
 const void *SKFloatRetain(CFAllocatorRef allocator, const void *value) {
     float *floatPtr = (float *)CFAllocatorAllocate(allocator, sizeof(float), 
0);
     *floatPtr = *(float *)value;
@@ -96,6 +188,15 @@
     NULL // hash
 };
 
+const CFDictionaryKeyCallBacks SKCaseInsensitiveDictionaryKeyCallbacks = {
+    0,   // version
+    SKNSObjectRetain,
+    SKNSObjectRelease,
+    SKNSObjectCopyDescription,
+    SKCaseInsensitiveStringEqual,
+    SKCaseInsensitiveStringHash
+};
+
 const CFDictionaryValueCallBacks SKFloatDictionaryValueCallbacks = {
     0, // version
     SKFloatRetain,

Modified: trunk/SKPDFSynchronizer.m
===================================================================
--- trunk/SKPDFSynchronizer.m   2008-08-02 23:55:43 UTC (rev 4339)
+++ trunk/SKPDFSynchronizer.m   2008-08-03 10:17:53 UTC (rev 4340)
@@ -44,6 +44,7 @@
 #import <Carbon/Carbon.h>
 #import "Files_SKExtensions.h"
 #import "NSString_SKExtensions.h"
+#import "SKCFCallBacks.h"
 
 #define SYNC_TO_PDF(coord) ((float)coord / 65536.0)
 #define PDF_TO_SYNC(coord) (int)(coord * 65536.0)
@@ -56,7 +57,7 @@
         file = [file 
stringByAppendingPathExtension:SKPDFSynchronizerTexExtension];
     if ([file isAbsolutePath] == NO)
         file = [base stringByAppendingPathComponent:file];
-    return SKRealPath(file);
+    return file;
 }
 
 #pragma mark -
@@ -99,9 +100,9 @@
         isPdfsync = YES;
         
         pages = [[NSMutableArray alloc] init];
-        lines = [[NSMutableDictionary alloc] init];
+        lines = (NSMutableDictionary 
*)CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&SKCaseInsensitiveDictionaryKeyCallbacks, &kCFTypeDictionaryValueCallBacks);
         
-        filenames = [[NSMutableDictionary alloc] init];
+        filenames = (NSMutableDictionary 
*)CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&SKCaseInsensitiveDictionaryKeyCallbacks, &kCFTypeDictionaryValueCallBacks);
         scanner = NULL;
         
         NSPort *port1 = [NSPort port];
@@ -663,8 +664,6 @@
         NSPoint foundPoint = NSZeroPoint;
         BOOL success = NO;
         
-        file = SKRealPath(file);
-        
         if (isPdfsync)
             success = [self pdfsyncFindPage:&foundPageIndex 
location:&foundPoint forLine:line inFile:file];
         else


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 the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to