diff options
Diffstat (limited to 'src/lib/misc/roughtime/roughtime.cpp')
-rw-r--r-- | src/lib/misc/roughtime/roughtime.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/lib/misc/roughtime/roughtime.cpp b/src/lib/misc/roughtime/roughtime.cpp index c9767546a..94a9a6b82 100644 --- a/src/lib/misc/roughtime/roughtime.cpp +++ b/src/lib/misc/roughtime/roughtime.cpp @@ -21,6 +21,34 @@ namespace Botan { namespace { +template< bool B, class T = void > +using enable_if_t = typename std::enable_if<B,T>::type; + +template<class T> +struct is_array : std::false_type {}; + +template<class T, std::size_t N> +struct is_array<std::array<T,N>>:std::true_type{}; + +template<typename T> +T from_little_endian(const uint8_t* t, size_t N = sizeof(T)) + { + static_assert(sizeof(T)<=sizeof(int64_t),""); + return (N == 0) ? T(0) : (T(static_cast<int64_t>(t[N-1]) << ((N-1)*8)) + from_little_endian<T>(t,N-1)); + } + +template<typename T, enable_if_t<is_array<T>::value>* = nullptr> +T copy(const uint8_t* t) + { + return typecast_copy<T>(t); //arrays are endianess indepedent, so we do a memcpy + } + +template<typename T, enable_if_t<!is_array<T>::value>* = nullptr> +T copy(const uint8_t* t) + { + return from_little_endian<T>(t); //other types are arithmetic, so we account that roughtime serializes as little endian + } + template<typename T> std::map<std::string, std::vector<uint8_t>> unpack_roughtime_packet(T bytes) { @@ -35,7 +63,7 @@ std::map<std::string, std::vector<uint8_t>> unpack_roughtime_packet(T bytes) std::map<std::string, std::vector<uint8_t>> tags; for(uint32_t i=0; i<num_tags; ++i) { - const uint32_t end = ((i+1) == num_tags) ? bytes.size() : start_content + typecast_copy<uint32_t>(buf + 4 + i*4); + const uint32_t end = ((i+1) == num_tags) ? bytes.size() : start_content + from_little_endian<uint32_t>(buf + 4 + i*4); if(end > bytes.size()) { throw Roughtime::Roughtime_Error("Tag end index out of bounds"); } if(end < start) @@ -58,7 +86,7 @@ T get(const std::map<std::string, std::vector<uint8_t>>& map, const std::string& { throw Roughtime::Roughtime_Error("Tag " + label + " not found"); } if(tag->second.size() != sizeof(T)) { throw Roughtime::Roughtime_Error("Tag " + label + " has unexpected size"); } - return typecast_copy<T>(tag->second.data()); + return copy<T>(tag->second.data()); } const std::vector<uint8_t>& get_v(const std::map<std::string, std::vector<uint8_t>>& map, const std::string& label) |