#include <Security/SecRuntime.h>
#ifndef NDEBUG
#include <Security/debugging.h>
#endif
using namespace KeychainCore;
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, CFTypeID typeID) throw(std::bad_alloc)
{
void *p = const_cast<void *>(_CFRuntimeCreateInstance(NULL, 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);
secdebug("sec", "SecCFObject allocated %p of type %lu", q, typeID);
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()
{
secdebug("sec", "SecCFObject::~SecCFObject %p", this);
}
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;
}