2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // CoreFoundation related utilities
28 #include <security_utilities/cfutilities.h>
29 #include <security_utilities/errors.h>
30 #include <security_utilities/debugging.h>
38 ModuleNexus
<CFEmptyArray
> cfEmptyArray
;
40 CFEmptyArray::CFEmptyArray()
42 mArray
= CFArrayCreate(NULL
, NULL
, 0, NULL
);
47 // Turn a C(++) string into a CFURLRef indicating a file: path
49 CFURLRef
makeCFURL(const char *s
, bool isDirectory
, CFURLRef base
)
51 CFStringRef ss
= CFStringCreateWithCStringNoCopy(NULL
, s
, kCFStringEncodingUTF8
, kCFAllocatorNull
);
52 CFURLRef returnValue
= NULL
;
56 returnValue
= CFURLCreateWithFileSystemPathRelativeToBase(NULL
,
57 ss
, kCFURLPOSIXPathStyle
, isDirectory
, base
);
61 returnValue
= CFURLCreateWithFileSystemPath(NULL
,
62 ss
, kCFURLPOSIXPathStyle
, isDirectory
);
69 CFURLRef
makeCFURL(CFStringRef s
, bool isDirectory
, CFURLRef base
)
72 return CFURLCreateWithFileSystemPathRelativeToBase(NULL
, s
, kCFURLPOSIXPathStyle
, isDirectory
, base
);
74 return CFURLCreateWithFileSystemPath(NULL
, s
, kCFURLPOSIXPathStyle
, isDirectory
);
79 // CFMallocData objects
81 CFMallocData::operator CFDataRef ()
83 CFDataRef result
= makeCFDataMalloc(mData
, mSize
);
86 mData
= NULL
; // release ownership
92 // Make CFDictionaries from stuff
94 CFDictionaryRef
makeCFDictionary(unsigned count
, ...)
96 CFTypeRef keys
[count
], values
[count
];
98 va_start(args
, count
);
99 for (unsigned n
= 0; n
< count
; n
++) {
100 keys
[n
] = va_arg(args
, CFTypeRef
);
101 values
[n
] = va_arg(args
, CFTypeRef
);
104 return CFDictionaryCreate(NULL
, (const void **)keys
, (const void **)values
, count
,
105 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
108 CFMutableDictionaryRef
makeCFMutableDictionary()
110 if (CFMutableDictionaryRef r
= CFDictionaryCreateMutable(NULL
, 0,
111 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
))
116 CFMutableDictionaryRef
makeCFMutableDictionary(unsigned count
, ...)
118 CFMutableDictionaryRef dict
= makeCFMutableDictionary();
121 va_start(args
, count
);
122 for (unsigned n
= 0; n
< count
; n
++) {
123 CFTypeRef key
= va_arg(args
, CFTypeRef
);
124 CFTypeRef value
= va_arg(args
, CFTypeRef
);
125 CFDictionaryAddValue(dict
, key
, value
);
132 CFMutableDictionaryRef
makeCFMutableDictionary(CFDictionaryRef dict
)
134 if (CFMutableDictionaryRef r
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
))
139 CFDictionaryRef
makeCFDictionaryFrom(CFDataRef data
)
142 CFPropertyListRef plist
= CFPropertyListCreateFromXMLData(NULL
, data
,
143 kCFPropertyListImmutable
, NULL
);
144 if (plist
&& CFGetTypeID(plist
) != CFDictionaryGetTypeID())
146 return CFDictionaryRef(plist
);
152 CFDictionaryRef
makeCFDictionaryFrom(const void *data
, size_t length
)
154 return makeCFDictionaryFrom(CFTempData(data
, length
).get());
159 // Turn a CFString into a UTF8-encoded C++ string.
160 // If release==true, the argument will be CFReleased even in case of error.
162 string
cfString(CFStringRef str
)
167 if (const char *s
= CFStringGetCStringPtr(str
, kCFStringEncodingUTF8
)) {
171 // need to extract into buffer
173 CFIndex length
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(str
), kCFStringEncodingUTF8
);
174 std::vector
<char> buffer
;
175 buffer
.resize(length
+ 1);
176 if (CFStringGetCString(str
, &buffer
[0], length
+ 1, kCFStringEncodingUTF8
))
181 string
cfStringRelease(CFStringRef inStr
)
183 CFRef
<CFStringRef
> str(inStr
);
184 return cfString(str
);
187 string
cfString(CFURLRef inUrl
)
192 UInt8 buffer
[PATH_MAX
+1];
193 if (CFURLGetFileSystemRepresentation(inUrl
, true, buffer
, sizeof(buffer
)))
194 return string(reinterpret_cast<char *>(buffer
));
199 string
cfStringRelease(CFURLRef inUrl
)
201 CFRef
<CFURLRef
> bundle(inUrl
);
202 return cfString(bundle
);
205 string
cfString(CFBundleRef inBundle
)
209 return cfStringRelease(CFBundleCopyBundleURL(inBundle
));
212 string
cfStringRelease(CFBundleRef inBundle
)
214 CFRef
<CFBundleRef
> bundle(inBundle
);
215 return cfString(bundle
);
219 string
cfString(CFTypeRef it
, OSStatus err
)
222 MacOSError::throwMe(err
);
223 CFTypeID id
= CFGetTypeID(it
);
224 if (id
== CFStringGetTypeID())
225 return cfString(CFStringRef(it
));
226 else if (id
== CFURLGetTypeID())
227 return cfString(CFURLRef(it
));
228 else if (id
== CFBundleGetTypeID())
229 return cfString(CFBundleRef(it
));
231 return cfString(CFCopyDescription(it
), true);
236 // CFURLAccess wrappers for specific purposes
238 CFDataRef
cfLoadFile(CFURLRef url
)
243 if (CFURLCreateDataAndPropertiesFromResource(NULL
, url
,
244 &data
, NULL
, NULL
, &error
)) {
247 secdebug("cfloadfile", "failed to fetch %s error=%d", cfString(url
).c_str(), int(error
));
252 CFDataRef
cfLoadFile(int fd
, size_t bytes
)
254 uint8_t *buffer
= (uint8_t *) malloc(bytes
);
259 if (read(fd
, buffer
, bytes
) != bytes
) {
264 CFDataRef result
= CFDataCreateWithBytesNoCopy(kCFAllocatorMalloc
, buffer
, bytes
, kCFAllocatorMalloc
);
266 // If CFDataCreateWithBytesNoCopy fails, the buffer is not free()-ed
267 if (result
== NULL
) {
278 CFArrayRef
makeCFArray(CFIndex count
, ...)
280 CFTypeRef elements
[count
];
282 va_start(args
, count
);
283 for (CFIndex n
= 0; n
< count
; n
++)
284 elements
[n
] = va_arg(args
, CFTypeRef
);
286 return CFArrayCreate(NULL
, elements
, count
, &kCFTypeArrayCallBacks
);
289 CFMutableArrayRef
makeCFMutableArray(CFIndex count
, ...)
291 CFMutableArrayRef array
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
293 va_start(args
, count
);
294 for (CFIndex n
= 0; n
< count
; n
++)
295 CFArrayAppendValue(array
, va_arg(args
, CFTypeRef
));
301 } // end namespace Security