git repos / blockattack-game

blame: source/code/Libs/include/cereal/archives/portable_binary.hpp

normal view · raw

7a956470 sago007 2016-02-14 17:09 1
/*! \file binary.hpp
7a956470 sago007 2016-02-14 17:09 2
    \brief Binary input and output archives */
7a956470 sago007 2016-02-14 17:09 3
/*
7a956470 sago007 2016-02-14 17:09 4
  Copyright (c) 2014, Randolph Voorhies, Shane Grant
7a956470 sago007 2016-02-14 17:09 5
  All rights reserved.
7a956470 sago007 2016-02-14 17:09 6
7a956470 sago007 2016-02-14 17:09 7
  Redistribution and use in source and binary forms, with or without
7a956470 sago007 2016-02-14 17:09 8
  modification, are permitted provided that the following conditions are met:
7a956470 sago007 2016-02-14 17:09 9
      * Redistributions of source code must retain the above copyright
7a956470 sago007 2016-02-14 17:09 10
        notice, this list of conditions and the following disclaimer.
7a956470 sago007 2016-02-14 17:09 11
      * Redistributions in binary form must reproduce the above copyright
7a956470 sago007 2016-02-14 17:09 12
        notice, this list of conditions and the following disclaimer in the
7a956470 sago007 2016-02-14 17:09 13
        documentation and/or other materials provided with the distribution.
7a956470 sago007 2016-02-14 17:09 14
      * Neither the name of cereal nor the
7a956470 sago007 2016-02-14 17:09 15
        names of its contributors may be used to endorse or promote products
7a956470 sago007 2016-02-14 17:09 16
        derived from this software without specific prior written permission.
7a956470 sago007 2016-02-14 17:09 17
7a956470 sago007 2016-02-14 17:09 18
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
7a956470 sago007 2016-02-14 17:09 19
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7a956470 sago007 2016-02-14 17:09 20
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7a956470 sago007 2016-02-14 17:09 21
  DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
7a956470 sago007 2016-02-14 17:09 22
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7a956470 sago007 2016-02-14 17:09 23
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7a956470 sago007 2016-02-14 17:09 24
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7a956470 sago007 2016-02-14 17:09 25
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7a956470 sago007 2016-02-14 17:09 26
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7a956470 sago007 2016-02-14 17:09 27
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7a956470 sago007 2016-02-14 17:09 28
*/
7a956470 sago007 2016-02-14 17:09 29
#ifndef CEREAL_ARCHIVES_PORTABLE_BINARY_HPP_
7a956470 sago007 2016-02-14 17:09 30
#define CEREAL_ARCHIVES_PORTABLE_BINARY_HPP_
7a956470 sago007 2016-02-14 17:09 31
6c5f2c01 sago007 2017-03-15 17:56 32
#include "cereal/cereal.hpp"
7a956470 sago007 2016-02-14 17:09 33
#include <sstream>
7a956470 sago007 2016-02-14 17:09 34
#include <limits>
7a956470 sago007 2016-02-14 17:09 35
7a956470 sago007 2016-02-14 17:09 36
namespace cereal
7a956470 sago007 2016-02-14 17:09 37
{
7a956470 sago007 2016-02-14 17:09 38
  namespace portable_binary_detail
7a956470 sago007 2016-02-14 17:09 39
  {
7a956470 sago007 2016-02-14 17:09 40
    //! Returns true if the current machine is little endian
7a956470 sago007 2016-02-14 17:09 41
    /*! @ingroup Internal */
6c5f2c01 sago007 2017-03-15 17:56 42
    inline std::uint8_t is_little_endian()
7a956470 sago007 2016-02-14 17:09 43
    {
7a956470 sago007 2016-02-14 17:09 44
      static std::int32_t test = 1;
7a956470 sago007 2016-02-14 17:09 45
      return *reinterpret_cast<std::int8_t*>( &test ) == 1;
7a956470 sago007 2016-02-14 17:09 46
    }
7a956470 sago007 2016-02-14 17:09 47
7a956470 sago007 2016-02-14 17:09 48
    //! Swaps the order of bytes for some chunk of memory
7a956470 sago007 2016-02-14 17:09 49
    /*! @param data The data as a uint8_t pointer
7a956470 sago007 2016-02-14 17:09 50
        @tparam DataSize The true size of the data
7a956470 sago007 2016-02-14 17:09 51
        @ingroup Internal */
7a956470 sago007 2016-02-14 17:09 52
    template <std::size_t DataSize>
7a956470 sago007 2016-02-14 17:09 53
    inline void swap_bytes( std::uint8_t * data )
7a956470 sago007 2016-02-14 17:09 54
    {
7a956470 sago007 2016-02-14 17:09 55
      for( std::size_t i = 0, end = DataSize / 2; i < end; ++i )
7a956470 sago007 2016-02-14 17:09 56
        std::swap( data[i], data[DataSize - i - 1] );
7a956470 sago007 2016-02-14 17:09 57
    }
7a956470 sago007 2016-02-14 17:09 58
  } // end namespace portable_binary_detail
7a956470 sago007 2016-02-14 17:09 59
7a956470 sago007 2016-02-14 17:09 60
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 61
  //! An output archive designed to save data in a compact binary representation portable over different architectures
7a956470 sago007 2016-02-14 17:09 62
  /*! This archive outputs data to a stream in an extremely compact binary
7a956470 sago007 2016-02-14 17:09 63
      representation with as little extra metadata as possible.
7a956470 sago007 2016-02-14 17:09 64
6c5f2c01 sago007 2017-03-15 17:56 65
      This archive will record the endianness of the data as well as the desired in/out endianness
6c5f2c01 sago007 2017-03-15 17:56 66
      and assuming that the user takes care of ensuring serialized types are the same size
7a956470 sago007 2016-02-14 17:09 67
      across machines, is portable over different architectures.
7a956470 sago007 2016-02-14 17:09 68
7a956470 sago007 2016-02-14 17:09 69
      When using a binary archive and a file stream, you must use the
7a956470 sago007 2016-02-14 17:09 70
      std::ios::binary format flag to avoid having your data altered
7a956470 sago007 2016-02-14 17:09 71
      inadvertently.
7a956470 sago007 2016-02-14 17:09 72
7a956470 sago007 2016-02-14 17:09 73
      \warning This archive has not been thoroughly tested across different architectures.
7a956470 sago007 2016-02-14 17:09 74
               Please report any issues, optimizations, or feature requests at
7a956470 sago007 2016-02-14 17:09 75
               <a href="www.github.com/USCiLab/cereal">the project github</a>.
7a956470 sago007 2016-02-14 17:09 76
7a956470 sago007 2016-02-14 17:09 77
    \ingroup Archives */
7a956470 sago007 2016-02-14 17:09 78
  class PortableBinaryOutputArchive : public OutputArchive<PortableBinaryOutputArchive, AllowEmptyClassElision>
7a956470 sago007 2016-02-14 17:09 79
  {
7a956470 sago007 2016-02-14 17:09 80
    public:
6c5f2c01 sago007 2017-03-15 17:56 81
      //! A class containing various advanced options for the PortableBinaryOutput archive
6c5f2c01 sago007 2017-03-15 17:56 82
      class Options
6c5f2c01 sago007 2017-03-15 17:56 83
      {
6c5f2c01 sago007 2017-03-15 17:56 84
        public:
6c5f2c01 sago007 2017-03-15 17:56 85
          //! Represents desired endianness
6c5f2c01 sago007 2017-03-15 17:56 86
          enum class Endianness : std::uint8_t
6c5f2c01 sago007 2017-03-15 17:56 87
          { big, little };
6c5f2c01 sago007 2017-03-15 17:56 88
6c5f2c01 sago007 2017-03-15 17:56 89
          //! Default options, preserve system endianness
6c5f2c01 sago007 2017-03-15 17:56 90
          static Options Default(){ return Options(); }
6c5f2c01 sago007 2017-03-15 17:56 91
6c5f2c01 sago007 2017-03-15 17:56 92
          //! Save as little endian
6c5f2c01 sago007 2017-03-15 17:56 93
          static Options LittleEndian(){ return Options( Endianness::little ); }
6c5f2c01 sago007 2017-03-15 17:56 94
6c5f2c01 sago007 2017-03-15 17:56 95
          //! Save as big endian
6c5f2c01 sago007 2017-03-15 17:56 96
          static Options BigEndian(){ return Options( Endianness::big ); }
6c5f2c01 sago007 2017-03-15 17:56 97
6c5f2c01 sago007 2017-03-15 17:56 98
          //! Specify specific options for the PortableBinaryOutputArchive
6c5f2c01 sago007 2017-03-15 17:56 99
          /*! @param outputEndian The desired endianness of saved (output) data */
6c5f2c01 sago007 2017-03-15 17:56 100
          explicit Options( Endianness outputEndian = getEndianness() ) :
6c5f2c01 sago007 2017-03-15 17:56 101
            itsOutputEndianness( outputEndian ) { }
6c5f2c01 sago007 2017-03-15 17:56 102
6c5f2c01 sago007 2017-03-15 17:56 103
        private:
6c5f2c01 sago007 2017-03-15 17:56 104
          //! Gets the endianness of the system
6c5f2c01 sago007 2017-03-15 17:56 105
          inline static Endianness getEndianness()
6c5f2c01 sago007 2017-03-15 17:56 106
          { return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }
6c5f2c01 sago007 2017-03-15 17:56 107
6c5f2c01 sago007 2017-03-15 17:56 108
          //! Checks if Options is set for little endian
6c5f2c01 sago007 2017-03-15 17:56 109
          inline std::uint8_t is_little_endian() const
6c5f2c01 sago007 2017-03-15 17:56 110
          { return itsOutputEndianness == Endianness::little; }
6c5f2c01 sago007 2017-03-15 17:56 111
6c5f2c01 sago007 2017-03-15 17:56 112
          friend class PortableBinaryOutputArchive;
6c5f2c01 sago007 2017-03-15 17:56 113
          Endianness itsOutputEndianness;
6c5f2c01 sago007 2017-03-15 17:56 114
      };
6c5f2c01 sago007 2017-03-15 17:56 115
7a956470 sago007 2016-02-14 17:09 116
      //! Construct, outputting to the provided stream
6c5f2c01 sago007 2017-03-15 17:56 117
      /*! @param stream The stream to output to. Should be opened with std::ios::binary flag.
6c5f2c01 sago007 2017-03-15 17:56 118
          @param options The PortableBinary specific options to use.  See the Options struct
6c5f2c01 sago007 2017-03-15 17:56 119
                         for the values of default parameters */
6c5f2c01 sago007 2017-03-15 17:56 120
      PortableBinaryOutputArchive(std::ostream & stream, Options const & options = Options::Default()) :
7a956470 sago007 2016-02-14 17:09 121
        OutputArchive<PortableBinaryOutputArchive, AllowEmptyClassElision>(this),
6c5f2c01 sago007 2017-03-15 17:56 122
        itsStream(stream),
6c5f2c01 sago007 2017-03-15 17:56 123
        itsConvertEndianness( portable_binary_detail::is_little_endian() ^ options.is_little_endian() )
7a956470 sago007 2016-02-14 17:09 124
      {
6c5f2c01 sago007 2017-03-15 17:56 125
        this->operator()( options.is_little_endian() );
7a956470 sago007 2016-02-14 17:09 126
      }
7a956470 sago007 2016-02-14 17:09 127
6c5f2c01 sago007 2017-03-15 17:56 128
      ~PortableBinaryOutputArchive() CEREAL_NOEXCEPT = default;
6c5f2c01 sago007 2017-03-15 17:56 129
7a956470 sago007 2016-02-14 17:09 130
      //! Writes size bytes of data to the output stream
8f94a7f5 sago007 2020-05-10 10:26 131
      template <std::streamsize DataSize> inline
8f94a7f5 sago007 2020-05-10 10:26 132
      void saveBinary( const void * data, std::streamsize size )
7a956470 sago007 2016-02-14 17:09 133
      {
8f94a7f5 sago007 2020-05-10 10:26 134
        std::streamsize writtenSize = 0;
6c5f2c01 sago007 2017-03-15 17:56 135
6c5f2c01 sago007 2017-03-15 17:56 136
        if( itsConvertEndianness )
6c5f2c01 sago007 2017-03-15 17:56 137
        {
8f94a7f5 sago007 2020-05-10 10:26 138
          for( std::streamsize i = 0; i < size; i += DataSize )
8f94a7f5 sago007 2020-05-10 10:26 139
            for( std::streamsize j = 0; j < DataSize; ++j )
8f94a7f5 sago007 2020-05-10 10:26 140
              writtenSize += itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ) + DataSize - j - 1 + i, 1 );
6c5f2c01 sago007 2017-03-15 17:56 141
        }
6c5f2c01 sago007 2017-03-15 17:56 142
        else
8f94a7f5 sago007 2020-05-10 10:26 143
          writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
7a956470 sago007 2016-02-14 17:09 144
7a956470 sago007 2016-02-14 17:09 145
        if(writtenSize != size)
7a956470 sago007 2016-02-14 17:09 146
          throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize));
