That works perfectly. You are extremely precise. Thank you.
I have successfully checked it with aliases with type 'alis' (file), 'fdrp'
(folder) and 'fapa' (filePackage application).
I guess I¹d have to check the whole list here below, but sincerely I don¹t
even know how to create e.g. a kContainerTrashAliasType nor a
kContainerHardDiskAliasType... Do they all still exists? I will try to run
some check anyway.


enum {
  kContainerFolderAliasType = 'fdrp',
  kContainerTrashAliasType = 'trsh',
  kContainerHardDiskAliasType = 'hdsk',
  kContainerFloppyAliasType = 'flpy',
  kContainerServerAliasType = 'srvr',
  kApplicationAliasType = 'adrp',
  kContainerAliasType = 'drop',
  kDesktopPrinterAliasType = 'dtpa',
  kContainerCDROMAliasType = 'cddr',
  kApplicationCPAliasType = 'acdp',
  kApplicationDAAliasType = 'addp',
  kPackageAliasType = 'fpka',
  kAppPackageAliasType = 'fapa'
};


enum {
  kSystemFolderAliasType = 'fasy',
  kAppleMenuFolderAliasType = 'faam',
  kStartupFolderAliasType = 'fast',
  kPrintMonitorDocsFolderAliasType = 'fapn',
  kPreferencesFolderAliasType = 'fapf',
  kControlPanelFolderAliasType = 'fact',
  kExtensionFolderAliasType = 'faex'
};


enum {
  kExportedFolderAliasType = 'faet',
  kDropFolderAliasType = 'fadr',
  kSharedFolderAliasType = 'fash',
  kMountedFolderAliasType = 'famn'
};

 
Regards
-- Leonardo



Da: "Gary L. Wade" <garyw...@desisoftsystems.com>
Data: Tue, 1 Dec 2015 08:37:37 -0800
A: Leonardo <mac.iphone....@gmail.com>
Cc: <cocoa-dev@lists.apple.com>
Oggetto: Re: FSIsAliasFile deprecated - typeOfFile is slow

When looking at bytes and doing things like this, I prefer using uint8_t
rather than char or unsigned char since it's more representative (this is
basic signed/unsigned arithmetic); besides, you don't want to do an
equal-check but a bit-check since it's a flags field. Technically both
buffer[8] and buffer[9] would be combined to make a big-endian 16-bit
integer (Mac legacy of the 680x0 and PPC architectures before Intel), but
since all you need to know is if it's an alias, just do this differently:

   uint8_t *buffer = malloc(bufferSize);
   if(buffer == nil) return NO;

   getxattr(cPath, keyName, buffer, bufferSize, 0, 0);
   BOOL isAlias = (0 != (buffer[8] & 0x80));

This may be faster if FSIsAliasFile does extra sniffing in the file for
correct content, which may or may not be as important for you, or if it
checks more of the xattr for correctness; you need to decide for yourself
how far you need to go, but be sure to try this out on all kinds of alias
files, especially those for files, folders, servers, and volumes.
--
Gary L. Wade (Sent from my iPad)
http://www.garywade.com/

On Dec 1, 2015, at 4:06 AM, Leonardo <mac.iphone....@gmail.com> wrote:

> 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