1/* 2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18 19// 20// MetaAttribute.h 21// 22 23#ifndef _H_APPLEDL_METAATTRIBUTE 24#define _H_APPLEDL_METAATTRIBUTE 25 26#include "DbValue.h" 27#include <memory> 28 29namespace Security 30{ 31 32// A base class for all meta attributes. 33 34class MetaAttribute 35{ 36public: 37 typedef CSSM_DB_ATTRIBUTE_FORMAT Format; 38 39 virtual ~MetaAttribute(); 40 41 // construct an appropriate subclass of MetaAttribute 42 static MetaAttribute *create(Format format, uint32 attributeIndex, 43 uint32 attributeId); 44 45 Format attributeFormat() const { return mFormat; } 46 uint32 attributeIndex() const { return mAttributeIndex; } 47 uint32 attributeId() const { return mAttributeId; } 48 49 void packAttribute(WriteSection &ws, uint32 &valueOffset, 50 uint32 numValues, const CSSM_DATA *values) const; 51 void unpackAttribute(const ReadSection &rs, Allocator &allocator, 52 uint32 &numValues, CSSM_DATA *&values) const; 53 54 uint32 getNumberOfValues(const ReadSection &rs) const; 55 void copyValueBytes(uint32 valueIndex, const ReadSection &rs, WriteSection &ws, 56 uint32 &writeOffset) const; 57 58 // interface required of all subclasses, implemented with templates below 59 virtual DbValue *createValue(const CSSM_DATA &data) const = 0; 60 virtual DbValue *createValue(const ReadSection &rs, uint32 &offset) const = 0; 61 virtual void packValue(WriteSection &ws, uint32 &offset, const CSSM_DATA &data) const = 0; 62 virtual void unpackValue(const ReadSection &rs, uint32 &offset, CSSM_DATA &data, 63 Allocator &allocator) const = 0; 64 virtual void skipValue(const ReadSection &rs, uint32 &offset) const = 0; 65 virtual void copyValue(const ReadSection &rs, uint32 &readOffset, WriteSection &ws, 66 uint32 &writeOffset) const = 0; 67 virtual bool evaluate(const DbValue *value, const ReadSection &rs, CSSM_DB_OPERATOR op) const = 0; 68 virtual bool evaluate(const DbValue *value1, const DbValue *value2, CSSM_DB_OPERATOR op) const = 0; 69 virtual uint32 parse(const CssmData &inData, CSSM_DATA_PTR &outValues) const = 0; 70 71protected: 72 MetaAttribute(Format format, uint32 attributeIndex, uint32 attributeId) 73 : mFormat(format), mAttributeIndex(attributeIndex), mAttributeId(attributeId) {} 74 75 void packNumberOfValues(WriteSection &ws, uint32 numValues, uint32 &valueOffset) const; 76 void unpackNumberOfValues(const ReadSection &rs, uint32 &numValues, uint32 &valueOffset) const; 77 78 Format mFormat; 79 uint32 mAttributeIndex; 80 uint32 mAttributeId; 81}; 82 83// Template used to describe particular subclasses of MetaAttribute 84 85template <class T> 86class TypedMetaAttribute : public MetaAttribute 87{ 88public: 89 TypedMetaAttribute(Format format, uint32 attributeIndex, uint32 attributeId) 90 : MetaAttribute(format, attributeIndex, attributeId) {} 91 92 DbValue *createValue(const CSSM_DATA &data) const 93 { 94 return new T(data); 95 } 96 97 DbValue *createValue(const ReadSection &rs, uint32 &offset) const 98 { 99 return new T(rs, offset); 100 } 101 102 void packValue(WriteSection &ws, uint32 &offset, const CSSM_DATA &data) const 103 { 104 T value(data); 105 value.pack(ws, offset); 106 } 107 108 void unpackValue(const ReadSection &rs, uint32 &offset, CSSM_DATA &data, Allocator &allocator) const 109 { 110 T value(rs, offset); 111 data.Length = value.size(); 112 113 if (data.Length != 0) 114 { 115 data.Data = reinterpret_cast<uint8 *>(allocator.malloc(data.Length)); 116 memcpy(data.Data, value.bytes(), data.Length); 117 } 118 else 119 { 120 data.Data = NULL; 121 } 122 } 123 124 void skipValue(const ReadSection &rs, uint32 &offset) const 125 { 126 T value(rs, offset); 127 } 128 129 void copyValue(const ReadSection &rs, uint32 &readOffset, WriteSection &ws, uint32 &writeOffset) const 130 { 131 T value(rs, readOffset); 132 value.pack(ws, writeOffset); 133 } 134 135 bool evaluate(const DbValue *value, const ReadSection &rs, CSSM_DB_OPERATOR op) const 136 { 137 uint32 offset, numValues; 138 unpackNumberOfValues(rs, numValues, offset); 139 140 /* If any of the values for this attribute match we have a 141 match. This is the same behaviour that indexes have. */ 142 for (uint32 ix = 0; ix < numValues; ++ix) 143 if (dynamic_cast<const T *>(value)->evaluate(T(rs, offset), op)) 144 return true; 145 146 return false; 147 } 148 149 bool evaluate(const DbValue *value1, const DbValue *value2, CSSM_DB_OPERATOR op) const 150 { 151 return (dynamic_cast<const T *>(value1))->evaluate(*dynamic_cast<const T *>(value2), op); 152 } 153 154 uint32 parse(const CssmData &inData, CSSM_DATA_PTR &outValues) const 155 { 156 return 0; 157 } 158}; 159 160} // end namespace Security 161 162#endif // _H_APPLEDL_METAATTRIBUTE 163