Thank you Gary. Almost got it.
Still a small question. The 8th byte of the buffer, in case of alias (file
or folder) returns -128 and not 128 as you said. Am I missing something?

- (BOOL)IsAlias
{
    const char    *cPath = [[NSFileManager defaultManager]
fileSystemRepresentationWithPath:self];
    if(cPath == 0 || *cPath == _NUL) return NO;
    
    const char  *keyName = "com.apple.FinderInfo";
    ssize_t     bufferSize = getxattr(cPath, keyName, NULL, 0, 0, 0);
    if(bufferSize < 32) return NO;
    
    char *buffer = malloc(bufferSize);
    if(buffer == nil) return NO;
    
    getxattr(cPath, keyName, buffer, bufferSize, 0, 0);
    BOOL isAlias = buffer[8] == -128;
    
    free(buffer);
    
    return isAlias;
}

Also, this method returns NO in case of SymLinks, as I expected.
And it's even 3 times faster than FSIsAliasFile().
That's fine.
I just hope that will work for the next 10 OS X releases...

Regards
-- Leonardo


> Da: "Gary L. Wade" <garyw...@desisoftsystems.com>
> Data: Fri, 27 Nov 2015 16:48:43 -0800
> A: Leonardo <mac.iphone....@gmail.com>
> Cc: <cocoa-dev@lists.apple.com>
> Oggetto: Re: FSIsAliasFile deprecated - typeOfFile is slow
> 
> Although I have experience with your performance hit, one solution I would
> probably try when it becomes important again for me would be to do this:
> 
> 1. Using the BSD layer of APIs, see if the file (alias files are regular files
> from a statfs call, even folder aliases) has an extended attribute named
> "com.apple.FinderInfo". If it does not, it is not an alias file.
> 2. If the extended attribute does exist and is of length 32 bytes (or more
> although doubtful this would ever change), you might have an alias file. If
> less, just say no assuming corruption.
> 3. Get the bytes of the extended attribute and examine the byte at index 8
> (bytes[8]) to see if its high bit is set (bytes[8] | 0x80). If so, you have an
> alias; if not, you don't.
> 4. Add this logic in an appropriate category method (to keep this Cocoa).
> 
> For reference, look up ATTR_CMN_FNDRINFO, xattr, Finder.h. Note this extended
> attribute has its integers in big-endian format. You might also look at the
> fileType parameter of the CoreServices FileInfo that maps the first 16 bytes,
> but that requires more checking.
> --
> Gary L. Wade (Sent from my iPhone)
> http://www.garywade.com/
> 
>> On Nov 27, 2015, at 2:00 PM, Leonardo <mac.iphone....@gmail.com> wrote:
>> 
>> Hi,
>> I actually detect whether a file is an alias this way:
>> I use a NSString category where self is the filePath.
>> 
>> - (BOOL)IsAliasOld
>> {
>>    FSRef    sourceRef;
>> 
>>    OSErr    err = [self GetFSRef:&sourceRef];
>>    if(err) return NO;
>> 
>>    Boolean    isFSDirectory, aliasFileFlag;
>> 
>>    err = FSIsAliasFile(&sourceRef, &aliasFileFlag, &isFSDirectory);
>>    if(err) return NO;
>>    else return aliasFileFlag;
>> }
>> 
>> - (OSErr)GetFSRef:(FSRef*)sourceRef
>> {
>>    const char *cSrcPath = [[NSFileManager defaultManager]
>> fileSystemRepresentationWithPath:self];
>>    if(cSrcPath == 0 || *cSrcPath == _NUL) return -1;
>> 
>>    OSErr err = FSPathMakeRefWithOptions((UInt8*)cSrcPath,
>> kFSPathMakeRefDoNotFollowLeafSymlink, sourceRef, NULL);
>>    return err;
>> }
>> 
>> 
>> Since FSIsAliasFile is deprecated (I compile for 10.9) I would now use
>> 
>> - (BOOL)IsAliasNew
>> {
>>    NSString    *type = [[NSWorkspace sharedWorkspace] typeOfFile:self
>> error:nil];
>>    return [type isEqualToString:@"com.apple.alias-file"];
>> }
>> 
>> The problem is that the IsAliasNew method is 3.7 times slower than the
>> IsAliasOld method. Do you know a way to accomplish that with a faster
>> method?
>> 


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to