2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
24 #define _CPP_UTILITIES
27 #include <Security/cssmdb.h>
31 // CssmDbAttributeInfo
34 CssmDbAttributeInfo::operator <(const CssmDbAttributeInfo
& other
) const
36 if (nameFormat() < other
.nameFormat()) return true;
37 if (other
.nameFormat() < nameFormat()) return false;
38 // nameFormat's are equal.
41 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
43 int res
= strcmp(static_cast<const char *>(*this), static_cast<const char *>(other
));
44 if (res
< 0) return true;
45 if (res
> 0) return false;
48 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
49 if (static_cast<const CssmOid
&>(*this) < static_cast<const CssmOid
&>(other
)) return true;
50 if (static_cast<const CssmOid
&>(other
) < static_cast<const CssmOid
&>(*this)) return false;
52 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
53 if (static_cast<uint32
>(*this) < static_cast<uint32
>(other
)) return true;
54 if (static_cast<uint32
>(other
) < static_cast<uint32
>(*this)) return false;
57 CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME
);
60 return format() < other
.format();
64 CssmDbAttributeInfo::operator ==(const CssmDbAttributeInfo
& other
) const
66 if (nameFormat() != other
.nameFormat()) return false;
67 if (format() != other
.format()) return false;
70 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
71 return !strcmp(static_cast<const char *>(*this), static_cast<const char *>(other
));
72 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
73 return static_cast<const CssmOid
&>(*this) == static_cast<const CssmOid
&>(other
);
74 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
75 return static_cast<uint32
>(*this) == static_cast<uint32
>(other
);
77 CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME
);
82 // CssmDbAttributeData
85 CssmDbAttributeData::deleteValues(CssmAllocator
&inAllocator
)
87 // Loop over all values and delete each one.
90 for (uint32 anIndex
= 0; anIndex
< NumberOfValues
; anIndex
++)
92 if (Value
[anIndex
].Data
)
94 inAllocator
.free(Value
[anIndex
].Data
);
97 Value
[anIndex
].Length
= 0;
100 inAllocator
.free(Value
);
108 CssmDbAttributeData::operator <(const CssmDbAttributeData
&other
) const
110 if (info() < other
.info()) return true;
111 if (other
.info() < info()) return false;
113 uint32 minSize
= min(size(), other
.size());
114 for (uint32 ix
= 0; ix
< minSize
; ++ix
)
116 if (at
<const CssmData
&>(ix
) < other
.at
<const CssmData
&>(ix
))
118 if (other
.at
<const CssmData
&>(ix
) < at
<const CssmData
&>(ix
))
122 return size() < other
.size();
126 CssmDbAttributeData::add(const CssmDbAttributeData
&src
, CssmAllocator
&inAllocator
)
128 // Add all the values from another attribute into this attribute.
130 Value
= reinterpret_cast<CSSM_DATA
*>(inAllocator
.realloc(Value
,
131 sizeof(*Value
) * (NumberOfValues
+ src
.NumberOfValues
)));
133 for (uint32 srcIndex
= 0; srcIndex
< src
.NumberOfValues
; srcIndex
++) {
134 uint32 destIndex
= NumberOfValues
+ srcIndex
;
136 Value
[destIndex
].Length
= 0;
137 Value
[destIndex
].Data
= inAllocator
.alloc
<uint8
>(src
.Value
[srcIndex
].Length
);
138 Value
[destIndex
].Length
= src
.Value
[srcIndex
].Length
;
139 memcpy(Value
[destIndex
].Data
, src
.Value
[srcIndex
].Data
, src
.Value
[srcIndex
].Length
);
142 NumberOfValues
+= src
.NumberOfValues
;
146 CssmDbAttributeData::deleteValue(const CssmData
&src
, CssmAllocator
&inAllocator
)
148 // Delete a single value from this attribute, if it is present.
150 for (uint32 i
= 0; i
< NumberOfValues
; i
++)
151 if (CssmData::overlay(Value
[i
]) == src
)
153 inAllocator
.free(Value
[i
].Data
);
157 Value
[i
].Data
= Value
[NumberOfValues
].Data
;
158 Value
[i
].Length
= Value
[NumberOfValues
].Length
;
166 // Delete those values found in src from this object, if they are present.
167 // Warning: This is O(N^2) worst case; if this becomes a performance bottleneck
168 // then it will need to be changed.
171 CssmDbAttributeData::deleteValues(const CssmDbAttributeData
&src
, CssmAllocator
&inAllocator
)
173 for (uint32 i
= 0; i
< src
.NumberOfValues
; i
++)
174 deleteValue(CssmData::overlay(src
.Value
[i
]), inAllocator
);
178 // CssmDbRecordAttributeData
180 CssmDbAttributeData
*
181 CssmDbRecordAttributeData::find(const CSSM_DB_ATTRIBUTE_INFO
&inInfo
)
183 const CssmDbAttributeInfo
&anInfo
= CssmDbAttributeInfo::overlay(inInfo
);
184 for (uint32 ix
= 0; ix
< size(); ++ix
)
186 if (at(ix
).info() == anInfo
)
194 CssmDbRecordAttributeData::operator <(const CssmDbRecordAttributeData
&other
) const
196 if (recordType() < other
.recordType()) return true;
197 if (other
.recordType() < recordType()) return false;
198 if (semanticInformation() < other
.semanticInformation()) return true;
199 if (other
.semanticInformation() < semanticInformation()) return false;
201 uint32 minSize
= min(size(), other
.size());
202 for (uint32 ix
= 0; ix
< minSize
; ++ix
)
204 if (at(ix
) < other
.at(ix
))
206 if (other
.at(ix
) < at(ix
))
210 return size() < other
.size();
215 // CssmAutoDbRecordAttributeData
217 CssmAutoDbRecordAttributeData::~CssmAutoDbRecordAttributeData()
223 CssmAutoDbRecordAttributeData::clear()
226 ArrayBuilder
<CssmDbAttributeData
>::clear();
231 static bool CompareAttributeInfos (const CSSM_DB_ATTRIBUTE_INFO
&a
, const CSSM_DB_ATTRIBUTE_INFO
&b
)
233 // check the format of the names
234 if (a
.AttributeNameFormat
!= b
.AttributeNameFormat
)
239 switch (a
.AttributeNameFormat
)
241 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
243 return strcmp (a
.Label
.AttributeName
, b
.Label
.AttributeName
) == 0;
246 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
248 if (a
.Label
.AttributeOID
.Length
!= b
.Label
.AttributeOID
.Length
)
253 return memcmp (a
.Label
.AttributeOID
.Data
, b
.Label
.AttributeOID
.Data
, a
.Label
.AttributeOID
.Length
) == 0;
257 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
259 return a
.Label
.AttributeID
== b
.Label
.AttributeID
;
263 return true; // just to keep the compiler from complaining
268 CssmDbAttributeData
* CssmAutoDbRecordAttributeData::findAttribute (const CSSM_DB_ATTRIBUTE_INFO
&info
)
270 // walk through the data, looking for an attribute of the same type
272 for (i
= 0; i
< size (); ++i
)
274 CssmDbAttributeData
& d
= at (i
);
275 CSSM_DB_ATTRIBUTE_INFO
&inInfo
= d
.info ();
277 if (CompareAttributeInfos (info
, inInfo
))
289 CssmDbAttributeData
& CssmAutoDbRecordAttributeData::getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO
&info
)
291 // Either find an existing reference to an attribute in the list, or make a new one.
292 CssmDbAttributeData
*anAttr
= findAttribute (info
);
293 if (anAttr
) // was this already in the list?
296 anAttr
->deleteValues (mValueAllocator
);
309 CssmDbAttributeData
&
310 CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO
&info
)
312 CssmDbAttributeData
& anAttr
= getAttributeReference (info
);
317 CssmDbAttributeData
&
318 CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO
&info
, const CssmPolyData
&value
)
320 CssmDbAttributeData
&anAttr
= getAttributeReference (info
);
321 anAttr
.set(info
, value
, mValueAllocator
);
328 CssmAutoQuery::CssmAutoQuery(const CSSM_QUERY
&query
, CssmAllocator
&allocator
)
329 : ArrayBuilder
<CssmSelectionPredicate
>(CssmSelectionPredicate::overlayVar(SelectionPredicate
),
330 NumSelectionPredicates
,
331 query
.NumSelectionPredicates
, allocator
)
333 RecordType
= query
.RecordType
;
334 Conjunctive
= query
.Conjunctive
;
335 QueryLimits
= query
.QueryLimits
;
336 QueryFlags
= query
.QueryFlags
;
337 for (uint32 ix
= 0; ix
< query
.NumSelectionPredicates
; ++ix
)
338 add().set(query
.SelectionPredicate
[ix
], allocator
);
341 CssmAutoQuery::~CssmAutoQuery()
347 CssmAutoQuery::clear()
350 ArrayBuilder
<CssmSelectionPredicate
>::clear();
353 CssmSelectionPredicate
&
354 CssmAutoQuery::add(CSSM_DB_OPERATOR dbOperator
, const CSSM_DB_ATTRIBUTE_INFO
&info
, const CssmPolyData
&value
)
356 CssmSelectionPredicate
&predicate
= add();
357 predicate
.dbOperator(dbOperator
);
358 predicate
.set(info
, value
, allocator());