1 // Copyright 2016 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_ARRAY_DATA_VIEW_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_DATA_VIEW_H_ 7 8 #include <type_traits> 9 10 #include "mojo/public/cpp/bindings/lib/array_internal.h" 11 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" 12 #include "mojo/public/cpp/bindings/lib/serialization_context.h" 13 #include "mojo/public/cpp/bindings/lib/serialization_forward.h" 14 15 namespace mojo { 16 namespace internal { 17 18 template <typename T, typename EnableType = void> 19 class ArrayDataViewImpl; 20 21 template <typename T> 22 class ArrayDataViewImpl< 23 T, 24 typename std::enable_if< 25 BelongsTo<T, MojomTypeCategory::POD>::value>::type> { 26 public: 27 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 28 ArrayDataViewImpl(Data_ * data,SerializationContext * context)29 ArrayDataViewImpl(Data_* data, SerializationContext* context) 30 : data_(data), context_(context) {} 31 32 T operator[](size_t index) const { return data_->at(index); } 33 data()34 const T* data() const { return data_->storage(); } 35 36 protected: 37 Data_* data_; 38 SerializationContext* context_; 39 }; 40 41 template <typename T> 42 class ArrayDataViewImpl< 43 T, 44 typename std::enable_if< 45 BelongsTo<T, MojomTypeCategory::BOOLEAN>::value>::type> { 46 public: 47 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 48 ArrayDataViewImpl(Data_ * data,SerializationContext * context)49 ArrayDataViewImpl(Data_* data, SerializationContext* context) 50 : data_(data), context_(context) {} 51 52 bool operator[](size_t index) const { return data_->at(index); } 53 54 protected: 55 Data_* data_; 56 SerializationContext* context_; 57 }; 58 59 template <typename T> 60 class ArrayDataViewImpl< 61 T, 62 typename std::enable_if< 63 BelongsTo<T, MojomTypeCategory::ENUM>::value>::type> { 64 public: 65 static_assert(sizeof(T) == sizeof(int32_t), "Unexpected enum size"); 66 67 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 68 ArrayDataViewImpl(Data_ * data,SerializationContext * context)69 ArrayDataViewImpl(Data_* data, SerializationContext* context) 70 : data_(data), context_(context) {} 71 72 T operator[](size_t index) const { return static_cast<T>(data_->at(index)); } 73 data()74 const T* data() const { return reinterpret_cast<const T*>(data_->storage()); } 75 76 template <typename U> Read(size_t index,U * output)77 bool Read(size_t index, U* output) { 78 return Deserialize<T>(data_->at(index), output); 79 } 80 81 protected: 82 Data_* data_; 83 SerializationContext* context_; 84 }; 85 86 template <typename T> 87 class ArrayDataViewImpl< 88 T, 89 typename std::enable_if< 90 BelongsTo<T, 91 MojomTypeCategory::ASSOCIATED_INTERFACE | 92 MojomTypeCategory::ASSOCIATED_INTERFACE_REQUEST | 93 MojomTypeCategory::INTERFACE | 94 MojomTypeCategory::INTERFACE_REQUEST>::value>::type> { 95 public: 96 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 97 ArrayDataViewImpl(Data_ * data,SerializationContext * context)98 ArrayDataViewImpl(Data_* data, SerializationContext* context) 99 : data_(data), context_(context) {} 100 101 template <typename U> Take(size_t index)102 U Take(size_t index) { 103 U result; 104 bool ret = Deserialize<T>(&data_->at(index), &result, context_); 105 DCHECK(ret); 106 return result; 107 } 108 109 protected: 110 Data_* data_; 111 SerializationContext* context_; 112 }; 113 114 template <typename T> 115 class ArrayDataViewImpl< 116 T, 117 typename std::enable_if< 118 BelongsTo<T, MojomTypeCategory::HANDLE>::value>::type> { 119 public: 120 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 121 ArrayDataViewImpl(Data_ * data,SerializationContext * context)122 ArrayDataViewImpl(Data_* data, SerializationContext* context) 123 : data_(data), context_(context) {} 124 Take(size_t index)125 T Take(size_t index) { 126 T result; 127 bool ret = Deserialize<T>(&data_->at(index), &result, context_); 128 DCHECK(ret); 129 return result; 130 } 131 132 protected: 133 Data_* data_; 134 SerializationContext* context_; 135 }; 136 137 template <typename T> 138 class ArrayDataViewImpl<T, 139 typename std::enable_if<BelongsTo< 140 T, 141 MojomTypeCategory::ARRAY | MojomTypeCategory::MAP | 142 MojomTypeCategory::STRING | 143 MojomTypeCategory::STRUCT>::value>::type> { 144 public: 145 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 146 ArrayDataViewImpl(Data_ * data,SerializationContext * context)147 ArrayDataViewImpl(Data_* data, SerializationContext* context) 148 : data_(data), context_(context) {} 149 GetDataView(size_t index,T * output)150 void GetDataView(size_t index, T* output) { 151 *output = T(data_->at(index).Get(), context_); 152 } 153 154 template <typename U> Read(size_t index,U * output)155 bool Read(size_t index, U* output) { 156 return Deserialize<T>(data_->at(index).Get(), output, context_); 157 } 158 159 protected: 160 Data_* data_; 161 SerializationContext* context_; 162 }; 163 164 template <typename T> 165 class ArrayDataViewImpl< 166 T, 167 typename std::enable_if< 168 BelongsTo<T, MojomTypeCategory::UNION>::value>::type> { 169 public: 170 using Data_ = typename MojomTypeTraits<ArrayDataView<T>>::Data; 171 ArrayDataViewImpl(Data_ * data,SerializationContext * context)172 ArrayDataViewImpl(Data_* data, SerializationContext* context) 173 : data_(data), context_(context) {} 174 GetDataView(size_t index,T * output)175 void GetDataView(size_t index, T* output) { 176 *output = T(&data_->at(index), context_); 177 } 178 179 template <typename U> Read(size_t index,U * output)180 bool Read(size_t index, U* output) { 181 return Deserialize<T>(&data_->at(index), output, context_); 182 } 183 184 protected: 185 Data_* data_; 186 SerializationContext* context_; 187 }; 188 189 } // namespace internal 190 191 template <typename K, typename V> 192 class MapDataView; 193 194 template <typename T> 195 class ArrayDataView : public internal::ArrayDataViewImpl<T> { 196 public: 197 using Element = T; 198 using Data_ = typename internal::ArrayDataViewImpl<T>::Data_; 199 ArrayDataView()200 ArrayDataView() : internal::ArrayDataViewImpl<T>(nullptr, nullptr) {} 201 ArrayDataView(Data_ * data,internal::SerializationContext * context)202 ArrayDataView(Data_* data, internal::SerializationContext* context) 203 : internal::ArrayDataViewImpl<T>(data, context) {} 204 is_null()205 bool is_null() const { return !this->data_; } 206 size()207 size_t size() const { return this->data_->size(); } 208 209 // Methods to access elements are different for different element types. They 210 // are inherited from internal::ArrayDataViewImpl: 211 212 // POD types except boolean and enums: 213 // T operator[](size_t index) const; 214 // const T* data() const; 215 216 // Boolean: 217 // bool operator[](size_t index) const; 218 219 // Enums: 220 // T operator[](size_t index) const; 221 // const T* data() const; 222 // template <typename U> 223 // bool Read(size_t index, U* output); 224 225 // Handles: 226 // T Take(size_t index); 227 228 // Interfaces: 229 // template <typename U> 230 // U Take(size_t index); 231 232 // Object types: 233 // void GetDataView(size_t index, T* output); 234 // template <typename U> 235 // bool Read(size_t index, U* output); 236 237 private: 238 template <typename K, typename V> 239 friend class MapDataView; 240 }; 241 242 } // namespace mojo 243 244 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_DATA_VIEW_H_ 245