1 /* 2 * Copyright 2021, The Android Open Source Project 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 #pragma once 18 19 #include <array> 20 #include <cstdint> 21 22 namespace cuttlefish { 23 namespace confui { 24 namespace support { 25 using auth_token_key_t = std::array<std::uint8_t, 32>; 26 using hmac_t = auth_token_key_t; 27 28 template <typename T> 29 auto bytes_cast(const T& v) -> const uint8_t (&)[sizeof(T)] { 30 return *reinterpret_cast<const uint8_t(*)[sizeof(T)]>(&v); 31 } 32 template <typename T> 33 auto bytes_cast(T& v) -> uint8_t (&)[sizeof(T)] { 34 return *reinterpret_cast<uint8_t(*)[sizeof(T)]>(&v); 35 } 36 37 template <typename IntType, uint32_t byteOrder> 38 struct choose_hton; 39 40 template <typename IntType> 41 struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> { 42 inline static IntType hton(const IntType& value) { 43 IntType result = {}; 44 const unsigned char* inbytes = 45 reinterpret_cast<const unsigned char*>(&value); 46 unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result); 47 for (int i = sizeof(IntType) - 1; i >= 0; --i) { 48 *(outbytes++) = inbytes[i]; 49 } 50 return result; 51 } 52 }; 53 54 template <typename IntType> 55 struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> { 56 inline static IntType hton(const IntType& value) { return value; } 57 }; 58 59 template <typename IntType> 60 inline IntType hton(const IntType& value) { 61 return choose_hton<IntType, __BYTE_ORDER__>::hton(value); 62 } 63 64 class ByteBufferProxy { 65 template <typename T> 66 struct has_data { 67 template <typename U> 68 static int f(const U*, const void*) { 69 return 0; 70 } 71 template <typename U> 72 static int* f(const U* u, decltype(u->data())) { 73 return nullptr; 74 } 75 static constexpr bool value = 76 std::is_pointer<decltype(f((T*)nullptr, ""))>::value; 77 }; 78 79 public: 80 template <typename T> 81 ByteBufferProxy(const T& buffer, decltype(buffer.data()) = nullptr) 82 : data_(reinterpret_cast<const uint8_t*>(buffer.data())), 83 size_(buffer.size()) { 84 static_assert(sizeof(decltype(*buffer.data())) == 1, "elements to large"); 85 } 86 87 // this overload kicks in for types that have .c_str() but not .data(), such 88 // as hidl_string. std::string has both so we need to explicitly disable this 89 // overload if .data() is present. 90 template <typename T> 91 ByteBufferProxy( 92 const T& buffer, 93 std::enable_if_t<!has_data<T>::value, decltype(buffer.c_str())> = nullptr) 94 : data_(reinterpret_cast<const uint8_t*>(buffer.c_str())), 95 size_(buffer.size()) { 96 static_assert(sizeof(decltype(*buffer.c_str())) == 1, "elements to large"); 97 } 98 99 template <size_t size> 100 ByteBufferProxy(const char (&buffer)[size]) 101 : data_(reinterpret_cast<const uint8_t*>(buffer)), size_(size - 1) { 102 static_assert(size > 0, "even an empty string must be 0-terminated"); 103 } 104 105 template <size_t size> 106 ByteBufferProxy(const uint8_t (&buffer)[size]) : data_(buffer), size_(size) {} 107 108 ByteBufferProxy() : data_(nullptr), size_(0) {} 109 110 const uint8_t* data() const { return data_; } 111 size_t size() const { return size_; } 112 113 const uint8_t* begin() const { return data_; } 114 const uint8_t* end() const { return data_ + size_; } 115 116 private: 117 const uint8_t* data_; 118 size_t size_; 119 }; 120 121 // copied from: 122 // hardware/interface/confirmationui/support/include/android/hardware/confirmationui/support/confirmationui_utils.h 123 124 } // end of namespace support 125 } // end of namespace confui 126 } // end of namespace cuttlefish 127