]>
git.saurik.com Git - apple/security.git/blob - OSX/include/security_utilities/buffers.h
2 * Copyright (c) 2000-2001,2003-2004,2011,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // buffer - simple data buffers with convenience
31 #include <security_utilities/utilities.h>
41 Buffer(size_t size
); // allocate empty buffer
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
); }
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
; }
55 size_t length() const { return mEnd
- mStart
; }
56 void *data() { assert(mStart
== mBase
); return mStart
; }
58 void clear() { mStart
= mEnd
= mBase
; }
61 // private constructor with full flexibility
62 Buffer(void *base
, size_t size
, bool filled
, bool owned
= false);
64 // perform expensive realignment to coalesce freespace
65 size_t shuffle(size_t needed
= UINT_MAX
);
67 // perform cheap adjustments after data was taken out
70 if (isEmpty()) // empty buffer. Reset pointers to base
71 mStart
= mEnd
= mBase
;
75 // elementary put: copy mode
76 size_t put(const void *data
, size_t length
)
78 if (length
> available())
79 length
= shuffle(length
);
80 memcpy(mEnd
, data
, length
);
85 // elementary put: locate mode. Remember that each can shuffle memory
86 template <class T
> void locatePut(T
* &addr
, size_t &length
)
88 if (length
> available())
89 length
= shuffle(length
);
90 addr
= reinterpret_cast<T
*>(mEnd
);
93 void usePut(size_t length
)
95 assert(length
<= available());
99 // elementary get: locate mode
100 template <class T
> void locateGet(T
* &addr
, size_t &length
)
102 if (length
> size_t(mEnd
- mStart
))
103 length
= mEnd
- mStart
;
104 addr
= reinterpret_cast<T
*>(mStart
);
107 void useGet(size_t length
)
109 assert(length
<= this->length());
115 // I/O via FileDescoid objects
118 size_t read(IO
&io
, size_t length
)
120 if (length
> available())
121 length
= shuffle(length
);
122 size_t bytesRead
= io
.read(mEnd
, length
);
128 size_t write(IO
&io
, size_t length
)
130 length
= min(this->length(), length
);
131 size_t bytesWritten
= io
.write(mStart
, length
);
132 mStart
+= bytesWritten
;
137 template <class IO
> size_t read(IO
&io
, bool heavy
= false)
138 { return read(io
, available(heavy
)); }
140 template <class IO
> size_t write(IO
&io
)
141 { return write(io
, length()); }
143 // printf-style output to a buffer
144 void printf(const char *format
, ...);
145 void vprintf(const char *format
, va_list args
);
148 void own() { mOwningMemory
= true; }
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)
159 } // end namespace Security