#include <Security/SecRuntime.h>
#include <Security/SecCFTypes.h>
using namespace KeychainCore;
SecCFObject::~SecCFObject()
{
}
bool
SecCFObject::equal(SecCFObject &other)
{
return this == &other;
}
CFHashCode
SecCFObject::hash()
{
return CFHashCode(this);
}
SecCFType::SecCFType(SecCFObject *obj) :
mObject(obj)
{
}
SecCFType::~SecCFType()
{
mObject = NULL;
}
CFClassBase::CFClassBase(const char *name)
{
version = 0;
className = name;
init = NULL;
copy = NULL;
finalize = finalizeType;
equal = equalType;
hash = hashType;
copyFormattingDesc = NULL;
copyDebugDesc = NULL;
typeId = _CFRuntimeRegisterClass(this);
assert(typeId != _kCFRuntimeNotATypeID);
}
void
CFClassBase::finalizeType(CFTypeRef cf)
{
const SecCFType *type = reinterpret_cast<const SecCFType *>(cf);
StLock<Mutex> _(gTypes().mapLock);
gTypes().map.erase(type->mObject.get());
type->~SecCFType();
}
Boolean
CFClassBase::equalType(CFTypeRef cf1, CFTypeRef cf2)
{
const SecCFType *t1 = reinterpret_cast<const SecCFType *>(cf1);
const SecCFType *t2 = reinterpret_cast<const SecCFType *>(cf2);
return t1->mObject->equal(*t2->mObject);
}
CFHashCode
CFClassBase::hashType(CFTypeRef cf)
{
return reinterpret_cast<const SecCFType *>(cf)->mObject->hash();
}
const SecCFType *
CFClassBase::makeNew(SecCFObject *obj)
{
void *p = const_cast<void *>(_CFRuntimeCreateInstance(NULL, typeId,
sizeof(SecCFType) - sizeof(CFRuntimeBase), NULL));
new (p) SecCFType(obj);
return reinterpret_cast<const SecCFType *>(p);
}
const SecCFType *
CFClassBase::handle(SecCFObject *obj)
{
SecCFTypes::Map &map = gTypes().map;
StLock<Mutex> _(gTypes().mapLock);
SecCFTypes::Map::const_iterator it = map.find(obj);
if (it == map.end())
{
const SecCFType *p = makeNew(obj);
map[obj] = p;
return p;
}
else
{
CFRetain(it->second);
return it->second;
}
}
SecCFObject *
CFClassBase::required(const SecCFType *type, OSStatus errorCode)
{
if (!type)
MacOSError::throwMe(errorCode);
return type->mObject.get();
}