#include <Security/SecCFTypes.h>
#include <Security/SecRuntime.h>
#include <Security/threading.h>
#include <Security/Globals.h>
namespace Security
{
namespace KeychainCore
{
SecCFTypes &
gTypes()
{
static ModuleNexus<SecCFTypes> nexus;
return nexus();
}
}
}
using namespace KeychainCore;
SecCFTypes::SecCFTypes() :
Access("SecAccess"),
ACL("SecACL"),
Certificate("SecCertificate"),
CertificateRequest("SecCertificateRequest"),
Identity("SecIdentity"),
IdentityCursor("SecIdentitySearch"),
ItemImpl("SecKeychainItem"),
KCCursorImpl("SecKeychainSearch"),
KeychainImpl("SecKeychain"),
KeyItem("SecKey"),
Policy("SecPolicy"),
PolicyCursor("SecPolicySearch"),
Trust("SecTrust"),
TrustedApplication("SecTrustedApplication"),
allocator(CFAllocatorCreate(NULL, &CFClass::allocatorContext))
{
}
CFAllocatorContext CFClass::allocatorContext =
{
0,
NULL,
NULL,
NULL,
NULL,
allocatorAllocate,
allocatorReallocate,
allocatorDeallocate,
allocatorPreferredSize
};
CFClass::CFClass(const char *name)
{
version = 0;
className = name;
init = NULL;
copy = NULL;
finalize = NULL;
equal = equalType;
hash = hashType;
copyFormattingDesc = copyFormattingDescType;
copyDebugDesc = copyDebugDescType;
typeID = _CFRuntimeRegisterClass(this);
assert(typeID != _kCFRuntimeNotATypeID);
}
Boolean
CFClass::equalType(CFTypeRef cf1, CFTypeRef cf2)
{
return SecCFObject::optional(cf1)->equal(*SecCFObject::optional(cf2));
}
CFHashCode
CFClass::hashType(CFTypeRef cf)
{
return SecCFObject::optional(cf)->hash();
}
CFStringRef
CFClass::copyFormattingDescType(CFTypeRef cf, CFDictionaryRef dict)
{
return SecCFObject::optional(cf)->copyFormattingDesc(dict);
}
CFStringRef
CFClass::copyDebugDescType(CFTypeRef cf)
{
return SecCFObject::optional(cf)->copyDebugDesc();
}
void *
CFClass::allocatorAllocate(CFIndex allocSize, CFOptionFlags hint, void *info)
{
return malloc(allocSize);
}
void *
CFClass::allocatorReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info)
{
return realloc(ptr, newsize);
}
void
CFClass::allocatorDeallocate(void *ptr, void *info)
{
StLock<Mutex> _(globals().apiLock);
CFTypeRef cf = reinterpret_cast<CFTypeRef>(reinterpret_cast<intptr_t>(ptr) + sizeof(CFAllocatorRef));
CFIndex rc = CFGetRetainCount(cf);
if (rc == 1)
{
SecCFObject *obj = SecCFObject::optional(cf);
if (!obj->isNew())
obj->~SecCFObject();
free(ptr);
}
else if (rc > 1)
{
CFRetain(CFGetAllocator(cf));
CFRelease(cf);
}
else
{
}
}
CFIndex
CFClass::allocatorPreferredSize(CFIndex size, CFOptionFlags hint, void *info)
{
return size;
}