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