7a956470 sago007 2016-02-14 17:09 147
      }
7a956470 sago007 2016-02-14 17:09 148
7a956470 sago007 2016-02-14 17:09 149
    private:
7a956470 sago007 2016-02-14 17:09 150
      std::ostream & itsStream;
6c5f2c01 sago007 2017-03-15 17:56 151
      const uint8_t itsConvertEndianness; //!< If set to true, we will need to swap bytes upon saving
7a956470 sago007 2016-02-14 17:09 152
  };
7a956470 sago007 2016-02-14 17:09 153
7a956470 sago007 2016-02-14 17:09 154
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 155
  //! An input archive designed to load data saved using PortableBinaryOutputArchive
7a956470 sago007 2016-02-14 17:09 156
  /*! This archive outputs data to a stream in an extremely compact binary
7a956470 sago007 2016-02-14 17:09 157
      representation with as little extra metadata as possible.
7a956470 sago007 2016-02-14 17:09 158
7a956470 sago007 2016-02-14 17:09 159
      This archive will load the endianness of the serialized data and
7a956470 sago007 2016-02-14 17:09 160
      if necessary transform it to match that of the local machine.  This comes
7a956470 sago007 2016-02-14 17:09 161
      at a significant performance cost compared to non portable archives if
7a956470 sago007 2016-02-14 17:09 162
      the transformation is necessary, and also causes a small performance hit
7a956470 sago007 2016-02-14 17:09 163
      even if it is not necessary.
7a956470 sago007 2016-02-14 17:09 164
7a956470 sago007 2016-02-14 17:09 165
      It is recommended to use portable archives only if you know that you will
7a956470 sago007 2016-02-14 17:09 166
      be sending binary data to machines with different endianness.
7a956470 sago007 2016-02-14 17:09 167
7a956470 sago007 2016-02-14 17:09 168
      The archive will do nothing to ensure types are the same size - that is
7a956470 sago007 2016-02-14 17:09 169
      the responsibility of the user.
7a956470 sago007 2016-02-14 17:09 170
7a956470 sago007 2016-02-14 17:09 171
      When using a binary archive and a file stream, you must use the
7a956470 sago007 2016-02-14 17:09 172
      std::ios::binary format flag to avoid having your data altered
7a956470 sago007 2016-02-14 17:09 173
      inadvertently.
7a956470 sago007 2016-02-14 17:09 174
7a956470 sago007 2016-02-14 17:09 175
      \warning This archive has not been thoroughly tested across different architectures.
7a956470 sago007 2016-02-14 17:09 176
               Please report any issues, optimizations, or feature requests at
7a956470 sago007 2016-02-14 17:09 177
               <a href="www.github.com/USCiLab/cereal">the project github</a>.
7a956470 sago007 2016-02-14 17:09 178
7a956470 sago007 2016-02-14 17:09 179
    \ingroup Archives */
