1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_UTILITY_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_UTILITY_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstdint> 54535179ba093861ecdb408fb34adcc947957f86fCorey Tabaka#include <cstdlib> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <iterator> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/sequence.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utilities for testing object serialization. 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ByteBuffer { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using iterator = uint8_t*; 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using const_iterator = const uint8_t*; 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using size_type = size_t; 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ByteBuffer() = default; 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ByteBuffer(const ByteBuffer& other) { 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko resize(other.size()); 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (other.size()) 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(data_, other.data(), other.size()); 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 274535179ba093861ecdb408fb34adcc947957f86fCorey Tabaka ~ByteBuffer() { std::free(data_); } 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ByteBuffer& operator=(const ByteBuffer& other) { 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko resize(other.size()); 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (other.size()) 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(data_, other.data(), other.size()); 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ByteBuffer& operator=(ByteBuffer&& other) { 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::swap(data_, other.data_); 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::swap(size_, other.size_); 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::swap(capacity_, other.capacity_); 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other.clear(); 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline const uint8_t* data() const { return data_; } 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline uint8_t* data() { return data_; } 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline size_t size() const { return size_; } 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline size_t capacity() const { return capacity_; } 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iterator begin() { return data_; } 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_iterator begin() const { return data_; } 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iterator end() { return data_ + size_; } 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_iterator end() const { return data_ + size_; } 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline bool operator==(const ByteBuffer& other) const { 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size_ == other.size_ && 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (size_ == 0 || memcmp(data_, other.data_, size_) == 0); 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline bool operator!=(const ByteBuffer& other) const { 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return !operator==(other); 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline void reserve(size_t size) { 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size <= capacity_) 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Find next power of 2 (assuming the size is 32 bits for now). 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size--; 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size |= size >> 1; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size |= size >> 2; 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size |= size >> 4; 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size |= size >> 8; 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size |= size >> 16; 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size++; 744535179ba093861ecdb408fb34adcc947957f86fCorey Tabaka void* new_data = data_ ? std::realloc(data_, size) : std::malloc(size); 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(avakulenko): Check for allocation failures. 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko data_ = static_cast<uint8_t*>(new_data); 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko capacity_ = size; 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline void resize(size_t size) { 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko reserve(size); 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_ = size; 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline uint8_t* grow_by(size_t size_delta) { 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t old_size = size_; 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko resize(old_size + size_delta); 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return data_ + old_size; 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko inline void clear() { size_ = 0; } 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint8_t* data_{nullptr}; 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_{0}; 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t capacity_{0}; 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility functions to increment/decrement void pointers to data buffers. 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename OFFSET_T> 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline const void* AdvancePointer(const void* ptr, OFFSET_T offset) { 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return static_cast<const uint8_t*>(ptr) + offset; 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename OFFSET_T> 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void* AdvancePointer(void* ptr, OFFSET_T offset) { 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return static_cast<uint8_t*>(ptr) + offset; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ptrdiff_t PointerDistance(const void* end, const void* begin) { 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return static_cast<const uint8_t*>(end) - static_cast<const uint8_t*>(begin); 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility to build sequences of types. 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename, typename> 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct AppendTypeSequence; 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename... S, template <typename...> class TT> 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct AppendTypeSequence<T, TT<S...>> { 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using type = TT<S..., T>; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility to generate repeated types. 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t N, template <typename...> class TT> 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct RepeatedType { 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using type = typename AppendTypeSequence< 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko T, typename RepeatedType<T, N - 1, TT>::type>::type; 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, template <typename...> class TT> 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct RepeatedType<T, 0, TT> { 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using type = TT<>; 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename V, typename S> 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline V ReturnValueHelper(V value, S /*ignore*/) { 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return value; 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename R, typename V, size_t... S> 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline R GetNTupleHelper(V value, rpc::IndexSequence<S...>) { 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::make_tuple(ReturnValueHelper(value, S)...); 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Returns an N-tuple of type std::tuple<T,...T> containing |value| in each 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// element. 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <size_t N, typename T, 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename R = typename RepeatedType<T, N, std::tuple>::type> 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline R GetNTuple(T value) { 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return GetNTupleHelper<R>(value, rpc::MakeIndexSequence<N>{}); 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass NoOpOutputResourceMapper : public OutputResourceMapper { 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 155f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(const LocalHandle& handle) override { 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 159f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override { 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 163f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(const RemoteHandle& handle) override { 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 167f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle( 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& handle) override { 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 172f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle( 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedChannelHandle& handle) override { 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle( 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteChannelHandle& handle) override { 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass NoOpInputResourceMapper : public InputResourceMapper { 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetFileHandle(FileReference ref, LocalHandle* handle) override { 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalHandle{ref}; 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetChannelHandle(ChannelReference ref, 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* handle) override { 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalChannelHandle{nullptr, ref}; 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass NoOpResourceMapper : public NoOpOutputResourceMapper, 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public NoOpInputResourceMapper {}; 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Simple implementation of the payload interface, required by 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serialize/Deserialize. This is intended for test cases, where compatibility 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// with std::vector is helpful. 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass Payload : public MessageWriter, 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public MessageReader, 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public OutputResourceMapper { 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using BaseType = ByteBuffer; 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using iterator = typename BaseType::iterator; 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using const_iterator = typename BaseType::const_iterator; 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using size_type = typename BaseType::size_type; 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Payload() = default; 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit Payload(size_type count, uint8_t value = 0) { Append(count, value); } 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Payload(const Payload& other) : buffer_(other.buffer_) {} 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Payload(const std::initializer_list<uint8_t>& initializer) { 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_.resize(initializer.size()); 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::copy(initializer.begin(), initializer.end(), buffer_.begin()); 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Payload& operator=(const Payload& other) { 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_ = other.buffer_; 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = 0; 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Payload& operator=(const std::initializer_list<uint8_t>& initializer) { 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_.resize(initializer.size()); 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::copy(initializer.begin(), initializer.end(), buffer_.begin()); 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = 0; 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return *this; 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Compares Payload with Payload. 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool operator==(const Payload& other) const { 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_ == other.buffer_; 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool operator!=(const Payload& other) const { 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_ != other.buffer_; 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Compares Payload with std::vector. 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename Type, typename AllocatorType> 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko operator==(const std::vector<Type, AllocatorType>& other) const { 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_.size() == other.size() && 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcmp(buffer_.data(), other.data(), other.size()) == 0; 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko template <typename Type, typename AllocatorType> 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko operator!=(const std::vector<Type, AllocatorType>& other) const { 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return !operator!=(other); 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iterator begin() { return buffer_.begin(); } 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_iterator begin() const { return buffer_.begin(); } 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iterator end() { return buffer_.end(); } 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const_iterator end() const { return buffer_.end(); } 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Append(size_type count, uint8_t value) { 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* data = buffer_.grow_by(count); 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::fill(data, data + count, value); 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Clear() { 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_.clear(); 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.clear(); 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = 0; 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Rewind() { read_pos_ = 0; } 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint8_t* Data() { return buffer_.data(); } 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const uint8_t* Data() const { return buffer_.data(); } 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_type Size() const { return buffer_.size(); } 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // MessageWriter 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void* GetNextWriteBufferSection(size_t size) override { 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_.grow_by(size); 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko OutputResourceMapper* GetOutputResourceMapper() override { return this; } 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // OutputResourceMapper 283f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(const LocalHandle& handle) override { 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.Get()); 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 293f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override { 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.Get()); 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 303f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(const RemoteHandle& handle) override { 304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 307f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle( 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& handle) override { 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.value()); 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 318f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle( 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedChannelHandle& handle) override { 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.value()); 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 329f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle( 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteChannelHandle& handle) override { 331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // MessageReader 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BufferSection GetNextReadBufferSection() override { 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {buffer_.data() + read_pos_, &*buffer_.end()}; 337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void ConsumeReadBufferSectionData(const void* new_start) override { 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = PointerDistance(new_start, buffer_.data()); 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko InputResourceMapper* GetInputResourceMapper() override { 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return &input_resource_mapper_; 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int* FdArray() const { return file_handles_.data(); } 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::size_t FdCount() const { return file_handles_.size(); } 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko NoOpInputResourceMapper input_resource_mapper_; 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ByteBuffer buffer_; 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<int> file_handles_; 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t read_pos_{0}; 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Helper macros for branch prediction hinting. 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifdef __GNUC__ 362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_LIKELY(x) __builtin_expect(!!(x), true) 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_UNLIKELY(x) __builtin_expect(!!(x), false) 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#else 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_LIKELY(x) (x) 366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define PDX_UNLIKELY(x) (x) 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif 368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_PDX_UTILITY_H_ 370