]> git.saurik.com Git - apple/security.git/blame - libsecurity_utilities/lib/seccfobject.cpp
Security-55471.14.18.tar.gz
[apple/security.git] / libsecurity_utilities / lib / seccfobject.cpp
CommitLineData
b1ab9ed8
A
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#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
33SecPointerBase::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
45static void CheckForRelease(SecCFObject* ptr)
46{
47 CFTypeRef tr = ptr->operator CFTypeRef();
427c49bc 48 CFIndex retainCount = CFGetRetainCount(tr);
b1ab9ed8
A
49 if (retainCount == 1 || retainCount == -1)
50 {
51 ptr->aboutToDestruct();
52 }
53}
54
55
56
57SecPointerBase::SecPointerBase(SecCFObject *p)
58{
59 if (p && !p->isNew())
60 {
61 CFRetain(p->operator CFTypeRef());
62 }
63 ptr = p;
64}
65
66
67
68SecPointerBase::~SecPointerBase()
69{
70 if (ptr)
71 {
72 CheckForRelease(ptr);
73 CFRelease(ptr->operator CFTypeRef());
74 }
75}
76
77
78
79SecPointerBase& 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
97void 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
113void 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//
129SecCFObject *
130SecCFObject::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
138SecCFObject *
139SecCFObject::required(CFTypeRef cfTypeRef, OSStatus error)
140{
141 SecCFObject *object = optional(cfTypeRef);
142 if (!object)
143 MacOSError::throwMe(error);
144
145 return object;
146}
147
148void *
149SecCFObject::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);
427c49bc 162 SECURITY_DEBUG_SEC_CREATE(q, rtc ? (char *)rtc->className : NULL, (unsigned int)cfclass.typeID);
b1ab9ed8
A
163 }
164 return q;
165}
166
167void
168SecCFObject::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
180SecCFObject::SecCFObject()
181{
182 mRetainCount = 1;
183 mRetainSpinLock = OS_SPINLOCK_INIT;
184}
185
186uint32_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
213SecCFObject::~SecCFObject()
214{
215 SECURITY_DEBUG_SEC_DESTROY(this);
216}
217
218bool
219SecCFObject::equal(SecCFObject &other)
220{
221 return this == &other;
222}
223
224CFHashCode
225SecCFObject::hash()
226{
227 return CFHashCode(this);
228}
229
230CFStringRef
231SecCFObject::copyFormattingDesc(CFDictionaryRef dict)
232{
233 return NULL;
234}
235
236CFStringRef
237SecCFObject::copyDebugDesc()
238{
239 return NULL;
240}
241
242CFTypeRef
243SecCFObject::handle(bool retain) throw()
244{
245 CFTypeRef cfType = *this;
246 if (retain && !isNew()) CFRetain(cfType);
247 return cfType;
248}
249
250
251
252void
253SecCFObject::aboutToDestruct()
254{
255}
256
257
258
259Mutex*
260SecCFObject::getMutexForObject()
261{
262 return NULL; // we only worry about descendants of KeychainImpl and ItemImpl
263}
427c49bc
A
264
265
266
267bool SecCFObject::mayDelete()
268{
269 return true;
270}