Revision: 26797
          http://sourceforge.net/p/bibdesk/svn/26797
Author:   hofman
Date:     2021-09-04 12:12:44 +0000 (Sat, 04 Sep 2021)
Log Message:
-----------
Wrap AliasHandle for linked file in an object

Modified Paths:
--------------
    trunk/bibdesk/BDSKLinkedFile.m

Modified: trunk/bibdesk/BDSKLinkedFile.m
===================================================================
--- trunk/bibdesk/BDSKLinkedFile.m      2021-09-04 06:30:28 UTC (rev 26796)
+++ trunk/bibdesk/BDSKLinkedFile.m      2021-09-04 12:12:44 UTC (rev 26797)
@@ -53,21 +53,20 @@
 #define RELATIVEPATH_KEY @"relativePath"
 
 static NSURL *BDSKCreateURLFromFSRef(const FSRef *inRef);
-static void BDSKDisposeAliasHandle(AliasHandle inAlias);
-static AliasHandle BDSKDataToAliasHandle(NSData *inData);
-static NSData *BDSKAliasHandleToData(AliasHandle inAlias);
-static BOOL BDSKAliasHandleToFSRef(const AliasHandle inAlias, const FSRef 
*inBaseRef, FSRef *outRef, BOOL *shouldUpdate);
-static AliasHandle BDSKFSRefToAliasHandle(const FSRef *inRef, const FSRef 
*inBaseRef);
-static void BDSKUpdateAliasWithFSRef(AliasHandle alias, const FSRef *inRef, 
const FSRef *inBaseRef);
 static BOOL BDSKPathToFSRef(NSString *inPath, FSRef *outRef);
-static AliasHandle BDSKPathToAliasHandle(NSString *inPath, NSString 
*inBasePath);
 static NSDictionary *BDSKDictionaryFromPlistData(NSData *data);
 static NSDictionary *BDSKDictionaryFromArchivedData(NSData *data);
 
-typedef union _BDSKLocator {
+@interface BDSKAlias : NSObject {
     AliasHandle alias;
-    NSData *bookmark;
-} BDSKLocator;
+}
++ (id)newWithData:(NSData *)data;
++ (id)newWithFSRef:(const FSRef *)aRef baseRef:(const FSRef *)baseRef;
++ (id)newWithPath:(NSString *)path basePath:(NSString *)basePath;
+- (BOOL)getFSRef:(FSRef *)outRef baseRef:(const FSRef *)baseRef 
shouldUpdate:(BOOL *)shouldUpdate;
+- (void)updateWithFSRef:(const FSRef *)outRef baseRef:(const FSRef *)baseRef;
+@property (nonatomic, readonly) NSData *data;
+@end
 
 // Private placeholder subclass
 
