2 * Copyright (c) 2000-2004,2011,2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 #ifndef _SECCFOBJECT_H
27 #define _SECCFOBJECT_H
29 #include <CoreFoundation/CFRuntime.h>
31 #include "threading.h"
33 #if( __cplusplus <= 201103L)
34 #include <stdatomic.h>
41 #define SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR) \
43 operator APIPTR() const \
44 { return (APIPTR)(this->operator CFTypeRef()); } \
47 { SecCFObject::handle(true); return this; } \
48 APIPTR handle(bool retain = true) \
49 { return (APIPTR)SecCFObject::handle(retain); }
51 #define SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \
52 SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR)\
54 void *operator new(size_t size) throw(std::bad_alloc) \
55 { return SecCFObject::allocate(size, CFCLASS); }
57 #define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE, CFCLASS) \
58 SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \
60 static OBJTYPE *required(APIPTR ptr) \
61 { if (OBJTYPE *p = dynamic_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE))) \
62 return p; else MacOSError::throwMe(ERRCODE); } \
64 static OBJTYPE *optional(APIPTR ptr) \
65 { if (SecCFObject *p = SecCFObject::optional(ptr)) \
66 if (OBJTYPE *pp = dynamic_cast<OBJTYPE *>(p)) return pp; else MacOSError::throwMe(ERRCODE); \
69 #define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
71 struct SecRuntimeBase
: CFRuntimeBase
79 void *operator new(size_t) throw(std::bad_alloc
);
81 // Align up to a multiple of 16 bytes
82 static const size_t kAlignedRuntimeSize
= SECALIGNUP(sizeof(SecRuntimeBase
), 4);
84 uint32_t mRetainCount
;
85 OSSpinLock mRetainSpinLock
;
88 // For use by SecPointer only. Returns true once the first time it's called after the object has been created.
91 SecRuntimeBase
*base
= reinterpret_cast<SecRuntimeBase
*>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize
);
93 // atomic flags start clear, and like to go high.
94 return !atomic_flag_test_and_set(&(base
->isOld
));
97 static SecCFObject
*optional(CFTypeRef
) throw();
98 static SecCFObject
*required(CFTypeRef
, OSStatus error
);
99 static void *allocate(size_t size
, const CFClass
&cfclass
) throw(std::bad_alloc
);
102 virtual ~SecCFObject();
103 uint32_t updateRetainCount(intptr_t direction
, uint32_t *oldCount
);
104 uint32_t getRetainCount() {return updateRetainCount(0, NULL
);}
106 static void operator delete(void *object
) throw();
107 virtual operator CFTypeRef() const throw()
109 return reinterpret_cast<CFTypeRef
>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize
);
112 // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true
113 CFTypeRef
handle(bool retain
= true) throw();
115 virtual bool equal(SecCFObject
&other
);
116 virtual CFHashCode
hash();
117 virtual CFStringRef
copyFormattingDesc(CFDictionaryRef dict
);
118 virtual CFStringRef
copyDebugDesc();
119 virtual void aboutToDestruct();
120 virtual Mutex
* getMutexForObject() const;
121 virtual bool mayDelete();
125 // A pointer type for SecCFObjects.
126 // T must be derived from SecCFObject.
131 SecPointerBase() : ptr(NULL
)
133 SecPointerBase(const SecPointerBase
& p
);
134 SecPointerBase(SecCFObject
*p
);
136 SecPointerBase
& operator = (const SecPointerBase
& p
);
139 void assign(SecCFObject
* p
);
140 void copy(SecCFObject
* p
);
145 class SecPointer
: public SecPointerBase
148 SecPointer() : SecPointerBase() {}
149 SecPointer(const SecPointer
& p
) : SecPointerBase(p
) {}
150 SecPointer(T
*p
): SecPointerBase(p
) {}
151 SecPointer
&operator =(T
*p
) { this->assign(p
); return *this; }
152 SecPointer
&take(T
*p
) { this->copy(p
); return *this; }
153 T
*yield() { T
*result
= static_cast<T
*>(ptr
); ptr
= NULL
; return result
; }
155 // dereference operations
156 T
* get () const { return static_cast<T
*>(ptr
); } // mimic auto_ptr
157 operator T
* () const { return static_cast<T
*>(ptr
); }
158 T
* operator -> () const { return static_cast<T
*>(ptr
); }
159 T
& operator * () const { return *static_cast<T
*>(ptr
); }
163 bool operator <(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
165 T
*p1
= r1
.get(), *p2
= r2
.get();
166 return p1
&& p2
? *p1
< *p2
: p1
< p2
;
170 bool operator ==(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
172 T
*p1
= r1
.get(), *p2
= r2
.get();
173 return p1
&& p2
? *p1
== *p2
: p1
== p2
;
177 bool operator !=(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
179 T
*p1
= r1
.get(), *p2
= r2
.get();
180 return p1
&& p2
? *p1
!= *p2
: p1
!= p2
;
183 } // end namespace Security