alternative new version of the AppleUtility library
[ardour.git] / libs / appleutility / CoreAudio / PublicUtility / CAFilePathUtils.cpp
1 /*
2      File: CAFilePathUtils.cpp
3  Abstract: CAFilePathUtils.h
4   Version: 1.1
5  
6  Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
7  Inc. ("Apple") in consideration of your agreement to the following
8  terms, and your use, installation, modification or redistribution of
9  this Apple software constitutes acceptance of these terms.  If you do
10  not agree with these terms, please do not use, install, modify or
11  redistribute this Apple software.
12  
13  In consideration of your agreement to abide by the following terms, and
14  subject to these terms, Apple grants you a personal, non-exclusive
15  license, under Apple's copyrights in this original Apple software (the
16  "Apple Software"), to use, reproduce, modify and redistribute the Apple
17  Software, with or without modifications, in source and/or binary forms;
18  provided that if you redistribute the Apple Software in its entirety and
19  without modifications, you must retain this notice and the following
20  text and disclaimers in all such redistributions of the Apple Software.
21  Neither the name, trademarks, service marks or logos of Apple Inc. may
22  be used to endorse or promote products derived from the Apple Software
23  without specific prior written permission from Apple.  Except as
24  expressly stated in this notice, no other rights or licenses, express or
25  implied, are granted by Apple herein, including but not limited to any
26  patent rights that may be infringed by your derivative works or by other
27  works in which the Apple Software may be incorporated.
28  
29  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
30  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34  
35  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42  POSSIBILITY OF SUCH DAMAGE.
43  
44  Copyright (C) 2014 Apple Inc. All Rights Reserved.
45  
46 */
47 #include "CAFilePathUtils.h"
48 #include <string.h>
49
50 #if !CA_NO_CORE_SERVICES
51 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
52         #include <CoreServices/CoreServices.h> // FSRef
53     #include <CoreAudio/CoreAudioTypes.h>
54 #else
55         #include <CoreServices.h>
56         #include <CoreAudioTypes.h>
57 #endif
58
59 OSStatus        PosixPathToParentFSRefAndName(const char *path, FSRef &outParentDir, CFStringRef &outFileName)
60 {
61         // convert C string to CFString
62 #if !TARGET_OS_WIN32
63         CFStringRef cfFullPath = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
64 #else
65         CFStringRef cfFullPath = CFStringCreateWithCString(NULL, path, kCFStringEncodingWindowsLatin1);
66 #endif
67         // convert CF string to URL
68         CFURLRef fullurl = CFURLCreateWithFileSystemPath(NULL, cfFullPath, TARGET_OS_WIN32 ? kCFURLWindowsPathStyle : kCFURLPOSIXPathStyle, false);
69         CFRelease(cfFullPath);
70         // get the directory portion of the URL
71         CFURLRef dirurl = CFURLCreateCopyDeletingLastPathComponent(NULL, fullurl);
72         // get the directory's FSRef
73         OSStatus err = CFURLGetFSRef(dirurl, &outParentDir) ? OSStatus(noErr) : OSStatus(kAudio_FileNotFoundError);
74         CFRelease(dirurl);
75         
76         CFStringRef lastPathComponent = CFURLCopyLastPathComponent(fullurl);
77         CFRelease(fullurl);
78         CFMutableStringRef filename = CFStringCreateMutableCopy(NULL, 0, lastPathComponent);
79         CFRelease(lastPathComponent);
80         // convert colons (legal in POSIX paths, illegal in File Manager) to slashes
81         CFStringFindAndReplace(filename, CFSTR(":"), CFSTR("/"), CFRangeMake(0, CFStringGetLength(filename)), 0);
82         
83         outFileName = filename;
84         
85         return err;
86 }
87 #endif // !CA_NO_CORE_SERVICES
88
89
90 #if TARGET_OS_WIN32
91
92 char*   dirname(const char* inPath)
93 {
94         static char sAnswer[1024];
95         
96         char* theAnswer = NULL;
97         SInt32 thePathLength = strlen(inPath);
98         if(thePathLength < 1023)
99         {
100                 //      make a working copy
101                 strlcpy(sAnswer, inPath, sizeof(sAnswer));
102                 
103                 //      start at the end of the string
104                 SInt32 theIndex = thePathLength - 1;
105                 
106                 //      walk back over the '\' characters
107                 while((theIndex > 0) && (sAnswer[theIndex] == '\\'))
108                 {
109                         --theIndex;
110                 }
111                 
112                 //      now keep walking back until we get to a '\'
113                 while((theIndex > 0) && (sAnswer[theIndex] != '\\'))
114                 {
115                         --theIndex;
116                 }
117                 
118                 //      where we are now is either the first character of the path or the '\' that marks the end of the directory name
119                 if(theIndex > 0)
120                 {
121                         //      we have a name so put a '\0' in place of the '\'
122                         sAnswer[theIndex] = 0;
123                 }
124                 else
125                 {
126                         //      no name, so the answer is "."
127                         sAnswer[0] = '.';
128                         sAnswer[1] = 0;
129                 }
130                 
131                 //      set the return value
132                 theAnswer = sAnswer;
133         }
134         
135         return theAnswer;
136 }
137
138 char*   basename(const char* inPath)
139 {
140         static char sAnswer[1024];
141         
142         char* theAnswer = NULL;
143         SInt32 thePathLength = strlen(inPath);
144         if(thePathLength < 1023)
145         {
146                 //      make a working copy
147                 strlcpy(sAnswer, inPath, sizeof(sAnswer));
148                 
149                 //      start at the end of the string
150                 SInt32 theLastIndex = thePathLength - 1;
151                 
152                 //      walk back over the '\' characters
153                 while((theLastIndex > 0) && (sAnswer[theLastIndex] == '\\'))
154                 {
155                         --theLastIndex;
156                 }
157                 
158                 //      check to see if we're at the beginning now
159                 if(theLastIndex > 0)
160                 {
161                         //      there's a name in there now, so start where we are and go back to the next '\'
162                         UInt32 theFirstIndex = theLastIndex;
163                         while((theFirstIndex > 0) && (sAnswer[theFirstIndex] != '\\'))
164                         {
165                                 --theFirstIndex;
166                         }
167                         
168                         //      we now have a string, so put a '\0' after the last character
169                         sAnswer[theLastIndex + 1] = 0;
170                         
171                         //      and set the return value
172                         theAnswer = &sAnswer[theFirstIndex];
173                 }
174                 else
175                 {
176                         //      the path was entirely '\' characters, so the return value is "\"
177                         sAnswer[0] = '\\';
178                         sAnswer[1] = 0;
179                 
180                         //      set the return value
181                         theAnswer = sAnswer;
182                 }
183         }
184         
185         return theAnswer;
186 }
187
188 #endif