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"
34 #if( __cplusplus <= 201103L)
35 #include <stdatomic.h>
42 #define SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR) \
44 operator APIPTR() const \
45 { return (APIPTR)(this->operator CFTypeRef()); } \
48 { SecCFObject::handle(true); return this; } \
49 APIPTR handle(bool retain = true) \
50 { return (APIPTR)SecCFObject::handle(retain); }
52 #define SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \
53 SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR)\
55 void *operator new(size_t size) throw(std::bad_alloc) \
56 { return SecCFObject::allocate(size, CFCLASS); }
58 #define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE, CFCLASS) \
59 SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \
61 static OBJTYPE *required(APIPTR ptr) \
62 { if (OBJTYPE *p = dynamic_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE))) \
63 return p; else MacOSError::throwMe(ERRCODE); } \
65 static OBJTYPE *optional(APIPTR ptr) \
66 { if (SecCFObject *p = SecCFObject::optional(ptr)) \
67 if (OBJTYPE *pp = dynamic_cast<OBJTYPE *>(p)) return pp; else MacOSError::throwMe(ERRCODE); \
70 #define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
72 struct SecRuntimeBase
: CFRuntimeBase
80 void *operator new(size_t) throw(std::bad_alloc
);
82 // Align up to a multiple of 16 bytes
83 static const size_t kAlignedRuntimeSize
= SECALIGNUP(sizeof(SecRuntimeBase
), 4);
85 uint32_t mRetainCount
;
86 os_unfair_lock mRetainLock
;
89 // For use by SecPointer only. Returns true once the first time it's called after the object has been created.
92 SecRuntimeBase
*base
= reinterpret_cast<SecRuntimeBase
*>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize
);
94 // atomic flags start clear, and like to go high.
95 return !atomic_flag_test_and_set(&(base
->isOld
));
98 static SecCFObject
*optional(CFTypeRef
) throw();
99 static SecCFObject
*required(CFTypeRef
, OSStatus error
);
100 static void *allocate(size_t size
, const CFClass
&cfclass
) throw(std::bad_alloc
);
103 virtual ~SecCFObject();
104 uint32_t updateRetainCount(intptr_t direction
, uint32_t *oldCount
);
105 uint32_t getRetainCount() {return updateRetainCount(0, NULL
);}
107 static void operator delete(void *object
) throw();
108 virtual operator CFTypeRef() const throw()
110 return reinterpret_cast<CFTypeRef
>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize
);
113 // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true
114 CFTypeRef
handle(bool retain
= true) throw();
116 virtual bool equal(SecCFObject
&other
);
117 virtual CFHashCode
hash();
118 virtual CFStringRef
copyFormattingDesc(CFDictionaryRef dict
);
119 virtual CFStringRef
copyDebugDesc();
120 virtual void aboutToDestruct();
121 virtual Mutex
* getMutexForObject() const;
122 virtual bool mayDelete();
126 // A pointer type for SecCFObjects.
127 // T must be derived from SecCFObject.
132 SecPointerBase() : ptr(NULL
)
134 SecPointerBase(const SecPointerBase
& p
);
135 SecPointerBase(SecCFObject
*p
);
137 SecPointerBase
& operator = (const SecPointerBase
& p
);
140 void assign(SecCFObject
* p
);
141 void copy(SecCFObject
* p
);
146 class SecPointer
: public SecPointerBase
149 SecPointer() : SecPointerBase() {}
150 SecPointer(const SecPointer
& p
) : SecPointerBase(p
) {}
151 SecPointer(T
*p
): SecPointerBase(p
) {}
152 SecPointer
&operator =(T
*p
) { this->assign(p
); return *this; }
153 SecPointer
&take(T
*p
) { this->copy(p
); return *this; }
154 T
*yield() { T
*result
= static_cast<T
*>(ptr
); ptr
= NULL
; return result
; }
156 // dereference operations
157 T
* get () const { return static_cast<T
*>(ptr
); } // mimic auto_ptr
158 operator T
* () const { return static_cast<T
*>(ptr
); }
159 T
* operator -> () const { return static_cast<T
*>(ptr
); }
160 T
& operator * () const { return *static_cast<T
*>(ptr
); }
164 bool operator <(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
166 T
*p1
= r1
.get(), *p2
= r2
.get();
167 return p1
&& p2
? *p1
< *p2
: p1
< p2
;
171 bool operator ==(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
173 T
*p1
= r1
.get(), *p2
= r2
.get();
174 return p1
&& p2
? *p1
== *p2
: p1
== p2
;
178 bool operator !=(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
180 T
*p1
= r1
.get(), *p2
= r2
.get();
181 return p1
&& p2
? *p1
!= *p2
: p1
!= p2
;
184 } // end namespace Security