7a956470 sago007 2016-02-14 17:09 180
  class PortableBinaryInputArchive : public InputArchive<PortableBinaryInputArchive, AllowEmptyClassElision>
7a956470 sago007 2016-02-14 17:09 181
  {
7a956470 sago007 2016-02-14 17:09 182
    public:
6c5f2c01 sago007 2017-03-15 17:56 183
      //! A class containing various advanced options for the PortableBinaryInput archive
6c5f2c01 sago007 2017-03-15 17:56 184
      class Options
6c5f2c01 sago007 2017-03-15 17:56 185
      {
6c5f2c01 sago007 2017-03-15 17:56 186
        public:
6c5f2c01 sago007 2017-03-15 17:56 187
          //! Represents desired endianness
6c5f2c01 sago007 2017-03-15 17:56 188
          enum class Endianness : std::uint8_t
6c5f2c01 sago007 2017-03-15 17:56 189
          { big, little };
6c5f2c01 sago007 2017-03-15 17:56 190
6c5f2c01 sago007 2017-03-15 17:56 191
          //! Default options, preserve system endianness
6c5f2c01 sago007 2017-03-15 17:56 192
          static Options Default(){ return Options(); }
6c5f2c01 sago007 2017-03-15 17:56 193
6c5f2c01 sago007 2017-03-15 17:56 194
          //! Load into little endian
6c5f2c01 sago007 2017-03-15 17:56 195
          static Options LittleEndian(){ return Options( Endianness::little ); }
6c5f2c01 sago007 2017-03-15 17:56 196
6c5f2c01 sago007 2017-03-15 17:56 197
          //! Load into big endian
6c5f2c01 sago007 2017-03-15 17:56 198
          static Options BigEndian(){ return Options( Endianness::big ); }
6c5f2c01 sago007 2017-03-15 17:56 199
6c5f2c01 sago007 2017-03-15 17:56 200
          //! Specify specific options for the PortableBinaryInputArchive
6c5f2c01 sago007 2017-03-15 17:56 201
          /*! @param inputEndian The desired endianness of loaded (input) data */
6c5f2c01 sago007 2017-03-15 17:56 202
          explicit Options( Endianness inputEndian = getEndianness() ) :
6c5f2c01 sago007 2017-03-15 17:56 203
            itsInputEndianness( inputEndian ) { }
6c5f2c01 sago007 2017-03-15 17:56 204
6c5f2c01 sago007 2017-03-15 17:56 205
        private:
6c5f2c01 sago007 2017-03-15 17:56 206
          //! Gets the endianness of the system
6c5f2c01 sago007 2017-03-15 17:56 207
          inline static Endianness getEndianness()
6c5f2c01 sago007 2017-03-15 17:56 208
          { return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }
6c5f2c01 sago007 2017-03-15 17:56 209
6c5f2c01 sago007 2017-03-15 17:56 210
          //! Checks if Options is set for little endian
6c5f2c01 sago007 2017-03-15 17:56 211
          inline std::uint8_t is_little_endian() const
6c5f2c01 sago007 2017-03-15 17:56 212
          { return itsInputEndianness == Endianness::little; }
6c5f2c01 sago007 2017-03-15 17:56 213
6c5f2c01 sago007 2017-03-15 17:56 214
          friend class PortableBinaryInputArchive;
6c5f2c01 sago007 2017-03-15 17:56 215
          Endianness itsInputEndianness;
6c5f2c01 sago007 2017-03-15 17:56 216
      };
6c5f2c01 sago007 2017-03-15 17:56 217
7a956470 sago007 2016-02-14 17:09 218
      //! Construct, loading from the provided stream
6c5f2c01 sago007 2017-03-15 17:56 219
      /*! @param stream The stream to read from. Should be opened with std::ios::binary flag.
6c5f2c01 sago007 2017-03-15 17:56 220
          @param options The PortableBinary specific options to use.  See the Options struct
6c5f2c01 sago007 2017-03-15 17:56 221
                         for the values of default parameters */
6c5f2c01 sago007 2017-03-15 17:56 222
      PortableBinaryInputArchive(std::istream & stream, Options const & options = Options::Default()) :
7a956470 sago007 2016-02-14 17:09 223
        InputArchive<PortableBinaryInputArchive, AllowEmptyClassElision>(this),
7a956470 sago007 2016-02-14 17:09 224
        itsStream(stream),
7a956470 sago007 2016-02-14 17:09 225
        itsConvertEndianness( false )
7a956470 sago007 2016-02-14 17:09 226
      {
6c5f2c01 sago007 2017-03-15 17:56 227
        uint8_t streamLittleEndian;
7a956470 sago007 2016-02-14 17:09 228
        this->operator()( streamLittleEndian );
6c5f2c01 sago007 2017-03-15 17:56 229
        itsConvertEndianness = options.is_little_endian() ^ streamLittleEndian;
7a956470 sago007 2016-02-14 17:09 230
      }
7a956470 sago007 2016-02-14 17:09 231
6c5f2c01 sago007 2017-03-15 17:56 232
      ~PortableBinaryInputArchive() CEREAL_NOEXCEPT = default;
6c5f2c01 sago007 2017-03-15 17:56 233
7a956470 sago007 2016-02-14 17:09 234
      //! Reads size bytes of data from the input stream
7a956470 sago007 2016-02-14 17:09 235
      /*! @param data The data to save
7a956470 sago007 2016-02-14 17:09 236
          @param size The number of bytes in the data
7a956470 sago007 2016-02-14 17:09 237
          @tparam DataSize T The size of the actual type of the data elements being loaded */
8f94a7f5 sago007 2020-05-10 10:26 238
      template <std::streamsize DataSize> inline
8f94a7f5 sago007 2020-05-10 10:26 239
      void loadBinary( void * const data, std::streamsize size )
7a956470 sago007 2016-02-14 17:09 240
      {
7a956470 sago007 2016-02-14 17:09 241
        // load data
8f94a7f5 sago007 2020-05-10 10:26 242
        auto const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
7a956470 sago007 2016-02-14 17:09 243
7a956470 sago007 2016-02-14 17:09 244
        if(readSize != size)
7a956470 sago007 2016-02-14 17:09 245
          throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));
