On 25 août 2011, at 07:58, Roberto Colnaghi wrote: int collationAnyCIAI(void *arg1, int str1Length, const void *str1, int str2Length, const void *str2) { NSString *strA = [NSString hexStringWithData:str1 ofLength:1]; NSString *strB = [NSString hexStringWithData:str2 ofLength:1]; int striA; sscanf([strA cString], "%x", &striA); int striB; sscanf([strB cString], "%x", &striB);
I am a lot more experienced with iOS than SQLite, so my 2 cents are biased. In particular, I have never had to use a custom collation for SQLite. That being said, the snippet of code I quoted makes me cringe a little, and unless you have reasons to avoid Cocoa [Touch] entirely, why don't you use it? In the present case, the NSString class has extensive comparison options, including the following: NSDiacriticInsensitiveSearch Search ignores diacritic marks. For example, ‘ö’ is equal to ‘o’. Available in iOS 2.0 and later. Declared in NSString.h. This option is passed to: - (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask Using this option is as simple as calling: return [strA compare:strB options: NSDiacriticInsensitiveSearch]; You also have variations that take into account the user's current locale: return [strA localizedCompare:strB]; return [strA localizedCaseInsensitiveCompare:strB]; As those two routines end up calling - (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)range locale:(id)locale They call it passing the current user locale as the locale ([NSLocale currentLocale]), and the string full range as the range. You could even use a "smart" comparison using return [strA localizedStandardCompare: strB] The methods orders strings in a "natural" order "as in the Finder". For example, it would order the strings "file 9.txt", "file 20.txt", "file 100.txt" in that order. (By the way, the result returned by Cocoa string comparison methods seems compatible with what SQLite expects: enum { NSOrderedAscending<file:///Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS5_0.iOSLibrary.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html#//apple_ref/doc/c_ref/NSOrderedAscending> = -1, NSOrderedSame<file:///Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS5_0.iOSLibrary.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html#//apple_ref/doc/c_ref/NSOrderedSame>, NSOrderedDescending<file:///Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS5_0.iOSLibrary.docset/Contents/Resources/Documents/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html#//apple_ref/doc/c_ref/NSOrderedDescending> }; typedef NSInteger NSComparisonResult; if I am mistaken (I haven't looked it put), it looks like converting it should be straightforward). But maybe you have good reasons to ignore the Apple-provided collations. In that case, I still don't get why you don't work directly on the Unicode strings. You call hexStringWithData:ofLength: (which is not an Apple method and for which you don't provide the code). Why? What would be wrong with: NSString *strA = [[NSString alloc] initWithUTF8String:str1]; // release me before returning NSString *strB = [[NSString alloc] initWithUTF8String:str2]; // release me before returning Or, if the strings from SQLite are not UTF-8 encoded, use - (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding Then you don't have to do this wasteful charade with hex conversion. Finally, if hexStringWithData:ofLength: is properly implemented, it returns an autoreleased string. If the collation routine is called a lot by SQLite, you will allocate NSStrings like crazy, which is not good citizenship on an iPhone that could lead your app to be killed by the OS, even if the autoreleased strings eventually get deallocated the next time in the run loop. Unless you wrap the whole enchilada in your own autorelease pool (you didn't show that). In your specific case, it's better to allocate and release your NSStrings right in your collation routine. I hope this helps a little. JD _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users