#ifndef _H_APPLEDL_METAATTRIBUTE
#define _H_APPLEDL_METAATTRIBUTE
#include "DbValue.h"
#include <memory>
namespace Security
{
class MetaAttribute
{
public:
typedef CSSM_DB_ATTRIBUTE_FORMAT Format;
virtual ~MetaAttribute();
static MetaAttribute *create(Format format, uint32 attributeIndex,
uint32 attributeId);
Format attributeFormat() const { return mFormat; }
uint32 attributeIndex() const { return mAttributeIndex; }
uint32 attributeId() const { return mAttributeId; }
void packAttribute(WriteSection &ws, uint32 &valueOffset,
uint32 numValues, const CSSM_DATA *values) const;
void unpackAttribute(const ReadSection &rs, CssmAllocator &allocator,
uint32 &numValues, CSSM_DATA *&values) const;
uint32 getNumberOfValues(const ReadSection &rs) const;
void copyValueBytes(uint32 valueIndex, const ReadSection &rs, WriteSection &ws,
uint32 &writeOffset) const;
virtual DbValue *createValue(const CSSM_DATA &data) const = 0;
virtual DbValue *createValue(const ReadSection &rs, uint32 &offset) const = 0;
virtual void packValue(WriteSection &ws, uint32 &offset, const CSSM_DATA &data) const = 0;
virtual void unpackValue(const ReadSection &rs, uint32 &offset, CSSM_DATA &data,
CssmAllocator &allocator) const = 0;
virtual void skipValue(const ReadSection &rs, uint32 &offset) const = 0;
virtual void copyValue(const ReadSection &rs, uint32 &readOffset, WriteSection &ws,
uint32 &writeOffset) const = 0;
virtual bool evaluate(const DbValue *value, const ReadSection &rs, CSSM_DB_OPERATOR op) const = 0;
virtual bool evaluate(const DbValue *value1, const DbValue *value2, CSSM_DB_OPERATOR op) const = 0;
virtual uint32 parse(const CssmData &inData, CSSM_DATA_PTR &outValues) const = 0;
protected:
MetaAttribute(Format format, uint32 attributeIndex, uint32 attributeId)
: mFormat(format), mAttributeIndex(attributeIndex), mAttributeId(attributeId) {}
void packNumberOfValues(WriteSection &ws, uint32 numValues, uint32 &valueOffset) const;
void unpackNumberOfValues(const ReadSection &rs, uint32 &numValues, uint32 &valueOffset) const;
Format mFormat;
uint32 mAttributeIndex;
uint32 mAttributeId;
};
template <class T>
class TypedMetaAttribute : public MetaAttribute
{
public:
TypedMetaAttribute(Format format, uint32 attributeIndex, uint32 attributeId)
: MetaAttribute(format, attributeIndex, attributeId) {}
DbValue *createValue(const CSSM_DATA &data) const
{
return new T(data);
}
DbValue *createValue(const ReadSection &rs, uint32 &offset) const
{
return new T(rs, offset);
}
void packValue(WriteSection &ws, uint32 &offset, const CSSM_DATA &data) const
{
T value(data);
value.pack(ws, offset);
}
void unpackValue(const ReadSection &rs, uint32 &offset, CSSM_DATA &data, CssmAllocator &allocator) const
{
T value(rs, offset);
data.Length = value.size();
if (data.Length != 0)
{
data.Data = reinterpret_cast<uint8 *>(allocator.malloc(data.Length));
memcpy(data.Data, value.bytes(), data.Length);
}
else
{
data.Data = NULL;
}
}
void skipValue(const ReadSection &rs, uint32 &offset) const
{
T value(rs, offset);
}
void copyValue(const ReadSection &rs, uint32 &readOffset, WriteSection &ws, uint32 &writeOffset) const
{
T value(rs, readOffset);
value.pack(ws, writeOffset);
}
bool evaluate(const DbValue *value, const ReadSection &rs, CSSM_DB_OPERATOR op) const
{
uint32 offset, numValues;
unpackNumberOfValues(rs, numValues, offset);
if (numValues == 0)
return false;
return (dynamic_cast<const T *>(value))->evaluate(T(rs, offset), op);
}
bool evaluate(const DbValue *value1, const DbValue *value2, CSSM_DB_OPERATOR op) const
{
return (dynamic_cast<const T *>(value1))->evaluate(*dynamic_cast<const T *>(value2), op);
}
uint32 parse(const CssmData &inData, CSSM_DATA_PTR &outValues) const
{
return 0;
}
};
}
#endif // _H_APPLEDL_METAATTRIBUTE