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"
37 #define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE, CFCLASS) \
39 void *operator new(size_t size) throw(std::bad_alloc) \
40 { return SecCFObject::allocate(size, CFCLASS); } \
42 operator APIPTR() const \
43 { return (APIPTR)(this->operator CFTypeRef()); } \
46 { SecCFObject::handle(true); return this; } \
47 APIPTR handle(bool retain = true) \
48 { return (APIPTR)SecCFObject::handle(retain); } \
50 static OBJTYPE *required(APIPTR ptr) \
51 { if (OBJTYPE *p = dynamic_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE))) \
52 return p; else MacOSError::throwMe(ERRCODE); } \
54 static OBJTYPE *optional(APIPTR ptr) \
55 { if (SecCFObject *p = SecCFObject::optional(ptr)) \
56 if (OBJTYPE *pp = dynamic_cast<OBJTYPE *>(p)) return pp; else MacOSError::throwMe(ERRCODE); \
59 #define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
61 struct SecRuntimeBase
: CFRuntimeBase
69 void *operator new(size_t) throw(std::bad_alloc
);
71 // Align up to a multiple of 16 bytes
72 static const size_t kAlignedRuntimeSize
= SECALIGNUP(sizeof(SecRuntimeBase
), 4);
74 uint32_t mRetainCount
;
75 OSSpinLock mRetainSpinLock
;
78 // For use by SecPointer only. Returns true once the first time it's called after the object has been created.
81 SecRuntimeBase
*base
= reinterpret_cast<SecRuntimeBase
*>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize
);
82 bool isNew
= base
->isNew
;
87 static SecCFObject
*optional(CFTypeRef
) throw();
88 static SecCFObject
*required(CFTypeRef
, OSStatus error
);
89 static void *allocate(size_t size
, const CFClass
&cfclass
) throw(std::bad_alloc
);
92 virtual ~SecCFObject();
93 uint32_t updateRetainCount(intptr_t direction
, uint32_t *oldCount
);
94 uint32_t getRetainCount() {return updateRetainCount(0, NULL
);}
96 static void operator delete(void *object
) throw();
97 operator CFTypeRef() const throw()
99 return reinterpret_cast<CFTypeRef
>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize
);
102 // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true
103 CFTypeRef
handle(bool retain
= true) throw();
105 virtual bool equal(SecCFObject
&other
);
106 virtual CFHashCode
hash();
107 virtual CFStringRef
copyFormattingDesc(CFDictionaryRef dict
);
108 virtual CFStringRef
copyDebugDesc();
109 virtual void aboutToDestruct();
110 virtual Mutex
* getMutexForObject();
111 virtual bool mayDelete();
115 // A pointer type for SecCFObjects.
116 // T must be derived from SecCFObject.
121 SecPointerBase() : ptr(NULL
)
123 SecPointerBase(const SecPointerBase
& p
);
124 SecPointerBase(SecCFObject
*p
);
126 SecPointerBase
& operator = (const SecPointerBase
& p
);
129 void assign(SecCFObject
* p
);
130 void copy(SecCFObject
* p
);
135 class SecPointer
: public SecPointerBase
138 SecPointer() : SecPointerBase() {}
139 SecPointer(const SecPointer
& p
) : SecPointerBase(p
) {}
140 SecPointer(T
*p
): SecPointerBase(p
) {}
141 SecPointer
&operator =(T
*p
) { this->assign(p
); return *this; }
142 SecPointer
&take(T
*p
) { this->copy(p
); return *this; }
143 T
*yield() { T
*result
= static_cast<T
*>(ptr
); ptr
= NULL
; return result
; }
145 // dereference operations
146 T
* get () const { return static_cast<T
*>(ptr
); } // mimic auto_ptr
147 operator T
* () const { return static_cast<T
*>(ptr
); }
148 T
* operator -> () const { return static_cast<T
*>(ptr
); }
149 T
& operator * () const { return *static_cast<T
*>(ptr
); }
153 bool operator <(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
155 T
*p1
= r1
.get(), *p2
= r2
.get();
156 return p1
&& p2
? *p1
< *p2
: p1
< p2
;
160 bool operator ==(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
162 T
*p1
= r1
.get(), *p2
= r2
.get();
163 return p1
&& p2
? *p1
== *p2
: p1
== p2
;
167 bool operator !=(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
)
169 T
*p1
= r1
.get(), *p2
= r2
.get();
170 return p1
&& p2
? *p1
!= *p2
: p1
!= p2
;
173 } // end namespace Security