2 * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 // classes for the DL related data structures
30 #ifndef _H_CDSA_UTILITIES_CSSMDB
31 #define _H_CDSA_UTILITIES_CSSMDB
33 #include <security_cdsa_utilities/cssmdata.h>
34 #include <security_cdsa_utilities/cssmpods.h>
35 #include <security_cdsa_utilities/cssmalloc.h>
36 #include <security_cdsa_utilities/cssmwalkers.h>
37 #include <security_cdsa_utilities/cssmdbname.h>
44 // Template class to build and maintain external arrays.
45 // Feel free to add and vector<> member functions and behaviours as needed.
47 // This class differs from vector mainly because it does not construct or
48 // destruct any of the elements it contains. Rather it zero fills the
49 // storage and returns references to elements.
50 // Also it does not implement insert(), erase() or assign(). It does implement
51 // which is equivalent to calling *insert(end()) on a vector.
56 typedef _Tp value_type
;
57 typedef value_type
* pointer
;
58 typedef const value_type
* const_pointer
;
59 typedef value_type
* iterator
;
60 typedef const value_type
* const_iterator
;
61 typedef value_type
& reference
;
62 typedef const value_type
& const_reference
;
63 typedef uint32 size_type
;
64 typedef ptrdiff_t difference_type
;
66 typedef reverse_iterator
<const_iterator
> const_reverse_iterator
;
67 typedef reverse_iterator
<iterator
> reverse_iterator
;
70 void insert_aux(iterator __position
, const _Tp
& __x
);
71 void insert_aux(iterator __position
);
74 iterator
begin() { return mArray
; }
75 const_iterator
begin() const { return mArray
; }
76 iterator
end() { return &mArray
[mSize
]; }
77 const_iterator
end() const { return &mArray
[mSize
]; }
79 reverse_iterator
rbegin()
80 { return reverse_iterator(end()); }
81 const_reverse_iterator
rbegin() const
82 { return const_reverse_iterator(end()); }
83 reverse_iterator
rend()
84 { return reverse_iterator(begin()); }
85 const_reverse_iterator
rend() const
86 { return const_reverse_iterator(begin()); }
88 // Must be defined in base class.
89 //size_type size() const
91 size_type
max_size() const
92 { return size_type(-1) / sizeof(_Tp
); }
93 size_type
capacity() const
96 { return begin() == end(); }
98 ArrayBuilder(pointer
&array
, size_type
&size
, size_type capacity
= 0, Allocator
&allocator
= Allocator::standard()) :
99 mArray(array
), mSize(size
), mCapacity(capacity
), mAllocator(allocator
)
102 mArray
= reinterpret_cast<pointer
>(mAllocator
.malloc(sizeof(value_type
) * mCapacity
));
104 mArray
= reinterpret_cast<pointer
>(mAllocator
.malloc(sizeof(value_type
) * mCapacity
));
105 //mArray = mAllocator.alloc(mCapacity);
107 memset(mArray
, 0, sizeof(value_type
) * mCapacity
);
110 ~ArrayBuilder() { mAllocator
.free(mArray
); }
112 reference
front() { return *begin(); }
113 const_reference
front() const { return *begin(); }
114 reference
back() { return *(end() - 1); }
115 const_reference
back() const { return *(end() - 1); }
117 void reserve(size_type newCapacity
)
119 if (newCapacity
> mCapacity
)
122 mArray
= reinterpret_cast<pointer
>(mAllocator
.realloc(mArray
, sizeof(value_type
) * newCapacity
));
124 mArray
= reinterpret_cast<pointer
>(mAllocator
.realloc(mArray
, sizeof(value_type
) * newCapacity
));
125 //mArray = mAllocator.realloc<value_type>(mArray, newCapacity));
127 memset(&mArray
[mCapacity
], 0, sizeof(value_type
) * (newCapacity
- mCapacity
));
128 mCapacity
= newCapacity
;
132 // XXX Replace by push_back and insert.
135 if (mSize
>= mCapacity
)
136 reserve(max(mSize
+ 1, mCapacity
? 2 * mCapacity
: 1));
138 return mArray
[mSize
++];
141 const_pointer
get() const { return mArray
; }
142 pointer
release() { const_pointer array
= mArray
; mArray
= NULL
; return array
; }
143 void clear() { if (mSize
) { memset(mArray
, 0, sizeof(value_type
) * mSize
); } mSize
= 0; }
145 // Must be defined in base class.
146 //reference at(size_type ix) { return mArray[ix]; }
147 //const_reference at(size_type ix) const { return mArray[ix]; }
148 //reference operator[] (size_type ix) { assert(ix < size()); return at(ix); }
149 //const_reference operator[] (size_type ix) const { assert(ix < size()); return at(ix); }
151 Allocator
&allocator() const { return mAllocator
; }
158 Allocator
&mAllocator
;
163 // A CSSM_DL_DB_LIST wrapper.
164 // Note that there is a DLDBList class elsewhere that is quite
165 // unrelated to this structure.
167 class CssmDlDbHandle
: public PodWrapper
<CssmDlDbHandle
, CSSM_DL_DB_HANDLE
> {
169 CssmDlDbHandle() { clearPod(); }
170 CssmDlDbHandle(CSSM_DL_HANDLE dl
, CSSM_DB_HANDLE db
) { DLHandle
= dl
; DBHandle
= db
; }
172 CSSM_DL_HANDLE
dl() const { return DLHandle
; }
173 CSSM_DB_HANDLE
db() const { return DBHandle
; }
175 operator bool() const { return DLHandle
&& DBHandle
; }
178 inline bool operator < (const CSSM_DL_DB_HANDLE
&h1
, const CSSM_DL_DB_HANDLE
&h2
)
180 return h1
.DLHandle
< h2
.DLHandle
181 || (h1
.DLHandle
== h2
.DLHandle
&& h1
.DBHandle
< h2
.DBHandle
);
184 inline bool operator == (const CSSM_DL_DB_HANDLE
&h1
, const CSSM_DL_DB_HANDLE
&h2
)
186 return h1
.DLHandle
== h2
.DLHandle
&& h1
.DBHandle
== h2
.DBHandle
;
189 inline bool operator != (const CSSM_DL_DB_HANDLE
&h1
, const CSSM_DL_DB_HANDLE
&h2
)
191 return h1
.DLHandle
!= h2
.DLHandle
|| h1
.DBHandle
!= h2
.DBHandle
;
195 class CssmDlDbList
: public PodWrapper
<CssmDlDbList
, CSSM_DL_DB_LIST
> {
197 uint32
count() const { return NumHandles
; }
198 uint32
&count() { return NumHandles
; }
199 CssmDlDbHandle
*handles() const { return CssmDlDbHandle::overlay(DLDBHandle
); }
200 CssmDlDbHandle
* &handles() { return CssmDlDbHandle::overlayVar(DLDBHandle
); }
202 CssmDlDbHandle
&operator [] (uint32 ix
) const {
204 secemergency("CssmDlDbList: attempt to index beyond bounds");
207 return CssmDlDbHandle::overlay(DLDBHandle
[ix
]);
210 void setDlDbList(uint32 n
, CSSM_DL_DB_HANDLE
*list
)
211 { count() = n
; handles() = CssmDlDbHandle::overlay(list
); }
221 CssmDLPolyData(const CSSM_DATA
&data
, CSSM_DB_ATTRIBUTE_FORMAT format
)
222 : mData(CssmData::overlay(data
))
226 // @@@ Don't use assert, but throw an exception.
227 // @@@ Do a size check on mData as well.
229 // @@@ This method is dangerous since the returned string is not guaranteed to be zero terminated.
230 operator const char *() const
232 assert(mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_STRING
233 || mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
);
234 return reinterpret_cast<const char *>(mData
.Data
);
236 operator bool() const
238 assert(mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_UINT32
|| mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_SINT32
);
239 return *reinterpret_cast<uint32
*>(mData
.Data
);
241 operator uint32() const
243 assert(mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_UINT32
);
244 return *reinterpret_cast<uint32
*>(mData
.Data
);
246 operator const uint32
*() const
248 assert(mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32
);
249 return reinterpret_cast<const uint32
*>(mData
.Data
);
251 operator sint32() const
253 assert(mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_SINT32
);
254 return *reinterpret_cast<sint32
*>(mData
.Data
);
256 operator double() const
258 assert(mFormat
== CSSM_DB_ATTRIBUTE_FORMAT_REAL
);
259 return *reinterpret_cast<double *>(mData
.Data
);
261 operator CSSM_DATE () const;
262 operator Guid () const;
263 operator const CssmData
&() const
269 const CssmData
&mData
;
270 CSSM_DB_ATTRIBUTE_FORMAT mFormat
;
275 // CssmDbAttributeInfo pod wrapper for CSSM_DB_ATTRIBUTE_INFO
277 class CssmDbAttributeInfo
: public PodWrapper
<CssmDbAttributeInfo
, CSSM_DB_ATTRIBUTE_INFO
>
280 CssmDbAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO
&attr
)
283 CssmDbAttributeInfo(const char *name
,
284 CSSM_DB_ATTRIBUTE_FORMAT vFormat
= CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
);
285 CssmDbAttributeInfo(const CSSM_OID
&oid
,
286 CSSM_DB_ATTRIBUTE_FORMAT vFormat
= CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
);
287 CssmDbAttributeInfo(uint32 id
,
288 CSSM_DB_ATTRIBUTE_FORMAT vFormat
= CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
);
290 CSSM_DB_ATTRIBUTE_NAME_FORMAT
nameFormat() const { return AttributeNameFormat
; }
291 void nameFormat(CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat
) { AttributeNameFormat
= nameFormat
; }
293 CSSM_DB_ATTRIBUTE_FORMAT
format() const { return AttributeFormat
; }
294 void format(CSSM_DB_ATTRIBUTE_FORMAT format
) { AttributeFormat
= format
; }
296 const char *stringName() const
298 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_STRING
);
299 return Label
.AttributeName
;
301 const CssmOid
&oidName() const
303 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_OID
);
304 return CssmOid::overlay(Label
.AttributeOID
);
306 uint32
intName() const
308 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
);
309 return Label
.AttributeID
;
312 operator const char *() const { return stringName(); }
313 operator const CssmOid
&() const { return oidName(); }
314 operator uint32() const { return intName(); }
316 bool operator <(const CssmDbAttributeInfo
& other
) const;
317 bool operator ==(const CssmDbAttributeInfo
& other
) const;
318 bool operator !=(const CssmDbAttributeInfo
& other
) const
319 { return !(*this == other
); }
323 // CssmDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
325 class CssmDbRecordAttributeInfo
: public PodWrapper
<CssmDbRecordAttributeInfo
, CSSM_DB_RECORD_ATTRIBUTE_INFO
>
328 CssmDbRecordAttributeInfo()
329 { DataRecordType
= CSSM_DL_DB_RECORD_ANY
; }
331 CssmDbRecordAttributeInfo(CSSM_DB_RECORDTYPE recordType
, uint32 numberOfAttributes
,
332 CSSM_DB_ATTRIBUTE_INFO_PTR attributeInfo
)
334 DataRecordType
= recordType
;
335 NumberOfAttributes
= numberOfAttributes
;
336 AttributeInfo
= attributeInfo
;
339 CSSM_DB_RECORDTYPE
recordType() const { return DataRecordType
; }
340 void recordType(CSSM_DB_RECORDTYPE recordType
) { DataRecordType
= recordType
; }
342 uint32
size() const { return NumberOfAttributes
; }
345 CssmDbAttributeInfo
*&attributes()
346 { return CssmDbAttributeInfo::overlayVar(AttributeInfo
); }
347 CssmDbAttributeInfo
*attributes() const
348 { return CssmDbAttributeInfo::overlay(AttributeInfo
); }
349 CssmDbAttributeInfo
&at(uint32 ix
) const {
351 secemergency("CssmDbRecordAttributeInfo: attempt to index beyond bounds");
354 return attributes()[ix
];
357 CssmDbAttributeInfo
&operator [] (uint32 ix
) const { return at(ix
); }
361 // CssmAutoDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
363 class CssmAutoDbRecordAttributeInfo
: public CssmDbRecordAttributeInfo
, public ArrayBuilder
<CssmDbAttributeInfo
>
366 CssmAutoDbRecordAttributeInfo(uint32 capacity
= 0, Allocator
&allocator
= Allocator::standard()) :
367 CssmDbRecordAttributeInfo(),
368 ArrayBuilder
<CssmDbAttributeInfo
>(CssmDbAttributeInfo::overlayVar(AttributeInfo
),
369 NumberOfAttributes
, capacity
, allocator
) {}
374 // CssmDbAttributeData pod wrapper for CSSM_DB_ATTRIBUTE_DATA
376 class CssmDbAttributeData
: public PodWrapper
<CssmDbAttributeData
, CSSM_DB_ATTRIBUTE_DATA
>
379 CssmDbAttributeData() { NumberOfValues
= 0; Value
= NULL
; }
380 CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_DATA
&attr
)
382 CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_INFO
&info
)
383 { Info
= info
; NumberOfValues
= 0; Value
= NULL
; }
385 CssmDbAttributeInfo
&info() { return CssmDbAttributeInfo::overlay(Info
); }
386 const CssmDbAttributeInfo
&info() const { return CssmDbAttributeInfo::overlay(Info
); }
387 void info (const CSSM_DB_ATTRIBUTE_INFO
&inInfo
) { Info
= inInfo
; }
389 CSSM_DB_ATTRIBUTE_FORMAT
format() const { return info().format(); }
390 void format(CSSM_DB_ATTRIBUTE_FORMAT f
) { info().format(f
); }
392 uint32
size() const { return NumberOfValues
; }
393 CssmData
*&values() { return CssmData::overlayVar(Value
); }
394 CssmData
*values() const { return CssmData::overlay(Value
); }
396 CssmData
&at(unsigned int ix
) const
398 if (ix
>= size()) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE
);
402 CssmData
&operator [] (unsigned int ix
) const { return at(ix
); }
405 T
at(unsigned int ix
) const { return CssmDLPolyData(Value
[ix
], format()); }
407 // this is intentionally unspecified since it could lead to bugs; the
408 // data is not guaranteed to be NULL-terminated
409 // operator const char *() const;
411 operator string() const;
412 operator const Guid
&() const;
413 operator bool() const;
414 operator uint32() const;
415 operator const uint32
*() const;
416 operator sint32() const;
417 operator double() const;
418 operator const CssmData
&() const;
420 // set values without allocation (caller owns the data contents)
421 void set(CssmData
&data
) { set(1, &data
); }
422 void set(uint32 count
, CssmData
*datas
) { NumberOfValues
= count
; Value
= datas
; }
424 // Set the value of this Attr (assuming it was not set before).
425 void set(const CSSM_DB_ATTRIBUTE_INFO
&inInfo
, const CssmPolyData
&inValue
,
426 Allocator
&inAllocator
);
428 // copy (just) the return-value part from another AttributeData to this one
429 void copyValues(const CssmDbAttributeData
&source
, Allocator
&alloc
);
431 // Set the value of this Attr (which must be unset so far)
432 void set(const CSSM_DB_ATTRIBUTE_DATA
&source
, Allocator
&alloc
)
435 copyValues(source
, alloc
);
438 // Add a value to this attribute.
439 void add(const CssmPolyData
&inValue
, Allocator
&inAllocator
);
441 void add(const char *value
, Allocator
&alloc
)
442 { format(CSSM_DB_ATTRIBUTE_FORMAT_STRING
); add(CssmPolyData(value
), alloc
); }
444 void add(const std::string
&value
, Allocator
&alloc
)
445 { format(CSSM_DB_ATTRIBUTE_FORMAT_STRING
); add(CssmPolyData(value
), alloc
); }
447 void add(uint32 value
, Allocator
&alloc
)
448 { format(CSSM_DB_ATTRIBUTE_FORMAT_UINT32
); add(CssmPolyData(value
), alloc
); }
450 void add(sint32 value
, Allocator
&alloc
)
451 { format(CSSM_DB_ATTRIBUTE_FORMAT_SINT32
); add(CssmPolyData(value
), alloc
); }
453 void add(const CssmData
&value
, Allocator
&alloc
)
454 { format(CSSM_DB_ATTRIBUTE_FORMAT_BLOB
); add(CssmPolyData(value
), alloc
); }
456 void add(const CssmDbAttributeData
&src
, Allocator
&inAllocator
);
458 // delete specific values if they are present in this attribute data
459 bool deleteValue(const CssmData
&src
, Allocator
&inAllocator
);
460 void deleteValues(const CssmDbAttributeData
&src
, Allocator
&inAllocator
);
462 void deleteValues(Allocator
&inAllocator
);
464 bool operator <(const CssmDbAttributeData
& other
) const;
469 // CssmDbRecordAttributeData pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_DATA
471 class CssmDbRecordAttributeData
: public PodWrapper
<CssmDbRecordAttributeData
, CSSM_DB_RECORD_ATTRIBUTE_DATA
>
474 CssmDbRecordAttributeData()
475 { clearPod(); DataRecordType
= CSSM_DL_DB_RECORD_ANY
; }
477 CSSM_DB_RECORDTYPE
recordType() const { return DataRecordType
; }
478 void recordType(CSSM_DB_RECORDTYPE recordType
) { DataRecordType
= recordType
; }
480 uint32
semanticInformation() const { return SemanticInformation
; }
481 void semanticInformation(uint32 semanticInformation
) { SemanticInformation
= semanticInformation
; }
483 uint32
size() const { return NumberOfAttributes
; }
484 CssmDbAttributeData
*&attributes()
485 { return CssmDbAttributeData::overlayVar(AttributeData
); }
486 CssmDbAttributeData
*attributes() const
487 { return CssmDbAttributeData::overlay(AttributeData
); }
489 // Attributes by position
490 CssmDbAttributeData
&at(unsigned int ix
) const {
492 secemergency("CssmDbRecordAttributeData: attempt to index beyond bounds");
495 return attributes()[ix
];
498 CssmDbAttributeData
&operator [] (unsigned int ix
) const { return at(ix
); }
500 void deleteValues(Allocator
&allocator
)
501 { for (uint32 ix
= 0; ix
< size(); ++ix
) at(ix
).deleteValues(allocator
); }
503 CssmDbAttributeData
*find(const CSSM_DB_ATTRIBUTE_INFO
&inInfo
);
505 bool operator <(const CssmDbRecordAttributeData
& other
) const;
510 // CssmAutoDbRecordAttributeData
512 class CssmAutoDbRecordAttributeData
: public CssmDbRecordAttributeData
, public ArrayBuilder
<CssmDbAttributeData
>
515 CssmAutoDbRecordAttributeData(uint32 capacity
= 0,
516 Allocator
&valueAllocator
= Allocator::standard(),
517 Allocator
&dataAllocator
= Allocator::standard()) :
518 CssmDbRecordAttributeData(),
519 ArrayBuilder
<CssmDbAttributeData
>(CssmDbAttributeData::overlayVar(AttributeData
),
520 NumberOfAttributes
, capacity
, dataAllocator
),
521 mValueAllocator(valueAllocator
) {}
522 ~CssmAutoDbRecordAttributeData();
525 void deleteValues() { CssmDbRecordAttributeData::deleteValues(mValueAllocator
); }
528 CssmDbAttributeData
&add() { return ArrayBuilder
<CssmDbAttributeData
>::add(); } // XXX using doesn't work here.
529 CssmDbAttributeData
&add(const CSSM_DB_ATTRIBUTE_INFO
&info
);
530 CssmDbAttributeData
&add(const CSSM_DB_ATTRIBUTE_INFO
&info
, const CssmPolyData
&value
);
532 // Take the attributes from the object, and overlay them onto this one
533 void updateWith(const CssmAutoDbRecordAttributeData
* newValues
);
535 // So clients can pass this as the allocator argument to add()
536 operator Allocator
&() const { return mValueAllocator
; }
538 CssmDbAttributeData
* findAttribute (const CSSM_DB_ATTRIBUTE_INFO
&info
);
540 Allocator
&mValueAllocator
;
542 CssmDbAttributeData
& getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO
&info
);
547 // CssmSelectionPredicate a PodWrapper for CSSM_SELECTION_PREDICATE
549 class CssmSelectionPredicate
: public PodWrapper
<CssmSelectionPredicate
, CSSM_SELECTION_PREDICATE
> {
551 CssmSelectionPredicate() { clearPod(); }
553 CSSM_DB_OPERATOR
dbOperator() const { return DbOperator
; }
554 void dbOperator(CSSM_DB_OPERATOR dbOperator
) { DbOperator
= dbOperator
; }
556 CssmSelectionPredicate(CSSM_DB_OPERATOR inDbOperator
)
557 { dbOperator(inDbOperator
); Attribute
.NumberOfValues
= 0; Attribute
.Value
= NULL
; }
559 CssmDbAttributeData
&attribute() { return CssmDbAttributeData::overlay(Attribute
); }
560 const CssmDbAttributeData
&attribute() const { return CssmDbAttributeData::overlay(Attribute
); }
562 // Set the value of this CssmSelectionPredicate (assuming it was not set before).
563 void set(const CSSM_DB_ATTRIBUTE_INFO
&inInfo
,
564 const CssmPolyData
&inValue
, Allocator
&inAllocator
)
565 { attribute().set(inInfo
, inValue
, inAllocator
); }
567 // Set the value of this CssmSelectionPredicate using another CssmSelectionPredicate's value.
568 void set(const CSSM_SELECTION_PREDICATE
&other
, Allocator
&inAllocator
)
569 { DbOperator
= other
.DbOperator
; attribute().set(other
.Attribute
, inAllocator
); }
571 // Add a value to the list of values for this CssmSelectionPredicate.
572 void add(const CssmPolyData
&inValue
, Allocator
&inAllocator
)
573 { attribute().add(inValue
, inAllocator
); }
575 void deleteValues(Allocator
&inAllocator
) { attribute().deleteValues(inAllocator
); }
578 class CssmQuery
: public PodWrapper
<CssmQuery
, CSSM_QUERY
> {
580 CssmQuery(CSSM_DB_RECORDTYPE type
= CSSM_DL_DB_RECORD_ANY
)
581 { clearPod(); RecordType
= type
; }
583 // copy or assign flat from CSSM_QUERY
584 CssmQuery(const CSSM_QUERY
&q
) { assignPod(q
); }
585 CssmQuery
&operator = (const CSSM_QUERY
&q
) { assignPod(q
); return *this; }
587 // flat copy and change record type
588 CssmQuery(const CssmQuery
&q
, CSSM_DB_RECORDTYPE type
)
589 { *this = q
; RecordType
= type
; }
591 CSSM_DB_RECORDTYPE
recordType() const { return RecordType
; }
592 void recordType(CSSM_DB_RECORDTYPE recordType
) { RecordType
= recordType
; }
594 CSSM_DB_CONJUNCTIVE
conjunctive() const { return Conjunctive
; }
595 void conjunctive(CSSM_DB_CONJUNCTIVE conjunctive
) { Conjunctive
= conjunctive
; }
597 CSSM_QUERY_LIMITS
queryLimits() const { return QueryLimits
; }
598 void queryLimits(CSSM_QUERY_LIMITS queryLimits
) { QueryLimits
= queryLimits
; }
600 CSSM_QUERY_FLAGS
queryFlags() const { return QueryFlags
; }
601 void queryFlags(CSSM_QUERY_FLAGS queryFlags
) { QueryFlags
= queryFlags
; }
603 uint32
size() const { return NumSelectionPredicates
; }
605 CssmSelectionPredicate
*&predicates()
606 { return CssmSelectionPredicate::overlayVar(SelectionPredicate
); }
607 CssmSelectionPredicate
*predicates() const
608 { return CssmSelectionPredicate::overlay(SelectionPredicate
); }
610 CssmSelectionPredicate
&at(uint32 ix
) const {
612 secemergency("CssmDbRecordAttributeData: attempt to index beyond bounds");
615 return predicates()[ix
];
618 CssmSelectionPredicate
&operator[] (uint32 ix
) const { return at(ix
); }
620 void set(uint32 count
, CSSM_SELECTION_PREDICATE
*preds
)
621 { NumSelectionPredicates
= count
; SelectionPredicate
= preds
; }
623 void deleteValues(Allocator
&allocator
)
624 { for (uint32 ix
= 0; ix
< size(); ++ix
) at(ix
).deleteValues(allocator
); }
628 class CssmAutoQuery
: public CssmQuery
, public ArrayBuilder
<CssmSelectionPredicate
> {
630 CssmAutoQuery(const CSSM_QUERY
&query
, Allocator
&allocator
= Allocator::standard());
631 CssmAutoQuery(uint32 capacity
= 0, Allocator
&allocator
= Allocator::standard()) :
632 ArrayBuilder
<CssmSelectionPredicate
>(CssmSelectionPredicate::overlayVar(SelectionPredicate
),
633 NumSelectionPredicates
,
634 capacity
, allocator
) {}
637 void deleteValues() { CssmQuery::deleteValues(allocator()); }
639 CssmSelectionPredicate
&add() { return ArrayBuilder
<CssmSelectionPredicate
>::add(); }
640 CssmSelectionPredicate
&add(CSSM_DB_OPERATOR dbOperator
, const CSSM_DB_ATTRIBUTE_INFO
&info
, const CssmPolyData
&value
);
642 // So clients can pass this as the allocator argument to add()
643 operator Allocator
&() const { return allocator(); }
653 class Impl
: public RefCount
657 Impl(const CSSM_SUBSERVICE_UID
&ssuid
,const char *DbName
,const CSSM_NET_ADDRESS
*DbLocation
) :
658 mCssmSubserviceUid(ssuid
),mDbName(DbName
,DbLocation
) {}
660 ~Impl() {} // Must be public since RefPointer uses it.
663 const CssmSubserviceUid
&ssuid() const { return mCssmSubserviceUid
; }
664 const char *dbName() const { return mDbName
.dbName(); }
665 const CssmNetAddress
*dbLocation() const { return mDbName
.dbLocation(); }
667 // comparison (simple lexicographic)
668 bool operator < (const Impl
&other
) const;
669 bool operator == (const Impl
&other
) const;
671 // Private member variables
672 CssmSubserviceUid mCssmSubserviceUid
;
679 DLDbIdentifier(const CSSM_SUBSERVICE_UID
&ssuid
, const char *DbName
, const CSSM_NET_ADDRESS
*DbLocation
)
680 : mImpl(new Impl(ssuid
, DbName
, DbLocation
)) {}
681 DLDbIdentifier(const char *name
, const Guid
&guid
, uint32 ssid
, uint32 sstype
,
682 const CSSM_NET_ADDRESS
*location
= NULL
)
683 : mImpl(new Impl(CssmSubserviceUid(guid
, NULL
, ssid
, sstype
), name
, location
)) { }
685 DLDbIdentifier(const DLDbIdentifier
& i
) : mImpl(i
.mImpl
) {}
687 // Conversion Operators
688 bool operator !() const { return !mImpl
; }
689 operator bool() const { return mImpl
; }
692 bool operator <(const DLDbIdentifier
&other
) const
693 { return mImpl
&& other
.mImpl
? *mImpl
< *other
.mImpl
: mImpl
.get() < other
.mImpl
.get(); }
694 bool operator ==(const DLDbIdentifier
&other
) const
695 { return mImpl
&& other
.mImpl
? *mImpl
== *other
.mImpl
: mImpl
.get() == other
.mImpl
.get(); }
696 DLDbIdentifier
&operator =(const DLDbIdentifier
&other
)
697 { mImpl
= other
.mImpl
; return *this; }
700 const CssmSubserviceUid
&ssuid() const { return mImpl
->ssuid(); }
701 const char *dbName() const { return mImpl
->dbName(); }
702 const CssmNetAddress
*dbLocation() const { return mImpl
->dbLocation(); }
703 bool IsImplEmpty() const {return mImpl
== NULL
;}
705 RefPointer
<Impl
> mImpl
;
708 // Wrappers for index-related CSSM objects.
710 class CssmDbIndexInfo
: public PodWrapper
<CssmDbIndexInfo
, CSSM_DB_INDEX_INFO
>
713 CssmDbIndexInfo(const CSSM_DB_INDEX_INFO
&attr
)
714 { (CSSM_DB_INDEX_INFO
&)*this = attr
; }
716 CSSM_DB_INDEX_TYPE
indexType() const { return IndexType
; }
717 void indexType(CSSM_DB_INDEX_TYPE indexType
) { IndexType
= indexType
; }
719 CSSM_DB_INDEXED_DATA_LOCATION
dataLocation() const { return IndexedDataLocation
; }
720 void dataLocation(CSSM_DB_INDEXED_DATA_LOCATION dataLocation
)
722 IndexedDataLocation
= dataLocation
;
725 const CssmDbAttributeInfo
&attributeInfo() const
727 return CssmDbAttributeInfo::overlay(Info
);
732 namespace DataWalkers
{
736 // DLDbIdentifiers don't walk directly because they have Impl structure and use strings.
737 // Happily, they are easily transcribed into a walkable form.
739 struct DLDbFlatIdentifier
{
740 CssmSubserviceUid
*uid
; // module reference
741 char *name
; // string name
742 CssmNetAddress
*address
; // optional network address
744 DLDbFlatIdentifier(const DLDbIdentifier
&ident
) :
745 uid(const_cast<CssmSubserviceUid
*>(&ident
.ssuid())),
746 name(const_cast<char *>(ident
.dbName())),
747 address(const_cast<CssmNetAddress
*>(ident
.dbLocation()))
750 operator DLDbIdentifier () {
751 DLDbIdentifier
db(*uid
, name
, address
);
756 template<class Action
>
757 DLDbFlatIdentifier
*walk(Action
&operate
, DLDbFlatIdentifier
* &ident
)
761 walk(operate
, ident
->uid
);
762 walk(operate
, ident
->name
);
764 walk(operate
, ident
->address
);
770 // Walkers for the byzantine data structures of the DL universe.
771 // Geez, what WERE they smoking when they invented this?
775 template<class Action
>
776 void enumerate(Action
&operate
, CssmDbAttributeInfo
&info
)
778 switch (info
.nameFormat()) {
779 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING
:
780 walk(operate
, info
.Label
.AttributeName
);
782 case CSSM_DB_ATTRIBUTE_NAME_AS_OID
:
783 walk(operate
, info
.Label
.AttributeOID
);
790 template <class Action
>
791 void walk(Action
&operate
, CssmDbAttributeInfo
&info
)
794 enumerate(operate
, info
);
797 template <class Action
>
798 CssmDbAttributeInfo
*walk(Action
&operate
, CssmDbAttributeInfo
* &info
)
801 enumerate(operate
, *info
);
805 // DbRecordAttributeInfo
806 template <class Action
>
807 void walk(Action
&operate
, CssmDbRecordAttributeInfo
&info
)
810 enumerateArray(operate
, info
, &CssmDbRecordAttributeInfo::attributes
);
813 template <class Action
>
814 CssmDbRecordAttributeInfo
*walk(Action
&operate
, CssmDbRecordAttributeInfo
* &info
)
817 enumerateArray(operate
, *info
, &CssmDbRecordAttributeInfo::attributes
);
821 // DbAttributeData (Info + value vector)
822 template <class Action
>
823 void walk(Action
&operate
, CssmDbAttributeData
&data
)
826 walk(operate
, data
.info());
827 enumerateArray(operate
, data
, &CssmDbAttributeData::values
);
830 template <class Action
>
831 CssmDbAttributeData
*walk(Action
&operate
, CssmDbAttributeData
* &data
)
834 walk(operate
, data
->info());
835 enumerateArray(operate
, *data
, &CssmDbAttributeData::values
);
839 // DbRecordAttributeData (array of ...datas)
840 template <class Action
>
841 void walk(Action
&operate
, CssmDbRecordAttributeData
&data
)
844 enumerateArray(operate
, data
, &CssmDbRecordAttributeData::attributes
);
847 template <class Action
>
848 CssmDbRecordAttributeData
*walk(Action
&operate
, CssmDbRecordAttributeData
* &data
)
851 enumerateArray(operate
, *data
, &CssmDbRecordAttributeData::attributes
);
855 // SelectionPredicates
856 template <class Action
>
857 CssmSelectionPredicate
*walk(Action
&operate
, CssmSelectionPredicate
* &predicate
)
860 walk(operate
, predicate
->attribute());
864 template<class Action
>
865 void walk(Action
&operate
, CssmSelectionPredicate
&predicate
)
868 walk(operate
, predicate
.attribute());
872 template <class Action
>
873 void walk(Action
&operate
, CssmQuery
&query
)
876 enumerateArray(operate
, query
, &CssmQuery::predicates
);
879 template <class Action
>
880 CssmQuery
*walk(Action
&operate
, CssmQuery
* &query
)
883 enumerateArray(operate
, *query
, &CssmQuery::predicates
);
887 template <class Action
>
888 CSSM_QUERY
*walk(Action
&operate
, CSSM_QUERY
* &query
)
890 return walk(operate
, CssmQuery::overlayVar(query
));
894 } // end namespace DataWalkers
895 } // end namespace Security
898 #endif // _H_CDSA_UTILITIES_CSSMDB