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" 
  32 #include <stdatomic.h> 
  38 #define SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR) \ 
  40 operator APIPTR() const \ 
  41 { return (APIPTR)(this->operator CFTypeRef()); } \ 
  44 { SecCFObject::handle(true); return this; } \ 
  45 APIPTR handle(bool retain = true) \ 
  46 { return (APIPTR)SecCFObject::handle(retain); } 
  48 #define SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \ 
  49 SECCFFUNCTIONS_BASE(OBJTYPE, APIPTR)\ 
  51 void *operator new(size_t size) throw(std::bad_alloc) \ 
  52 { return SecCFObject::allocate(size, CFCLASS); } 
  54 #define SECCFFUNCTIONS(OBJTYPE, APIPTR, ERRCODE, CFCLASS) \ 
  55 SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \ 
  57 static OBJTYPE *required(APIPTR ptr) \ 
  58 { if (OBJTYPE *p = dynamic_cast<OBJTYPE *>(SecCFObject::required(ptr, ERRCODE))) \ 
  59         return p; else MacOSError::throwMe(ERRCODE); } \ 
  61 static OBJTYPE *optional(APIPTR ptr) \ 
  62 { if (SecCFObject *p = SecCFObject::optional(ptr)) \ 
  63         if (OBJTYPE *pp = dynamic_cast<OBJTYPE *>(p)) return pp; else MacOSError::throwMe(ERRCODE); \ 
  66 #define SECALIGNUP(SIZE, ALIGNMENT) (((SIZE - 1) & ~(ALIGNMENT - 1)) + ALIGNMENT) 
  68 struct SecRuntimeBase
: CFRuntimeBase
 
  76         void *operator new(size_t) throw(std::bad_alloc
); 
  78         // Align up to a multiple of 16 bytes 
  79         static const size_t kAlignedRuntimeSize 
= SECALIGNUP(sizeof(SecRuntimeBase
), 4); 
  81     uint32_t mRetainCount
; 
  82     OSSpinLock mRetainSpinLock
; 
  85         // For use by SecPointer only. Returns true once the first time it's called after the object has been created. 
  88                 SecRuntimeBase 
*base 
= reinterpret_cast<SecRuntimeBase 
*>(reinterpret_cast<uint8_t *>(this) - kAlignedRuntimeSize
); 
  90         // atomic flags start clear, and like to go high. 
  91         return !atomic_flag_test_and_set(&(base
->isOld
)); 
  94         static SecCFObject 
*optional(CFTypeRef
) throw(); 
  95         static SecCFObject 
*required(CFTypeRef
, OSStatus error
); 
  96         static void *allocate(size_t size
, const CFClass 
&cfclass
) throw(std::bad_alloc
); 
  99         virtual ~SecCFObject(); 
 100     uint32_t updateRetainCount(intptr_t direction
, uint32_t *oldCount
); 
 101     uint32_t getRetainCount() {return updateRetainCount(0, NULL
);} 
 103         static void operator delete(void *object
) throw(); 
 104         virtual operator CFTypeRef() const throw() 
 106                 return reinterpret_cast<CFTypeRef
>(reinterpret_cast<const uint8_t *>(this) - kAlignedRuntimeSize
); 
 109         // This bumps up the retainCount by 1, by calling CFRetain(), iff retain is true 
 110         CFTypeRef 
handle(bool retain 
= true) throw(); 
 112     virtual bool equal(SecCFObject 
&other
); 
 113     virtual CFHashCode 
hash(); 
 114         virtual CFStringRef 
copyFormattingDesc(CFDictionaryRef dict
); 
 115         virtual CFStringRef 
copyDebugDesc(); 
 116         virtual void aboutToDestruct(); 
 117         virtual Mutex
* getMutexForObject() const; 
 118     virtual bool mayDelete(); 
 122 // A pointer type for SecCFObjects. 
 123 // T must be derived from SecCFObject. 
 128         SecPointerBase() : ptr(NULL
) 
 130         SecPointerBase(const SecPointerBase
& p
); 
 131         SecPointerBase(SecCFObject 
*p
); 
 133         SecPointerBase
& operator = (const SecPointerBase
& p
); 
 136         void assign(SecCFObject 
* p
); 
 137         void copy(SecCFObject 
* p
); 
 142 class SecPointer 
: public SecPointerBase
 
 145         SecPointer() : SecPointerBase() {} 
 146         SecPointer(const SecPointer
& p
) : SecPointerBase(p
) {} 
 147         SecPointer(T 
*p
): SecPointerBase(p
) {} 
 148         SecPointer 
&operator =(T 
*p
) { this->assign(p
); return *this; } 
 149         SecPointer 
&take(T 
*p
) { this->copy(p
); return *this; } 
 150         T 
*yield() { T 
*result 
= static_cast<T 
*>(ptr
); ptr 
= NULL
; return result
; } 
 152         // dereference operations 
 153     T
* get () const                             { return static_cast<T
*>(ptr
); }        // mimic auto_ptr 
 154         operator T 
* () const           { return static_cast<T
*>(ptr
); } 
 155         T 
* operator -> () const        { return static_cast<T
*>(ptr
); } 
 156         T 
& operator * () const         { return *static_cast<T
*>(ptr
); } 
 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
; 
 174 bool operator !=(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
) 
 176         T 
*p1 
= r1
.get(), *p2 
= r2
.get(); 
 177         return p1 
&& p2 
? *p1 
!= *p2 
: p1 
!= p2
; 
 180 } // end namespace Security