1/* 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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 11 * file. 12 * 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. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23// 24// CoreFoundation building and parsing functions 25// 26#ifndef _H_CFMUNGE 27#define _H_CFMUNGE 28 29#include <security_utilities/cfutilities.h> 30#include <CoreFoundation/CoreFoundation.h> 31#include <cstdarg> 32 33namespace Security { 34 35 36// 37// Common interface to Mungers. 38// A CFMunge provides a one-pass, non-resettable scan through a format string, 39// performing various actions on the way. 40// 41class CFMunge { 42public: 43 CFMunge(const char *fmt, va_list arg); 44 ~CFMunge(); 45 46protected: 47 char next(); 48 bool next(char c); 49 50 bool parameter(); 51 52protected: 53 const char *format; 54 va_list args; 55 CFAllocatorRef allocator; 56 OSStatus error; 57}; 58 59 60// 61// A CFMake is a CFMunge for making CF data structures. 62// 63class CFMake : public CFMunge { 64public: 65 CFMake(const char *fmt, va_list arg) : CFMunge(fmt, arg) { } 66 67 CFTypeRef make(); 68 CFDictionaryRef addto(CFMutableDictionaryRef dict); 69 70protected: 71 CFTypeRef makedictionary(); 72 CFTypeRef makearray(); 73 CFTypeRef makenumber(); 74 CFTypeRef makestring(); 75 CFTypeRef makeformat(); 76 CFTypeRef makespecial(); 77 78 CFDictionaryRef add(CFMutableDictionaryRef dict); 79}; 80 81 82// 83// Make a CF object following a general recipe 84// 85CFTypeRef cfmake(const char *format, ...); 86CFTypeRef vcfmake(const char *format, va_list args); 87 88template <class CFType> 89CFType cfmake(const char *format, ...) 90{ 91 va_list args; 92 va_start(args, format); 93 CFType result = CFType(vcfmake(format, args)); 94 va_end(args); 95 return result; 96} 97 98CFDictionaryRef cfadd(CFMutableDictionaryRef dict, const char *format, ...); 99 100 101// 102// Parse out parts of a CF object following a general recipe. 103// Cfscan returns false on error; cfget throws. 104// 105bool cfscan(CFTypeRef source, const char *format, ...); 106bool vcfscan(CFTypeRef source, const char *format, va_list args); 107 108CFTypeRef cfget(CFTypeRef source, const char *format, ...); 109CFTypeRef vcfget(CFTypeRef source, const char *format, va_list args); 110 111template <class CFType> 112CFType cfget(CFTypeRef source, const char *format, ...) 113{ 114 va_list args; 115 va_start(args, format); 116 CFType result = CFType(vcfget(source, format, args)); 117 va_end(args); 118 return (result && CFTraits<CFType>::check(result)) ? result : NULL; 119} 120 121template <class CFType> 122class CFTemp : public CFRef<CFType> { 123public: 124 CFTemp(const char *format, ...) 125 { 126 va_list args; 127 va_start(args, format); 128 this->take(CFType(vcfmake(format, args))); 129 va_end(args); 130 } 131}; 132 133 134} // end namespace Security 135 136#endif //_H_CFMUNGE 137