7a956470 sago007 2016-02-14 17:09 246
7a956470 sago007 2016-02-14 17:09 247
        // flip bits if needed
7a956470 sago007 2016-02-14 17:09 248
        if( itsConvertEndianness )
7a956470 sago007 2016-02-14 17:09 249
        {
7a956470 sago007 2016-02-14 17:09 250
          std::uint8_t * ptr = reinterpret_cast<std::uint8_t*>( data );
8f94a7f5 sago007 2020-05-10 10:26 251
          for( std::streamsize i = 0; i < size; i += DataSize )
6c5f2c01 sago007 2017-03-15 17:56 252
            portable_binary_detail::swap_bytes<DataSize>( ptr + i );
7a956470 sago007 2016-02-14 17:09 253
        }
7a956470 sago007 2016-02-14 17:09 254
      }
7a956470 sago007 2016-02-14 17:09 255
7a956470 sago007 2016-02-14 17:09 256
    private:
7a956470 sago007 2016-02-14 17:09 257
      std::istream & itsStream;
6c5f2c01 sago007 2017-03-15 17:56 258
      uint8_t itsConvertEndianness; //!< If set to true, we will need to swap bytes upon loading
7a956470 sago007 2016-02-14 17:09 259
  };
7a956470 sago007 2016-02-14 17:09 260
7a956470 sago007 2016-02-14 17:09 261
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 262
  // Common BinaryArchive serialization functions
