]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/cssmdb.h
Security-54.1.3.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / cssmdb.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, 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 // cssmdb.h
20 //
21 // classes for the DL related data structures
22 //
23
24 #ifndef _H_CDSA_UTILITIES_CSSMDB
25 #define _H_CDSA_UTILITIES_CSSMDB
26
27 #include <Security/cssmdata.h>
28 #include <Security/cssmalloc.h>
29 #include <Security/walkers.h>
30 #include <Security/DbName.h>
31
32 #ifdef _CPP_UTILITIES
33 #pragma export on
34 #endif
35
36 namespace Security
37 {
38
39
40 #if 0
41 //
42 // XXX Obsolete --mb
43 //
44 // some prototypes for utility functions
45 CSSM_RETURN AddFooToIntelList( void** theIntelListToAddItTo, unsigned long* theNumberOfThingsAlreadyInTheList, const void* theThingToAdd, size_t theSizeOfTheThingToAdd);
46 #endif
47
48 //
49 // Template class to build and maintain external arrays.
50 // Feel free to add and vector<> member functions and behaviours as needed.
51 //
52 // This class differs from vector mainly because it does not construct or
53 // destruct any of the elements it contains. Rather it zero fills the
54 // storage and returns references to elements.
55 // Also it does not implement insert(), erase() or assign(). It does implement
56 // which is equivalent to calling *insert(end()) on a vector.
57 //
58 template <class _Tp>
59 class ArrayBuilder {
60 public:
61 typedef _Tp value_type;
62 typedef value_type* pointer;
63 typedef const value_type* const_pointer;
64 typedef value_type* iterator;
65 typedef const value_type* const_iterator;
66 typedef value_type& reference;
67 typedef const value_type& const_reference;
68 typedef uint32 size_type;
69 typedef ptrdiff_t difference_type;
70
71 typedef reverse_iterator<const_iterator> const_reverse_iterator;
72 typedef reverse_iterator<iterator> reverse_iterator;
73
74 protected:
75 void insert_aux(iterator __position, const _Tp& __x);
76 void insert_aux(iterator __position);
77
78 public:
79 iterator begin() { return mArray; }
80 const_iterator begin() const { return mArray; }
81 iterator end() { return &mArray[mSize]; }
82 const_iterator end() const { return &mArray[mSize]; }
83
84 reverse_iterator rbegin()
85 { return reverse_iterator(end()); }
86 const_reverse_iterator rbegin() const
87 { return const_reverse_iterator(end()); }
88 reverse_iterator rend()
89 { return reverse_iterator(begin()); }
90 const_reverse_iterator rend() const
91 { return const_reverse_iterator(begin()); }
92
93 // Must be defined in base class.
94 //size_type size() const
95 //{ return mSize; }
96 size_type max_size() const
97 { return size_type(-1) / sizeof(_Tp); }
98 size_type capacity() const
99 { return mCapacity; }
100 bool empty() const
101 { return begin() == end(); }
102
103 ArrayBuilder(pointer &array, size_type &size, size_type capacity = 0, CssmAllocator &allocator = CssmAllocator::standard()) :
104 mArray(array), mSize(size), mCapacity(capacity), mAllocator(allocator)
105 {
106 #if BUG_GCC
107 mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
108 #else
109 mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
110 //mArray = mAllocator.alloc(mCapacity);
111 #endif
112 memset(mArray, 0, sizeof(value_type) * mCapacity);
113 mSize = 0;
114 }
115 ~ArrayBuilder() { mAllocator.free(mArray); }
116
117 reference front() { return *begin(); }
118 const_reference front() const { return *begin(); }
119 reference back() { return *(end() - 1); }
120 const_reference back() const { return *(end() - 1); }
121
122 void reserve(size_type newCapacity)
123 {
124 if (newCapacity > mCapacity)
125 {
126 #if BUG_GCC
127 mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
128 #else
129 mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
130 //mArray = mAllocator.realloc<value_type>(mArray, newCapacity));
131 #endif
132 memset(&mArray[mCapacity], 0, sizeof(value_type) * (newCapacity - mCapacity));
133 mCapacity = newCapacity;
134 }
135 }
136
137 // XXX Replace by push_back and insert.
138 reference add()
139 {
140 if (mSize >= mCapacity)
141 reserve(max(mSize + 1, mCapacity ? 2 * mCapacity : 1));
142
143 return mArray[mSize++];
144 }
145
146 const_pointer get() const { return mArray; }
147 pointer release() { const_pointer array = mArray; mArray = NULL; return array; }
148 void clear() { if (mSize) { memset(mArray, 0, sizeof(value_type) * mSize); } mSize = 0; }
149
150 // Must be defined in base class.
151 //reference at(size_type ix) { return mArray[ix]; }
152 //const_reference at(size_type ix) const { return mArray[ix]; }
153 //reference operator[] (size_type ix) { assert(ix < size()); return at(ix); }
154 //const_reference operator[] (size_type ix) const { assert(ix < size()); return at(ix); }
155 protected:
156 CssmAllocator &allocator() const { return mAllocator; }
157
158 private:
159
160 pointer &mArray;
161 size_type &mSize;
162 size_type mCapacity;
163 CssmAllocator &mAllocator;
164 };
165
166
167 //
168 // CssmDbAttributeInfo pod wrapper for CSSM_DB_ATTRIBUTE_INFO
169 //
170 class CssmDbAttributeInfo : public PodWrapper<CssmDbAttributeInfo, CSSM_DB_ATTRIBUTE_INFO>
171 {
172 public:
173 CssmDbAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &attr)
174 { (CSSM_DB_ATTRIBUTE_INFO &)*this = attr; }
175
176 CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat() const { return AttributeNameFormat; }
177 void nameFormat(CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat) { AttributeNameFormat = nameFormat; }
178
179 CSSM_DB_ATTRIBUTE_FORMAT format() const { return AttributeFormat; }
180 void format(CSSM_DB_ATTRIBUTE_FORMAT format) { AttributeFormat = format; }
181
182 operator const char *() const
183 {
184 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_STRING);
185 return Label.AttributeName;
186 }
187 operator const CssmOid &() const
188 {
189 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_OID);
190 return CssmOid::overlay(Label.AttributeOID);
191 }
192 operator uint32() const
193 {
194 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER);
195 return Label.AttributeID;
196 }
197
198 bool operator <(const CssmDbAttributeInfo& other) const;
199 bool operator ==(const CssmDbAttributeInfo& other) const;
200 bool operator !=(const CssmDbAttributeInfo& other) const
201 { return !(*this == other); }
202
203 // XXX Add setting member functions.
204 };
205
206 //
207 // CssmDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
208 //
209 class CssmDbRecordAttributeInfo : public PodWrapper<CssmDbRecordAttributeInfo, CSSM_DB_RECORD_ATTRIBUTE_INFO>
210 {
211 public:
212 CssmDbRecordAttributeInfo()
213 { DataRecordType = CSSM_DL_DB_RECORD_ANY; }
214
215 CssmDbRecordAttributeInfo(CSSM_DB_RECORDTYPE recordType, uint32 numberOfAttributes,
216 CSSM_DB_ATTRIBUTE_INFO_PTR attributeInfo)
217 {
218 DataRecordType = recordType;
219 NumberOfAttributes = numberOfAttributes;
220 AttributeInfo = attributeInfo;
221 }
222
223 CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
224 void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
225
226 uint32 size() const { return NumberOfAttributes; }
227
228 // Attributes by position
229 CssmDbAttributeInfo &at(uint32 ix)
230 { return CssmDbAttributeInfo::overlay(AttributeInfo[ix]); }
231 const CssmDbAttributeInfo &at(uint32 ix) const
232 { return CssmDbAttributeInfo::overlay(AttributeInfo[ix]); }
233
234 CssmDbAttributeInfo &operator [](uint32 ix)
235 { assert(ix < size()); return at(ix); }
236 const CssmDbAttributeInfo &operator [](uint32 ix) const
237 { assert(ix < size()); return at(ix); }
238 };
239
240 //
241 // CssmAutoDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
242 //
243 class CssmAutoDbRecordAttributeInfo: public CssmDbRecordAttributeInfo, public ArrayBuilder<CssmDbAttributeInfo>
244 {
245 public:
246 CssmAutoDbRecordAttributeInfo(uint32 capacity = 0, CssmAllocator &allocator = CssmAllocator::standard()) :
247 CssmDbRecordAttributeInfo(),
248 ArrayBuilder<CssmDbAttributeInfo>(static_cast<CssmDbAttributeInfo *>(AttributeInfo),
249 NumberOfAttributes, capacity, allocator) {}
250 };
251
252
253 //
254 // CssmDbAttributeData pod wrapper for CSSM_DB_ATTRIBUTE_DATA
255 //
256 class CssmDbAttributeData : public PodWrapper<CssmDbAttributeData, CSSM_DB_ATTRIBUTE_DATA>
257 {
258 public:
259 CssmDbAttributeData() { NumberOfValues = 0; Value = NULL; }
260 CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_DATA &attr)
261 { (CSSM_DB_ATTRIBUTE_DATA &)*this = attr; }
262 CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_INFO &info)
263 { Info = info; NumberOfValues = 0; Value = NULL; }
264
265 CssmDbAttributeInfo &info() { return CssmDbAttributeInfo::overlay(Info); }
266 const CssmDbAttributeInfo &info() const { return CssmDbAttributeInfo::overlay(Info); }
267 void info (const CSSM_DB_ATTRIBUTE_INFO &inInfo) { Info = inInfo; }
268
269 CSSM_DB_ATTRIBUTE_FORMAT format() const { return info().format(); }
270
271 uint32 size() const { return NumberOfValues; }
272
273 template <class T>
274 T at(unsigned int ix) const { return CssmDLPolyData(Value[ix], format()); }
275
276 template <class T>
277 T operator [](unsigned int ix) const
278 { if (ix >= size()) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE); return at(ix); }
279
280 // this is intentionally unspecified since it could lead to bugs; the
281 // data is not guaranteed to be NULL-terminated
282 // operator const char *() const;
283
284 // XXX Don't use assert, but throw an exception.
285 operator string() const
286 {
287 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
288 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_STRING);
289 return Value[0].Length ? string(reinterpret_cast<const char *>(Value[0].Data), Value[0].Length) : string();
290 }
291 operator bool() const
292 {
293 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
294 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_UINT32 || format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
295 return *reinterpret_cast<uint32 *>(Value[0].Data);
296 }
297 operator uint32() const
298 {
299 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
300 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_UINT32);
301 return *reinterpret_cast<uint32 *>(Value[0].Data);
302 }
303 operator const uint32 *() const
304 {
305 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
306 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
307 return reinterpret_cast<const uint32 *>(Value[0].Data);
308 }
309 operator sint32() const
310 {
311 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
312 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
313 return *reinterpret_cast<sint32 *>(Value[0].Data);
314 }
315 operator double() const
316 {
317 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
318 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_REAL);
319 return *reinterpret_cast<double *>(Value[0].Data);
320 }
321 operator CssmData &() const
322 {
323 if (size() < 1) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
324 assert(format() == CSSM_DB_ATTRIBUTE_FORMAT_STRING
325 || format() == CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM
326 || format() == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
327 || format() == CSSM_DB_ATTRIBUTE_FORMAT_BLOB
328 || format() == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
329 return CssmData::overlay(Value[0]);
330 }
331
332 // Set the value of this Attr (assuming it was not set before).
333 void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, const CssmPolyData &inValue,
334 CssmAllocator &inAllocator)
335 {
336 info(inInfo);
337 NumberOfValues = 0;
338 Value = inAllocator.alloc<CSSM_DATA>();
339 Value[0].Length = 0;
340 Value[0].Data = inAllocator.alloc<uint8>(inValue.Length);
341 Value[0].Length = inValue.Length;
342 memcpy(Value[0].Data, inValue.Data, inValue.Length);
343 NumberOfValues = 1;
344 }
345
346 // Set the value of this Attr (assuming it was not set before).
347 void set(const CSSM_DB_ATTRIBUTE_DATA &other, CssmAllocator &inAllocator)
348 {
349 info(other.Info);
350 Value = inAllocator.alloc<CSSM_DATA>(other.NumberOfValues);
351 NumberOfValues = other.NumberOfValues;
352 for (NumberOfValues = 0; NumberOfValues < other.NumberOfValues; NumberOfValues++)
353 {
354 Value[NumberOfValues].Length = 0;
355 Value[NumberOfValues].Data = inAllocator.alloc<uint8>(other.Value[NumberOfValues].Length);
356 Value[NumberOfValues].Length = other.Value[NumberOfValues].Length;
357 memcpy(Value[NumberOfValues].Data, other.Value[NumberOfValues].Data,
358 other.Value[NumberOfValues].Length);
359 }
360 }
361
362 // Add a value to this attribute.
363 void add(const CssmPolyData &inValue, CssmAllocator &inAllocator)
364 {
365 Value = reinterpret_cast<CSSM_DATA *>(inAllocator.realloc(Value, sizeof(*Value) * (NumberOfValues + 1)));
366 Value[NumberOfValues].Length = 0;
367 Value[NumberOfValues].Data = inAllocator.alloc<uint8>(inValue.Length);
368 Value[NumberOfValues].Length = inValue.Length;
369 memcpy(Value[NumberOfValues++].Data, inValue.Data, inValue.Length);
370 }
371
372 void add(const CssmDbAttributeData &src, CssmAllocator &inAllocator);
373
374 // delete specific values if they are present in this attribute data
375 bool deleteValue(const CssmData &src, CssmAllocator &inAllocator);
376 void deleteValues(const CssmDbAttributeData &src, CssmAllocator &inAllocator);
377
378 void deleteValues(CssmAllocator &inAllocator);
379
380 bool operator <(const CssmDbAttributeData& other) const;
381 };
382
383
384 //
385 // CssmDbRecordAttributeData pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_DATA
386 //
387 class CssmDbRecordAttributeData : public PodWrapper<CssmDbRecordAttributeData, CSSM_DB_RECORD_ATTRIBUTE_DATA>
388 {
389 public:
390 CssmDbRecordAttributeData()
391 { DataRecordType = CSSM_DL_DB_RECORD_ANY; SemanticInformation = 0; }
392
393 CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
394 void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
395
396 uint32 semanticInformation() const { return SemanticInformation; }
397 void semanticInformation(uint32 semanticInformation) { SemanticInformation = semanticInformation; }
398
399 uint32 size() const { return NumberOfAttributes; }
400
401 // Attributes by position
402 CssmDbAttributeData &at(unsigned int ix)
403 { return CssmDbAttributeData::overlay(AttributeData[ix]); }
404 const CssmDbAttributeData &at(unsigned int ix) const
405 { return CssmDbAttributeData::overlay(AttributeData[ix]); }
406
407 CssmDbAttributeData &operator [](unsigned int ix)
408 { assert(ix < size()); return at(ix); }
409 const CssmDbAttributeData &operator [](unsigned int ix) const
410 { assert(ix < size()); return at(ix); }
411
412 void deleteValues(CssmAllocator &allocator)
413 { for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
414
415 CssmDbAttributeData *find(const CSSM_DB_ATTRIBUTE_INFO &inInfo);
416
417 bool operator <(const CssmDbRecordAttributeData& other) const;
418 };
419
420
421 //
422 // CssmAutoDbRecordAttributeData
423 //
424 class CssmAutoDbRecordAttributeData : public CssmDbRecordAttributeData, public ArrayBuilder<CssmDbAttributeData>
425 {
426 public:
427 CssmAutoDbRecordAttributeData(uint32 capacity = 0,
428 CssmAllocator &valueAllocator = CssmAllocator::standard(),
429 CssmAllocator &dataAllocator = CssmAllocator::standard()) :
430 CssmDbRecordAttributeData(),
431 ArrayBuilder<CssmDbAttributeData>(static_cast<CssmDbAttributeData *>(AttributeData),
432 NumberOfAttributes, capacity, dataAllocator),
433 mValueAllocator(valueAllocator) {}
434 ~CssmAutoDbRecordAttributeData();
435
436 void clear();
437 void deleteValues() { CssmDbRecordAttributeData::deleteValues(mValueAllocator); }
438
439 CssmDbAttributeData &add() { return ArrayBuilder<CssmDbAttributeData>::add(); } // XXX using doesn't work here.
440 CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info);
441 CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
442
443 // So clients can pass this as the allocator argument to add()
444 operator CssmAllocator &() const { return mValueAllocator; }
445 private:
446 CssmAllocator &mValueAllocator;
447
448 CssmDbAttributeData* findAttribute (const CSSM_DB_ATTRIBUTE_INFO &info);
449 CssmDbAttributeData& getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO &info);
450 };
451
452
453 //
454 // CssmSelectionPredicate a PodWrapper for CSSM_SELECTION_PREDICATE
455 //
456 class CssmSelectionPredicate : public PodWrapper<CssmSelectionPredicate, CSSM_SELECTION_PREDICATE> {
457 public:
458 CssmSelectionPredicate() { /*IFDEBUG(*/ memset(this, 0, sizeof(*this)) /*)*/ ; }
459
460 CSSM_DB_OPERATOR dbOperator() const { return DbOperator; }
461 void dbOperator(CSSM_DB_OPERATOR dbOperator) { DbOperator = dbOperator; }
462
463 CssmSelectionPredicate(CSSM_DB_OPERATOR inDbOperator)
464 { dbOperator(inDbOperator); Attribute.NumberOfValues = 0; Attribute.Value = NULL; }
465
466 CssmDbAttributeData &attribute() { return CssmDbAttributeData::overlay(Attribute); }
467 const CssmDbAttributeData &attribute() const { return CssmDbAttributeData::overlay(Attribute); }
468
469 // Set the value of this CssmSelectionPredicate (assuming it was not set before).
470 void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo,
471 const CssmPolyData &inValue, CssmAllocator &inAllocator)
472 { attribute().set(inInfo, inValue, inAllocator); }
473
474 // Set the value of this CssmSelectionPredicate using another CssmSelectionPredicate's value.
475 void set(const CSSM_SELECTION_PREDICATE &other, CssmAllocator &inAllocator)
476 { DbOperator = other.DbOperator; attribute().set(other.Attribute, inAllocator); }
477
478 // Add a value to the list of values for this CssmSelectionPredicate.
479 void add(const CssmPolyData &inValue, CssmAllocator &inAllocator)
480 { attribute().add(inValue, inAllocator); }
481
482 void deleteValues(CssmAllocator &inAllocator) { attribute().deleteValues(inAllocator); }
483 };
484
485 class CssmQuery : public PodWrapper<CssmQuery, CSSM_QUERY> {
486 public:
487 CssmQuery()
488 { memset(this, 0, sizeof(*this)) ; RecordType = CSSM_DL_DB_RECORD_ANY; }
489 //CssmDLQuery(const CSSM_QUERY &q) { memcpy(this, &q, sizeof(*this)); }
490
491 //CssmDLQuery &operator = (const CSSM_QUERY &q)
492 //{ memcpy(this, &q, sizeof(*this)); return *this; }
493
494 CSSM_DB_RECORDTYPE recordType() const { return RecordType; }
495 void recordType(CSSM_DB_RECORDTYPE recordType) { RecordType = recordType; }
496
497 CSSM_DB_CONJUNCTIVE conjunctive() const { return Conjunctive; }
498 void conjunctive(CSSM_DB_CONJUNCTIVE conjunctive) { Conjunctive = conjunctive; }
499
500 CSSM_QUERY_LIMITS queryLimits() const { return QueryLimits; }
501 void queryLimits(CSSM_QUERY_LIMITS queryLimits) { QueryLimits = queryLimits; }
502
503 CSSM_QUERY_FLAGS queryFlags() const { return QueryFlags; }
504 void queryFlags(CSSM_QUERY_FLAGS queryFlags) { QueryFlags = queryFlags; }
505
506 uint32 size() const { return NumSelectionPredicates; }
507
508 CssmSelectionPredicate &at(uint32 ix)
509 { return CssmSelectionPredicate::overlay(SelectionPredicate[ix]); }
510 const CssmSelectionPredicate &at(uint32 ix) const
511 { return CssmSelectionPredicate::overlay(SelectionPredicate[ix]); }
512
513 CssmSelectionPredicate &operator[] (uint32 ix) { assert(ix < size()); return at(ix); }
514 const CssmSelectionPredicate &operator[] (uint32 ix) const { assert(ix < size()); return at(ix); }
515
516 void deleteValues(CssmAllocator &allocator)
517 { for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
518 };
519
520
521 class CssmAutoQuery : public CssmQuery, public ArrayBuilder<CssmSelectionPredicate> {
522 public:
523 CssmAutoQuery(const CSSM_QUERY &query, CssmAllocator &allocator = CssmAllocator::standard());
524 CssmAutoQuery(uint32 capacity = 0, CssmAllocator &allocator = CssmAllocator::standard()) :
525 ArrayBuilder<CssmSelectionPredicate>(static_cast<CssmSelectionPredicate *>(SelectionPredicate),
526 NumSelectionPredicates,
527 capacity, allocator) {}
528 ~CssmAutoQuery();
529 void clear();
530 void deleteValues() { CssmQuery::deleteValues(allocator()); }
531
532 CssmSelectionPredicate &add() { return ArrayBuilder<CssmSelectionPredicate>::add(); }
533 CssmSelectionPredicate &add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
534
535 // So clients can pass this as the allocator argument to add()
536 operator CssmAllocator &() const { return allocator(); }
537 };
538
539
540 //
541 // DLDbIdentifier
542 //
543 class DLDbIdentifier
544 {
545 protected:
546 class Impl : public RefCount
547 {
548 NOCOPY(Impl)
549 public:
550 Impl(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation) :
551 mCssmSubserviceUid(ssuid),mDbName(DbName,DbLocation) {}
552
553 ~Impl() {} // Must be public since RefPointer uses it.
554
555 // Accessors
556 const CssmSubserviceUid &ssuid() const { return mCssmSubserviceUid; }
557 const char *dbName() const { return mDbName.dbName().c_str(); }
558 const CssmNetAddress *dbLocation() const { return mDbName.dbLocation(); }
559
560 // operators
561 bool operator < (const Impl &other) const
562 { return (mCssmSubserviceUid < other.mCssmSubserviceUid ||
563 (!(other.mCssmSubserviceUid < mCssmSubserviceUid) && mDbName < other.mDbName)); }
564
565 bool operator == (const Impl &other) const
566 { return mCssmSubserviceUid == other.mCssmSubserviceUid && mDbName == other.mDbName; }
567
568 private:
569 // Private member variables
570 CssmSubserviceUid mCssmSubserviceUid;
571 DbName mDbName;
572 };
573
574 public:
575 // Constructors
576 DLDbIdentifier() {}
577 DLDbIdentifier(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation)
578 : mImpl(new Impl(ssuid, DbName, DbLocation)) {}
579
580 // Conversion Operators
581 bool operator !() const { return !mImpl; }
582 operator bool() const { return mImpl; }
583
584 // Operators
585 bool operator <(const DLDbIdentifier &other) const
586 { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl.get() < other.mImpl.get(); }
587 bool operator ==(const DLDbIdentifier &other) const
588 { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl.get() == other.mImpl.get(); }
589
590 // Accessors
591 const CssmSubserviceUid &ssuid() const { return mImpl->ssuid(); }
592 const char *dbName() const { return mImpl->dbName(); }
593 const CssmNetAddress *dbLocation() const { return mImpl->dbLocation(); }
594
595 RefPointer<Impl> mImpl;
596 };
597
598 // Wrappers for index-related CSSM objects.
599
600 class CssmDbIndexInfo : public PodWrapper<CssmDbIndexInfo, CSSM_DB_INDEX_INFO>
601 {
602 public:
603 CssmDbIndexInfo(const CSSM_DB_INDEX_INFO &attr)
604 { (CSSM_DB_INDEX_INFO &)*this = attr; }
605
606 CSSM_DB_INDEX_TYPE indexType() const { return IndexType; }
607 void indexType(CSSM_DB_INDEX_TYPE indexType) { IndexType = indexType; }
608
609 CSSM_DB_INDEXED_DATA_LOCATION dataLocation() const { return IndexedDataLocation; }
610 void dataLocation(CSSM_DB_INDEXED_DATA_LOCATION dataLocation)
611 {
612 IndexedDataLocation = dataLocation;
613 }
614
615 const CssmDbAttributeInfo &attributeInfo() const
616 {
617 return CssmDbAttributeInfo::overlay(Info);
618 }
619 };
620
621
622 namespace DataWalkers
623 {
624
625 //
626 // DLDbIdentifiers don't walk directly because they have Impl structure and use strings.
627 // Happily, they are easily transcribed into a walkable form.
628 //
629 struct DLDbFlatIdentifier {
630 const CssmSubserviceUid *uid; // module reference
631 const char *name; // string name
632 const CssmNetAddress *address; // optional network address
633
634 DLDbFlatIdentifier(const DLDbIdentifier &ident)
635 : uid(&ident.ssuid()), name(ident.dbName()), address(ident.dbLocation()) { }
636
637 operator DLDbIdentifier () { return DLDbIdentifier(*uid, name, address); }
638 };
639
640 template<class Action>
641 DLDbFlatIdentifier *walk(Action &operate, DLDbFlatIdentifier * &ident)
642 {
643 operate(ident);
644 if (ident->uid)
645 walk(operate, ident->uid);
646 walk(operate, ident->name);
647 if (ident->address)
648 walk(operate, ident->address);
649 return ident;
650 }
651
652 } // end namespace DataWalkers
653
654 } // end namespace Security
655
656 #ifdef _CPP_UTILITIES
657 #pragma export off
658 #endif
659
660
661 #endif // _H_CDSA_UTILITIES_CSSMDB