]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/buffers.h
Security-54.1.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / buffers.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 //
20 // buffer - simple data buffers with convenience
21 //
22 #ifndef _H_BUFFER
23 #define _H_BUFFER
24
25 #include <Security/utilities.h>
26 #include <cstdarg>
27 #include <limits.h>
28
29
30 namespace Security {
31
32
33 class Buffer {
34 public:
35 Buffer(size_t size); // allocate empty buffer
36 ~Buffer();
37
38 static Buffer reader(void *base, size_t size, bool owned = false)
39 { return Buffer(base, size, true, owned); }
40 static Buffer writer(void *base, size_t size, bool owned = false)
41 { return Buffer(base, size, false, owned); }
42
43 size_t available(bool heavy = false) const
44 { return heavy ? ((mTop - mEnd) + (mStart - mBase)): (mTop - mEnd); }
45 bool isFull(bool heavy = false) const
46 { return heavy ? (mEnd == mTop && mStart == mBase) : (mEnd == mTop); }
47 bool isEmpty() const { return mStart == mEnd; }
48
49 size_t length() const { return mEnd - mStart; }
50 void *data() { assert(mStart == mBase); return mStart; }
51
52 void clear() { mStart = mEnd = mBase; }
53
54 protected:
55 // private constructor with full flexibility
56 Buffer(void *base, size_t size, bool filled, bool owned = false);
57
58 // perform expensive realignment to coalesce freespace
59 size_t shuffle(size_t needed = UINT_MAX);
60
61 // perform cheap adjustments after data was taken out
62 void adjustGet()
63 {
64 if (isEmpty()) // empty buffer. Reset pointers to base
65 mStart = mEnd = mBase;
66 }
67
68 public:
69 // elementary put: copy mode
70 size_t put(const void *data, size_t length)
71 {
72 if (length > available())
73 length = shuffle(length);
74 memcpy(mEnd, data, length);
75 mEnd += length;
76 return length;
77 }
78
79 // elementary put: locate mode. Remember that each can shuffle memory
80 template <class T> void locatePut(T * &addr, size_t &length)
81 {
82 if (length > available())
83 length = shuffle(length);
84 addr = reinterpret_cast<T *>(mEnd);
85 }
86
87 void usePut(size_t length)
88 {
89 assert(length <= available());
90 mEnd += length;
91 }
92
93 // elementary get: locate mode
94 template <class T> void locateGet(T * &addr, size_t &length)
95 {
96 if (length > size_t(mEnd - mStart))
97 length = mEnd - mStart;
98 addr = reinterpret_cast<T *>(mStart);
99 }
100
101 void useGet(size_t length)
102 {
103 assert(length <= this->length());
104 mStart += length;
105 adjustGet();
106 }
107
108 //
109 // I/O via FileDescoid objects
110 //
111 template <class IO>
112 size_t read(IO &io, size_t length)
113 {
114 if (length > available())
115 length = shuffle(length);
116 size_t bytesRead = io.read(mEnd, length);
117 mEnd += bytesRead;
118 return bytesRead;
119 }
120
121 template <class IO>
122 size_t write(IO &io, size_t length)
123 {
124 length = min(this->length(), length);
125 size_t bytesWritten = io.write(mStart, length);
126 mStart += bytesWritten;
127 adjustGet();
128 return bytesWritten;
129 }
130
131 template <class IO> size_t read(IO &io, bool heavy = false)
132 { return read(io, available(heavy)); }
133
134 template <class IO> size_t write(IO &io)
135 { return write(io, length()); }
136
137 // printf-style output to a buffer
138 void printf(const char *format, ...);
139 void vprintf(const char *format, va_list args);
140
141 // memory ownership
142 void own() { mOwningMemory = true; }
143
144 private:
145 char *const mBase; // base pointer
146 char *const mTop; // end pointer + 1
147 char *mStart; // start of used area
148 char *mEnd; // end of used area + 1
149 bool mOwningMemory; // true if we own the memory (free on destruction)
150 };
151
152
153 } // end namespace Security
154
155
156 #endif //_H_BUFFER