7a956470 sago007 2016-02-14 17:09 263
7a956470 sago007 2016-02-14 17:09 264
  //! Saving for POD types to portable binary
7a956470 sago007 2016-02-14 17:09 265
  template<class T> inline
7a956470 sago007 2016-02-14 17:09 266
  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
7a956470 sago007 2016-02-14 17:09 267
  CEREAL_SAVE_FUNCTION_NAME(PortableBinaryOutputArchive & ar, T const & t)
7a956470 sago007 2016-02-14 17:09 268
  {
7a956470 sago007 2016-02-14 17:09 269
    static_assert( !std::is_floating_point<T>::value ||
7a956470 sago007 2016-02-14 17:09 270
                   (std::is_floating_point<T>::value && std::numeric_limits<T>::is_iec559),
7a956470 sago007 2016-02-14 17:09 271
                   "Portable binary only supports IEEE 754 standardized floating point" );
6c5f2c01 sago007 2017-03-15 17:56 272
    ar.template saveBinary<sizeof(T)>(std::addressof(t), sizeof(t));
7a956470 sago007 2016-02-14 17:09 273
  }
7a956470 sago007 2016-02-14 17:09 274
7a956470 sago007 2016-02-14 17:09 275
  //! Loading for POD types from portable binary
7a956470 sago007 2016-02-14 17:09 276
  template<class T> inline
