#ifndef _H_CDSA_UTILITIES_CSSMDB
#define _H_CDSA_UTILITIES_CSSMDB
#include <security_cdsa_utilities/cssmdata.h>
#include <security_cdsa_utilities/cssmpods.h>
#include <security_cdsa_utilities/cssmalloc.h>
#include <security_cdsa_utilities/walkers.h>
#include <security_cdsa_utilities/cssmdbname.h>
namespace Security {
template <class _Tp>
class ArrayBuilder {
public:
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef uint32 size_type;
typedef ptrdiff_t difference_type;
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
protected:
void insert_aux(iterator __position, const _Tp& __x);
void insert_aux(iterator __position);
public:
iterator begin() { return mArray; }
const_iterator begin() const { return mArray; }
iterator end() { return &mArray[mSize]; }
const_iterator end() const { return &mArray[mSize]; }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(end()); }
reverse_iterator rend()
{ return reverse_iterator(begin()); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(begin()); }
size_type max_size() const
{ return size_type(-1) / sizeof(_Tp); }
size_type capacity() const
{ return mCapacity; }
bool empty() const
{ return begin() == end(); }
ArrayBuilder(pointer &array, size_type &size, size_type capacity = 0, Allocator &allocator = Allocator::standard()) :
mArray(array), mSize(size), mCapacity(capacity), mAllocator(allocator)
{
#if BUG_GCC
mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
#else
mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
#endif
memset(mArray, 0, sizeof(value_type) * mCapacity);
mSize = 0;
}
~ArrayBuilder() { mAllocator.free(mArray); }
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(end() - 1); }
const_reference back() const { return *(end() - 1); }
void reserve(size_type newCapacity)
{
if (newCapacity > mCapacity)
{
#if BUG_GCC
mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
#else
mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
#endif
memset(&mArray[mCapacity], 0, sizeof(value_type) * (newCapacity - mCapacity));
mCapacity = newCapacity;
}
}
reference add()
{
if (mSize >= mCapacity)
reserve(max(mSize + 1, mCapacity ? 2 * mCapacity : 1));
return mArray[mSize++];
}
const_pointer get() const { return mArray; }
pointer release() { const_pointer array = mArray; mArray = NULL; return array; }
void clear() { if (mSize) { memset(mArray, 0, sizeof(value_type) * mSize); } mSize = 0; }
protected:
Allocator &allocator() const { return mAllocator; }
private:
pointer &mArray;
size_type &mSize;
size_type mCapacity;
Allocator &mAllocator;
};
class CssmDlDbHandle : public PodWrapper<CssmDlDbHandle, CSSM_DL_DB_HANDLE> {
public:
CssmDlDbHandle() { clearPod(); }
CssmDlDbHandle(CSSM_DL_HANDLE dl, CSSM_DB_HANDLE db) { DLHandle = dl; DBHandle = db; }
CSSM_DL_HANDLE dl() const { return DLHandle; }
CSSM_DB_HANDLE db() const { return DBHandle; }
operator bool() const { return DLHandle && DBHandle; }
};
inline bool operator < (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
{
return h1.DLHandle < h2.DLHandle
|| (h1.DLHandle == h2.DLHandle && h1.DBHandle < h2.DBHandle);
}
inline bool operator == (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
{
return h1.DLHandle == h2.DLHandle && h1.DBHandle == h2.DBHandle;
}
inline bool operator != (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
{
return h1.DLHandle != h2.DLHandle || h1.DBHandle != h2.DBHandle;
}
class CssmDlDbList : public PodWrapper<CssmDlDbList, CSSM_DL_DB_LIST> {
public:
uint32 count() const { return NumHandles; }
uint32 &count() { return NumHandles; }
CssmDlDbHandle *handles() const { return CssmDlDbHandle::overlay(DLDBHandle); }
CssmDlDbHandle * &handles() { return CssmDlDbHandle::overlayVar(DLDBHandle); }
CssmDlDbHandle &operator [] (uint32 ix) const
{ assert(ix < count()); return CssmDlDbHandle::overlay(DLDBHandle[ix]); }
void setDlDbList(uint32 n, CSSM_DL_DB_HANDLE *list)
{ count() = n; handles() = CssmDlDbHandle::overlay(list); }
};
class CssmDLPolyData
{
public:
CssmDLPolyData(const CSSM_DATA &data, CSSM_DB_ATTRIBUTE_FORMAT format)
: mData(CssmData::overlay(data)), mFormat(format) {}
operator const char *() const
{
assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_STRING
|| mFormat == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE);
return reinterpret_cast<const char *>(mData.Data);
}
operator bool() const
{
assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32 || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
return *reinterpret_cast<uint32 *>(mData.Data);
}
operator uint32() const
{
assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32);
return *reinterpret_cast<uint32 *>(mData.Data);
}
operator const uint32 *() const
{
assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
return reinterpret_cast<const uint32 *>(mData.Data);
}
operator sint32() const
{
assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
return *reinterpret_cast<sint32 *>(mData.Data);
}
operator double() const
{
assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_REAL);
return *reinterpret_cast<double *>(mData.Data);
}
operator CSSM_DATE () const;
operator Guid () const;
operator const CssmData &() const
{
return mData;
}
private:
const CssmData &mData;
CSSM_DB_ATTRIBUTE_FORMAT mFormat;
};
class CssmDbAttributeInfo : public PodWrapper<CssmDbAttributeInfo, CSSM_DB_ATTRIBUTE_INFO>
{
public:
CssmDbAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &attr)
{ assignPod(attr); }
CssmDbAttributeInfo(const char *name,
CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX);
CssmDbAttributeInfo(const CSSM_OID &oid,
CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX);
CssmDbAttributeInfo(uint32 id,
CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX);
CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat() const { return AttributeNameFormat; }
void nameFormat(CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat) { AttributeNameFormat = nameFormat; }
CSSM_DB_ATTRIBUTE_FORMAT format() const { return AttributeFormat; }
void format(CSSM_DB_ATTRIBUTE_FORMAT format) { AttributeFormat = format; }
const char *stringName() const
{
assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_STRING);
return Label.AttributeName;
}
const CssmOid &oidName() const
{
assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_OID);
return CssmOid::overlay(Label.AttributeOID);
}
uint32 intName() const
{
assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER);
return Label.AttributeID;
}
operator const char *() const { return stringName(); }
operator const CssmOid &() const { return oidName(); }
operator uint32() const { return intName(); }
bool operator <(const CssmDbAttributeInfo& other) const;
bool operator ==(const CssmDbAttributeInfo& other) const;
bool operator !=(const CssmDbAttributeInfo& other) const
{ return !(*this == other); }
};
class CssmDbRecordAttributeInfo : public PodWrapper<CssmDbRecordAttributeInfo, CSSM_DB_RECORD_ATTRIBUTE_INFO>
{
public:
CssmDbRecordAttributeInfo()
{ DataRecordType = CSSM_DL_DB_RECORD_ANY; }
CssmDbRecordAttributeInfo(CSSM_DB_RECORDTYPE recordType, uint32 numberOfAttributes,
CSSM_DB_ATTRIBUTE_INFO_PTR attributeInfo)
{
DataRecordType = recordType;
NumberOfAttributes = numberOfAttributes;
AttributeInfo = attributeInfo;
}
CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
uint32 size() const { return NumberOfAttributes; }
CssmDbAttributeInfo *&attributes()
{ return CssmDbAttributeInfo::overlayVar(AttributeInfo); }
CssmDbAttributeInfo *attributes() const
{ return CssmDbAttributeInfo::overlay(AttributeInfo); }
CssmDbAttributeInfo &at(uint32 ix) const
{ assert(ix < size()); return attributes()[ix]; }
CssmDbAttributeInfo &operator [] (uint32 ix) const { return at(ix); }
};
class CssmAutoDbRecordAttributeInfo: public CssmDbRecordAttributeInfo, public ArrayBuilder<CssmDbAttributeInfo>
{
public:
CssmAutoDbRecordAttributeInfo(uint32 capacity = 0, Allocator &allocator = Allocator::standard()) :
CssmDbRecordAttributeInfo(),
ArrayBuilder<CssmDbAttributeInfo>(CssmDbAttributeInfo::overlayVar(AttributeInfo),
NumberOfAttributes, capacity, allocator) {}
};
class CssmDbAttributeData : public PodWrapper<CssmDbAttributeData, CSSM_DB_ATTRIBUTE_DATA>
{
public:
CssmDbAttributeData() { NumberOfValues = 0; Value = NULL; }
CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_DATA &attr)
{ assignPod(attr); }
CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_INFO &info)
{ Info = info; NumberOfValues = 0; Value = NULL; }
CssmDbAttributeInfo &info() { return CssmDbAttributeInfo::overlay(Info); }
const CssmDbAttributeInfo &info() const { return CssmDbAttributeInfo::overlay(Info); }
void info (const CSSM_DB_ATTRIBUTE_INFO &inInfo) { Info = inInfo; }
CSSM_DB_ATTRIBUTE_FORMAT format() const { return info().format(); }
void format(CSSM_DB_ATTRIBUTE_FORMAT f) { info().format(f); }
uint32 size() const { return NumberOfValues; }
CssmData *&values() { return CssmData::overlayVar(Value); }
CssmData *values() const { return CssmData::overlay(Value); }
CssmData &at(unsigned int ix) const
{
if (ix >= size()) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
return values()[ix];
}
CssmData &operator [] (unsigned int ix) const { return at(ix); }
template <class T>
T at(unsigned int ix) const { return CssmDLPolyData(Value[ix], format()); }
operator string() const;
operator const Guid &() const;
operator bool() const;
operator uint32() const;
operator const uint32 *() const;
operator sint32() const;
operator double() const;
operator const CssmData &() const;
void set(CssmData &data) { set(1, &data); }
void set(uint32 count, CssmData *datas) { NumberOfValues = count; Value = datas; }
void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, const CssmPolyData &inValue,
Allocator &inAllocator);
void copyValues(const CssmDbAttributeData &source, Allocator &alloc);
void set(const CSSM_DB_ATTRIBUTE_DATA &source, Allocator &alloc)
{
info(source.Info);
copyValues(source, alloc);
}
void add(const CssmPolyData &inValue, Allocator &inAllocator);
void add(const char *value, Allocator &alloc)
{ format(CSSM_DB_ATTRIBUTE_FORMAT_STRING); add(CssmPolyData(value), alloc); }
void add(const std::string &value, Allocator &alloc)
{ format(CSSM_DB_ATTRIBUTE_FORMAT_STRING); add(CssmPolyData(value), alloc); }
void add(uint32 value, Allocator &alloc)
{ format(CSSM_DB_ATTRIBUTE_FORMAT_UINT32); add(CssmPolyData(value), alloc); }
void add(sint32 value, Allocator &alloc)
{ format(CSSM_DB_ATTRIBUTE_FORMAT_SINT32); add(CssmPolyData(value), alloc); }
void add(const CssmData &value, Allocator &alloc)
{ format(CSSM_DB_ATTRIBUTE_FORMAT_BLOB); add(CssmPolyData(value), alloc); }
void add(const CssmDbAttributeData &src, Allocator &inAllocator);
bool deleteValue(const CssmData &src, Allocator &inAllocator);
void deleteValues(const CssmDbAttributeData &src, Allocator &inAllocator);
void deleteValues(Allocator &inAllocator);
bool operator <(const CssmDbAttributeData& other) const;
};
class CssmDbRecordAttributeData : public PodWrapper<CssmDbRecordAttributeData, CSSM_DB_RECORD_ATTRIBUTE_DATA>
{
public:
CssmDbRecordAttributeData()
{ clearPod(); DataRecordType = CSSM_DL_DB_RECORD_ANY; }
CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
uint32 semanticInformation() const { return SemanticInformation; }
void semanticInformation(uint32 semanticInformation) { SemanticInformation = semanticInformation; }
uint32 size() const { return NumberOfAttributes; }
CssmDbAttributeData *&attributes()
{ return CssmDbAttributeData::overlayVar(AttributeData); }
CssmDbAttributeData *attributes() const
{ return CssmDbAttributeData::overlay(AttributeData); }
CssmDbAttributeData &at(unsigned int ix) const
{ assert(ix < size()); return attributes()[ix]; }
CssmDbAttributeData &operator [] (unsigned int ix) const { return at(ix); }
void deleteValues(Allocator &allocator)
{ for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
CssmDbAttributeData *find(const CSSM_DB_ATTRIBUTE_INFO &inInfo);
bool operator <(const CssmDbRecordAttributeData& other) const;
};
class CssmAutoDbRecordAttributeData : public CssmDbRecordAttributeData, public ArrayBuilder<CssmDbAttributeData>
{
public:
CssmAutoDbRecordAttributeData(uint32 capacity = 0,
Allocator &valueAllocator = Allocator::standard(),
Allocator &dataAllocator = Allocator::standard()) :
CssmDbRecordAttributeData(),
ArrayBuilder<CssmDbAttributeData>(CssmDbAttributeData::overlayVar(AttributeData),
NumberOfAttributes, capacity, dataAllocator),
mValueAllocator(valueAllocator) {}
~CssmAutoDbRecordAttributeData();
void clear();
void deleteValues() { CssmDbRecordAttributeData::deleteValues(mValueAllocator); }
void invalidate();
CssmDbAttributeData &add() { return ArrayBuilder<CssmDbAttributeData>::add(); } CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info);
CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
operator Allocator &() const { return mValueAllocator; }
private:
Allocator &mValueAllocator;
CssmDbAttributeData* findAttribute (const CSSM_DB_ATTRIBUTE_INFO &info);
CssmDbAttributeData& getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO &info);
};
class CssmSelectionPredicate : public PodWrapper<CssmSelectionPredicate, CSSM_SELECTION_PREDICATE> {
public:
CssmSelectionPredicate() { clearPod(); }
CSSM_DB_OPERATOR dbOperator() const { return DbOperator; }
void dbOperator(CSSM_DB_OPERATOR dbOperator) { DbOperator = dbOperator; }
CssmSelectionPredicate(CSSM_DB_OPERATOR inDbOperator)
{ dbOperator(inDbOperator); Attribute.NumberOfValues = 0; Attribute.Value = NULL; }
CssmDbAttributeData &attribute() { return CssmDbAttributeData::overlay(Attribute); }
const CssmDbAttributeData &attribute() const { return CssmDbAttributeData::overlay(Attribute); }
void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo,
const CssmPolyData &inValue, Allocator &inAllocator)
{ attribute().set(inInfo, inValue, inAllocator); }
void set(const CSSM_SELECTION_PREDICATE &other, Allocator &inAllocator)
{ DbOperator = other.DbOperator; attribute().set(other.Attribute, inAllocator); }
void add(const CssmPolyData &inValue, Allocator &inAllocator)
{ attribute().add(inValue, inAllocator); }
void deleteValues(Allocator &inAllocator) { attribute().deleteValues(inAllocator); }
};
class CssmQuery : public PodWrapper<CssmQuery, CSSM_QUERY> {
public:
CssmQuery(CSSM_DB_RECORDTYPE type = CSSM_DL_DB_RECORD_ANY)
{ clearPod(); RecordType = type; }
CssmQuery(const CSSM_QUERY &q) { assignPod(q); }
CssmQuery &operator = (const CSSM_QUERY &q) { assignPod(q); return *this; }
CssmQuery(const CssmQuery &q, CSSM_DB_RECORDTYPE type)
{ *this = q; RecordType = type; }
CSSM_DB_RECORDTYPE recordType() const { return RecordType; }
void recordType(CSSM_DB_RECORDTYPE recordType) { RecordType = recordType; }
CSSM_DB_CONJUNCTIVE conjunctive() const { return Conjunctive; }
void conjunctive(CSSM_DB_CONJUNCTIVE conjunctive) { Conjunctive = conjunctive; }
CSSM_QUERY_LIMITS queryLimits() const { return QueryLimits; }
void queryLimits(CSSM_QUERY_LIMITS queryLimits) { QueryLimits = queryLimits; }
CSSM_QUERY_FLAGS queryFlags() const { return QueryFlags; }
void queryFlags(CSSM_QUERY_FLAGS queryFlags) { QueryFlags = queryFlags; }
uint32 size() const { return NumSelectionPredicates; }
CssmSelectionPredicate *&predicates()
{ return CssmSelectionPredicate::overlayVar(SelectionPredicate); }
CssmSelectionPredicate *predicates() const
{ return CssmSelectionPredicate::overlay(SelectionPredicate); }
CssmSelectionPredicate &at(uint32 ix) const
{ assert(ix < size()); return predicates()[ix]; }
CssmSelectionPredicate &operator[] (uint32 ix) const { return at(ix); }
void set(uint32 count, CSSM_SELECTION_PREDICATE *preds)
{ NumSelectionPredicates = count; SelectionPredicate = preds; }
void deleteValues(Allocator &allocator)
{ for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
};
class CssmAutoQuery : public CssmQuery, public ArrayBuilder<CssmSelectionPredicate> {
public:
CssmAutoQuery(const CSSM_QUERY &query, Allocator &allocator = Allocator::standard());
CssmAutoQuery(uint32 capacity = 0, Allocator &allocator = Allocator::standard()) :
ArrayBuilder<CssmSelectionPredicate>(CssmSelectionPredicate::overlayVar(SelectionPredicate),
NumSelectionPredicates,
capacity, allocator) {}
~CssmAutoQuery();
void clear();
void deleteValues() { CssmQuery::deleteValues(allocator()); }
CssmSelectionPredicate &add() { return ArrayBuilder<CssmSelectionPredicate>::add(); }
CssmSelectionPredicate &add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
operator Allocator &() const { return allocator(); }
};
class DLDbIdentifier
{
protected:
class Impl : public RefCount
{
NOCOPY(Impl)
public:
Impl(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation) :
mCssmSubserviceUid(ssuid),mDbName(DbName,DbLocation) {}
~Impl() {}
const CssmSubserviceUid &ssuid() const { return mCssmSubserviceUid; }
const char *dbName() const { return mDbName.dbName(); }
const CssmNetAddress *dbLocation() const { return mDbName.dbLocation(); }
bool operator < (const Impl &other) const;
bool operator == (const Impl &other) const;
private:
CssmSubserviceUid mCssmSubserviceUid;
DbName mDbName;
};
public:
DLDbIdentifier() {}
DLDbIdentifier(const CSSM_SUBSERVICE_UID &ssuid, const char *DbName, const CSSM_NET_ADDRESS *DbLocation)
: mImpl(new Impl(ssuid, DbName, DbLocation)) {}
DLDbIdentifier(const char *name, const Guid &guid, uint32 ssid, uint32 sstype,
const CSSM_NET_ADDRESS *location = NULL)
: mImpl(new Impl(CssmSubserviceUid(guid, NULL, ssid, sstype), name, location)) { }
bool operator !() const { return !mImpl; }
operator bool() const { return mImpl; }
bool operator <(const DLDbIdentifier &other) const
{ return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl.get() < other.mImpl.get(); }
bool operator ==(const DLDbIdentifier &other) const
{ return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl.get() == other.mImpl.get(); }
DLDbIdentifier &operator =(const DLDbIdentifier &other)
{ mImpl = other.mImpl; return *this; }
const CssmSubserviceUid &ssuid() const { return mImpl->ssuid(); }
const char *dbName() const { return mImpl->dbName(); }
const CssmNetAddress *dbLocation() const { return mImpl->dbLocation(); }
bool IsImplEmpty() const {return mImpl == NULL;}
RefPointer<Impl> mImpl;
};
class CssmDbIndexInfo : public PodWrapper<CssmDbIndexInfo, CSSM_DB_INDEX_INFO>
{
public:
CssmDbIndexInfo(const CSSM_DB_INDEX_INFO &attr)
{ (CSSM_DB_INDEX_INFO &)*this = attr; }
CSSM_DB_INDEX_TYPE indexType() const { return IndexType; }
void indexType(CSSM_DB_INDEX_TYPE indexType) { IndexType = indexType; }
CSSM_DB_INDEXED_DATA_LOCATION dataLocation() const { return IndexedDataLocation; }
void dataLocation(CSSM_DB_INDEXED_DATA_LOCATION dataLocation)
{
IndexedDataLocation = dataLocation;
}
const CssmDbAttributeInfo &attributeInfo() const
{
return CssmDbAttributeInfo::overlay(Info);
}
};
namespace DataWalkers {
struct DLDbFlatIdentifier {
CssmSubserviceUid *uid; char *name; CssmNetAddress *address;
DLDbFlatIdentifier(const DLDbIdentifier &ident) :
uid(const_cast<CssmSubserviceUid *>(&ident.ssuid())),
name(const_cast<char *>(ident.dbName())),
address(const_cast<CssmNetAddress *>(ident.dbLocation()))
{ }
operator DLDbIdentifier () { return DLDbIdentifier(*uid, name, address); }
};
template<class Action>
DLDbFlatIdentifier *walk(Action &operate, DLDbFlatIdentifier * &ident)
{
operate(ident);
if (ident->uid)
walk(operate, ident->uid);
walk(operate, ident->name);
if (ident->address)
walk(operate, ident->address);
return ident;
}
template<class Action>
void enumerate(Action &operate, CssmDbAttributeInfo &info)
{
switch (info.nameFormat()) {
case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
walk(operate, info.Label.AttributeName);
break;
case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
walk(operate, info.Label.AttributeOID);
break;
default:
break;
}
}
template <class Action>
void walk(Action &operate, CssmDbAttributeInfo &info)
{
operate(info);
enumerate(operate, info);
}
template <class Action>
CssmDbAttributeInfo *walk(Action &operate, CssmDbAttributeInfo * &info)
{
operate(info);
enumerate(operate, *info);
return info;
}
template <class Action>
void walk(Action &operate, CssmDbRecordAttributeInfo &info)
{
operate(info);
enumerateArray(operate, info, &CssmDbRecordAttributeInfo::attributes);
}
template <class Action>
CssmDbRecordAttributeInfo *walk(Action &operate, CssmDbRecordAttributeInfo * &info)
{
operate(info);
enumerateArray(operate, *info, &CssmDbRecordAttributeInfo::attributes);
return info;
}
template <class Action>
void walk(Action &operate, CssmDbAttributeData &data)
{
operate(data);
walk(operate, data.info());
enumerateArray(operate, data, &CssmDbAttributeData::values);
}
template <class Action>
CssmDbAttributeData *walk(Action &operate, CssmDbAttributeData * &data)
{
operate(data);
walk(operate, data->info());
enumerateArray(operate, *data, &CssmDbAttributeData::values);
return data;
}
template <class Action>
void walk(Action &operate, CssmDbRecordAttributeData &data)
{
operate(data);
enumerateArray(operate, data, &CssmDbRecordAttributeData::attributes);
}
template <class Action>
CssmDbRecordAttributeData *walk(Action &operate, CssmDbRecordAttributeData * &data)
{
operate(data);
enumerateArray(operate, *data, &CssmDbRecordAttributeData::attributes);
return data;
}
template <class Action>
CssmSelectionPredicate *walk(Action &operate, CssmSelectionPredicate * &predicate)
{
operate(predicate);
walk(operate, predicate->attribute());
return predicate;
}
template<class Action>
void walk(Action &operate, CssmSelectionPredicate &predicate)
{
operate(predicate);
walk(operate, predicate.attribute());
}
template <class Action>
void walk(Action &operate, CssmQuery &query)
{
operate(query);
enumerateArray(operate, query, &CssmQuery::predicates);
}
template <class Action>
CssmQuery *walk(Action &operate, CssmQuery * &query)
{
operate(query);
enumerateArray(operate, *query, &CssmQuery::predicates);
return query;
}
template <class Action>
CSSM_QUERY *walk(Action &operate, CSSM_QUERY * &query)
{
return walk(operate, CssmQuery::overlayVar(query));
}
} }
#endif // _H_CDSA_UTILITIES_CSSMDB