aboutsummaryrefslogtreecommitdiff
path: root/external/cppcodec/detail/codec.hpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-04-13 05:39:25 +0200
committerdec05eba <dec05eba@protonmail.com>2021-04-13 05:41:53 +0200
commit84984bdfd0273b789e0c9bfe397440dd6912912d (patch)
treeb509e5d48e27d727429a39a8b48fda10145875e7 /external/cppcodec/detail/codec.hpp
parentbc26e012f3041529939d38ac522c18499ddff982 (diff)
Include cppcodec instead of using it a system library. Its not available in ubuntu repos for example
Diffstat (limited to 'external/cppcodec/detail/codec.hpp')
-rw-r--r--external/cppcodec/detail/codec.hpp327
1 files changed, 327 insertions, 0 deletions
diff --git a/external/cppcodec/detail/codec.hpp b/external/cppcodec/detail/codec.hpp
new file mode 100644
index 0000000..47d9802
--- /dev/null
+++ b/external/cppcodec/detail/codec.hpp
@@ -0,0 +1,327 @@
+/**
+ * Copyright (C) 2015 Topology LP
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CPPCODEC_DETAIL_CODEC
+#define CPPCODEC_DETAIL_CODEC
+
+#include <assert.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "../data/access.hpp"
+#include "../data/raw_result_buffer.hpp"
+
+namespace cppcodec {
+namespace detail {
+
+// SFINAE: Templates sometimes beat sensible overloads - make sure we don't call the wrong one.
+template <typename T>
+struct non_numeric : std::enable_if<!std::is_arithmetic<T>::value> { };
+
+
+/**
+ * Public interface for all the codecs. For API documentation, see README.md.
+ */
+template <typename CodecImpl>
+class codec
+{
+public:
+ //
+ // Encoding
+
+ // Convenient version, returns an std::string.
+ static std::string encode(const uint8_t* binary, size_t binary_size);
+ static std::string encode(const char* binary, size_t binary_size);
+ // static std::string encode(const T& binary); -> provided by template below
+
+ // Convenient version with templated result type.
+ template <typename Result> static Result encode(const uint8_t* binary, size_t binary_size);
+ template <typename Result> static Result encode(const char* binary, size_t binary_size);
+ template <typename Result = std::string, typename T = std::vector<uint8_t>>
+ static Result encode(const T& binary);
+
+ // Reused result container version. Resizes encoded_result before writing to it.
+ template <typename Result>
+ static void encode(Result& encoded_result, const uint8_t* binary, size_t binary_size);
+ template <typename Result>
+ static void encode(Result& encoded_result, const char* binary, size_t binary_size);
+ template <typename Result, typename T, typename non_numeric<T>::type* = nullptr>
+ static void encode(Result& encoded_result, const T& binary);
+
+ // Raw pointer output, assumes pre-allocated memory with size > encoded_size(binary_size).
+ static size_t encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const uint8_t* binary, size_t binary_size) noexcept;
+ static size_t encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const char* binary, size_t binary_size) noexcept;
+ template<typename T>
+ static size_t encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const T& binary) noexcept;
+
+ // Calculate the exact length of the encoded string based on binary size.
+ static constexpr size_t encoded_size(size_t binary_size) noexcept;
+
+ //
+ // Decoding
+
+ // Convenient version, returns an std::vector<uint8_t>.
+ static std::vector<uint8_t> decode(const char* encoded, size_t encoded_size);
+ // static std::vector<uint8_t> decode(const T& encoded); -> provided by template below
+
+ // Convenient version with templated result type.
+ template <typename Result> static Result decode(const char* encoded, size_t encoded_size);
+ template <typename Result = std::vector<uint8_t>, typename T = std::string>
+ static Result decode(const T& encoded);
+
+ // Reused result container version. Resizes binary_result before writing to it.
+ template <typename Result>
+ static void decode(Result& binary_result, const char* encoded, size_t encoded_size);
+ template <typename Result, typename T, typename non_numeric<T>::type* = nullptr>
+ static void decode(Result& binary_result, const T& encoded);
+
+ // Raw pointer output, assumes pre-allocated memory with size > decoded_max_size(encoded_size).
+ static size_t decode(
+ uint8_t* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size);
+ static size_t decode(
+ char* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size);
+ template<typename T> static size_t decode(
+ uint8_t* binary_result, size_t binary_buffer_size, const T& encoded);
+ template<typename T> static size_t decode(
+ char* binary_result, size_t binary_buffer_size, const T& encoded);
+
+ // Calculate the maximum size of the decoded binary buffer based on the encoded string length.
+ static constexpr size_t decoded_max_size(size_t encoded_size) noexcept;
+};
+
+
+//
+// Inline definitions of the above functions, using CRTP to call into CodecImpl
+//
+
+//
+// Encoding
+
+template <typename CodecImpl>
+inline std::string codec<CodecImpl>::encode(const uint8_t* binary, size_t binary_size)
+{
+ return encode<std::string>(binary, binary_size);
+}
+
+template <typename CodecImpl>
+inline std::string codec<CodecImpl>::encode(const char* binary, size_t binary_size)
+{
+ return encode<std::string>(reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline Result codec<CodecImpl>::encode(const uint8_t* binary, size_t binary_size)
+{
+ Result encoded_result;
+ encode(encoded_result, binary, binary_size);
+ return encoded_result;
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline Result codec<CodecImpl>::encode(const char* binary, size_t binary_size)
+{
+ return encode<Result>(reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename Result, typename T>
+inline Result codec<CodecImpl>::encode(const T& binary)
+{
+ return encode<Result>(data::uchar_data(binary), data::size(binary));
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline void codec<CodecImpl>::encode(
+ Result& encoded_result, const uint8_t* binary, size_t binary_size)
+{
+ // This overload is where we reserve buffer capacity and call into CodecImpl.
+ size_t encoded_buffer_size = encoded_size(binary_size);
+ auto state = data::create_state(encoded_result, data::specific_t());
+ data::init(encoded_result, state, encoded_buffer_size);
+
+ CodecImpl::encode(encoded_result, state, binary, binary_size);
+ data::finish(encoded_result, state);
+ assert(data::size(encoded_result) == encoded_buffer_size);
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline void codec<CodecImpl>::encode(
+ Result& encoded_result, const char* binary, size_t binary_size)
+{
+ encode(encoded_result, reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename Result, typename T, typename non_numeric<T>::type*>
+inline void codec<CodecImpl>::encode(Result& encoded_result, const T& binary)
+{
+ encode(encoded_result, data::uchar_data(binary), data::size(binary));
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const uint8_t* binary, size_t binary_size) noexcept
+{
+ // This overload is where we wrap the result pointer & size.
+ data::raw_result_buffer encoded(encoded_result, encoded_buffer_size);
+ encode(encoded, binary, binary_size);
+
+ size_t encoded_size = data::size(encoded);
+ if (encoded_size < encoded_buffer_size) {
+ encoded_result[encoded_size] = '\0';
+ }
+ return encoded_size;
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const char* binary, size_t binary_size) noexcept
+{
+ // This overload is where we wrap the result pointer & size.
+ return encode(encoded_result, encoded_buffer_size,
+ reinterpret_cast<const uint8_t*>(binary), binary_size);
+}
+
+template <typename CodecImpl>
+template <typename T>
+inline size_t codec<CodecImpl>::encode(
+ char* encoded_result, size_t encoded_buffer_size,
+ const T& binary) noexcept
+{
+ return encode(encoded_result, encoded_buffer_size, data::uchar_data(binary), data::size(binary));
+}
+
+template <typename CodecImpl>
+inline constexpr size_t codec<CodecImpl>::encoded_size(size_t binary_size) noexcept
+{
+ return CodecImpl::encoded_size(binary_size);
+}
+
+
+//
+// Decoding
+
+template <typename CodecImpl>
+inline std::vector<uint8_t> codec<CodecImpl>::decode(const char* encoded, size_t encoded_size)
+{
+ return decode<std::vector<uint8_t>>(encoded, encoded_size);
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline Result codec<CodecImpl>::decode(const char* encoded, size_t encoded_size)
+{
+ Result result;
+ decode(result, encoded, encoded_size);
+ return result;
+}
+
+template <typename CodecImpl>
+template <typename Result, typename T>
+inline Result codec<CodecImpl>::decode(const T& encoded)
+{
+ return decode<Result>(data::char_data(encoded), data::size(encoded));
+}
+
+template <typename CodecImpl>
+template <typename Result>
+inline void codec<CodecImpl>::decode(Result& binary_result, const char* encoded, size_t encoded_size)
+{
+ // This overload is where we reserve buffer capacity and call into CodecImpl.
+ size_t binary_buffer_size = decoded_max_size(encoded_size);
+ auto state = data::create_state(binary_result, data::specific_t());
+ data::init(binary_result, state, binary_buffer_size);
+
+ CodecImpl::decode(binary_result, state, encoded, encoded_size);
+ data::finish(binary_result, state);
+ assert(data::size(binary_result) <= binary_buffer_size);
+}
+
+
+template <typename CodecImpl>
+template <typename Result, typename T, typename non_numeric<T>::type*>
+inline void codec<CodecImpl>::decode(Result& binary_result, const T& encoded)
+{
+ decode(binary_result, data::char_data(encoded), data::size(encoded));
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::decode(
+ uint8_t* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size)
+{
+ return decode(reinterpret_cast<char*>(binary_result), binary_buffer_size, encoded, encoded_size);
+}
+
+template <typename CodecImpl>
+inline size_t codec<CodecImpl>::decode(
+ char* binary_result, size_t binary_buffer_size,
+ const char* encoded, size_t encoded_size)
+{
+ // This overload is where we wrap the result pointer & size.
+ data::raw_result_buffer binary(binary_result, binary_buffer_size);
+ decode(binary, encoded, encoded_size);
+ return data::size(binary);
+}
+
+template <typename CodecImpl>
+template <typename T>
+inline size_t codec<CodecImpl>::decode(
+ uint8_t* binary_result, size_t binary_buffer_size, const T& encoded)
+{
+ return decode(reinterpret_cast<char*>(binary_result), binary_buffer_size, encoded);
+}
+
+template <typename CodecImpl>
+template <typename T>
+inline size_t codec<CodecImpl>::decode(char* binary_result, size_t binary_buffer_size, const T& encoded)
+{
+ return decode(binary_result, binary_buffer_size, data::char_data(encoded), data::size(encoded));
+}
+
+template <typename CodecImpl>
+inline constexpr size_t codec<CodecImpl>::decoded_max_size(size_t encoded_size) noexcept
+{
+ return CodecImpl::decoded_max_size(encoded_size);
+}
+
+
+} // namespace detail
+} // namespace cppcodec
+
+#endif