7a956470 sago007 2016-02-14 17:09 277
  typename std::enable_if<std::is_arithmetic<T>::value, void>::type
7a956470 sago007 2016-02-14 17:09 278
  CEREAL_LOAD_FUNCTION_NAME(PortableBinaryInputArchive & ar, T & t)
7a956470 sago007 2016-02-14 17:09 279
  {
7a956470 sago007 2016-02-14 17:09 280
    static_assert( !std::is_floating_point<T>::value ||
7a956470 sago007 2016-02-14 17:09 281
                   (std::is_floating_point<T>::value && std::numeric_limits<T>::is_iec559),
7a956470 sago007 2016-02-14 17:09 282
                   "Portable binary only supports IEEE 754 standardized floating point" );
7a956470 sago007 2016-02-14 17:09 283
    ar.template loadBinary<sizeof(T)>(std::addressof(t), sizeof(t));
7a956470 sago007 2016-02-14 17:09 284
  }
7a956470 sago007 2016-02-14 17:09 285
7a956470 sago007 2016-02-14 17:09 286
  //! Serializing NVP types to portable binary
7a956470 sago007 2016-02-14 17:09 287
  template <class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 288
  CEREAL_ARCHIVE_RESTRICT(PortableBinaryInputArchive, PortableBinaryOutputArchive)
