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