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 NETUTILS_MEMBLOCK_H
18 #define NETUTILS_MEMBLOCK_H
19 
20 #include <memory>
21 #include "netdutils/Slice.h"
22 
23 namespace android {
24 namespace netdutils {
25 
26 // A class to encapsulate self-deleting byte arrays while preserving access
27 // to the underlying length (without the length being part of the type, e.g.
28 // std::array<>). By design, the only interface to the underlying bytes is
29 // via Slice, to encourage safer memory access usage.
30 //
31 // No thread-safety guarantees whatsoever.
32 class MemBlock {
33   public:
MemBlock()34     MemBlock() : MemBlock(0U) {}
MemBlock(size_t len)35     MemBlock(size_t len)
36             : mData((len > 0U) ? new uint8_t[len]{} : nullptr),
37               mLen(len) {}
38     // Allocate memory of size src.size() and copy src into this MemBlock.
MemBlock(Slice src)39     MemBlock(Slice src) : MemBlock(src.size()) {
40         copy(get(), src);
41     }
42 
43     // No copy construction or assignment.
44     MemBlock(const MemBlock&) = delete;
45     MemBlock& operator=(const MemBlock&) = delete;
46 
47     // Move construction and assignment are okay.
48     MemBlock(MemBlock&&) = default;
49     MemBlock& operator=(MemBlock&&) = default;
50 
51     // Even though this method is const, the memory wrapped by the
52     // returned Slice is mutable.
get()53     Slice get() const noexcept { return Slice(mData.get(), mLen); }
54 
55     // Implicit cast to Slice.
Slice()56     const operator Slice() const noexcept { return get(); }
57 
58   private:
59     std::unique_ptr<uint8_t[]> mData;
60     size_t mLen;
61 };
62 
63 }  // namespace netdutils
64 }  // namespace android
65 
66 #endif /* NETUTILS_MEMBLOCK_H */
67