7a956470 sago007 2016-02-14 17:09 289
  CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, NameValuePair<T> & t )
7a956470 sago007 2016-02-14 17:09 290
  {
7a956470 sago007 2016-02-14 17:09 291
    ar( t.value );
7a956470 sago007 2016-02-14 17:09 292
  }
7a956470 sago007 2016-02-14 17:09 293
7a956470 sago007 2016-02-14 17:09 294
  //! Serializing SizeTags to portable binary
7a956470 sago007 2016-02-14 17:09 295
  template <class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 296
  CEREAL_ARCHIVE_RESTRICT(PortableBinaryInputArchive, PortableBinaryOutputArchive)
7a956470 sago007 2016-02-14 17:09 297
  CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, SizeTag<T> & t )
7a956470 sago007 2016-02-14 17:09 298
  {
7a956470 sago007 2016-02-14 17:09 299
    ar( t.size );
7a956470 sago007 2016-02-14 17:09 300
  }
7a956470 sago007 2016-02-14 17:09 301
7a956470 sago007 2016-02-14 17:09 302
  //! Saving binary data to portable binary
7a956470 sago007 2016-02-14 17:09 303
  template <class T> inline
7a956470 sago007 2016-02-14 17:09 304
  void CEREAL_SAVE_FUNCTION_NAME(PortableBinaryOutputArchive & ar, BinaryData<T> const & bd)
