]> git.saurik.com Git - apple/security.git/blob - Keychain/SecRuntime.h
Security-176.tar.gz
[apple/security.git] / Keychain / SecRuntime.h
1 /*
2 * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18 //
19 // SecRuntime.h - CF runtime interface
20 //
21 #ifndef _SECURITY_SECRUNTIME_H_
22 #define _SECURITY_SECRUNTIME_H_
23
24 #include <CoreFoundation/CFRuntime.h>
25 #include <new>
26
27 #include <Security/SecCFTypes.h>
28
29 namespace Security
30 {
31
32 namespace KeychainCore
33 {
34
35 #define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE) \
36 \
37 void *operator new(size_t size) throw(std::bad_alloc) \
38 { return SecCFObject::allocate(size, gTypes().OBJTYPE.typeID); } \
39 \
40 operator APIPTR() const \
41 { return (APIPTR)(this->operator CFTypeRef()); } \
42 \
43 APIPTR handle(bool retain = true) \
44 { return (APIPTR)SecCFObject::handle(retain); } \
45 \
46 static OBJTYPE *required(APIPTR ptr) \
47 { return static_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE)); } \
48 \
49 static OBJTYPE *optional(APIPTR ptr) \
50 { return static_cast<OBJTYPE *>(SecCFObject::optional(ptr)); }
51
52 #define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
53
54 struct SecRuntimeBase: CFRuntimeBase
55 {
56 bool isNew;
57 };
58
59 class SecCFObject
60 {
61 private:
62 void *operator new(size_t) throw(std::bad_alloc);
63
64 // Align up to a multiple of 16 bytes
65 static const size_t kAlignedRuntimeSize = SECALIGNUP(sizeof(SecRuntimeBase), 16);
66
67 public:
68 // For use by SecPointer only. Returns true once the first time it's called after the object has been created.
69 bool isNew()
70 {
71 SecRuntimeBase *base = reinterpret_cast<SecRuntimeBase *>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize);
72 bool isNew = base->isNew;
73 base->isNew = false;
74 return isNew;
75 }
76
77 static SecCFObject *optional(CFTypeRef) throw();
78 static SecCFObject *required(CFTypeRef, OSStatus error);
79 static void *allocate(size_t size, CFTypeID typeID) throw(std::bad_alloc);
80
81 virtual ~SecCFObject() throw();
82
83 void operator delete(void *object) throw();
84 operator CFTypeRef() const throw()
85 {
86 return reinterpret_cast<CFTypeRef>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize);
87 }
88
89 // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true
90 CFTypeRef handle(bool retain = true) throw();
91
92 virtual bool equal(SecCFObject &other);
93 virtual CFHashCode hash();
94 virtual CFStringRef copyFormattingDesc(CFDictionaryRef dict);
95 virtual CFStringRef copyDebugDesc();
96 };
97
98 //
99 // A pointer type for SecCFObjects.
100 // T must be derived from SecCFObject.
101 //
102 class SecPointerBase
103 {
104 public:
105 SecPointerBase() : ptr(NULL)
106 {}
107 SecPointerBase(const SecPointerBase& p)
108 {
109 if (p.ptr)
110 CFRetain(p.ptr->operator CFTypeRef());
111 ptr = p.ptr;
112 }
113 SecPointerBase(SecCFObject *p)
114 {
115 if (p && !p->isNew())
116 CFRetain(p->operator CFTypeRef());
117 ptr = p;
118 }
119 ~SecPointerBase()
120 {
121 if (ptr)
122 CFRelease(ptr->operator CFTypeRef());
123 }
124 SecPointerBase& operator = (const SecPointerBase& p)
125 {
126 if (p.ptr)
127 CFRetain(p.ptr->operator CFTypeRef());
128 if (ptr)
129 CFRelease(ptr->operator CFTypeRef());
130 ptr = p.ptr;
131 return *this;
132 }
133
134 protected:
135 void assign(SecCFObject * p)
136 {
137 if (p && !p->isNew())
138 CFRetain(p->operator CFTypeRef());
139 if (ptr)
140 CFRelease(ptr->operator CFTypeRef());
141 ptr = p;
142 }
143
144 SecCFObject *ptr;
145 };
146
147 template <class T>
148 class SecPointer : public SecPointerBase
149 {
150 public:
151 SecPointer() : SecPointerBase() {}
152 SecPointer(const SecPointer& p) : SecPointerBase(p) {}
153 SecPointer(T *p): SecPointerBase(p) {}
154 SecPointer &operator =(T *p) { this->assign(p); return *this; }
155
156 // dereference operations
157 T* get () const { return static_cast<T*>(ptr); } // mimic auto_ptr
158 operator T * () const { return static_cast<T*>(ptr); }
159 T * operator -> () const { return static_cast<T*>(ptr); }
160 T & operator * () const { return *static_cast<T*>(ptr); }
161 };
162
163 template <class T>
164 bool operator <(const SecPointer<T> &r1, const SecPointer<T> &r2)
165 {
166 T *p1 = r1.get(), *p2 = r2.get();
167 return p1 && p2 ? *p1 < *p2 : p1 < p2;
168 }
169
170 template <class T>
171 bool operator ==(const SecPointer<T> &r1, const SecPointer<T> &r2)
172 {
173 T *p1 = r1.get(), *p2 = r2.get();
174 return p1 && p2 ? *p1 == *p2 : p1 == p2;
175 }
176
177 template <class T>
178 bool operator !=(const SecPointer<T> &r1, const SecPointer<T> &r2)
179 {
180 T *p1 = r1.get(), *p2 = r2.get();
181 return p1 && p2 ? *p1 != *p2 : p1 != p2;
182 }
183
184
185 } // end namespace KeychainCore
186
187 } // end namespace Security
188
189 #endif // !_SECURITY_SECRUNTIME_H_