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