]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_utilities/lib/seccfobject.cpp
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurity_utilities / lib / seccfobject.cpp
1 /*
2 * Copyright (c) 2000-2004,2011-2014 Apple 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 #include <security_utilities/seccfobject.h>
25 #include <security_utilities/cfclass.h>
26 #include <security_utilities/errors.h>
27 #include <security_utilities/debugging.h>
28
29 #include <list>
30 #include <security_utilities/globalizer.h>
31 #include <auto_zone.h>
32
33 SecPointerBase::SecPointerBase(const SecPointerBase& p)
34 {
35 if (p.ptr)
36 {
37 CFRetain(p.ptr->operator CFTypeRef());
38 }
39 ptr = p.ptr;
40 }
41
42
43
44
45 static void CheckForRelease(SecCFObject* ptr)
46 {
47 CFTypeRef tr = ptr->operator CFTypeRef();
48 CFIndex retainCount = CFGetRetainCount(tr);
49 if (retainCount == 1 || retainCount == -1)
50 {
51 ptr->aboutToDestruct();
52 }
53 }
54
55
56
57 SecPointerBase::SecPointerBase(SecCFObject *p)
58 {
59 if (p && !p->isNew())
60 {
61 CFRetain(p->operator CFTypeRef());
62 }
63 ptr = p;
64 }
65
66
67
68 SecPointerBase::~SecPointerBase()
69 {
70 if (ptr)
71 {
72 CheckForRelease(ptr);
73 CFRelease(ptr->operator CFTypeRef());
74 }
75 }
76
77
78
79 SecPointerBase& SecPointerBase::operator = (const SecPointerBase& p)
80 {
81 if (p.ptr)
82 {
83 CFTypeRef tr = p.ptr->operator CFTypeRef();
84 CFRetain(tr);
85 }
86 if (ptr)
87 {
88 CheckForRelease(ptr);
89 CFRelease(ptr->operator CFTypeRef());
90 }
91 ptr = p.ptr;
92 return *this;
93 }
94
95
96
97 void SecPointerBase::assign(SecCFObject * p)
98 {
99 if (p && !p->isNew())
100 {
101 CFRetain(p->operator CFTypeRef());
102 }
103 if (ptr)
104 {
105 CheckForRelease(ptr);
106 CFRelease(ptr->operator CFTypeRef());
107 }
108 ptr = p;
109 }
110
111
112
113 void SecPointerBase::copy(SecCFObject * p)
114 {
115 if (ptr)
116 {
117 CheckForRelease(ptr);
118 CFRelease(ptr->operator CFTypeRef());
119 }
120
121 ptr = p;
122 }
123
124
125
126 //
127 // SecCFObject
128 //
129 SecCFObject *
130 SecCFObject::optional(CFTypeRef cfTypeRef) throw()
131 {
132 if (!cfTypeRef)
133 return NULL;
134
135 return const_cast<SecCFObject *>(reinterpret_cast<const SecCFObject *>(reinterpret_cast<const uint8_t *>(cfTypeRef) + kAlignedRuntimeSize));
136 }
137
138 SecCFObject *
139 SecCFObject::required(CFTypeRef cfTypeRef, OSStatus error)
140 {
141 SecCFObject *object = optional(cfTypeRef);
142 if (!object)
143 MacOSError::throwMe(error);
144
145 return object;
146 }
147
148 void *
149 SecCFObject::allocate(size_t size, const CFClass &cfclass) throw(std::bad_alloc)
150 {
151 CFTypeRef p = _CFRuntimeCreateInstance(NULL, cfclass.typeID,
152 size + kAlignedRuntimeSize - sizeof(CFRuntimeBase), NULL);
153 if (p == NULL)
154 throw std::bad_alloc();
155
156 ((SecRuntimeBase*) p)->isNew = true;
157
158 void *q = ((u_int8_t*) p) + kAlignedRuntimeSize;
159
160 if (SECURITY_DEBUG_SEC_CREATE_ENABLED()) {
161 const CFRuntimeClass *rtc = _CFRuntimeGetClassWithTypeID(cfclass.typeID);
162 SECURITY_DEBUG_SEC_CREATE(q, rtc ? (char *)rtc->className : NULL, (unsigned int)cfclass.typeID);
163 }
164 return q;
165 }
166
167 void
168 SecCFObject::operator delete(void *object) throw()
169 {
170 CFTypeRef cfType = reinterpret_cast<CFTypeRef>(reinterpret_cast<const uint8_t *>(object) - kAlignedRuntimeSize);
171 if (CF_IS_COLLECTABLE(cfType))
172 {
173 return;
174 }
175
176 CFAllocatorRef allocator = CFGetAllocator(cfType);
177 CFAllocatorDeallocate(allocator, (void*) cfType);
178 }
179
180 SecCFObject::SecCFObject()
181 {
182 mRetainCount = 1;
183 mRetainSpinLock = OS_SPINLOCK_INIT;
184 }
185
186 uint32_t SecCFObject::updateRetainCount(intptr_t direction, uint32_t *oldCount)
187 {
188 OSSpinLockLock(&mRetainSpinLock);
189
190 if (oldCount != NULL)
191 {
192 *oldCount = mRetainCount;
193 }
194
195 if (direction != -1 || mRetainCount != 0)
196 {
197 // if we are decrementing
198 if (direction == -1 || UINT32_MAX != mRetainCount)
199 {
200 mRetainCount += direction;
201 }
202 }
203
204 uint32_t result = mRetainCount;
205
206 OSSpinLockUnlock(&mRetainSpinLock);
207
208 return result;
209 }
210
211
212
213 SecCFObject::~SecCFObject()
214 {
215 SECURITY_DEBUG_SEC_DESTROY(this);
216 }
217
218 bool
219 SecCFObject::equal(SecCFObject &other)
220 {
221 return this == &other;
222 }
223
224 CFHashCode
225 SecCFObject::hash()
226 {
227 return CFHashCode(this);
228 }
229
230 CFStringRef
231 SecCFObject::copyFormattingDesc(CFDictionaryRef dict)
232 {
233 return NULL;
234 }
235
236 CFStringRef
237 SecCFObject::copyDebugDesc()
238 {
239 return NULL;
240 }
241
242 CFTypeRef
243 SecCFObject::handle(bool retain) throw()
244 {
245 CFTypeRef cfType = *this;
246 if (retain && !isNew()) CFRetain(cfType);
247 return cfType;
248 }
249
250
251
252 void
253 SecCFObject::aboutToDestruct()
254 {
255 }
256
257
258
259 Mutex*
260 SecCFObject::getMutexForObject()
261 {
262 return NULL; // we only worry about descendants of KeychainImpl and ItemImpl
263 }
264
265
266
267 bool SecCFObject::mayDelete()
268 {
269 return true;
270 }