1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_UTIL_BUFFER_H_
18 #define CHRE_UTIL_BUFFER_H_
19 
20 #include <type_traits>
21 
22 #include "chre/util/buffer_base.h"
23 
24 namespace chre {
25 
26 /**
27  * Manages a buffer of objects. This buffer may be allocated by this object or
28  * wrapped into this object. Usage of this template is restricted to trivial
29  * types.
30  *
31  * The intent of this container is to group a pointer with the number of
32  * elements in that pointer. This allows passing a pointer from one place to
33  * another with an optional memory release when the copy_array API below is
34  * used. Destructors are not called on the memory owned here, hence the
35  * restriction to trivial types. This is the C-equivalent to wrapping a void
36  * pointer and size into a simple struct, but with the added benefit of type
37  * safety.
38  */
39 template <typename ElementType>
40 class Buffer : private BufferBase {
41  public:
42   static_assert(std::is_trivial<ElementType>::value,
43                 "ElementType must be trivial");
44   static_assert(std::is_trivially_destructible<ElementType>::value,
45                 "ElementType must be trivially destructible");
46 
47   /**
48    * @return the data buffered here.
49    */
data()50   ElementType *data() const {
51     return static_cast<ElementType *>(mBuffer);
52   }
53 
54   /**
55    * @return the number of elements in the underlying buffer.
56    */
size()57   size_t size() const {
58     return mSize;
59   }
60 
61   /**
62    * Wraps an existing C-style array so it can be used as a Buffer. A
63    * reference to the supplied array is kept, as opposed to making a copy. The
64    * caller retains ownership of the memory. Calling code must therefore ensure
65    * that the lifetime of the supplied array is at least as long as that of this
66    * object, and that the memory is released after this object is destructed, as
67    * this object will not attempt to free the memory itself.
68    *
69    * @param buffer A pointer to a pre-allocated array.
70    * @param size The number of elements in the array.
71    */
wrap(ElementType * buffer,size_t size)72   void wrap(ElementType *buffer, size_t size) {
73     BufferBase::wrap(buffer, size);
74   }
75 
76   /**
77    * Copies the supplied array into the buffer managed by this object. In the
78    * interest of simplicity and codesize, the underlying buffer is always
79    * reallocated. The expected use of this object is to copy just once. This
80    * also avoids the issue of copying a very large buffer, then copying a
81    * smaller buffer and being left with a very large outstanding allocation. If
82    * an empty input is supplied (size zero), the buffer is cleared and true is
83    * returned.
84    *
85    * @param buffer A pointer to an array to copy.
86    * @param size The number of elements in the array.
87    * @return true if capacity was reserved to fit the supplied buffer and the
88    *         supplied buffer was copied into the internal buffer of this object,
89    *         or if the supplied input is empty, false otherwise.
90    */
copy_array(const ElementType * buffer,size_t size)91   bool copy_array(const ElementType *buffer, size_t size) {
92     return BufferBase::copy_array(buffer, size, sizeof(ElementType));
93   }
94 };
95 
96 }  // namespace chre
97 
98 #endif  // CHRE_UTIL_BUFFER_H_
99