1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIB_FIDL_CPP_MESSAGE_PART_H_ 6 #define LIB_FIDL_CPP_MESSAGE_PART_H_ 7 8 #include <stdint.h> 9 #include <string.h> 10 11 #include <zircon/types.h> 12 13 namespace fidl { 14 15 // Part of a FIDL message. 16 // 17 // A FIDL message has two parts: the bytes and the handles. This class is used 18 // to represent both kinds of parts. 19 // 20 // Each part of the message has a data buffer, which contains the actual data 21 // for that part of the message, a capacity for that buffer, and the actual 22 // amount of data stored in the buffer, which might be less that the capacity if 23 // the buffer is not completely full. 24 template<typename T> 25 class MessagePart { 26 public: 27 using value_type = T; 28 using const_iterator = const T*; 29 30 // A message part with no storage. MessagePart()31 MessagePart() : data_(nullptr), capacity_(0u), actual_(0u) {} 32 33 // A message part that uses the given storage. 34 // 35 // The constructed |MessagePart| object does not take ownership of the given 36 // storage. 37 MessagePart(T* data, uint32_t capacity, uint32_t actual = 0u) data_(data)38 : data_(data), capacity_(capacity), actual_(actual) {} 39 40 MessagePart(const MessagePart& other) = delete; 41 MessagePart& operator=(const MessagePart& other) = delete; 42 MessagePart(MessagePart && other)43 MessagePart(MessagePart&& other) 44 : data_(other.data_), 45 capacity_(other.capacity_), 46 actual_(other.actual_) { 47 other.data_ = nullptr; 48 other.capacity_ = 0u; 49 other.actual_ = 0u; 50 } 51 52 MessagePart& operator=(MessagePart&& other) { 53 if (this == &other) 54 return *this; 55 data_ = other.data_; 56 capacity_ = other.capacity_; 57 actual_ = other.actual_; 58 other.data_ = nullptr; 59 other.capacity_ = 0u; 60 other.actual_ = 0u; 61 return *this; 62 } 63 64 // The data stored in this part of the message. data()65 T* data() const { return data_; } 66 67 // The total amount of storage available for this part of the message. 68 // 69 // This part of the message might not actually use all of this storage. To 70 // determine how much storage is actually being used, see |actual()|. capacity()71 uint32_t capacity() const { return capacity_; } 72 73 // The amount of storage that is actually being used for this part of the 74 // message. 75 // 76 // There might be more storage available than is actually being used. To 77 // determine how much storage is available, see |capacity()|. actual()78 uint32_t actual() const { return actual_; } set_actual(uint32_t actual)79 void set_actual(uint32_t actual) { actual_ = actual; } 80 begin()81 T* begin() { return data_; } begin()82 const T* begin() const { return data_; } cbegin()83 const T* cbegin() const { return data_; } 84 end()85 T* end() { return data_ + actual_; } end()86 const T* end() const { return data_ + actual_; } cend()87 const T* cend() const { return data_ + actual_; } 88 size()89 size_t size() const { return actual_; } 90 91 private: 92 T* data_; 93 uint32_t capacity_; 94 uint32_t actual_; 95 }; 96 97 using BytePart = MessagePart<uint8_t>; 98 using HandlePart = MessagePart<zx_handle_t>; 99 100 } // namespace fidl 101 102 #endif // LIB_FIDL_CPP_MESSAGE_PART_H_ 103