2  * Copyright (c) 2000-2004 Apple Computer, 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(); 
 114 // A pointer type for SecCFObjects. 
 115 // T must be derived from SecCFObject. 
 120         SecPointerBase() : ptr(NULL
) 
 122         SecPointerBase(const SecPointerBase
& p
); 
 123         SecPointerBase(SecCFObject 
*p
); 
 125         SecPointerBase
& operator = (const SecPointerBase
& p
); 
 128         void assign(SecCFObject 
* p
); 
 129         void copy(SecCFObject 
* p
); 
 134 class SecPointer 
: public SecPointerBase
 
 137         SecPointer() : SecPointerBase() {} 
 138         SecPointer(const SecPointer
& p
) : SecPointerBase(p
) {} 
 139         SecPointer(T 
*p
): SecPointerBase(p
) {} 
 140         SecPointer 
&operator =(T 
*p
) { this->assign(p
); return *this; } 
 141         SecPointer 
&take(T 
*p
) { this->copy(p
); return *this; } 
 142         T 
*yield() { T 
*result 
= static_cast<T 
*>(ptr
); ptr 
= NULL
; return result
; } 
 144         // dereference operations 
 145     T
* get () const                             { return static_cast<T
*>(ptr
); }        // mimic auto_ptr 
 146         operator T 
* () const           { return static_cast<T
*>(ptr
); } 
 147         T 
* operator -> () const        { return static_cast<T
*>(ptr
); } 
 148         T 
& operator * () const         { return *static_cast<T
*>(ptr
); } 
 152 bool operator <(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
) 
 154         T 
*p1 
= r1
.get(), *p2 
= r2
.get(); 
 155         return p1 
&& p2 
? *p1 
< *p2 
: p1 
< p2
; 
 159 bool operator ==(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
) 
 161         T 
*p1 
= r1
.get(), *p2 
= r2
.get(); 
 162         return p1 
&& p2 
? *p1 
== *p2 
: p1 
== p2
; 
 166 bool operator !=(const SecPointer
<T
> &r1
, const SecPointer
<T
> &r2
) 
 168         T 
*p1 
= r1
.get(), *p2 
= r2
.get(); 
 169         return p1 
&& p2 
? *p1 
!= *p2 
: p1 
!= p2
; 
 172 } // end namespace Security