]> git.saurik.com Git - apple/security.git/blob - libsecurity_utilities/lib/seccfobject.h
Security-55178.0.1.tar.gz
[apple/security.git] / libsecurity_utilities / lib / seccfobject.h
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
25
26 #ifndef _SECCFOBJECT_H
27 #define _SECCFOBJECT_H
28
29 #include <CoreFoundation/CFRuntime.h>
30 #include <new>
31 #include "threading.h"
32
33 namespace Security {
34
35 class CFClass;
36
37 #define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE, CFCLASS) \
38 \
39 void *operator new(size_t size) throw(std::bad_alloc) \
40 { return SecCFObject::allocate(size, CFCLASS); } \
41 \
42 operator APIPTR() const \
43 { return (APIPTR)(this->operator CFTypeRef()); } \
44 \
45 OBJTYPE *retain() \
46 { SecCFObject::handle(true); return this; } \
47 APIPTR handle(bool retain = true) \
48 { return (APIPTR)SecCFObject::handle(retain); } \
49 \
50 static OBJTYPE *required(APIPTR ptr) \
51 { if (OBJTYPE *p = dynamic_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE))) \
52 return p; else MacOSError::throwMe(ERRCODE); } \
53 \
54 static OBJTYPE *optional(APIPTR ptr) \
55 { if (SecCFObject *p = SecCFObject::optional(ptr)) \
56 if (OBJTYPE *pp = dynamic_cast<OBJTYPE *>(p)) return pp; else MacOSError::throwMe(ERRCODE); \
57 else return NULL; }
58
59 #define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
60
61 struct SecRuntimeBase: CFRuntimeBase
62 {
63 bool isNew;
64 };
65
66 class SecCFObject
67 {
68 private:
69 void *operator new(size_t) throw(std::bad_alloc);
70
71 // Align up to a multiple of 16 bytes
72 static const size_t kAlignedRuntimeSize = SECALIGNUP(sizeof(SecRuntimeBase), 4);
73
74 uint32_t mRetainCount;
75 OSSpinLock mRetainSpinLock;
76
77 public:
78 // For use by SecPointer only. Returns true once the first time it's called after the object has been created.
79 bool isNew()
80 {
81 SecRuntimeBase *base = reinterpret_cast<SecRuntimeBase *>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize);
82 bool isNew = base->isNew;
83 base->isNew = false;
84 return isNew;
85 }
86
87 static SecCFObject *optional(CFTypeRef) throw();
88 static SecCFObject *required(CFTypeRef, OSStatus error);
89 static void *allocate(size_t size, const CFClass &cfclass) throw(std::bad_alloc);
90
91 SecCFObject();
92 virtual ~SecCFObject();
93 uint32_t updateRetainCount(intptr_t direction, uint32_t *oldCount);
94 uint32_t getRetainCount() {return updateRetainCount(0, NULL);}
95
96 static void operator delete(void *object) throw();
97 operator CFTypeRef() const throw()
98 {
99 return reinterpret_cast<CFTypeRef>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize);
100 }
101
102 // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true
103 CFTypeRef handle(bool retain = true) throw();
104
105 virtual bool equal(SecCFObject &other);
106 virtual CFHashCode hash();
107 virtual CFStringRef copyFormattingDesc(CFDictionaryRef dict);
108 virtual CFStringRef copyDebugDesc();
109 virtual void aboutToDestruct();
110 virtual Mutex* getMutexForObject();
111 };
112
113 //
114 // A pointer type for SecCFObjects.
115 // T must be derived from SecCFObject.
116 //
117 class SecPointerBase
118 {
119 public:
120 SecPointerBase() : ptr(NULL)
121 {}
122 SecPointerBase(const SecPointerBase& p);
123 SecPointerBase(SecCFObject *p);
124 ~SecPointerBase();
125 SecPointerBase& operator = (const SecPointerBase& p);
126
127 protected:
128 void assign(SecCFObject * p);
129 void copy(SecCFObject * p);
130 SecCFObject *ptr;
131 };
132
133 template <class T>
134 class SecPointer : public SecPointerBase
135 {
136 public:
137 SecPointer() : SecPointerBase() {}
138 SecPointer(const SecPointer& p) : SecPointerBase(p) {}
139 SecPointer(T *p): SecPointerBase(p) {}
140 SecPointer &operator =(T *p) { this->assign(p); return *this; }
141 SecPointer &take(T *p) { this->copy(p); return *this; }
142 T *yield() { T *result = static_cast<T *>(ptr); ptr = NULL; return result; }
143
144 // dereference operations
145 T* get () const { return static_cast<T*>(ptr); } // mimic auto_ptr
146 operator T * () const { return static_cast<T*>(ptr); }
147 T * operator -> () const { return static_cast<T*>(ptr); }
148 T & operator * () const { return *static_cast<T*>(ptr); }
149 };
150
151 template <class T>
152 bool operator <(const SecPointer<T> &r1, const SecPointer<T> &r2)
153 {
154 T *p1 = r1.get(), *p2 = r2.get();
155 return p1 && p2 ? *p1 < *p2 : p1 < p2;
156 }
157
158 template <class T>
159 bool operator ==(const SecPointer<T> &r1, const SecPointer<T> &r2)
160 {
161 T *p1 = r1.get(), *p2 = r2.get();
162 return p1 && p2 ? *p1 == *p2 : p1 == p2;
163 }
164
165 template <class T>
166 bool operator !=(const SecPointer<T> &r1, const SecPointer<T> &r2)
167 {
168 T *p1 = r1.get(), *p2 = r2.get();
169 return p1 && p2 ? *p1 != *p2 : p1 != p2;
170 }
171
172 } // end namespace Security
173
174
175 #endif