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