Line data Source code
1 : // file : xsd/cxx/tree/buffer.hxx
2 : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 : // license : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 :
5 : /**
6 : * @file
7 : *
8 : * @brief Contains a simple binary buffer abstraction that is used to
9 : * implement the base64Binary and hexBinary XML Schema built-in types.
10 : *
11 : * This is an internal header and is included by the generated code. You
12 : * normally should not include it directly.
13 : *
14 : */
15 :
16 : #ifndef XSD_CXX_TREE_BUFFER_HXX
17 : #define XSD_CXX_TREE_BUFFER_HXX
18 :
19 : #include <new> // operator new/delete
20 : #include <cstddef> // std::size_t
21 : #include <cstring> // std::memcpy, std::memcmp
22 :
23 : #include <xsd/cxx/tree/exceptions.hxx>
24 :
25 : namespace xsd
26 : {
27 : namespace cxx
28 : {
29 : /**
30 : * @brief C++/Tree mapping runtime namespace.
31 : *
32 : * This is an internal namespace and normally should not be referenced
33 : * directly. Instead you should use the aliases for types in this
34 : * namespaces that are created in the generated code.
35 : *
36 : */
37 : namespace tree
38 : {
39 : //@cond
40 :
41 : class buffer_base
42 : {
43 : protected:
44 : virtual
45 0 : ~buffer_base ()
46 0 : {
47 0 : if (free_ && data_)
48 0 : operator delete (data_);
49 0 : }
50 :
51 0 : buffer_base ()
52 0 : : data_ (0), size_ (0), capacity_ (0), free_ (true)
53 : {
54 0 : }
55 :
56 : protected:
57 : char* data_;
58 : size_t size_;
59 : size_t capacity_;
60 : bool free_;
61 : };
62 :
63 : //@endcond
64 :
65 : /**
66 : * @brief Simple binary %buffer abstraction
67 : *
68 : * The %buffer class manages a continuous binary %buffer. The base
69 : * concepts are data (actual memory region), size (the portion of
70 : * the %buffer that contains useful information), and capacity (the
71 : * actual size of the underlying memory region). The bounds
72 : * %exception is thrown from the constructors and modifier functions
73 : * if the (size <= capacity) constraint is violated.
74 : *
75 : * Note that the template parameter is only used to instantiate
76 : * %exception types. The underlying %buffer type is always @c char.
77 : *
78 : * @nosubgrouping
79 : */
80 : template<typename C>
81 : class buffer: protected buffer_base
82 : {
83 : public:
84 : /**
85 : * @brief Size type
86 : */
87 : typedef std::size_t size_t;
88 :
89 : public:
90 : /**
91 : * @name Constructors
92 : */
93 : //@{
94 :
95 : /**
96 : * @brief Allocate a %buffer of the specified size.
97 : *
98 : * The resulting %buffer has the same size and capacity.
99 : *
100 : * @param size A %buffer size in bytes.
101 : */
102 : explicit
103 : buffer (size_t size = 0);
104 :
105 : /**
106 : * @brief Allocate a %buffer of the specified size and capacity.
107 : *
108 : * @param size A %buffer size in bytes.
109 : * @param capacity A %buffer capacity in bytes.
110 : * @throw bounds If @a size exceeds @a capacity
111 : */
112 : buffer (size_t size, size_t capacity);
113 :
114 : /**
115 : * @brief Allocate a %buffer of the specified size and copy
116 : * the data.
117 : *
118 : * The resulting %buffer has the same size and capacity with
119 : * @a size bytes copied from @a data.
120 : *
121 : * @param data A %buffer to copy the data from.
122 : * @param size A %buffer size in bytes.
123 : */
124 : buffer (const void* data, size_t size);
125 :
126 : /**
127 : * @brief Allocate a %buffer of the specified size and capacity
128 : * and copy the data.
129 : *
130 : * @a size bytes are copied from @a data to the resulting
131 : * %buffer.
132 : *
133 : * @param data A %buffer to copy the data from.
134 : * @param size A %buffer size in bytes.
135 : * @param capacity A %buffer capacity in bytes.
136 : * @throw bounds If @a size exceeds @a capacity
137 : */
138 : buffer (const void* data, size_t size, size_t capacity);
139 :
140 : /**
141 : * @brief Reuse an existing %buffer.
142 : *
143 : * If the @a assume_ownership argument is true, the %buffer will
144 : * assume ownership of @a data and will release the memory
145 : * by calling @c operator @c delete().
146 : *
147 : * @param data A %buffer to reuse.
148 : * @param size A %buffer size in bytes.
149 : * @param capacity A %buffer capacity in bytes.
150 : * @param assume_ownership A boolean value indication whether to
151 : * assume ownership.
152 : * @throw bounds If @a size exceeds @a capacity
153 : */
154 : buffer (void* data,
155 : size_t size,
156 : size_t capacity,
157 : bool assume_ownership);
158 :
159 : /**
160 : * @brief Copy constructor.
161 : *
162 : * The copy constructor performs a deep copy of the underlying
163 : * memory %buffer.
164 : *
165 : * @param x An instance to make a copy of.
166 : */
167 : buffer (const buffer& x);
168 :
169 : //@}
170 :
171 : public:
172 : /**
173 : * @brief Copy assignment operator.
174 : *
175 : * The copy assignment operator changes the buffer's capacity
176 : * to @c x.capacity() and copies @c x.size() bytes from @a x.
177 : *
178 : * @param x An instance to assign.
179 : * @return A reference to the instance.
180 : */
181 : buffer&
182 : operator= (const buffer& x);
183 :
184 : public:
185 : /**
186 : * @brief Get buffer's capacity.
187 : *
188 : * @return A number of bytes that the %buffer can hold without
189 : * reallocation.
190 : */
191 : size_t
192 : capacity () const
193 : {
194 : return capacity_;
195 : }
196 :
197 : /**
198 : * @brief Set buffer's capacity.
199 : *
200 : * @param c The new capacity in bytes.
201 : * @return True if the underlying %buffer has moved, false otherwise.
202 : */
203 : bool
204 0 : capacity (size_t c)
205 : {
206 0 : return this->capacity (c, true);
207 : }
208 :
209 : public:
210 : /**
211 : * @brief Get buffer's size.
212 : *
213 : * @return A number of bytes that the %buffer holds.
214 : */
215 : size_t
216 0 : size () const {return size_;}
217 :
218 : /**
219 : * @brief Set buffer's size.
220 : *
221 : * @param s The new size in bytes.
222 : * @return True if the underlying %buffer has moved, false otherwise.
223 : */
224 : bool
225 : size (size_t s)
226 : {
227 : bool r (false);
228 :
229 : if (s > capacity_)
230 : r = capacity (s);
231 :
232 : size_ = s;
233 :
234 : return r;
235 : }
236 :
237 : public:
238 : /**
239 : * @brief Get the underlying memory region.
240 : *
241 : * @return A constant pointer to the underlying memory region.
242 : */
243 : const char*
244 0 : data () const {return data_;}
245 :
246 : /**
247 : * @brief Get the underlying memory region.
248 : *
249 : * @return A pointer to the underlying memory region.
250 : */
251 : char*
252 : data () {return data_;}
253 :
254 : /**
255 : * @brief Get the beginning of the underlying memory region.
256 : *
257 : * @return A constant pointer to the first byte of the underlying
258 : * memory region.
259 : */
260 : const char*
261 : begin () const {return data_;}
262 :
263 : /**
264 : * @brief Get the beginning of the underlying memory region.
265 : *
266 : * @return A pointer to the first byte of the underlying memory
267 : * region.
268 : */
269 : char*
270 : begin () {return data_;}
271 :
272 : /**
273 : * @brief Get the end of the underlying memory region.
274 : *
275 : * @return A constant pointer to the one past last byte of the
276 : * underlying memory region (that is @c %begin() @c + @c %size() ).
277 : */
278 : const char*
279 : end () const {return data_ + size_;}
280 :
281 : /**
282 : * @brief Get the end of the underlying memory region.
283 : *
284 : * @return A pointer to the one past last byte of the underlying
285 : * memory region (that is @c %begin() @c + @c %size() ).
286 : */
287 : char*
288 : end () {return data_ + size_;}
289 :
290 : public:
291 : /**
292 : * @brief Swap data with another %buffer.
293 : *
294 : * @param x A %buffer to swap with.
295 : */
296 : void
297 : swap (buffer& x);
298 :
299 : private:
300 : bool
301 : capacity (size_t capacity, bool copy);
302 : };
303 :
304 : /**
305 : * @brief %buffer comparison operator.
306 : *
307 : * @return True if the buffers have the same sizes and the same
308 : * data.
309 : */
310 : template <typename C>
311 : inline bool
312 : operator== (const buffer<C>& a, const buffer<C>& b)
313 : {
314 : return a.size () == b.size () &&
315 : std::memcmp (a.data (), b.data (), a.size ()) == 0;
316 : }
317 :
318 : /**
319 : * @brief %buffer comparison operator.
320 : *
321 : * @return True if the buffers have different sizes or different
322 : * data.
323 : */
324 : template <typename C>
325 : inline bool
326 : operator!= (const buffer<C>& a, const buffer<C>& b)
327 : {
328 : return !(a == b);
329 : }
330 : }
331 : }
332 : }
333 :
334 : #include <xsd/cxx/tree/buffer.txx>
335 :
336 : #endif // XSD_CXX_TREE_BUFFER_HXX
|