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//
20// MetaRecord.h
21//
22
23#ifndef _H_APPLEDL_METARECORD
24#define _H_APPLEDL_METARECORD
25
26#include "MetaAttribute.h"
27
28namespace Security
29{
30
31//
32// Part of the Unique record identifier needed to identify the actual record.
33//
34class RecordId
35{
36public:
37	RecordId() : mRecordNumber(~(uint32)0), mCreateVersion(~(uint32)0), mRecordVersion(~(uint32)0) {}
38    RecordId(uint32 inRecordNumber, uint32 inCreateVersion, uint32 inRecordVersion = 0)
39	  : mRecordNumber(inRecordNumber),
40        mCreateVersion(inCreateVersion),
41		mRecordVersion(inRecordVersion) {}
42    bool operator <(const RecordId &inRecordId) const
43    {
44        return (mRecordNumber < inRecordId.mRecordNumber
45                || (mRecordNumber == inRecordId.mRecordNumber
46                    && (mCreateVersion < inRecordId.mCreateVersion
47						|| (mCreateVersion == inRecordId.mCreateVersion
48							&& mRecordVersion < inRecordId.mRecordVersion))));
49    }
50    uint32 mRecordNumber;
51    uint32 mCreateVersion;
52	uint32 mRecordVersion;
53};
54
55//
56// Meta (or Schema) representation of an a Record.  Used for packing and unpacking objects.
57//
58
59class MetaRecord
60{
61	NOCOPY(MetaRecord)
62
63public:
64    MetaRecord(CSSM_DB_RECORDTYPE inRecordType);
65	MetaRecord(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo);
66    MetaRecord(CSSM_DB_RECORDTYPE inRelationID,
67               uint32 inNumberOfAttributes,
68			   const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo);
69	~MetaRecord();
70
71    void setRecordAttributeInfo(const CSSM_DB_RECORD_ATTRIBUTE_INFO &inInfo);
72
73    void createAttribute(const string *inAttributeName,
74						 const CssmOid *inAttributeOID,
75                         uint32 inAttributeID,
76						 CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat);
77
78    // Create a packed record from the given inputs.
79    void packRecord(WriteSection &inWriteSection,
80                    const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
81                    const CssmData *inData) const;
82
83	// Unpack a record from the given inputs and return the RecordId of the record.
84    void unpackRecord(const ReadSection &inReadSection,
85					  Allocator &inAllocator,
86					  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
87					  CssmData *inoutData,
88					  CSSM_QUERY_FLAGS inQueryFlags) const;
89
90	const MetaAttribute &metaAttribute(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
91
92	void updateRecord(const ReadSection &inReadSection,
93					  WriteSection &inWriteSection,
94					  const CssmDbRecordAttributeData *inAttributes,
95					  const CssmData *inData,
96					  CSSM_DB_MODIFY_MODE inModifyMode) const;
97
98    CSSM_DB_RECORDTYPE dataRecordType() const { return mRecordType; }
99
100	Range dataRange(const ReadSection &inReadSection) const
101	{
102        return Range((uint32)(OffsetAttributeOffsets + mAttributeVector.size() * AtomSize),
103					 inReadSection[OffsetDataSize]);
104	}
105
106	// Currently this is not a real attribute.  We should probably fix this.
107	uint32 semanticInformation(const ReadSection &inReadSection) const
108	{
109		return inReadSection[OffsetSemanticInformation];
110	}
111
112    // Return the ReadSection for record at offset
113	static const ReadSection readSection(const ReadSection &inTableSection, uint32 inOffset)
114	{
115		return inTableSection.subsection(inOffset,
116										 inTableSection[inOffset + OffsetRecordSize]);
117	}
118
119	// Set the RecordId of the record in inWriteSection
120	static void packRecordId(const RecordId &inRecordId,
121							 WriteSection &inWriteSection)
122	{
123		inWriteSection.put(OffsetRecordNumber, inRecordId.mRecordNumber);
124		inWriteSection.put(OffsetCreateVersion, inRecordId.mCreateVersion);
125		inWriteSection.put(OffsetRecordVersion, inRecordId.mRecordVersion);
126	}
127
128	// Return the RecordId for the record inRecordSection
129	static const uint32 unpackRecordNumber(const ReadSection &inRecordSection)
130	{
131		return inRecordSection[OffsetRecordNumber];
132	}
133
134	// Return the RecordId for the record inRecordSection
135	static const RecordId unpackRecordId(const ReadSection &inRecordSection)
136	{
137		return RecordId(inRecordSection[OffsetRecordNumber],
138						inRecordSection[OffsetCreateVersion],
139						inRecordSection[OffsetRecordVersion]);
140	}
141
142private:
143    // Return the index (0 though NumAttributes - 1) of the attribute
144    // represented by inAttributeInfo
145    uint32 attributeIndex(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
146
147    void unpackAttribute(const ReadSection &inReadSection, Allocator &inAllocator,
148                         CSSM_DB_ATTRIBUTE_DATA &inoutAttribute) const;
149
150    friend class MetaAttribute;
151	enum
152	{
153		OffsetRecordSize			= AtomSize * 0,
154		OffsetRecordNumber			= AtomSize * 1,
155		OffsetCreateVersion			= AtomSize * 2,
156		OffsetRecordVersion			= AtomSize * 3,
157		OffsetDataSize				= AtomSize * 4,
158		OffsetSemanticInformation	= AtomSize * 5,
159		OffsetAttributeOffsets		= AtomSize * 6
160	};
161
162	CSSM_DB_RECORDTYPE mRecordType;
163	typedef std::map<string, uint32> NameStringMap;
164	typedef std::map<CssmBuffer<CssmOidContainer>, uint32> NameOIDMap;
165	typedef std::map<uint32, uint32> NameIntMap;
166	typedef std::vector<MetaAttribute *> AttributeVector;
167	NameStringMap mNameStringMap;
168	NameOIDMap mNameOIDMap;
169	NameIntMap mNameIntMap;
170	AttributeVector mAttributeVector;
171};
172
173} // end namespace Security
174
175#endif // _H_APPLEDL_METARECORD
176
177