.. _program_listing_file_liberate_serialization_integer.h: Program Listing for File integer.h ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``liberate/serialization/integer.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * This file is part of liberate. * * Author(s): Jens Finkhaeuser * * Copyright (c) 2020-2021 Jens Finkhaeuser. * Copyright (c) 2022 Interpeer gUG (haftungsbeschränkt) * * SPDX-License-Identifier: GPL-3.0-only * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LIBERATE_SERIALIZATION_INTEGER_H #define LIBERATE_SERIALIZATION_INTEGER_H #ifndef __cplusplus #error You are trying to include a C++ only header file #endif #include #include #include #include namespace liberate::serialization { template struct enable_integer_serialization {}; template struct enable_integer_serialization : enable_integer_serialization {}; template struct enable_integer_serialization : enable_integer_serialization {}; template struct enable_integer_serialization : enable_integer_serialization {}; template using integer_serialization_enabled = typename enable_integer_serialization::type; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; #if defined(LIBERATE_HAVE_WHCAR_T) template <> struct enable_integer_serialization { using type = std::size_t; }; #endif #if defined(LIBERATE_HAVE_CHAR8_T) template <> struct enable_integer_serialization { using type = std::size_t; }; #endif template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; template <> struct enable_integer_serialization { using type = std::size_t; }; namespace detail { template < typename outT, typename inT > constexpr integer_serialization_enabled serialize_int_impl(outT * output, std::size_t const & output_length, inT const & value) { if (!output || !output_length) { return 0; } constexpr std::size_t const input_size = sizeof(inT); constexpr std::size_t const out_unit_size = sizeof(outT); if (input_size > out_unit_size * output_length) { return 0; } std::size_t written = 0; for (std::size_t i = 0 ; i < input_size / out_unit_size ; ++i) { output[i] = static_cast(value >> ((input_size - ((i + 1) * out_unit_size)) * 8) ); ++written; } return written; } template < typename outT, typename inT > constexpr integer_serialization_enabled deserialize_int_impl(outT & output, inT const * input, std::size_t input_length) { if (!input || !input_length) { return 0; } constexpr std::size_t const output_size = sizeof(outT); constexpr std::size_t const in_unit_size = sizeof(inT); if (output_size > in_unit_size * input_length) { return 0; } std::size_t read = 0; output = outT{0}; using unsigned_inT = typename std::make_unsigned::type; constexpr unsigned_inT const IN_MASK = ~unsigned_inT{0}; for (std::size_t i = output_size / in_unit_size ; i > 0 ; --i) { output += (static_cast(input[i - 1]) & IN_MASK) << (output_size - (i * in_unit_size)) * 8; ++read; // flawfinder: ignore } return read; // flawfinder: ignore } } // namespace detail template < typename outT, typename inT, std::enable_if_t::value, int> = 0 > constexpr integer_serialization_enabled serialize_int(outT * output, std::size_t output_length, inT const & value) { return detail::serialize_int_impl(output, output_length, value); } template < typename outT, typename inT, std::enable_if_t::value, int> = 0 > constexpr integer_serialization_enabled deserialize_int(outT & output, inT const * input, std::size_t const & input_length) { return detail::deserialize_int_impl(output, input, input_length); } } // namespace liberate::serialization #endif // guard