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