this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

LaunchServices: Full UTTypes implementation, implement bits of LSOpen APIs

+517 -53
+1
src/frameworks/CoreServices/src/LaunchServices/CMakeLists.txt
··· 17 17 constants.c 18 18 LSInfo.m 19 19 LSOpen.m 20 + UTType.m 20 21 DEPENDENCIES 21 22 CoreFoundation 22 23 Foundation
+88 -35
src/frameworks/CoreServices/src/LaunchServices/LSInfo.m
··· 36 36 return db; 37 37 } 38 38 39 - // An SQL-safe fourcc string 40 - static NSString* fourcc(UInt32 code) 39 + __attribute__((visibility("hidden"))) 40 + NSString* escape(NSString* str) 41 41 { 42 - char buf[9]; 43 - int pos = 0; 44 - int shift = 24; 45 - 46 - do 47 - { 48 - buf[pos] = (code >> shift) & 0xff; 49 - 50 - // Escape ' by doubling it 51 - if (buf[pos++] == '\'') 52 - buf[pos++] = '\''; 53 - 54 - shift -= 8; 55 - } 56 - while (shift != 0); 57 - buf[pos] = '\0'; 58 - 59 - return [NSString stringWithCString:buf encoding:NSASCIIStringEncoding]; 42 + return [str stringByReplacingOccurrencesOfString:@"'" 43 + withString:@"''"]; 60 44 } 61 45 62 - static NSString* escape(NSString* str) 46 + // An SQL-safe fourcc string 47 + static NSString* fourcc(UInt32 code) 63 48 { 64 - return [str stringByReplacingOccurrencesOfString:@"'" 65 - withString:@"''"]; 49 + CFStringRef str = UTCreateStringForOSType(code); 50 + NSString* rv = escape((NSString*) str); 51 + CFRelease(str); 52 + 53 + return rv; 66 54 } 67 55 68 56 OSStatus ··· 80 68 return paramErr; 81 69 82 70 __block OSStatus retval; 83 - [getDatabaseQueue() inDatabase:^(FMDatabase* db) { 71 + FMDatabaseQueue* dq = getDatabaseQueue(); 72 + 73 + if (dq == nil) 74 + return fnfErr; 75 + 76 + [dq inDatabase:^(FMDatabase* db) { 84 77 NSString* query = @"select path from bundle where package_type='APPL'"; 85 78 86 79 if (inCreator != kLSUnknownCreator) ··· 119 112 } 120 113 121 114 __block CFArrayRef retval; 115 + FMDatabaseQueue* dq = getDatabaseQueue(); 122 116 123 - [getDatabaseQueue() inDatabase:^(FMDatabase* db) { 117 + if (dq == nil) 118 + { 119 + if (*outError) 120 + *outError = CFErrorCreate(NULL, kCFErrorDomainOSStatus, fnfErr, NULL); 121 + return NULL; 122 + } 123 + 124 + [dq inDatabase:^(FMDatabase* db) { 124 125 FMResultSet* rs = [db executeQuery:@"select path from bundle where package_type='APPL' and bundle_id = ?", inBundleIdentifier]; 125 126 126 127 if ([rs next]) ··· 188 189 return paramErr; 189 190 } 190 191 191 - [getDatabaseQueue() inDatabase:^(FMDatabase* db) { 192 - NSString* query = @"select path from bundle where package_type='APPL'"; 192 + FMDatabaseQueue* dq = getDatabaseQueue(); 193 + if (dq == nil) 194 + return fnfErr; 195 + 196 + [dq inDatabase:^(FMDatabase* db) { 197 + NSString* query = @"select path, AD.rank from bundle INNER JOIN app_doc AD on AD.bundle=bundle.id where bundle.package_type='APPL'"; 193 198 194 - if (inType != kLSUnknownType) 195 - query = [query stringByAppendingFormat:@" and signature='%@'", fourcc(inType)]; 196 - if (inCreator != kLSUnknownCreator) 197 - query = [query stringByAppendingFormat:@" and creator='%@'", fourcc(inCreator)]; 198 199 if (inExtension != NULL) 199 200 { 200 201 NSString* escaped = escape((NSString*) inExtension); 201 - query = [query stringByAppendingFormat:@" and (id IN (SELECT A.bundle FROM app_doc A LEFT JOIN app_doc_extension AE ON AE.doc=A.id WHERE AE.extension = '%@')" 202 + query = [query stringByAppendingFormat:@" and (EXISTS (SELECT * FROM app_doc_extension AE WHERE AE.doc=AD.class AND AE.extension = '%@')" 202 203 @" OR " 203 - @"id IN (SELECT A.bundle FROM app_doc A LEFT JOIN app_doc_uti AU ON AU.doc=A.id LEFT JOIN uti ON uti.type_identifier = AU.uti LEFT JOIN uti_tag UT ON UT.uti=uti.id WHERE UT.tag = 'public.filename-extension' AND UT.value='%@'))", 204 + @"EXISTS (SELECT * FROM app_doc_uti AU JOIN uti ON uti.type_identifier = AU.uti JOIN uti_tag UT ON UT.uti=uti.id WHERE AU.doc=AD.id AND UT.tag = 'public.filename-extension' AND UT.value='%@'))", 204 205 escaped, escaped]; 205 206 } 207 + 208 + if (inType != kLSUnknownType) 209 + query = [query stringByAppendingFormat:@" and signature='%@'", fourcc(inType)]; 210 + if (inCreator != kLSUnknownCreator) 211 + query = [query stringByAppendingFormat:@" and creator='%@'", fourcc(inCreator)]; 206 212 if (inRoleMask != kLSRolesAll) 207 213 { 208 214 query = [query stringByAppendingFormat:@" and id IN (SELECT A.bundle FROM app_doc WHERE role IN (%@))", roleSQLArray(inRoleMask)]; 209 215 } 210 216 217 + query = [query stringByAppendingString:@" order by case " 218 + @"when AD.rank='Owner' then 1 " 219 + @"when AD.rank='Default' then 2 " 220 + @"when AD.rank='Alternate' then 3 " 221 + @"else 5 " 222 + @"end asc"]; 223 + 211 224 FMResultSet* rs = [db executeQuery:query]; 212 225 if ([rs next]) 213 226 { ··· 230 243 CFURLRef LSCopyDefaultApplicationURLForContentType(CFStringRef inContentType, LSRolesMask inRoleMask, CFErrorRef _Nullable *outError) 231 244 { 232 245 __block CFURLRef retval; 246 + FMDatabaseQueue* dq = getDatabaseQueue(); 233 247 234 - [getDatabaseQueue() inDatabase:^(FMDatabase* db) { 235 - NSString* query = @"select path from bundle LEFT JOIN app_doc AD on AD.bundle=bundle.id LEFT JOIN app_doc_uti AU on AU.doc=AD.id WHERE uti=?"; 248 + if (dq == nil) 249 + { 250 + if (*outError) 251 + *outError = CFErrorCreate(NULL, kCFErrorDomainOSStatus, fnfErr, NULL); 252 + return NULL; 253 + } 254 + 255 + [dq inDatabase:^(FMDatabase* db) { 256 + NSString* query = @"select path, AD.rank from bundle INNER JOIN app_doc AD on AD.bundle=bundle.id LEFT JOIN app_doc_uti AU on AU.doc=AD.id WHERE bundle.package_type='APPL' AND uti=?"; 236 257 237 258 if (inRoleMask != kLSRolesAll) 238 259 { 239 260 query = [query stringByAppendingFormat:@" and AD.role in (%@)", roleSQLArray(inRoleMask)]; 240 261 } 241 262 263 + query = [query stringByAppendingString:@" order by case " 264 + @"when AD.rank='Owner' then 1 " 265 + @"when AD.rank='Default' then 2 " 266 + @"when AD.rank='Alternate' then 3 " 267 + @"else 5 " 268 + @"end asc"]; 269 + 242 270 FMResultSet* rs = [db executeQuery:query, inContentType]; 243 271 244 272 if ([rs next]) ··· 256 284 257 285 return retval; 258 286 } 287 + 288 + CFURLRef LSCopyDefaultApplicationURLForURL(CFURLRef inURL, LSRolesMask inRoleMask, CFErrorRef _Nullable *outError) 289 + { 290 + CFURLRef retval; 291 + OSStatus status = LSGetApplicationForURL(inURL, inRoleMask, NULL, &retval); 292 + 293 + if (status != noErr) 294 + { 295 + if (*outError) 296 + *outError = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, NULL); 297 + return NULL; 298 + } 299 + else 300 + { 301 + if (outError) 302 + *outError = NULL; 303 + return retval; 304 + } 305 + } 306 + 307 + OSStatus LSGetApplicationForURL(CFURLRef inURL, LSRolesMask inRoleMask, FSRef *outAppRef, CFURLRef *outAppURL) 308 + { 309 + NSString* extension = [(NSURL*) inURL pathExtension]; 310 + return LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, (CFStringRef) extension, inRoleMask, outAppRef, outAppURL); 311 + }
+104
src/frameworks/CoreServices/src/LaunchServices/LSOpen.m
··· 34 34 puts("LSOpenURLsWithRole STUB"); 35 35 return unimpErr; 36 36 } 37 + 38 + OSStatus 39 + LSOpenItemsWithRole( 40 + const FSRef * inItems, 41 + CFIndex inItemCount, 42 + LSRolesMask inRole, 43 + const AEKeyDesc * inAEParam, 44 + const LSApplicationParameters * inAppParams, 45 + ProcessSerialNumber * outPSNs, 46 + CFIndex inMaxPSNCount) 47 + { 48 + 49 + CFURLRef* urls = (CFURLRef*) malloc(inItemCount * sizeof(CFURLRef)); 50 + 51 + for (CFIndex i = 0; i < inItemCount; i++) 52 + { 53 + char path[4096]; 54 + 55 + OSStatus status = FSRefMakePath(&inItems[i], (UInt8*) path, sizeof(path)-1); 56 + if (status != noErr) 57 + { 58 + for (CFIndex j; j < i; j++) 59 + CFRelease(urls[j]); 60 + free(urls); 61 + return status; 62 + } 63 + 64 + CFStringRef urlStr = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8); 65 + urls[i] = CFURLCreateWithFileSystemPath(NULL, urlStr, kCFURLPOSIXPathStyle, FALSE); 66 + CFRelease(urlStr); 67 + } 68 + 69 + CFArrayRef urlArray = CFArrayCreate(NULL, (const void**) urls, inItemCount, &kCFTypeArrayCallBacks); 70 + for (CFIndex i; i < inItemCount; i++) 71 + CFRelease(urls[i]); 72 + free(urls); 73 + 74 + OSStatus status = LSOpenURLsWithRole(urlArray, inRole, inAEParam, inAppParams, outPSNs, inMaxPSNCount); 75 + 76 + CFRelease(urlArray); 77 + 78 + return status; 79 + } 80 + 81 + OSStatus LSOpenFSRef(const FSRef *inRef, FSRef *outLaunchedRef) 82 + { 83 + char path[4096]; 84 + 85 + OSStatus status = FSRefMakePath(inRef, (UInt8*) path, sizeof(path)-1); 86 + if (status != noErr) 87 + return status; 88 + 89 + CFStringRef urlStr = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8); 90 + CFURLRef url = CFURLCreateWithFileSystemPath(NULL, urlStr, kCFURLPOSIXPathStyle, FALSE); 91 + CFRelease(urlStr); 92 + 93 + CFURLRef launchedUrl; 94 + status = LSOpenCFURLRef(url, &launchedUrl); 95 + 96 + CFRelease(url); 97 + 98 + if (status != noErr) 99 + return status; 100 + 101 + if (outLaunchedRef) 102 + { 103 + CFStringRef path = CFURLCopyFileSystemPath(launchedUrl, kCFURLPOSIXPathStyle); 104 + status = FSPathMakeRef((const UInt8*) CFStringGetCStringPtr(path, kCFStringEncodingUTF8), outLaunchedRef, NULL); 105 + CFRelease(path); 106 + } 107 + 108 + CFRelease(launchedUrl); 109 + return status; 110 + } 111 + 112 + OSStatus LSOpenCFURLRef(CFURLRef inURL, CFURLRef *outLaunchedURL) 113 + { 114 + OSStatus ret; 115 + LSLaunchURLSpec spec; 116 + 117 + memset(&spec, 0, sizeof(spec)); 118 + 119 + spec.itemURLs = CFArrayCreate(kCFAllocatorDefault, (const void**)&inURL, 1, NULL); 120 + ret = LSOpenFromURLSpec(&spec, outLaunchedURL); 121 + CFRelease(spec.itemURLs); 122 + 123 + return ret; 124 + } 125 + 126 + /* 127 + OSStatus LSOpenApplication(const LSApplicationParameters *appParams, ProcessSerialNumber *outPSN) 128 + { 129 + 130 + } 131 + */ 132 + 133 + /* 134 + OSStatus 135 + LSOpenFromURLSpec( 136 + const LSLaunchURLSpec * inLaunchSpec, 137 + _Nullable CFURLRef *_Nullable outLaunchedURL) 138 + { 139 + } 140 + */
-10
src/frameworks/CoreServices/src/LaunchServices/LaunchServices.c
··· 31 31 return 0; 32 32 } 33 33 34 - OSStatus LSOpenCFURLRef(CFURLRef inURL, CFURLRef *outLaunchedURL) 35 - { 36 - OSStatus ret; 37 - LSLaunchURLSpec spec; 38 - spec.itemURLs = CFArrayCreate(kCFAllocatorDefault, (const void**)&inURL, 1, NULL); 39 - ret = LSOpenFromURLSpec(&spec, outLaunchedURL); 40 - CFRelease(spec.itemURLs); 41 - return ret; 42 - } 43 - 44 34 OSStatus LSOpenFromURLSpec(const LSLaunchURLSpec *inLaunchSpec, CFURLRef *outLaunchedURL) 45 35 { 46 36 CFStringRef scheme, extension;
-5
src/frameworks/CoreServices/src/LaunchServices/LaunchServices.cpp
··· 239 239 return unimpErr; 240 240 }*/ 241 241 242 - OSStatus LSOpenFSRef(const FSRef *inRef, FSRef *outLaunchedRef) 243 - { 244 - return unimpErr; 245 - } 246 - 247 242 OSStatus LSGetExtensionInfo(UniCharCount inNameLen, const UniChar* inNameBuffer, UniCharCount *outExtStartIndex) 248 243 { 249 244 if (!outExtStartIndex)
+321
src/frameworks/CoreServices/src/LaunchServices/UTType.m
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2020 Lubos Dolezel 5 + 6 + Darling is free software: you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation, either version 3 of the License, or 9 + (at your option) any later version. 10 + 11 + Darling is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + 21 + #include <LaunchServices/LaunchServices.h> 22 + #import <Foundation/NSString.h> 23 + #import <Foundation/NSArray.h> 24 + #import <Foundation/NSNumber.h> 25 + #import <fmdb/FMDatabaseQueue.h> 26 + 27 + extern FMDatabaseQueue* getDatabaseQueue(void); 28 + extern NSString* escape(NSString* str); 29 + 30 + _Nullable CFStringRef 31 + UTTypeCreatePreferredIdentifierForTag( 32 + CFStringRef inTagClass, 33 + CFStringRef inTag, 34 + _Nullable CFStringRef inConformingToUTI) 35 + { 36 + CFArrayRef array = UTTypeCreateAllIdentifiersForTag(inTagClass, inTag, inConformingToUTI); 37 + if (array == NULL) 38 + return NULL; 39 + 40 + CFStringRef str = (CFStringRef) CFRetain(CFArrayGetValueAtIndex(array, 0)); 41 + CFRelease(array); 42 + 43 + return str; 44 + } 45 + 46 + static CFArrayRef arrayForStringColumn0(FMResultSet* rs) 47 + { 48 + if ([rs next]) 49 + { 50 + NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 0]; 51 + do 52 + { 53 + [array addObject: [rs stringForColumnIndex:0]]; 54 + } 55 + while ([rs next]); 56 + 57 + CFArrayRef retval = (CFArrayRef) [[NSArray alloc] initWithArray:array]; 58 + [array release]; 59 + 60 + return retval; 61 + } 62 + else 63 + return NULL; 64 + } 65 + 66 + _Nullable CFArrayRef 67 + UTTypeCreateAllIdentifiersForTag( 68 + CFStringRef inTagClass, 69 + CFStringRef inTag, 70 + _Nullable CFStringRef inConformingToUTI) 71 + { 72 + FMDatabaseQueue* dq = getDatabaseQueue(); 73 + if (!dq) 74 + return NULL; 75 + 76 + __block CFArrayRef retval; 77 + [dq inDatabase:^(FMDatabase* db) { 78 + NSString* query = @"select type_identifier from uti inner join uti_tag UT on UT.uti=uti.id " 79 + @"where UT.tag = ? and UT.value = ?"; 80 + 81 + if (inConformingToUTI != NULL) 82 + { 83 + query = [query stringByAppendingFormat:@" and uti.id in (select uti from uti_conforms where conforms_to='%@')", 84 + escape((NSString*) inConformingToUTI)]; 85 + } 86 + 87 + FMResultSet* rs = [db executeQuery:query, inTagClass, inTag]; 88 + 89 + retval = arrayForStringColumn0(rs); 90 + 91 + [rs close]; 92 + }]; 93 + 94 + return retval; 95 + } 96 + 97 + _Nullable CFStringRef 98 + UTTypeCopyPreferredTagWithClass( 99 + CFStringRef inUTI, 100 + CFStringRef inTagClass) 101 + { 102 + CFArrayRef array = UTTypeCopyAllTagsWithClass(inUTI, inTagClass); 103 + if (array == NULL) 104 + return NULL; 105 + 106 + CFStringRef str = (CFStringRef) CFRetain(CFArrayGetValueAtIndex(array, 0)); 107 + CFRelease(array); 108 + 109 + return str; 110 + } 111 + 112 + _Nullable CFArrayRef 113 + UTTypeCopyAllTagsWithClass( 114 + CFStringRef inUTI, 115 + CFStringRef inTagClass) 116 + { 117 + FMDatabaseQueue* dq = getDatabaseQueue(); 118 + if (!dq) 119 + return NULL; 120 + 121 + __block CFArrayRef retval; 122 + [dq inDatabase:^(FMDatabase* db) { 123 + FMResultSet* rs = [db executeQuery:@"select UT.value from uti inner join uti_tag UT on UT.uti=uti.id where UT.tag = ? and type_identifier = ?", 124 + inTagClass, inUTI]; 125 + 126 + retval = arrayForStringColumn0(rs); 127 + 128 + [rs close]; 129 + }]; 130 + 131 + return retval; 132 + } 133 + 134 + Boolean 135 + UTTypeEqual( 136 + CFStringRef inUTI1, 137 + CFStringRef inUTI2) 138 + { 139 + return CFStringCompare(inUTI1, inUTI2, kCFCompareCaseInsensitive) == kCFCompareEqualTo; 140 + } 141 + 142 + Boolean 143 + UTTypeConformsTo( 144 + CFStringRef inUTI, 145 + CFStringRef inConformsToUTI) 146 + { 147 + FMDatabaseQueue* dq = getDatabaseQueue(); 148 + if (!dq) 149 + return FALSE; 150 + 151 + __block Boolean retval; 152 + [dq inDatabase:^(FMDatabase* db) { 153 + FMResultSet* rs = [db executeQuery:@"select UC.conforms_to from uti inner join uti_conforms UC on UC.uti=uti.id where type_identifier=? and UC.conforms_to=?", 154 + inUTI, inConformsToUTI]; 155 + 156 + retval = [rs next]; 157 + [rs close]; 158 + }]; 159 + 160 + return retval; 161 + } 162 + 163 + _Nullable CFStringRef 164 + UTTypeCopyDescription(CFStringRef inUTI) 165 + { 166 + FMDatabaseQueue* dq = getDatabaseQueue(); 167 + if (!dq) 168 + return NULL; 169 + 170 + __block CFStringRef retval; 171 + [dq inDatabase:^(FMDatabase* db) { 172 + FMResultSet* rs = [db executeQuery:@"select description from uti where type_identifier = ?", inUTI]; 173 + if ([rs next]) 174 + retval = (CFStringRef) [[rs stringForColumnIndex:0] retain]; 175 + else 176 + retval = NULL; 177 + [rs close]; 178 + }]; 179 + 180 + return retval; 181 + } 182 + 183 + Boolean 184 + UTTypeIsDeclared(CFStringRef inUTI) 185 + { 186 + CFStringRef str = UTTypeCopyDescription(inUTI); 187 + if (str != NULL) 188 + { 189 + CFRelease(str); 190 + return TRUE; 191 + } 192 + else 193 + return FALSE; 194 + } 195 + 196 + Boolean 197 + UTTypeIsDynamic(CFStringRef inUTI) 198 + { 199 + return FALSE; 200 + } 201 + 202 + _Nullable CFDictionaryRef 203 + UTTypeCopyDeclaration(CFStringRef inUTI) 204 + { 205 + FMDatabaseQueue* dq = getDatabaseQueue(); 206 + if (!dq) 207 + return NULL; 208 + 209 + __block CFDictionaryRef retval; 210 + [dq inDatabase:^(FMDatabase* db) { 211 + FMResultSet* rs = [db executeQuery:@"select id, description from uti where type_identifier = ?", inUTI]; 212 + if ([rs next]) 213 + { 214 + NSMutableDictionary* dict = [[NSMutableDictionary alloc] initWithCapacity: 5]; 215 + NSNumber* utiId = [NSNumber numberWithInt: [rs intForColumn:@"id"]]; 216 + 217 + dict[(NSString*) kUTTypeIdentifierKey] = (NSString*) inUTI; 218 + dict[(NSString*) kUTTypeDescriptionKey] = [rs stringForColumn:@"description"]; 219 + [rs close]; 220 + 221 + NSMutableArray* conformsTo = [[NSMutableArray alloc] initWithCapacity:0]; 222 + rs = [db executeQuery:@"select conforms_to from uti_conforms where uti = ?", utiId]; 223 + 224 + while ([rs next]) 225 + [conformsTo addObject: [rs stringForColumnIndex:0]]; 226 + 227 + [rs close]; 228 + dict[(NSString*) kUTTypeConformsToKey] = conformsTo; 229 + [conformsTo release]; 230 + 231 + NSMutableDictionary* tags = [[NSMutableDictionary alloc] initWithCapacity:0]; 232 + rs = [db executeQuery:@"select tag, value from uti_tag where uti = ?", utiId]; 233 + 234 + while ([rs next]) 235 + tags[[rs stringForColumn:@"tag"]] = [rs stringForColumn:@"value"]; 236 + 237 + [rs close]; 238 + dict[(NSString*) kUTTypeTagSpecificationKey] = tags; 239 + [tags release]; 240 + 241 + NSMutableArray* icons = [[NSMutableArray alloc] initWithCapacity:0]; 242 + rs = [db executeQuery:@"select file from uti_icon where uti = ?", utiId]; 243 + 244 + while ([rs next]) 245 + [icons addObject: [rs stringForColumnIndex:0]]; 246 + 247 + [rs close]; 248 + dict[@"UTTypeIconFiles"] = icons; 249 + [icons release]; 250 + 251 + retval = (CFDictionaryRef) [[NSDictionary alloc] initWithDictionary:dict copyItems:YES]; 252 + [dict release]; 253 + } 254 + else 255 + { 256 + [rs close]; 257 + retval = NULL; 258 + } 259 + }]; 260 + 261 + return retval; 262 + } 263 + 264 + _Nullable CFURLRef 265 + UTTypeCopyDeclaringBundleURL(CFStringRef inUTI) 266 + { 267 + FMDatabaseQueue* dq = getDatabaseQueue(); 268 + if (!dq) 269 + return NULL; 270 + 271 + __block CFURLRef retval; 272 + [dq inDatabase:^(FMDatabase* db) { 273 + FMResultSet* rs = [db executeQuery:@"select B.path from uti inner join bundle B on B.id=uti.bundle where type_identifier = ?", inUTI]; 274 + if ([rs next]) 275 + retval = CFURLCreateWithFileSystemPath(NULL, (CFStringRef) [rs stringForColumnIndex:0], kCFURLPOSIXPathStyle, TRUE); 276 + else 277 + retval = NULL; 278 + [rs close]; 279 + }]; 280 + 281 + return retval; 282 + } 283 + 284 + CFStringRef 285 + UTCreateStringForOSType(OSType inOSType) 286 + { 287 + char buf[5]; 288 + int pos = 0; 289 + int shift = 24; 290 + 291 + do 292 + { 293 + buf[pos++] = (inOSType >> shift) & 0xff; 294 + shift -= 8; 295 + } 296 + while (shift != 0); 297 + buf[pos] = '\0'; 298 + 299 + return CFStringCreateWithCString(NULL, buf, kCFStringEncodingASCII); 300 + } 301 + 302 + OSType 303 + UTGetOSTypeFromString(CFStringRef inString) 304 + { 305 + if (!inString) 306 + return 0; 307 + if (CFStringGetLength(inString) > 4) 308 + return 0; 309 + 310 + OSType retval = 0; 311 + const char* str = CFStringGetCStringPtr(inString, kCFStringEncodingASCII); 312 + 313 + for (int i = 0; i < 4; i++) 314 + { 315 + if (i < CFStringGetLength(inString)) 316 + retval |= ((UInt32) str[i]) & 0xff; 317 + retval <<= 8; 318 + } 319 + 320 + return retval; 321 + }
+3 -3
src/frameworks/CoreServices/src/LaunchServices/launchservicesd/schema.sql
··· 18 18 19 19 CREATE TABLE `uti` ( 20 20 `id` INTEGER PRIMARY KEY AUTOINCREMENT, 21 - `type_identifier` TEXT NOT NULL, -- UTTypeIdentifier 21 + `type_identifier` TEXT NOT NULL COLLATE NOCASE, -- UTTypeIdentifier 22 22 `description` TEXT, -- UTTypeDescription 23 23 `bundle` INTEGER, 24 24 FOREIGN KEY(`bundle`) REFERENCES `bundle`(`id`) ON DELETE CASCADE ··· 30 30 CREATE TABLE `uti_conforms` ( 31 31 `id` INTEGER PRIMARY KEY AUTOINCREMENT, 32 32 `uti` INTEGER, 33 - `conforms_to` TEXT NOT NULL, 33 + `conforms_to` TEXT NOT NULL COLLATE NOCASE, 34 34 FOREIGN KEY(`uti`) REFERENCES `uti`(`id`) ON DELETE CASCADE 35 35 ); 36 36 CREATE INDEX `uti_conforms_index` ON `uti_conforms`(`conforms_to`); ··· 50 50 `id` INTEGER PRIMARY KEY AUTOINCREMENT, 51 51 `uti` INTEGER, 52 52 `tag` TEXT NOT NULL, 53 - `value` TEXT NOT NULL, 53 + `value` TEXT NOT NULL COLLATE NOCASE, 54 54 FOREIGN KEY(`uti`) REFERENCES `uti`(`id`) ON DELETE CASCADE 55 55 ); 56 56 CREATE INDEX `uti_tag_uti_index` ON `uti_tag`(`uti`);