1 // Copyright 2021 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNWIRE_BUFFERCONSUMER_IMPL_H_ 16 #define DAWNWIRE_BUFFERCONSUMER_IMPL_H_ 17 18 #include "dawn_wire/BufferConsumer.h" 19 20 #include <limits> 21 #include <type_traits> 22 23 namespace dawn_wire { 24 25 template <typename BufferT> 26 template <typename T> Peek(T ** data)27 WireResult BufferConsumer<BufferT>::Peek(T** data) { 28 if (sizeof(T) > mSize) { 29 return WireResult::FatalError; 30 } 31 32 *data = reinterpret_cast<T*>(mBuffer); 33 return WireResult::Success; 34 } 35 36 template <typename BufferT> 37 template <typename T> Next(T ** data)38 WireResult BufferConsumer<BufferT>::Next(T** data) { 39 if (sizeof(T) > mSize) { 40 return WireResult::FatalError; 41 } 42 43 *data = reinterpret_cast<T*>(mBuffer); 44 mBuffer += sizeof(T); 45 mSize -= sizeof(T); 46 return WireResult::Success; 47 } 48 49 template <typename BufferT> 50 template <typename T, typename N> NextN(N count,T ** data)51 WireResult BufferConsumer<BufferT>::NextN(N count, T** data) { 52 static_assert(std::is_unsigned<N>::value, "|count| argument of NextN must be unsigned."); 53 54 constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T); 55 if (count > kMaxCountWithoutOverflows) { 56 return WireResult::FatalError; 57 } 58 59 // Cannot overflow because |count| is not greater than |kMaxCountWithoutOverflows|. 60 size_t totalSize = sizeof(T) * count; 61 if (totalSize > mSize) { 62 return WireResult::FatalError; 63 } 64 65 *data = reinterpret_cast<T*>(mBuffer); 66 mBuffer += totalSize; 67 mSize -= totalSize; 68 return WireResult::Success; 69 } 70 71 } // namespace dawn_wire 72 73 #endif // DAWNWIRE_BUFFERCONSUMER_IMPL_H_ 74