2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
23 #ifndef _H_APPLEDL_READWRITESECTION
24 #define _H_APPLEDL_READWRITESECTION
26 #include <security_utilities/alloc.h>
27 #include <security_filedb/AtomicFile.h>
28 #include <security_utilities/endian.h>
29 #include <security_cdsa_utilities/cssmerrors.h>
30 #include <Security/cssm.h>
31 #include "OverUnderflowCheck.h"
37 // Atom -- An Atom is a 32-bit unsigned integer value that is always internally
38 // represented using network byte order.
40 typedef Endian
<uint32
> Atom
;
43 AtomSize
= sizeof(uint32
) // XXX Why not just use sizeof(Atom)?
47 // Class representing a range (or subrange of a buffer).
52 Range(uint32 inOffset
, uint32 inSize
) : mOffset(inOffset
), mSize(inSize
) {}
58 // Class representing a packed record. All the accessors on this class are const since the
59 // underlying data is read-only
61 // XXX Should be replaced by Atom::Vector
65 ReadSection(uint8
*inAddress
, size_t inLength
) : mAddress(inAddress
), mLength(inLength
)
68 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
71 ReadSection() : mAddress(NULL
), mLength(0) {}
72 ReadSection(const uint8
*inAddress
, size_t inLength
) :
73 mAddress(const_cast<uint8
*>(inAddress
)), mLength(inLength
) {}
75 uint32
size() const { return (uint32
)mLength
; }
77 uint32
at(uint32 inOffset
) const
79 if (inOffset
> mLength
)
81 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
84 return ntohl(*reinterpret_cast<const uint32
*>(mAddress
+ inOffset
));
87 uint32
operator[](uint32 inOffset
) const
92 // Return a subsection from inOffset to end of section.
93 ReadSection
subsection(uint32 inOffset
) const
95 if (inOffset
> mLength
)
96 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
97 return ReadSection(mAddress
+ inOffset
, mLength
- inOffset
);
100 // Return a subsection from inOffset of inLength bytes.
101 ReadSection
subsection(uint32 inOffset
, uint32 inLength
) const
103 if (CheckUInt32Add(inOffset
, inLength
) > mLength
)
104 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
105 return ReadSection(mAddress
+ inOffset
, inLength
);
108 ReadSection
subsection(const Range
&inRange
) const
110 return subsection(inRange
.mOffset
, inRange
.mSize
);
113 const uint8
*range(const Range
&inRange
) const
115 if (CheckUInt32Add(inRange
.mOffset
, inRange
.mSize
) > mLength
)
116 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
117 return mAddress
+ inRange
.mOffset
;
120 uint8
*allocCopyRange(const Range
&inRange
, Allocator
&inAllocator
) const
123 if (inRange
.mSize
== 0)
127 if (CheckUInt32Add(inRange
.mOffset
, inRange
.mSize
) > mLength
)
128 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
130 aData
= reinterpret_cast<uint8
*>(inAllocator
.malloc(inRange
.mSize
));
131 memcpy(aData
, mAddress
+ inRange
.mOffset
, inRange
.mSize
);
137 static uint32
align(uint32 offset
) { return (CheckUInt32Subtract(CheckUInt32Add(offset
, AtomSize
), 1)) & ~(AtomSize
- 1); }
145 // Class representing a packed record (or buffer) used for writing.
147 class WriteSection
: public ReadSection
150 static const size_t DefaultCapacity
= 64;
152 WriteSection(Allocator
&inAllocator
, size_t inCapacity
) :
153 ReadSection(reinterpret_cast<uint8
*>(inAllocator
.malloc(inCapacity
)), 0),
154 mAllocator(inAllocator
),
155 mCapacity(inCapacity
)
158 memset(mAddress
, 0, mCapacity
);
161 WriteSection(Allocator
&inAllocator
= Allocator::standard()) :
162 ReadSection(reinterpret_cast<uint8
*>(inAllocator
.malloc(DefaultCapacity
)), 0),
163 mAllocator(inAllocator
),
164 mCapacity(DefaultCapacity
)
168 WriteSection(const WriteSection
&ws
, int length
) :
169 ReadSection(reinterpret_cast<uint8
*>(ws
.mAllocator
.malloc(length
)), length
),
170 mAllocator(ws
.mAllocator
),
173 memcpy(mAddress
, ws
.mAddress
, length
);
176 ~WriteSection() { mAllocator
.free(mAddress
); }
179 void grow(size_t inNewCapacity
);
183 uint32
size() const { return ReadSection::size(); }
185 // XXX This should work but egcs-2.95.2 doesn't like it.
186 using ReadSection::size
;
189 void size(uint32 inLength
) { mLength
= inLength
; }
190 uint32
put(uint32 inOffset
, uint32 inValue
);
191 uint32
put(uint32 inOffset
, uint32 inLength
, const uint8
*inData
);
193 const uint8
*address() const { return mAddress
; }
196 uint8
*anAddress
= mAddress
;
203 Allocator
&mAllocator
;
207 } // end namespace Security
209 #endif // _H_APPLEDL_READWRITESECTION