7a956470 sago007 2016-02-14 17:09 305
  {
7a956470 sago007 2016-02-14 17:09 306
    typedef typename std::remove_pointer<T>::type TT;
7a956470 sago007 2016-02-14 17:09 307
    static_assert( !std::is_floating_point<TT>::value ||
7a956470 sago007 2016-02-14 17:09 308
                   (std::is_floating_point<TT>::value && std::numeric_limits<TT>::is_iec559),
7a956470 sago007 2016-02-14 17:09 309
                   "Portable binary only supports IEEE 754 standardized floating point" );
7a956470 sago007 2016-02-14 17:09 310
8f94a7f5 sago007 2020-05-10 10:26 311
    ar.template saveBinary<sizeof(TT)>( bd.data, static_cast<std::streamsize>( bd.size ) );
7a956470 sago007 2016-02-14 17:09 312
  }
7a956470 sago007 2016-02-14 17:09 313
7a956470 sago007 2016-02-14 17:09 314
  //! Loading binary data from portable binary
7a956470 sago007 2016-02-14 17:09 315
  template <class T> inline
7a956470 sago007 2016-02-14 17:09 316
  void CEREAL_LOAD_FUNCTION_NAME(PortableBinaryInputArchive & ar, BinaryData<T> & bd)
7a956470 sago007 2016-02-14 17:09 317
  {
7a956470 sago007 2016-02-14 17:09 318
    typedef typename std::remove_pointer<T>::type TT;
7a956470 sago007 2016-02-14 17:09 319
    static_assert( !std::is_floating_point<TT>::value ||
7a956470 sago007 2016-02-14 17:09 320
                   (std::is_floating_point<TT>::value && std::numeric_limits<TT>::is_iec559),
7a956470 sago007 2016-02-14 17:09 321
                   "Portable binary only supports IEEE 754 standardized floating point" );
7a956470 sago007 2016-02-14 17:09 322
8f94a7f5 sago007 2020-05-10 10:26 323
    ar.template loadBinary<sizeof(TT)>( bd.data, static_cast<std::streamsize>( bd.size ) );
7a956470 sago007 2016-02-14 17:09 324
  }
7a956470 sago007 2016-02-14 17:09 325
} // namespace cereal
7a956470 sago007 2016-02-14 17:09 326
7a956470 sago007 2016-02-14 17:09 327
// register archives for polymorphic support
7a956470 sago007 2016-02-14 17:09 328
CEREAL_REGISTER_ARCHIVE(cereal::PortableBinaryOutputArchive)
7a956470 sago007 2016-02-14 17:09 329
CEREAL_REGISTER_ARCHIVE(cereal::PortableBinaryInputArchive)
7a956470 sago007 2016-02-14 17:09 330
7a956470 sago007 2016-02-14 17:09 331
// tie input and output archives together
7a956470 sago007 2016-02-14 17:09 332
CEREAL_SETUP_ARCHIVE_TRAITS(cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive)
7a956470 sago007 2016-02-14 17:09 333
7a956470 sago007 2016-02-14 17:09 334
#endif // CEREAL_ARCHIVES_PORTABLE_BINARY_HPP_
1970-01-01 00:00 335