1 /* 2 * Copyright 2021 Google Inc. All rights reserved. 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 FLATBUFFERS_DETACHED_BUFFER_H_ 18 #define FLATBUFFERS_DETACHED_BUFFER_H_ 19 20 #include "flatbuffers/allocator.h" 21 #include "flatbuffers/base.h" 22 #include "flatbuffers/default_allocator.h" 23 24 namespace flatbuffers { 25 26 // DetachedBuffer is a finished flatbuffer memory region, detached from its 27 // builder. The original memory region and allocator are also stored so that 28 // the DetachedBuffer can manage the memory lifetime. 29 class DetachedBuffer { 30 public: DetachedBuffer()31 DetachedBuffer() 32 : allocator_(nullptr), 33 own_allocator_(false), 34 buf_(nullptr), 35 reserved_(0), 36 cur_(nullptr), 37 size_(0) {} 38 DetachedBuffer(Allocator * allocator,bool own_allocator,uint8_t * buf,size_t reserved,uint8_t * cur,size_t sz)39 DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf, 40 size_t reserved, uint8_t *cur, size_t sz) 41 : allocator_(allocator), 42 own_allocator_(own_allocator), 43 buf_(buf), 44 reserved_(reserved), 45 cur_(cur), 46 size_(sz) {} 47 DetachedBuffer(DetachedBuffer && other)48 DetachedBuffer(DetachedBuffer &&other) noexcept 49 : allocator_(other.allocator_), 50 own_allocator_(other.own_allocator_), 51 buf_(other.buf_), 52 reserved_(other.reserved_), 53 cur_(other.cur_), 54 size_(other.size_) { 55 other.reset(); 56 } 57 58 DetachedBuffer &operator=(DetachedBuffer &&other) noexcept { 59 if (this == &other) return *this; 60 61 destroy(); 62 63 allocator_ = other.allocator_; 64 own_allocator_ = other.own_allocator_; 65 buf_ = other.buf_; 66 reserved_ = other.reserved_; 67 cur_ = other.cur_; 68 size_ = other.size_; 69 70 other.reset(); 71 72 return *this; 73 } 74 ~DetachedBuffer()75 ~DetachedBuffer() { destroy(); } 76 data()77 const uint8_t *data() const { return cur_; } 78 data()79 uint8_t *data() { return cur_; } 80 size()81 size_t size() const { return size_; } 82 begin()83 uint8_t *begin() { return data(); } begin()84 const uint8_t *begin() const { return data(); } end()85 uint8_t *end() { return data() + size(); } end()86 const uint8_t *end() const { return data() + size(); } 87 88 // These may change access mode, leave these at end of public section 89 FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other)); 90 FLATBUFFERS_DELETE_FUNC( 91 DetachedBuffer &operator=(const DetachedBuffer &other)); 92 93 protected: 94 Allocator *allocator_; 95 bool own_allocator_; 96 uint8_t *buf_; 97 size_t reserved_; 98 uint8_t *cur_; 99 size_t size_; 100 destroy()101 inline void destroy() { 102 if (buf_) Deallocate(allocator_, buf_, reserved_); 103 if (own_allocator_ && allocator_) { delete allocator_; } 104 reset(); 105 } 106 reset()107 inline void reset() { 108 allocator_ = nullptr; 109 own_allocator_ = false; 110 buf_ = nullptr; 111 reserved_ = 0; 112 cur_ = nullptr; 113 size_ = 0; 114 } 115 }; 116 117 } // namespace flatbuffers 118 119 #endif // FLATBUFFERS_DETACHED_BUFFER_H_ 120