#include "KCCursor.h"
#include "Item.h"
#include "Schema.h"
#include "cssmdatetime.h"
#include "Globals.h"
#include "StorageManager.h"
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
using namespace KeychainCore;
using namespace CssmClient;
using namespace CSSMDateTimeUtils;
KCCursorImpl::KCCursorImpl(const DbCursor &dbCursor, SecItemClass itemClass, const SecKeychainAttributeList *attrList)
: mDbCursor(dbCursor)
{
if (!attrList) return;
mDbCursor->recordType(Schema::recordTypeFor(itemClass));
mDbCursor->conjunctive(CSSM_DB_AND);
const SecKeychainAttribute *end=&attrList->attr[attrList->count];
for (const SecKeychainAttribute *attr=attrList->attr; attr != end; ++attr)
{
const CssmDbAttributeInfo &info = Schema::attributeInfo(attr->tag);
void *buf = attr->data;
UInt32 length = attr->length;
uint8 timeString[16];
if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
{
if (length == sizeof(UInt32))
{
MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf),
16, &timeString);
buf = &timeString;
length = 16;
}
else if (length == sizeof(SInt64))
{
MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
16, &timeString);
buf = &timeString;
length = 16;
}
}
mDbCursor->add(CSSM_DB_EQUAL,info, CssmData(buf,length));
}
}
KCCursorImpl::KCCursorImpl(const DbCursor &dbCursor, const SecKeychainAttributeList *attrList)
: mDbCursor(dbCursor)
{
if (!attrList) return;
mDbCursor->conjunctive(CSSM_DB_AND);
bool foundClassAttribute=false;
const SecKeychainAttribute *end=&attrList->attr[attrList->count];
for (const SecKeychainAttribute *attr=attrList->attr; attr != end; ++attr)
{
if (attr->tag!=kSecClassItemAttr) {
const CssmDbAttributeInfo &info = Schema::attributeInfo(attr->tag);
void *buf = attr->data;
UInt32 length = attr->length;
uint8 timeString[16];
if (info.format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE)
{
if (length == sizeof(UInt32))
{
MacSecondsToTimeString(*reinterpret_cast<const UInt32 *>(buf),
16, &timeString);
buf = &timeString;
length = 16;
}
else if (length == sizeof(SInt64))
{
MacLongDateTimeToTimeString(*reinterpret_cast<const SInt64 *>(buf),
16, &timeString);
buf = &timeString;
length = 16;
}
}
mDbCursor->add(CSSM_DB_EQUAL,info, CssmData(buf,length));
continue;
}
if (foundClassAttribute || attr->length != sizeof(SecItemClass))
MacOSError::throwMe(paramErr);
mDbCursor->recordType(Schema
::recordTypeFor(*reinterpret_cast<SecItemClass *>(attr->data)));
foundClassAttribute=true;
}
}
KCCursorImpl::~KCCursorImpl()
{
}
bool
KCCursorImpl::next(Item &item)
{
DbAttributes dbAttributes;
DbUniqueRecord uniqueId;
if (!mDbCursor)
MacOSError::throwMe(errSecInvalidSearchRef);
for (;;)
{
if (!mDbCursor->next(&dbAttributes, NULL, uniqueId))
{
mDbCursor = DbCursor();
return false;
}
if (Schema::itemClassFor(dbAttributes.recordType()))
break;
}
Keychain keychain = globals().storageManager.keychain(uniqueId->database()->dlDbIdentifier());
item = keychain->item(dbAttributes.recordType(), uniqueId);
return true;
}