@@ -77,7 +76,7 @@
 // Private concrete subclasses
 
 @interface BDSKLinkedAliasFile : BDSKLinkedFile {
-    BDSKLocator locator;
+    id alias; // can be a BDSKAlias or bookmark NSData
     const FSRef *fileRef;
     NSString *relativePath;
     NSURL *fileURL;
@@ -277,12 +276,12 @@
 
 @implementation BDSKLinkedAliasFile
 
-- (id)initWithLocator:(BDSKLocator)aLocator isBookmark:(BOOL)isBookmarkData 
relativePath:(NSString *)relPath delegate:(id<BDSKLinkedFileDelegate>)aDelegate;
+- (id)initWithAlias:(id)anAlias isBookmark:(BOOL)isBookmarkData 
relativePath:(NSString *)relPath delegate:(id<BDSKLinkedFileDelegate>)aDelegate;
 {
-    BDSKASSERT((isBookmarkData ? nil != aLocator.bookmark : NULL != 
aLocator.alias) || nil != relPath);
+    BDSKASSERT(nil != anAlias || nil != relPath);
     BDSKASSERT(nil == aDelegate || [aDelegate 
respondsToSelector:@selector(basePathForLinkedFile:)]);
     
-    if ((isBookmarkData ? aLocator.bookmark == nil : aLocator.alias == NULL) 
&& relPath == nil) {
+    if (anAlias == nil && relPath == nil) {
         [self release];
         self = nil;
     } else {
@@ -289,7 +288,7 @@
         self = [super init];
         if (self) {
             fileRef = NULL; // this is updated lazily, as we don't know the 
base path at this point
-            locator = aLocator;
+            alias = [anAlias retain];
             isBookmark = isBookmarkData;
             relativePath = [relPath copy];
             delegate = aDelegate;
@@ -312,10 +311,11 @@
     
     NSString *basePath = [aDelegate basePathForLinkedFile:self];
     NSString *relPath = basePath ? [aPath relativePathFromPath:basePath] : nil;
-    BDSKLocator aLocator;
-    aLocator.alias = BDSKPathToAliasHandle(aPath, basePath);
+    id anAlias;
+    anAlias = [BDSKAlias newWithPath:aPath basePath:basePath];
     
-    self = [self initWithLocator:aLocator isBookmark:NO relativePath:relPath 
delegate:aDelegate];
+    self = [self initWithAlias:anAlias isBookmark:NO relativePath:relPath 
delegate:aDelegate];
+    [anAlias release];
     if (self && basePath)
         // this initalizes the FSRef and update the alias
         [self updateFileRef];
@@ -324,13 +324,15 @@
 
 - (id)initWithData:(NSData *)data isBookmark:(BOOL)isBookmarkData 
relativePath:(NSString *)relPath delegate:(id<BDSKLinkedFileDelegate>)aDelegate;
 {
-    BDSKLocator aLocator;
+    id anAlias;
     if (isBookmarkData)
-        aLocator.bookmark = [data copy];
+        anAlias = [data copy];
     else
-        aLocator.alias = BDSKDataToAliasHandle(data);
+        anAlias = [BDSKAlias newWithData:data];
     
-    return [self initWithLocator:aLocator isBookmark:isBookmarkData 
relativePath:relPath delegate:aDelegate];
+    self = [self initWithAlias:anAlias isBookmark:isBookmarkData 
relativePath:relPath delegate:aDelegate];
+    [anAlias release];
+    return self;
 }
 
 - (id)initWithBase64String:(NSString *)base64String 
delegate:(id<BDSKLinkedFileDelegate>)aDelegate;
@@ -425,8 +427,8 @@
     NSData *data = [self aliasDataRelativeToPath:[delegate 
basePathForLinkedFile:self]];
     if ([coder allowsKeyedCoding]) {
         [coder encodeObject:data forKey:ALIASDATA_KEY];
-        if (data == nil && isBookmark && locator.bookmark)
-            [coder encodeObject:locator.bookmark forKey:BOOKMARK_KEY];
+        if (data == nil && isBookmark && alias)
+            [coder encodeObject:alias forKey:BOOKMARK_KEY];
         [coder encodeObject:relativePath forKey:RELATIVEPATH_KEY];
     } else {
         [coder encodeObject:data];
@@ -437,11 +439,7 @@
 - (void)dealloc
 {
     BDSKZONEDESTROY(fileRef);
-    if (isBookmark) {
-        BDSKDESTROY(locator.bookmark);
-    } else {
-        BDSKDisposeAliasHandle(locator.alias); locator.alias = NULL;
-    }
+    BDSKDESTROY(alias);
     BDSKDESTROY(relativePath);
     BDSKDESTROY(fileURL);
     [super dealloc];
@@ -453,8 +451,8 @@
     [self updateFileURL];
     NSData *data = [self aliasDataRelativeToPath:[delegate 
basePathForLinkedFile:self]];
     BOOL isBookmarkData = NO;
-    if (data == nil && isBookmark && locator.bookmark){
-        data = locator.bookmark;
+    if (data == nil && isBookmark && alias){
+        data = alias;
         isBookmarkData = YES;
     }
     return [[[self class] allocWithZone:aZone] initWithData:data 
isBookmark:isBookmarkData relativePath:relativePath delegate:delegate];
@@ -516,16 +514,16 @@
     BDSKASSERT(baseRef != NULL);
     
     // update the alias
-    if (isBookmark == NO && locator.alias != NULL) {
-        BDSKUpdateAliasWithFSRef(locator.alias, fileRef, baseRef);
+    if (isBookmark == NO && alias != nil) {
+        [alias updateWithFSRef:fileRef baseRef:baseRef];
     } else {
-        AliasHandle anAlias = BDSKFSRefToAliasHandle(fileRef, baseRef);
+        BDSKAlias *anAlias = [BDSKAlias newWithFSRef:fileRef baseRef:baseRef];
         if (anAlias) {
             if (isBookmark) {
-                BDSKDESTROY(locator.bookmark);
+                BDSKDESTROY(alias);
                 isBookmark = NO;
             }
-            locator.alias = anAlias;
+            alias = anAlias;
         }
     }
 }
@@ -552,11 +550,11 @@
         }
         
         if (hasRef == NO) {
-            if (isBookmark == NO && locator.alias != NULL) {
-                hasRef = BDSKAliasHandleToFSRef(locator.alias, hasBaseRef ? 
&baseRef : NULL, &aRef, &shouldUpdate);
+            if (isBookmark == NO && alias != nil) {
+                hasRef = [alias getFSRef:&aRef baseRef:hasBaseRef ? &baseRef : 
NULL shouldUpdate:&shouldUpdate];
                 shouldUpdate = (shouldUpdate || relativePath == nil) && 
hasBaseRef && hasRef;
-            } else if (isBookmark && locator.bookmark != nil) {
-                NSURL *aURL = [NSURL 
URLByResolvingBookmarkData:locator.bookmark 
options:NSURLBookmarkResolutionWithoutUI relativeToURL:(basePath ? [NSURL 
fileURLWithPath:basePath] : nil) bookmarkDataIsStale:NULL error:NULL];
+            } else if (isBookmark && alias != nil) {
+                NSURL *aURL = [NSURL URLByResolvingBookmarkData:alias 
options:NSURLBookmarkResolutionWithoutUI relativeToURL:(basePath ? [NSURL 
fileURLWithPath:basePath] : nil) bookmarkDataIsStale:NULL error:NULL];
                 hasRef = BDSKPathToFSRef([aURL path], &aRef);
                 shouldUpdate = hasBaseRef && hasRef;
             }
@@ -647,20 +645,20 @@
 - (NSData *)aliasDataRelativeToPath:(NSString *)basePath;
 {
     FSRef baseRef;
-    AliasHandle anAlias = NULL;
+    BDSKAlias *anAlias = NULL;
     NSData *data = nil;
     
     if (fileRef) {
         BOOL hasBaseRef = BDSKPathToFSRef(basePath, &baseRef);
-        anAlias = BDSKFSRefToAliasHandle(fileRef, hasBaseRef ? &baseRef : 
NULL);
+        anAlias = [BDSKAlias newWithFSRef:fileRef baseRef:&baseRef];
     } else if (relativePath && basePath) {
-        anAlias = BDSKPathToAliasHandle(([relativePath isAbsolutePath] ? 
relativePath : [basePath stringByAppendingPathComponent:relativePath]), 
basePath);
+        anAlias = [BDSKAlias newWithPath:([relativePath isAbsolutePath] ? 
relativePath : [basePath stringByAppendingPathComponent:relativePath]) 
basePath:basePath];
     }
     if (anAlias != NULL) {
-        data = BDSKAliasHandleToData(anAlias);
-        BDSKDisposeAliasHandle(anAlias);
-    } else if (isBookmark == NO && locator.alias != NULL) {
-        data = BDSKAliasHandleToData(locator.alias);
+        data = [anAlias data];
+        [anAlias release];
+    } else if (isBookmark == NO && alias != nil) {
+        data = [alias data];
     }
     
     return data;
@@ -679,7 +677,7 @@
     if (noAlias == NO || path == nil) {
         data = [self aliasDataRelativeToPath:newBasePath];
         if (data == nil && isBookmark) {
-            data = locator.bookmark;
+            data = alias;
             dataKey = BOOKMARK_KEY;
         }
     }
@@ -691,22 +689,22 @@
 }
 
 - (void)setAliasWithPath:(NSString *)aPath basePath:(NSString *)basePath {
-    AliasHandle anAlias = BDSKPathToAliasHandle(aPath, basePath);
-    if (anAlias != NULL) {
+    BDSKAlias *anAlias = [BDSKAlias newWithPath:aPath basePath:basePath];
+    if (anAlias != nil) {
         BOOL saveIsBookmark = isBookmark;
-        BDSKLocator saveLocator = locator;
-        locator.alias = anAlias;
+        id saveAlias = alias;
+        alias = anAlias;
         isBookmark = NO;
         [self updateFileRef];
         if (fileRef == NULL) {
-            BDSKDisposeAliasHandle(anAlias);
-            locator = saveLocator;
+            [anAlias release];
+            alias = saveAlias;
             isBookmark = saveIsBookmark;
             [self updateFileRef];
         } else if (saveIsBookmark) {
-            [saveLocator.bookmark release];
+            [saveAlias release];
         } else {
-            BDSKDisposeAliasHandle(saveLocator.alias);
+            [saveAlias release];
         }
     }
 }
@@ -868,50 +866,6 @@
     return inRef == NULL ? NULL : (NSURL *)CFURLCreateFromFSRef(NULL, inRef);
 }
 
-static void BDSKDisposeAliasHandle(AliasHandle inAlias)
-{
-    if (inAlias != NULL)
-        DisposeHandle((Handle)inAlias);
-}
-
-static AliasHandle BDSKDataToAliasHandle(NSData *inData)
-{
-    CFIndex len;
-    Handle handle = NULL;
-    
-    if (inData != nil) {
-        len = CFDataGetLength((CFDataRef)inData);
-        handle = NewHandle(len);
-        
-        if ((handle != NULL) && (len > 0)) {
-            HLock(handle);
-            memmove((void *)*handle, (const void 
*)CFDataGetBytePtr((CFDataRef)inData), len);
-            HUnlock(handle);
-        }
-    }
-    return (AliasHandle)handle;
-}
-
-static NSData *BDSKAliasHandleToData(AliasHandle inAlias)
-{
-    Handle inHandle = (Handle)inAlias;
-    CFDataRef data = NULL;
-    CFIndex len;
-    SInt8 handleState;
-    
-    if (inHandle != NULL) {
-        len = GetHandleSize(inHandle);
-        handleState = HGetState(inHandle);
-        
-        HLock(inHandle);
-        
-        data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *) *inHandle, 
len);
-        
-        HSetState(inHandle, handleState);
-    }
-    return [(NSData *)data autorelease];
-}
-
 static const FSRef *BDSKBaseRefIfOnSameVolume(const FSRef *inBaseRef, const 
FSRef *inRef)
 {
     FSCatalogInfo baseCatalogInfo, catalogInfo;
@@ -923,38 +877,6 @@
     return sameVolume ? inBaseRef : NULL;
 }
 
-static BOOL BDSKAliasHandleToFSRef(const AliasHandle inAlias, const FSRef 
*inBaseRef, FSRef *outRef, BOOL *shouldUpdate)
-{
-    OSStatus err = noErr;
-    short aliasCount = 1;
-    
-    // it would be preferable to search the (relative) path before the fileID, 
but than links to symlinks will always be resolved to the target
-    err = FSMatchAliasBulk(inBaseRef, kARMNoUI | kARMSearch | 
kARMSearchRelFirst | kARMTryFileIDFirst, inAlias, &aliasCount, outRef, (Boolean 
*)shouldUpdate, NULL, NULL);
-    
-    return noErr == err;
-}
-
-static AliasHandle BDSKFSRefToAliasHandle(const FSRef *inRef, const FSRef 
*inBaseRef)
-{
-    OSStatus err = noErr;
-    AliasHandle        alias = NULL;
-    
-    err = FSNewAlias(BDSKBaseRefIfOnSameVolume(inBaseRef, inRef), inRef, 
&alias);
-    
-    if (err != noErr && alias != NULL) {
-        DisposeHandle((Handle)alias);
-        alias = NULL;
-    }
-    
-    return alias;
-}
-
-static void BDSKUpdateAliasWithFSRef(AliasHandle alias, const FSRef *inRef, 
const FSRef *inBaseRef)
-{
-    Boolean didUpdate;
-    FSUpdateAlias(BDSKBaseRefIfOnSameVolume(inBaseRef, inRef), inRef, alias, 
&didUpdate);
-}
-
 static BOOL BDSKPathToFSRef(NSString *inPath, FSRef *outRef)
 {
     OSStatus err = fnfErr;
@@ -964,20 +886,9 @@
     
     return noErr == err;
 }
+
 #pragma clang diagnostic pop
 
-static AliasHandle BDSKPathToAliasHandle(NSString *inPath, NSString 
*inBasePath)
-{
-    FSRef ref, baseRef;
-    AliasHandle alias = NULL;
-    
-    if (BDSKPathToFSRef(inPath, &ref) &&
-        (inBasePath == nil || BDSKPathToFSRef(inBasePath, &baseRef)))
-        alias = BDSKFSRefToAliasHandle(&ref, inBasePath ? &baseRef : NULL);
-    
-    return alias;
-}
-
 static NSDictionary *BDSKDictionaryFromPlistData(NSData *data) {
     NSDictionary *dictionary = [NSPropertyListSerialization 
propertyListWithData:data options:NSPropertyListImmutable format:NULL 
error:NULL];
     if ([dictionary isKindOfClass:[NSDictionary class]] == NO)
@@ -999,3 +910,105 @@
         return nil;
     return dictionary;
 }
+
+@implementation BDSKAlias
+
+@dynamic data;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+- (id)initWithAliasHandle:(AliasHandle)handle {
+    self = [super init];
+    if (self) {
+        alias = (AliasHandle)handle;
+    }
+    return self;
+}
+
++ (id)newWithData:(NSData *)data {
+    CFIndex len;
+    Handle handle = NULL;
+    
+    if (data != nil) {
+        len = CFDataGetLength((CFDataRef)data);
+        handle = NewHandle(len);
+        
+        if ((handle != NULL) && (len > 0)) {
+            HLock(handle);
+            memmove((void *)*handle, (const void 
*)CFDataGetBytePtr((CFDataRef)data), len);
+            HUnlock(handle);
+        }
+    }
+    
+    return handle == NULL ? nil : [[self alloc] 
initWithAliasHandle:(AliasHandle)handle];
+}
+
++ (id)newWithFSRef:(const FSRef *)aRef baseRef:(const FSRef *)baseRef {
+    OSStatus err = noErr;
+    AliasHandle handle = NULL;
+    
+    err = FSNewAlias(BDSKBaseRefIfOnSameVolume(baseRef, aRef), aRef, &handle);
+    
+    if (err != noErr && handle != NULL) {
+        DisposeHandle((Handle)handle);
+        handle = NULL;
+    }
+    
+    return handle == NULL ? nil : [[self alloc] 
initWithAliasHandle:(AliasHandle)handle];
+}
+
++ (id)newWithPath:(NSString *)path basePath:(NSString *)basePath {
+    FSRef ref, baseRef;
+    
+    if (BDSKPathToFSRef(path, &ref) &&
+        (basePath == nil || BDSKPathToFSRef(basePath, &baseRef)))
+        return [self newWithFSRef:&ref baseRef:&baseRef];
+    return nil;
+}
+
+- (void)dealloc {
+    if (alias != NULL) {
+        DisposeHandle((Handle)alias);
+        alias = NULL;
+    }
+    [super dealloc];
+}
+
+- (BOOL)getFSRef:(FSRef *)outRef baseRef:(const FSRef *)baseRef 
shouldUpdate:(BOOL *)shouldUpdate {
+    OSStatus err = noErr;
+    short aliasCount = 1;
+    
+    // it would be preferable to search the (relative) path before the fileID, 
but than links to symlinks will always be resolved to the target
+    err = FSMatchAliasBulk(baseRef, kARMNoUI | kARMSearch | kARMSearchRelFirst 
| kARMTryFileIDFirst, alias, &aliasCount, outRef, (Boolean *)shouldUpdate, 
NULL, NULL);
+    
+    return noErr == err;
+}
+
+- (NSData *)data {
+    Handle handle = (Handle)alias;
+    CFDataRef data = NULL;
+    CFIndex len;
+    SInt8 handleState;
+    
+    if (handle != NULL) {
+        len = GetHandleSize(handle);
+        handleState = HGetState(handle);
+        
+        HLock(handle);
+        
+        data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *) *handle, len);
+        
+        HSetState(handle, handleState);
+    }
+    return [(NSData *)data autorelease];
+}
+
+- (void)updateWithFSRef:(const FSRef *)aRef baseRef:(const FSRef *)baseRef {
+    Boolean didUpdate;
+    FSUpdateAlias(BDSKBaseRefIfOnSameVolume(baseRef, aRef), aRef, alias, 
&didUpdate);
+}
+
+#pragma clang diagnostic pop
+
+@end

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
Bibdesk-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to