]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_utilities/lib/seccfobject.h
Security-59306.140.5.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / seccfobject.h
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2000-2004,2011,2013-2014 Apple Inc. All Rights Reserved.
b1ab9ed8
A
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
25
26#ifndef _SECCFOBJECT_H
27#define _SECCFOBJECT_H
28
29#include <CoreFoundation/CFRuntime.h>
30#include <new>
31#include "threading.h"
866f8763 32#include <os/lock.h>
6b200bc3
A
33
34#if( __cplusplus <= 201103L)
fa7225c8 35#include <stdatomic.h>
6b200bc3 36#endif
b1ab9ed8
A
37
38namespace Security {
39
40class CFClass;
41
fa7225c8 42#define SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR) \
b1ab9ed8
A
43\
44operator APIPTR() const \
45{ return (APIPTR)(this->operator CFTypeRef()); } \
46\
47OBJTYPE *retain() \
48{ SecCFObject::handle(true); return this; } \
b54c578e
A
49APIPTR CF_RETURNS_RETAINED handle() \
50{ return (APIPTR)SecCFObject::handle(true); } \
51APIPTR handle(bool retain) \
fa7225c8
A
52{ return (APIPTR)SecCFObject::handle(retain); }
53
54#define SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \
55SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR)\
56\
57void *operator new(size_t size) throw(std::bad_alloc) \
58{ return SecCFObject::allocate(size, CFCLASS); }
59
60#define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE, CFCLASS) \
61SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \
b1ab9ed8
A
62\
63static OBJTYPE *required(APIPTR ptr) \
64{ if (OBJTYPE *p = dynamic_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE))) \
65 return p; else MacOSError::throwMe(ERRCODE); } \
66\
67static OBJTYPE *optional(APIPTR ptr) \
68{ if (SecCFObject *p = SecCFObject::optional(ptr)) \
69 if (OBJTYPE *pp = dynamic_cast<OBJTYPE *>(p)) return pp; else MacOSError::throwMe(ERRCODE); \
70 else return NULL; }
71
72#define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT)
73
74struct SecRuntimeBase: CFRuntimeBase
75{
fa7225c8 76 atomic_flag isOld;
b1ab9ed8
A
77};
78
79class SecCFObject
80{
81private:
82 void *operator new(size_t) throw(std::bad_alloc);
83
84 // Align up to a multiple of 16 bytes
85 static const size_t kAlignedRuntimeSize = SECALIGNUP(sizeof(SecRuntimeBase), 4);
86
87 uint32_t mRetainCount;
866f8763 88 os_unfair_lock mRetainLock;
b1ab9ed8
A
89
90public:
91 // For use by SecPointer only. Returns true once the first time it's called after the object has been created.
92 bool isNew()
93 {
94 SecRuntimeBase *base = reinterpret_cast<SecRuntimeBase *>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize);
fa7225c8
A
95
96 // atomic flags start clear, and like to go high.
97 return !atomic_flag_test_and_set(&(base->isOld));
b1ab9ed8
A
98 }
99
100 static SecCFObject *optional(CFTypeRef) throw();
101 static SecCFObject *required(CFTypeRef, OSStatus error);
102 static void *allocate(size_t size, const CFClass &cfclass) throw(std::bad_alloc);
103
104 SecCFObject();
105 virtual ~SecCFObject();
106 uint32_t updateRetainCount(intptr_t direction, uint32_t *oldCount);
107 uint32_t getRetainCount() {return updateRetainCount(0, NULL);}
108
109 static void operator delete(void *object) throw();
fa7225c8 110 virtual operator CFTypeRef() const throw()
b1ab9ed8
A
111 {
112 return reinterpret_cast<CFTypeRef>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize);
113 }
114
115 // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true
116 CFTypeRef handle(bool retain = true) throw();
117
118 virtual bool equal(SecCFObject &other);
119 virtual CFHashCode hash();
120 virtual CFStringRef copyFormattingDesc(CFDictionaryRef dict);
121 virtual CFStringRef copyDebugDesc();
122 virtual void aboutToDestruct();
fa7225c8 123 virtual Mutex* getMutexForObject() const;
427c49bc 124 virtual bool mayDelete();
b1ab9ed8
A
125};
126
127//
128// A pointer type for SecCFObjects.
129// T must be derived from SecCFObject.
130//
131class SecPointerBase
132{
133public:
134 SecPointerBase() : ptr(NULL)
135 {}
136 SecPointerBase(const SecPointerBase& p);
137 SecPointerBase(SecCFObject *p);
138 ~SecPointerBase();
139 SecPointerBase& operator = (const SecPointerBase& p);
140
141protected:
142 void assign(SecCFObject * p);
143 void copy(SecCFObject * p);
144 SecCFObject *ptr;
145};
146
147template <class T>
148class SecPointer : public SecPointerBase
149{
150public:
151 SecPointer() : SecPointerBase() {}
152 SecPointer(const SecPointer& p) : SecPointerBase(p) {}
153 SecPointer(T *p): SecPointerBase(p) {}
154 SecPointer &operator =(T *p) { this->assign(p); return *this; }
155 SecPointer &take(T *p) { this->copy(p); return *this; }
156 T *yield() { T *result = static_cast<T *>(ptr); ptr = NULL; return result; }
157
158 // dereference operations
159 T* get () const { return static_cast<T*>(ptr); } // mimic auto_ptr
160 operator T * () const { return static_cast<T*>(ptr); }
161 T * operator -> () const { return static_cast<T*>(ptr); }
162 T & operator * () const { return *static_cast<T*>(ptr); }
163};
164
165template <class T>
166bool operator <(const SecPointer<T> &r1, const SecPointer<T> &r2)
167{
168 T *p1 = r1.get(), *p2 = r2.get();
169 return p1 && p2 ? *p1 < *p2 : p1 < p2;
170}
171
172template <class T>
173bool operator ==(const SecPointer<T> &r1, const SecPointer<T> &r2)
174{
175 T *p1 = r1.get(), *p2 = r2.get();
176 return p1 && p2 ? *p1 == *p2 : p1 == p2;
177}
178
179template <class T>
180bool operator !=(const SecPointer<T> &r1, const SecPointer<T> &r2)
181{
182 T *p1 = r1.get(), *p2 = r2.get();
183 return p1 && p2 ? *p1 != *p2 : p1 != p2;
184}
185
186} // end namespace Security
187
188
189#endif