#include <security_utilities/seccfobject.h>
#include <security_utilities/cfclass.h>
#include <security_utilities/errors.h>
#include <security_utilities/debugging.h>
SecCFObject *
SecCFObject::optional(CFTypeRef cfTypeRef) throw()
{
if (!cfTypeRef)
return NULL;
return const_cast<SecCFObject *>(reinterpret_cast<const SecCFObject *>(reinterpret_cast<const uint8_t *>(cfTypeRef) + kAlignedRuntimeSize));
}
SecCFObject *
SecCFObject::required(CFTypeRef cfTypeRef, OSStatus error)
{
SecCFObject *object = optional(cfTypeRef);
if (!object)
MacOSError::throwMe(error);
return object;
}
void *
SecCFObject::allocate(size_t size, const CFClass &cfclass) throw(std::bad_alloc)
{
void *p = const_cast<void *>(_CFRuntimeCreateInstance(cfclass.allocator, cfclass.typeID,
size + kAlignedRuntimeSize - sizeof(CFRuntimeBase), NULL));
if (p == NULL)
throw std::bad_alloc();
reinterpret_cast<SecRuntimeBase *>(p)->isNew = true;
void *q = reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(p) + kAlignedRuntimeSize);
#if !defined(NDEBUG)
const CFRuntimeClass *runtimeClass = _CFRuntimeGetClassWithTypeID(cfclass.typeID);
secdebug("sec", "allocated: %p: %s(%lu)", q,
runtimeClass && runtimeClass->className ? runtimeClass->className
: "SecCFObject", cfclass.typeID);
#endif
return q;
}
void
SecCFObject::operator delete(void *object) throw()
{
secdebug("sec", "SecCFObject operator delete %p", object);
CFTypeRef cfType = reinterpret_cast<CFTypeRef>(reinterpret_cast<const uint8_t *>(object) - kAlignedRuntimeSize);
CFRelease(cfType);
}
SecCFObject::~SecCFObject() throw()
{
#if !defined(NDEBUG)
CFTypeRef cfType = *this;
CFTypeID typeID = CFGetTypeID(cfType);
const CFRuntimeClass *runtimeClass = _CFRuntimeGetClassWithTypeID(typeID);
secdebug("sec", "destroyed: %p: %s(%lu)", this,
runtimeClass && runtimeClass->className ? runtimeClass->className
: "SecCFObject", typeID);
#endif
}
bool
SecCFObject::equal(SecCFObject &other)
{
return this == &other;
}
CFHashCode
SecCFObject::hash()
{
return CFHashCode(this);
}
CFStringRef
SecCFObject::copyFormattingDesc(CFDictionaryRef dict)
{
return NULL;
}
CFStringRef
SecCFObject::copyDebugDesc()
{
return NULL;
}
CFTypeRef
SecCFObject::handle(bool retain) throw()
{
CFTypeRef cfType = *this;
if (retain && !isNew()) CFRetain(cfType);
return cfType;
}