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 CSSM_RETURN
AddFooToIntelList( void** theIntelListToAddItTo
, unsigned long* theNumberOfThingsAlreadyInTheList
, const void* theThingToAdd
, size_t theSizeOfTheThingToAdd
)
32 { // this is to make adding things to Intel LISTs (also called Arrays by the rest of us) easy! We do it everywhere! Join the fun!
33 CSSM_RETURN result
= CSSM_OK
;
34 void* theReallocatedBuffer
= NULL
;
35 if( *theIntelListToAddItTo
== NULL
)
38 *theIntelListToAddItTo
= malloc(theSizeOfTheThingToAdd
);
39 if(!*theIntelListToAddItTo
)
41 result
= CSSMERR_CSSM_MEMORY_ERROR
;
46 theReallocatedBuffer
= realloc((void*)*theIntelListToAddItTo
, (*theNumberOfThingsAlreadyInTheList
+1) * (theSizeOfTheThingToAdd
) );
47 if(!theReallocatedBuffer
)
49 result
= CSSMERR_CSSM_MEMORY_ERROR
;
53 *theIntelListToAddItTo
= theReallocatedBuffer
;
57 if(result
== CSSM_OK
)
59 memcpy( (void*)((char*)*theIntelListToAddItTo
+(theSizeOfTheThingToAdd
* (*theNumberOfThingsAlreadyInTheList
))), theThingToAdd
, theSizeOfTheThingToAdd
);
60 (*theNumberOfThingsAlreadyInTheList
)++;
68 // CssmDbAttributeInfo
71 CssmDbAttributeInfo::operator <(const CssmDbAttributeInfo
& other
) const
73 if (nameFormat() < other
.nameFormat()) return true;
74 if (other
.nameFormat() < nameFormat()) return false;
75 // nameFormat's are equal.
78 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
80 int res
= strcmp(static_cast<const char *>(*this), static_cast<const char *>(other
));
81 if (res
< 0) return true;
82 if (res
> 0) return false;
85 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
86 if (static_cast<const CssmOid
&>(*this) < static_cast<const CssmOid
&>(other
)) return true;
87 if (static_cast<const CssmOid
&>(other
) < static_cast<const CssmOid
&>(*this)) return false;
89 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
90 if (static_cast<uint32
>(*this) < static_cast<uint32
>(other
)) return true;
91 if (static_cast<uint32
>(other
) < static_cast<uint32
>(*this)) return false;
94 CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME
);
97 return format() < other
.format();
101 CssmDbAttributeInfo::operator ==(const CssmDbAttributeInfo
& other
) const
103 if (nameFormat() != other
.nameFormat()) return false;
104 if (format() != other
.format()) return false;
105 switch (nameFormat())
107 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
108 return !strcmp(static_cast<const char *>(*this), static_cast<const char *>(other
));
109 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
110 return static_cast<const CssmOid
&>(*this) == static_cast<const CssmOid
&>(other
);
111 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
112 return static_cast<uint32
>(*this) == static_cast<uint32
>(other
);
114 CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME
);
119 // CssmDbAttributeData
122 CssmDbAttributeData::deleteValues(CssmAllocator
&inAllocator
)
124 // Loop over all values and delete each one.
127 for (uint32 anIndex
= 0; anIndex
< NumberOfValues
; anIndex
++)
129 if (Value
[anIndex
].Data
)
131 inAllocator
.free(Value
[anIndex
].Data
);
134 Value
[anIndex
].Length
= 0;
137 inAllocator
.free(Value
);
145 CssmDbAttributeData::operator <(const CssmDbAttributeData
&other
) const
147 if (info() < other
.info()) return true;
148 if (other
.info() < info()) return false;
150 uint32 minSize
= min(size(), other
.size());
151 for (uint32 ix
= 0; ix
< minSize
; ++ix
)
153 if (at
<const CssmData
&>(ix
) < other
.at
<const CssmData
&>(ix
))
155 if (other
.at
<const CssmData
&>(ix
) < at
<const CssmData
&>(ix
))
159 return size() < other
.size();
163 CssmDbAttributeData::add(const CssmDbAttributeData
&src
, CssmAllocator
&inAllocator
)
165 // Add all the values from another attribute into this attribute.
167 Value
= reinterpret_cast<CSSM_DATA
*>(inAllocator
.realloc(Value
,
168 sizeof(*Value
) * (NumberOfValues
+ src
.NumberOfValues
)));
170 for (uint32 srcIndex
= 0; srcIndex
< src
.NumberOfValues
; srcIndex
++) {
171 uint32 destIndex
= NumberOfValues
+ srcIndex
;
173 Value
[destIndex
].Length
= 0;
174 Value
[destIndex
].Data
= inAllocator
.alloc
<uint8
>(src
.Value
[srcIndex
].Length
);
175 Value
[destIndex
].Length
= src
.Value
[srcIndex
].Length
;
176 memcpy(Value
[destIndex
].Data
, src
.Value
[srcIndex
].Data
, src
.Value
[srcIndex
].Length
);
179 NumberOfValues
+= src
.NumberOfValues
;
183 CssmDbAttributeData::deleteValue(const CssmData
&src
, CssmAllocator
&inAllocator
)
185 // Delete a single value from this attribute, if it is present.
187 for (uint32 i
= 0; i
< NumberOfValues
; i
++)
188 if (CssmData::overlay(Value
[i
]) == src
)
190 inAllocator
.free(Value
[i
].Data
);
194 Value
[i
].Data
= Value
[NumberOfValues
].Data
;
195 Value
[i
].Length
= Value
[NumberOfValues
].Length
;
203 // Delete those values found in src from this object, if they are present.
204 // Warning: This is O(N^2) worst case; if this becomes a performance bottleneck
205 // then it will need to be changed.
208 CssmDbAttributeData::deleteValues(const CssmDbAttributeData
&src
, CssmAllocator
&inAllocator
)
210 for (uint32 i
= 0; i
< src
.NumberOfValues
; i
++)
211 deleteValue(CssmData::overlay(src
.Value
[i
]), inAllocator
);
215 // CssmDbRecordAttributeData
217 CssmDbAttributeData
*
218 CssmDbRecordAttributeData::find(const CSSM_DB_ATTRIBUTE_INFO
&inInfo
)
220 const CssmDbAttributeInfo
&anInfo
= CssmDbAttributeInfo::overlay(inInfo
);
221 for (uint32 ix
= 0; ix
< size(); ++ix
)
223 if (at(ix
).info() == anInfo
)
231 CssmDbRecordAttributeData::operator <(const CssmDbRecordAttributeData
&other
) const
233 if (recordType() < other
.recordType()) return true;
234 if (other
.recordType() < recordType()) return false;
235 if (semanticInformation() < other
.semanticInformation()) return true;
236 if (other
.semanticInformation() < semanticInformation()) return false;
238 uint32 minSize
= min(size(), other
.size());
239 for (uint32 ix
= 0; ix
< minSize
; ++ix
)
241 if (at(ix
) < other
.at(ix
))
243 if (other
.at(ix
) < at(ix
))
247 return size() < other
.size();
252 // CssmAutoDbRecordAttributeData
254 CssmAutoDbRecordAttributeData::~CssmAutoDbRecordAttributeData()
260 CssmAutoDbRecordAttributeData::clear()
263 ArrayBuilder
<CssmDbAttributeData
>::clear();
268 static bool CompareAttributeInfos (const CSSM_DB_ATTRIBUTE_INFO
&a
, const CSSM_DB_ATTRIBUTE_INFO
&b
)
270 // check the format of the names
271 if (a
.AttributeNameFormat
!= b
.AttributeNameFormat
)
276 switch (a
.AttributeNameFormat
)
278 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
280 return strcmp (a
.Label
.AttributeName
, b
.Label
.AttributeName
) == 0;
283 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
285 if (a
.Label
.AttributeOID
.Length
!= b
.Label
.AttributeOID
.Length
)
290 return memcmp (a
.Label
.AttributeOID
.Data
, b
.Label
.AttributeOID
.Data
, a
.Label
.AttributeOID
.Length
) == 0;
294 case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
:
296 return a
.Label
.AttributeID
== b
.Label
.AttributeID
;
300 return true; // just to keep the compiler from complaining
305 CssmDbAttributeData
* CssmAutoDbRecordAttributeData::findAttribute (const CSSM_DB_ATTRIBUTE_INFO
&info
)
307 // walk through the data, looking for an attribute of the same type
309 for (i
= 0; i
< size (); ++i
)
311 CssmDbAttributeData
& d
= at (i
);
312 CSSM_DB_ATTRIBUTE_INFO
&inInfo
= d
.info ();
314 if (CompareAttributeInfos (info
, inInfo
))
326 CssmDbAttributeData
& CssmAutoDbRecordAttributeData::getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO
&info
)
328 // Either find an existing reference to an attribute in the list, or make a new one.
329 CssmDbAttributeData
*anAttr
= findAttribute (info
);
330 if (anAttr
) // was this already in the list?
333 anAttr
->deleteValues (mValueAllocator
);
346 CssmDbAttributeData
&
347 CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO
&info
)
349 CssmDbAttributeData
& anAttr
= getAttributeReference (info
);
354 CssmDbAttributeData
&
355 CssmAutoDbRecordAttributeData::add(const CSSM_DB_ATTRIBUTE_INFO
&info
, const CssmPolyData
&value
)
357 CssmDbAttributeData
&anAttr
= getAttributeReference (info
);
358 anAttr
.set(info
, value
, mValueAllocator
);
365 CssmAutoQuery::CssmAutoQuery(const CSSM_QUERY
&query
, CssmAllocator
&allocator
)
366 : ArrayBuilder
<CssmSelectionPredicate
>(static_cast<CssmSelectionPredicate
*>(SelectionPredicate
),
367 NumSelectionPredicates
,
368 query
.NumSelectionPredicates
, allocator
)
370 RecordType
= query
.RecordType
;
371 Conjunctive
= query
.Conjunctive
;
372 QueryLimits
= query
.QueryLimits
;
373 QueryFlags
= query
.QueryFlags
;
374 for (uint32 ix
= 0; ix
< query
.NumSelectionPredicates
; ++ix
)
375 add().set(query
.SelectionPredicate
[ix
], allocator
);
378 CssmAutoQuery::~CssmAutoQuery()
384 CssmAutoQuery::clear()
387 ArrayBuilder
<CssmSelectionPredicate
>::clear();
390 CssmSelectionPredicate
&
391 CssmAutoQuery::add(CSSM_DB_OPERATOR dbOperator
, const CSSM_DB_ATTRIBUTE_INFO
&info
, const CssmPolyData
&value
)
393 CssmSelectionPredicate
&predicate
= add();
394 predicate
.dbOperator(dbOperator
);
395 predicate
.set(info
, value
, allocator());