]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | // cssmdb.h | |
26 | // | |
27 | // classes for the DL related data structures | |
28 | // | |
29 | ||
30 | #ifndef _H_CDSA_UTILITIES_CSSMDB | |
31 | #define _H_CDSA_UTILITIES_CSSMDB | |
32 | ||
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/walkers.h> | |
37 | #include <security_cdsa_utilities/cssmdbname.h> | |
38 | ||
39 | ||
40 | namespace Security { | |
41 | ||
42 | ||
43 | // | |
44 | // Template class to build and maintain external arrays. | |
45 | // Feel free to add and vector<> member functions and behaviours as needed. | |
46 | // | |
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. | |
52 | // | |
53 | template <class _Tp> | |
54 | class ArrayBuilder { | |
55 | public: | |
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; | |
65 | ||
66 | typedef reverse_iterator<const_iterator> const_reverse_iterator; | |
67 | typedef reverse_iterator<iterator> reverse_iterator; | |
68 | ||
69 | protected: | |
70 | void insert_aux(iterator __position, const _Tp& __x); | |
71 | void insert_aux(iterator __position); | |
72 | ||
73 | public: | |
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]; } | |
78 | ||
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()); } | |
87 | ||
88 | // Must be defined in base class. | |
89 | //size_type size() const | |
90 | //{ return mSize; } | |
91 | size_type max_size() const | |
92 | { return size_type(-1) / sizeof(_Tp); } | |
93 | size_type capacity() const | |
94 | { return mCapacity; } | |
95 | bool empty() const | |
96 | { return begin() == end(); } | |
97 | ||
98 | ArrayBuilder(pointer &array, size_type &size, size_type capacity = 0, Allocator &allocator = Allocator::standard()) : | |
99 | mArray(array), mSize(size), mCapacity(capacity), mAllocator(allocator) | |
100 | { | |
101 | #if BUG_GCC | |
102 | mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity)); | |
103 | #else | |
104 | mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity)); | |
105 | //mArray = mAllocator.alloc(mCapacity); | |
106 | #endif | |
107 | memset(mArray, 0, sizeof(value_type) * mCapacity); | |
108 | mSize = 0; | |
109 | } | |
110 | ~ArrayBuilder() { mAllocator.free(mArray); } | |
111 | ||
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); } | |
116 | ||
117 | void reserve(size_type newCapacity) | |
118 | { | |
119 | if (newCapacity > mCapacity) | |
120 | { | |
121 | #if BUG_GCC | |
122 | mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity)); | |
123 | #else | |
124 | mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity)); | |
125 | //mArray = mAllocator.realloc<value_type>(mArray, newCapacity)); | |
126 | #endif | |
127 | memset(&mArray[mCapacity], 0, sizeof(value_type) * (newCapacity - mCapacity)); | |
128 | mCapacity = newCapacity; | |
129 | } | |
130 | } | |
131 | ||
132 | // XXX Replace by push_back and insert. | |
133 | reference add() | |
134 | { | |
135 | if (mSize >= mCapacity) | |
136 | reserve(max(mSize + 1, mCapacity ? 2 * mCapacity : 1)); | |
137 | ||
138 | return mArray[mSize++]; | |
139 | } | |
140 | ||
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; } | |
144 | ||
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); } | |
150 | protected: | |
151 | Allocator &allocator() const { return mAllocator; } | |
152 | ||
153 | private: | |
154 | ||
155 | pointer &mArray; | |
156 | size_type &mSize; | |
157 | size_type mCapacity; | |
158 | Allocator &mAllocator; | |
159 | }; | |
160 | ||
161 | ||
162 | // | |
163 | // A CSSM_DL_DB_LIST wrapper. | |
164 | // Note that there is a DLDBList class elsewhere that is quite | |
165 | // unrelated to this structure. | |
166 | // | |
167 | class CssmDlDbHandle : public PodWrapper<CssmDlDbHandle, CSSM_DL_DB_HANDLE> { | |
168 | public: | |
169 | CssmDlDbHandle() { clearPod(); } | |
170 | CssmDlDbHandle(CSSM_DL_HANDLE dl, CSSM_DB_HANDLE db) { DLHandle = dl; DBHandle = db; } | |
171 | ||
172 | CSSM_DL_HANDLE dl() const { return DLHandle; } | |
173 | CSSM_DB_HANDLE db() const { return DBHandle; } | |
174 | ||
175 | operator bool() const { return DLHandle && DBHandle; } | |
176 | }; | |
177 | ||
178 | inline bool operator < (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2) | |
179 | { | |
180 | return h1.DLHandle < h2.DLHandle | |
181 | || (h1.DLHandle == h2.DLHandle && h1.DBHandle < h2.DBHandle); | |
182 | } | |
183 | ||
184 | inline bool operator == (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2) | |
185 | { | |
186 | return h1.DLHandle == h2.DLHandle && h1.DBHandle == h2.DBHandle; | |
187 | } | |
188 | ||
189 | inline bool operator != (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2) | |
190 | { | |
191 | return h1.DLHandle != h2.DLHandle || h1.DBHandle != h2.DBHandle; | |
192 | } | |
193 | ||
194 | ||
195 | class CssmDlDbList : public PodWrapper<CssmDlDbList, CSSM_DL_DB_LIST> { | |
196 | public: | |
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); } | |
201 | ||
202 | CssmDlDbHandle &operator [] (uint32 ix) const | |
203 | { assert(ix < count()); return CssmDlDbHandle::overlay(DLDBHandle[ix]); } | |
204 | ||
205 | void setDlDbList(uint32 n, CSSM_DL_DB_HANDLE *list) | |
206 | { count() = n; handles() = CssmDlDbHandle::overlay(list); } | |
207 | }; | |
208 | ||
209 | ||
210 | // | |
211 | // CssmDLPolyData | |
212 | // | |
213 | class CssmDLPolyData | |
214 | { | |
215 | public: | |
216 | CssmDLPolyData(const CSSM_DATA &data, CSSM_DB_ATTRIBUTE_FORMAT format) | |
427c49bc A |
217 | : mData(CssmData::overlay(data)) |
218 | #ifndef NDEBUG | |
219 | , mFormat(format) | |
220 | #endif | |
221 | {} | |
b1ab9ed8 A |
222 | |
223 | // @@@ Don't use assert, but throw an exception. | |
224 | // @@@ Do a size check on mData as well. | |
225 | ||
226 | // @@@ This method is dangerous since the returned string is not guaranteed to be zero terminated. | |
227 | operator const char *() const | |
228 | { | |
229 | assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_STRING | |
230 | || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE); | |
231 | return reinterpret_cast<const char *>(mData.Data); | |
232 | } | |
233 | operator bool() const | |
234 | { | |
235 | assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32 || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32); | |
236 | return *reinterpret_cast<uint32 *>(mData.Data); | |
237 | } | |
238 | operator uint32() const | |
239 | { | |
240 | assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32); | |
241 | return *reinterpret_cast<uint32 *>(mData.Data); | |
242 | } | |
243 | operator const uint32 *() const | |
244 | { | |
245 | assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32); | |
246 | return reinterpret_cast<const uint32 *>(mData.Data); | |
247 | } | |
248 | operator sint32() const | |
249 | { | |
250 | assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32); | |
251 | return *reinterpret_cast<sint32 *>(mData.Data); | |
252 | } | |
253 | operator double() const | |
254 | { | |
255 | assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_REAL); | |
256 | return *reinterpret_cast<double *>(mData.Data); | |
257 | } | |
258 | operator CSSM_DATE () const; | |
259 | operator Guid () const; | |
260 | operator const CssmData &() const | |
261 | { | |
262 | return mData; | |
263 | } | |
264 | ||
265 | private: | |
266 | const CssmData &mData; | |
427c49bc | 267 | #ifndef NDEBUG |
b1ab9ed8 | 268 | CSSM_DB_ATTRIBUTE_FORMAT mFormat; |
427c49bc | 269 | #endif |
b1ab9ed8 A |
270 | }; |
271 | ||
272 | ||
273 | // | |
274 | // CssmDbAttributeInfo pod wrapper for CSSM_DB_ATTRIBUTE_INFO | |
275 | // | |
276 | class CssmDbAttributeInfo : public PodWrapper<CssmDbAttributeInfo, CSSM_DB_ATTRIBUTE_INFO> | |
277 | { | |
278 | public: | |
279 | CssmDbAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &attr) | |
280 | { assignPod(attr); } | |
281 | ||
282 | CssmDbAttributeInfo(const char *name, | |
283 | CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX); | |
284 | CssmDbAttributeInfo(const CSSM_OID &oid, | |
285 | CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX); | |
286 | CssmDbAttributeInfo(uint32 id, | |
287 | CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX); | |
288 | ||
289 | CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat() const { return AttributeNameFormat; } | |
290 | void nameFormat(CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat) { AttributeNameFormat = nameFormat; } | |
291 | ||
292 | CSSM_DB_ATTRIBUTE_FORMAT format() const { return AttributeFormat; } | |
293 | void format(CSSM_DB_ATTRIBUTE_FORMAT format) { AttributeFormat = format; } | |
294 | ||
295 | const char *stringName() const | |
296 | { | |
297 | assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_STRING); | |
298 | return Label.AttributeName; | |
299 | } | |
300 | const CssmOid &oidName() const | |
301 | { | |
302 | assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_OID); | |
303 | return CssmOid::overlay(Label.AttributeOID); | |
304 | } | |
305 | uint32 intName() const | |
306 | { | |
307 | assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER); | |
308 | return Label.AttributeID; | |
309 | } | |
310 | ||
311 | operator const char *() const { return stringName(); } | |
312 | operator const CssmOid &() const { return oidName(); } | |
313 | operator uint32() const { return intName(); } | |
314 | ||
315 | bool operator <(const CssmDbAttributeInfo& other) const; | |
316 | bool operator ==(const CssmDbAttributeInfo& other) const; | |
317 | bool operator !=(const CssmDbAttributeInfo& other) const | |
318 | { return !(*this == other); } | |
319 | }; | |
320 | ||
321 | // | |
322 | // CssmDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO | |
323 | // | |
324 | class CssmDbRecordAttributeInfo : public PodWrapper<CssmDbRecordAttributeInfo, CSSM_DB_RECORD_ATTRIBUTE_INFO> | |
325 | { | |
326 | public: | |
327 | CssmDbRecordAttributeInfo() | |
328 | { DataRecordType = CSSM_DL_DB_RECORD_ANY; } | |
329 | ||
330 | CssmDbRecordAttributeInfo(CSSM_DB_RECORDTYPE recordType, uint32 numberOfAttributes, | |
331 | CSSM_DB_ATTRIBUTE_INFO_PTR attributeInfo) | |
332 | { | |
333 | DataRecordType = recordType; | |
334 | NumberOfAttributes = numberOfAttributes; | |
335 | AttributeInfo = attributeInfo; | |
336 | } | |
337 | ||
338 | CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; } | |
339 | void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; } | |
340 | ||
341 | uint32 size() const { return NumberOfAttributes; } | |
342 | ||
343 | // attribute access | |
344 | CssmDbAttributeInfo *&attributes() | |
345 | { return CssmDbAttributeInfo::overlayVar(AttributeInfo); } | |
346 | CssmDbAttributeInfo *attributes() const | |
347 | { return CssmDbAttributeInfo::overlay(AttributeInfo); } | |
348 | CssmDbAttributeInfo &at(uint32 ix) const | |
349 | { assert(ix < size()); return attributes()[ix]; } | |
350 | ||
351 | CssmDbAttributeInfo &operator [] (uint32 ix) const { return at(ix); } | |
352 | }; | |
353 | ||
354 | // | |
355 | // CssmAutoDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO | |
356 | // | |
357 | class CssmAutoDbRecordAttributeInfo: public CssmDbRecordAttributeInfo, public ArrayBuilder<CssmDbAttributeInfo> | |
358 | { | |
359 | public: | |
360 | CssmAutoDbRecordAttributeInfo(uint32 capacity = 0, Allocator &allocator = Allocator::standard()) : | |
361 | CssmDbRecordAttributeInfo(), | |
362 | ArrayBuilder<CssmDbAttributeInfo>(CssmDbAttributeInfo::overlayVar(AttributeInfo), | |
363 | NumberOfAttributes, capacity, allocator) {} | |
364 | }; | |
365 | ||
366 | ||
367 | // | |
368 | // CssmDbAttributeData pod wrapper for CSSM_DB_ATTRIBUTE_DATA | |
369 | // | |
370 | class CssmDbAttributeData : public PodWrapper<CssmDbAttributeData, CSSM_DB_ATTRIBUTE_DATA> | |
371 | { | |
372 | public: | |
373 | CssmDbAttributeData() { NumberOfValues = 0; Value = NULL; } | |
374 | CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_DATA &attr) | |
375 | { assignPod(attr); } | |
376 | CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_INFO &info) | |
377 | { Info = info; NumberOfValues = 0; Value = NULL; } | |
378 | ||
379 | CssmDbAttributeInfo &info() { return CssmDbAttributeInfo::overlay(Info); } | |
380 | const CssmDbAttributeInfo &info() const { return CssmDbAttributeInfo::overlay(Info); } | |
381 | void info (const CSSM_DB_ATTRIBUTE_INFO &inInfo) { Info = inInfo; } | |
382 | ||
383 | CSSM_DB_ATTRIBUTE_FORMAT format() const { return info().format(); } | |
384 | void format(CSSM_DB_ATTRIBUTE_FORMAT f) { info().format(f); } | |
385 | ||
386 | uint32 size() const { return NumberOfValues; } | |
387 | CssmData *&values() { return CssmData::overlayVar(Value); } | |
388 | CssmData *values() const { return CssmData::overlay(Value); } | |
389 | ||
390 | CssmData &at(unsigned int ix) const | |
391 | { | |
392 | if (ix >= size()) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE); | |
393 | return values()[ix]; | |
394 | } | |
395 | ||
396 | CssmData &operator [] (unsigned int ix) const { return at(ix); } | |
397 | ||
398 | template <class T> | |
399 | T at(unsigned int ix) const { return CssmDLPolyData(Value[ix], format()); } | |
400 | ||
401 | // this is intentionally unspecified since it could lead to bugs; the | |
402 | // data is not guaranteed to be NULL-terminated | |
403 | // operator const char *() const; | |
404 | ||
405 | operator string() const; | |
406 | operator const Guid &() const; | |
407 | operator bool() const; | |
408 | operator uint32() const; | |
409 | operator const uint32 *() const; | |
410 | operator sint32() const; | |
411 | operator double() const; | |
412 | operator const CssmData &() const; | |
413 | ||
414 | // set values without allocation (caller owns the data contents) | |
415 | void set(CssmData &data) { set(1, &data); } | |
416 | void set(uint32 count, CssmData *datas) { NumberOfValues = count; Value = datas; } | |
417 | ||
418 | // Set the value of this Attr (assuming it was not set before). | |
419 | void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, const CssmPolyData &inValue, | |
420 | Allocator &inAllocator); | |
421 | ||
422 | // copy (just) the return-value part from another AttributeData to this one | |
423 | void copyValues(const CssmDbAttributeData &source, Allocator &alloc); | |
424 | ||
425 | // Set the value of this Attr (which must be unset so far) | |
426 | void set(const CSSM_DB_ATTRIBUTE_DATA &source, Allocator &alloc) | |
427 | { | |
428 | info(source.Info); | |
429 | copyValues(source, alloc); | |
430 | } | |
431 | ||
432 | // Add a value to this attribute. | |
433 | void add(const CssmPolyData &inValue, Allocator &inAllocator); | |
434 | ||
435 | void add(const char *value, Allocator &alloc) | |
436 | { format(CSSM_DB_ATTRIBUTE_FORMAT_STRING); add(CssmPolyData(value), alloc); } | |
437 | ||
438 | void add(const std::string &value, Allocator &alloc) | |
439 | { format(CSSM_DB_ATTRIBUTE_FORMAT_STRING); add(CssmPolyData(value), alloc); } | |
440 | ||
441 | void add(uint32 value, Allocator &alloc) | |
442 | { format(CSSM_DB_ATTRIBUTE_FORMAT_UINT32); add(CssmPolyData(value), alloc); } | |
443 | ||
444 | void add(sint32 value, Allocator &alloc) | |
445 | { format(CSSM_DB_ATTRIBUTE_FORMAT_SINT32); add(CssmPolyData(value), alloc); } | |
446 | ||
447 | void add(const CssmData &value, Allocator &alloc) | |
448 | { format(CSSM_DB_ATTRIBUTE_FORMAT_BLOB); add(CssmPolyData(value), alloc); } | |
449 | ||
450 | void add(const CssmDbAttributeData &src, Allocator &inAllocator); | |
451 | ||
452 | // delete specific values if they are present in this attribute data | |
453 | bool deleteValue(const CssmData &src, Allocator &inAllocator); | |
454 | void deleteValues(const CssmDbAttributeData &src, Allocator &inAllocator); | |
455 | ||
456 | void deleteValues(Allocator &inAllocator); | |
457 | ||
458 | bool operator <(const CssmDbAttributeData& other) const; | |
459 | }; | |
460 | ||
461 | ||
462 | // | |
463 | // CssmDbRecordAttributeData pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_DATA | |
464 | // | |
465 | class CssmDbRecordAttributeData : public PodWrapper<CssmDbRecordAttributeData, CSSM_DB_RECORD_ATTRIBUTE_DATA> | |
466 | { | |
467 | public: | |
468 | CssmDbRecordAttributeData() | |
469 | { clearPod(); DataRecordType = CSSM_DL_DB_RECORD_ANY; } | |
470 | ||
471 | CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; } | |
472 | void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; } | |
473 | ||
474 | uint32 semanticInformation() const { return SemanticInformation; } | |
475 | void semanticInformation(uint32 semanticInformation) { SemanticInformation = semanticInformation; } | |
476 | ||
477 | uint32 size() const { return NumberOfAttributes; } | |
478 | CssmDbAttributeData *&attributes() | |
479 | { return CssmDbAttributeData::overlayVar(AttributeData); } | |
480 | CssmDbAttributeData *attributes() const | |
481 | { return CssmDbAttributeData::overlay(AttributeData); } | |
482 | ||
483 | // Attributes by position | |
484 | CssmDbAttributeData &at(unsigned int ix) const | |
485 | { assert(ix < size()); return attributes()[ix]; } | |
486 | ||
487 | CssmDbAttributeData &operator [] (unsigned int ix) const { return at(ix); } | |
488 | ||
489 | void deleteValues(Allocator &allocator) | |
490 | { for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); } | |
491 | ||
492 | CssmDbAttributeData *find(const CSSM_DB_ATTRIBUTE_INFO &inInfo); | |
493 | ||
494 | bool operator <(const CssmDbRecordAttributeData& other) const; | |
495 | }; | |
496 | ||
497 | ||
498 | // | |
499 | // CssmAutoDbRecordAttributeData | |
500 | // | |
501 | class CssmAutoDbRecordAttributeData : public CssmDbRecordAttributeData, public ArrayBuilder<CssmDbAttributeData> | |
502 | { | |
503 | public: | |
504 | CssmAutoDbRecordAttributeData(uint32 capacity = 0, | |
505 | Allocator &valueAllocator = Allocator::standard(), | |
506 | Allocator &dataAllocator = Allocator::standard()) : | |
507 | CssmDbRecordAttributeData(), | |
508 | ArrayBuilder<CssmDbAttributeData>(CssmDbAttributeData::overlayVar(AttributeData), | |
509 | NumberOfAttributes, capacity, dataAllocator), | |
510 | mValueAllocator(valueAllocator) {} | |
511 | ~CssmAutoDbRecordAttributeData(); | |
512 | ||
513 | void clear(); | |
514 | void deleteValues() { CssmDbRecordAttributeData::deleteValues(mValueAllocator); } | |
515 | void invalidate(); | |
516 | ||
517 | CssmDbAttributeData &add() { return ArrayBuilder<CssmDbAttributeData>::add(); } // XXX using doesn't work here. | |
518 | CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info); | |
519 | CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value); | |
520 | ||
521 | // So clients can pass this as the allocator argument to add() | |
522 | operator Allocator &() const { return mValueAllocator; } | |
523 | private: | |
524 | Allocator &mValueAllocator; | |
525 | ||
526 | CssmDbAttributeData* findAttribute (const CSSM_DB_ATTRIBUTE_INFO &info); | |
527 | CssmDbAttributeData& getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO &info); | |
528 | }; | |
529 | ||
530 | ||
531 | // | |
532 | // CssmSelectionPredicate a PodWrapper for CSSM_SELECTION_PREDICATE | |
533 | // | |
534 | class CssmSelectionPredicate : public PodWrapper<CssmSelectionPredicate, CSSM_SELECTION_PREDICATE> { | |
535 | public: | |
536 | CssmSelectionPredicate() { clearPod(); } | |
537 | ||
538 | CSSM_DB_OPERATOR dbOperator() const { return DbOperator; } | |
539 | void dbOperator(CSSM_DB_OPERATOR dbOperator) { DbOperator = dbOperator; } | |
540 | ||
541 | CssmSelectionPredicate(CSSM_DB_OPERATOR inDbOperator) | |
542 | { dbOperator(inDbOperator); Attribute.NumberOfValues = 0; Attribute.Value = NULL; } | |
543 | ||
544 | CssmDbAttributeData &attribute() { return CssmDbAttributeData::overlay(Attribute); } | |
545 | const CssmDbAttributeData &attribute() const { return CssmDbAttributeData::overlay(Attribute); } | |
546 | ||
547 | // Set the value of this CssmSelectionPredicate (assuming it was not set before). | |
548 | void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, | |
549 | const CssmPolyData &inValue, Allocator &inAllocator) | |
550 | { attribute().set(inInfo, inValue, inAllocator); } | |
551 | ||
552 | // Set the value of this CssmSelectionPredicate using another CssmSelectionPredicate's value. | |
553 | void set(const CSSM_SELECTION_PREDICATE &other, Allocator &inAllocator) | |
554 | { DbOperator = other.DbOperator; attribute().set(other.Attribute, inAllocator); } | |
555 | ||
556 | // Add a value to the list of values for this CssmSelectionPredicate. | |
557 | void add(const CssmPolyData &inValue, Allocator &inAllocator) | |
558 | { attribute().add(inValue, inAllocator); } | |
559 | ||
560 | void deleteValues(Allocator &inAllocator) { attribute().deleteValues(inAllocator); } | |
561 | }; | |
562 | ||
563 | class CssmQuery : public PodWrapper<CssmQuery, CSSM_QUERY> { | |
564 | public: | |
565 | CssmQuery(CSSM_DB_RECORDTYPE type = CSSM_DL_DB_RECORD_ANY) | |
566 | { clearPod(); RecordType = type; } | |
567 | ||
568 | // copy or assign flat from CSSM_QUERY | |
569 | CssmQuery(const CSSM_QUERY &q) { assignPod(q); } | |
570 | CssmQuery &operator = (const CSSM_QUERY &q) { assignPod(q); return *this; } | |
571 | ||
572 | // flat copy and change record type | |
573 | CssmQuery(const CssmQuery &q, CSSM_DB_RECORDTYPE type) | |
574 | { *this = q; RecordType = type; } | |
575 | ||
576 | CSSM_DB_RECORDTYPE recordType() const { return RecordType; } | |
577 | void recordType(CSSM_DB_RECORDTYPE recordType) { RecordType = recordType; } | |
578 | ||
579 | CSSM_DB_CONJUNCTIVE conjunctive() const { return Conjunctive; } | |
580 | void conjunctive(CSSM_DB_CONJUNCTIVE conjunctive) { Conjunctive = conjunctive; } | |
581 | ||
582 | CSSM_QUERY_LIMITS queryLimits() const { return QueryLimits; } | |
583 | void queryLimits(CSSM_QUERY_LIMITS queryLimits) { QueryLimits = queryLimits; } | |
584 | ||
585 | CSSM_QUERY_FLAGS queryFlags() const { return QueryFlags; } | |
586 | void queryFlags(CSSM_QUERY_FLAGS queryFlags) { QueryFlags = queryFlags; } | |
587 | ||
588 | uint32 size() const { return NumSelectionPredicates; } | |
589 | ||
590 | CssmSelectionPredicate *&predicates() | |
591 | { return CssmSelectionPredicate::overlayVar(SelectionPredicate); } | |
592 | CssmSelectionPredicate *predicates() const | |
593 | { return CssmSelectionPredicate::overlay(SelectionPredicate); } | |
594 | ||
595 | CssmSelectionPredicate &at(uint32 ix) const | |
596 | { assert(ix < size()); return predicates()[ix]; } | |
597 | ||
598 | CssmSelectionPredicate &operator[] (uint32 ix) const { return at(ix); } | |
599 | ||
600 | void set(uint32 count, CSSM_SELECTION_PREDICATE *preds) | |
601 | { NumSelectionPredicates = count; SelectionPredicate = preds; } | |
602 | ||
603 | void deleteValues(Allocator &allocator) | |
604 | { for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); } | |
605 | }; | |
606 | ||
607 | ||
608 | class CssmAutoQuery : public CssmQuery, public ArrayBuilder<CssmSelectionPredicate> { | |
609 | public: | |
610 | CssmAutoQuery(const CSSM_QUERY &query, Allocator &allocator = Allocator::standard()); | |
611 | CssmAutoQuery(uint32 capacity = 0, Allocator &allocator = Allocator::standard()) : | |
612 | ArrayBuilder<CssmSelectionPredicate>(CssmSelectionPredicate::overlayVar(SelectionPredicate), | |
613 | NumSelectionPredicates, | |
614 | capacity, allocator) {} | |
615 | ~CssmAutoQuery(); | |
616 | void clear(); | |
617 | void deleteValues() { CssmQuery::deleteValues(allocator()); } | |
618 | ||
619 | CssmSelectionPredicate &add() { return ArrayBuilder<CssmSelectionPredicate>::add(); } | |
620 | CssmSelectionPredicate &add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value); | |
621 | ||
622 | // So clients can pass this as the allocator argument to add() | |
623 | operator Allocator &() const { return allocator(); } | |
624 | }; | |
625 | ||
626 | ||
627 | // | |
628 | // DLDbIdentifier | |
629 | // | |
630 | class DLDbIdentifier | |
631 | { | |
632 | protected: | |
633 | class Impl : public RefCount | |
634 | { | |
635 | NOCOPY(Impl) | |
636 | public: | |
637 | Impl(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation) : | |
638 | mCssmSubserviceUid(ssuid),mDbName(DbName,DbLocation) {} | |
639 | ||
640 | ~Impl() {} // Must be public since RefPointer uses it. | |
641 | ||
642 | // Accessors | |
643 | const CssmSubserviceUid &ssuid() const { return mCssmSubserviceUid; } | |
644 | const char *dbName() const { return mDbName.dbName(); } | |
645 | const CssmNetAddress *dbLocation() const { return mDbName.dbLocation(); } | |
646 | ||
647 | // comparison (simple lexicographic) | |
648 | bool operator < (const Impl &other) const; | |
649 | bool operator == (const Impl &other) const; | |
650 | private: | |
651 | // Private member variables | |
652 | CssmSubserviceUid mCssmSubserviceUid; | |
653 | DbName mDbName; | |
654 | }; | |
655 | ||
656 | public: | |
657 | // Constructors | |
658 | DLDbIdentifier() {} | |
659 | DLDbIdentifier(const CSSM_SUBSERVICE_UID &ssuid, const char *DbName, const CSSM_NET_ADDRESS *DbLocation) | |
660 | : mImpl(new Impl(ssuid, DbName, DbLocation)) {} | |
661 | DLDbIdentifier(const char *name, const Guid &guid, uint32 ssid, uint32 sstype, | |
662 | const CSSM_NET_ADDRESS *location = NULL) | |
663 | : mImpl(new Impl(CssmSubserviceUid(guid, NULL, ssid, sstype), name, location)) { } | |
664 | ||
665 | // Conversion Operators | |
666 | bool operator !() const { return !mImpl; } | |
667 | operator bool() const { return mImpl; } | |
668 | ||
669 | // Operators | |
670 | bool operator <(const DLDbIdentifier &other) const | |
671 | { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl.get() < other.mImpl.get(); } | |
672 | bool operator ==(const DLDbIdentifier &other) const | |
673 | { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl.get() == other.mImpl.get(); } | |
674 | DLDbIdentifier &operator =(const DLDbIdentifier &other) | |
675 | { mImpl = other.mImpl; return *this; } | |
676 | ||
677 | // Accessors | |
678 | const CssmSubserviceUid &ssuid() const { return mImpl->ssuid(); } | |
679 | const char *dbName() const { return mImpl->dbName(); } | |
680 | const CssmNetAddress *dbLocation() const { return mImpl->dbLocation(); } | |
c38e3ce9 A |
681 | bool IsImplEmpty() const {return mImpl == NULL;} |
682 | ||
b1ab9ed8 A |
683 | RefPointer<Impl> mImpl; |
684 | }; | |
685 | ||
686 | // Wrappers for index-related CSSM objects. | |
687 | ||
688 | class CssmDbIndexInfo : public PodWrapper<CssmDbIndexInfo, CSSM_DB_INDEX_INFO> | |
689 | { | |
690 | public: | |
691 | CssmDbIndexInfo(const CSSM_DB_INDEX_INFO &attr) | |
692 | { (CSSM_DB_INDEX_INFO &)*this = attr; } | |
693 | ||
694 | CSSM_DB_INDEX_TYPE indexType() const { return IndexType; } | |
695 | void indexType(CSSM_DB_INDEX_TYPE indexType) { IndexType = indexType; } | |
696 | ||
697 | CSSM_DB_INDEXED_DATA_LOCATION dataLocation() const { return IndexedDataLocation; } | |
698 | void dataLocation(CSSM_DB_INDEXED_DATA_LOCATION dataLocation) | |
699 | { | |
700 | IndexedDataLocation = dataLocation; | |
701 | } | |
702 | ||
703 | const CssmDbAttributeInfo &attributeInfo() const | |
704 | { | |
705 | return CssmDbAttributeInfo::overlay(Info); | |
706 | } | |
707 | }; | |
708 | ||
709 | ||
710 | namespace DataWalkers { | |
711 | ||
712 | ||
713 | // | |
714 | // DLDbIdentifiers don't walk directly because they have Impl structure and use strings. | |
715 | // Happily, they are easily transcribed into a walkable form. | |
716 | // | |
717 | struct DLDbFlatIdentifier { | |
718 | CssmSubserviceUid *uid; // module reference | |
719 | char *name; // string name | |
720 | CssmNetAddress *address; // optional network address | |
721 | ||
722 | DLDbFlatIdentifier(const DLDbIdentifier &ident) : | |
723 | uid(const_cast<CssmSubserviceUid *>(&ident.ssuid())), | |
724 | name(const_cast<char *>(ident.dbName())), | |
725 | address(const_cast<CssmNetAddress *>(ident.dbLocation())) | |
726 | { } | |
727 | ||
728 | operator DLDbIdentifier () { return DLDbIdentifier(*uid, name, address); } | |
729 | }; | |
730 | ||
731 | template<class Action> | |
732 | DLDbFlatIdentifier *walk(Action &operate, DLDbFlatIdentifier * &ident) | |
733 | { | |
734 | operate(ident); | |
735 | if (ident->uid) | |
736 | walk(operate, ident->uid); | |
737 | walk(operate, ident->name); | |
738 | if (ident->address) | |
739 | walk(operate, ident->address); | |
740 | return ident; | |
741 | } | |
742 | ||
743 | ||
744 | // | |
745 | // Walkers for the byzantine data structures of the DL universe. | |
746 | // Geez, what WERE they smoking when they invented this? | |
747 | // | |
748 | ||
749 | // DbAttributeInfos | |
750 | template<class Action> | |
751 | void enumerate(Action &operate, CssmDbAttributeInfo &info) | |
752 | { | |
753 | switch (info.nameFormat()) { | |
754 | case CSSM_DB_ATTRIBUTE_NAME_AS_STRING: | |
755 | walk(operate, info.Label.AttributeName); | |
756 | break; | |
757 | case CSSM_DB_ATTRIBUTE_NAME_AS_OID: | |
758 | walk(operate, info.Label.AttributeOID); | |
759 | break; | |
760 | default: | |
761 | break; | |
762 | } | |
763 | } | |
764 | ||
765 | template <class Action> | |
766 | void walk(Action &operate, CssmDbAttributeInfo &info) | |
767 | { | |
768 | operate(info); | |
769 | enumerate(operate, info); | |
770 | } | |
771 | ||
772 | template <class Action> | |
773 | CssmDbAttributeInfo *walk(Action &operate, CssmDbAttributeInfo * &info) | |
774 | { | |
775 | operate(info); | |
776 | enumerate(operate, *info); | |
777 | return info; | |
778 | } | |
779 | ||
780 | // DbRecordAttributeInfo | |
781 | template <class Action> | |
782 | void walk(Action &operate, CssmDbRecordAttributeInfo &info) | |
783 | { | |
784 | operate(info); | |
785 | enumerateArray(operate, info, &CssmDbRecordAttributeInfo::attributes); | |
786 | } | |
787 | ||
788 | template <class Action> | |
789 | CssmDbRecordAttributeInfo *walk(Action &operate, CssmDbRecordAttributeInfo * &info) | |
790 | { | |
791 | operate(info); | |
792 | enumerateArray(operate, *info, &CssmDbRecordAttributeInfo::attributes); | |
793 | return info; | |
794 | } | |
795 | ||
796 | // DbAttributeData (Info + value vector) | |
797 | template <class Action> | |
798 | void walk(Action &operate, CssmDbAttributeData &data) | |
799 | { | |
800 | operate(data); | |
801 | walk(operate, data.info()); | |
802 | enumerateArray(operate, data, &CssmDbAttributeData::values); | |
803 | } | |
804 | ||
805 | template <class Action> | |
806 | CssmDbAttributeData *walk(Action &operate, CssmDbAttributeData * &data) | |
807 | { | |
808 | operate(data); | |
809 | walk(operate, data->info()); | |
810 | enumerateArray(operate, *data, &CssmDbAttributeData::values); | |
811 | return data; | |
812 | } | |
813 | ||
814 | // DbRecordAttributeData (array of ...datas) | |
815 | template <class Action> | |
816 | void walk(Action &operate, CssmDbRecordAttributeData &data) | |
817 | { | |
818 | operate(data); | |
819 | enumerateArray(operate, data, &CssmDbRecordAttributeData::attributes); | |
820 | } | |
821 | ||
822 | template <class Action> | |
823 | CssmDbRecordAttributeData *walk(Action &operate, CssmDbRecordAttributeData * &data) | |
824 | { | |
825 | operate(data); | |
826 | enumerateArray(operate, *data, &CssmDbRecordAttributeData::attributes); | |
827 | return data; | |
828 | } | |
829 | ||
830 | // SelectionPredicates | |
831 | template <class Action> | |
832 | CssmSelectionPredicate *walk(Action &operate, CssmSelectionPredicate * &predicate) | |
833 | { | |
834 | operate(predicate); | |
835 | walk(operate, predicate->attribute()); | |
836 | return predicate; | |
837 | } | |
838 | ||
839 | template<class Action> | |
840 | void walk(Action &operate, CssmSelectionPredicate &predicate) | |
841 | { | |
842 | operate(predicate); | |
843 | walk(operate, predicate.attribute()); | |
844 | } | |
845 | ||
846 | // Queries | |
847 | template <class Action> | |
848 | void walk(Action &operate, CssmQuery &query) | |
849 | { | |
850 | operate(query); | |
851 | enumerateArray(operate, query, &CssmQuery::predicates); | |
852 | } | |
853 | ||
854 | template <class Action> | |
855 | CssmQuery *walk(Action &operate, CssmQuery * &query) | |
856 | { | |
857 | operate(query); | |
858 | enumerateArray(operate, *query, &CssmQuery::predicates); | |
859 | return query; | |
860 | } | |
861 | ||
862 | template <class Action> | |
863 | CSSM_QUERY *walk(Action &operate, CSSM_QUERY * &query) | |
864 | { | |
865 | return walk(operate, CssmQuery::overlayVar(query)); | |
866 | } | |
867 | ||
868 | ||
869 | } // end namespace DataWalkers | |
870 | } // end namespace Security | |
871 | ||
872 | ||
873 | #endif // _H_CDSA_UTILITIES_CSSMDB |