LCOV - code coverage report
Current view: top level - cereal/archives - binary.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 31 33 93.9 %
Date: 2022-01-16 21:05:07 Functions: 49 51 96.1 %

          Line data    Source code
       1             : /*! \file binary.hpp
       2             :     \brief Binary input and output archives */
       3             : /*
       4             :   Copyright (c) 2014, Randolph Voorhies, Shane Grant
       5             :   All rights reserved.
       6             : 
       7             :   Redistribution and use in source and binary forms, with or without
       8             :   modification, are permitted provided that the following conditions are met:
       9             :       * Redistributions of source code must retain the above copyright
      10             :         notice, this list of conditions and the following disclaimer.
      11             :       * Redistributions in binary form must reproduce the above copyright
      12             :         notice, this list of conditions and the following disclaimer in the
      13             :         documentation and/or other materials provided with the distribution.
      14             :       * Neither the name of the copyright holder nor the
      15             :         names of its contributors may be used to endorse or promote products
      16             :         derived from this software without specific prior written permission.
      17             : 
      18             :   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
      19             :   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      20             :   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      21             :   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
      22             :   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      23             :   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      24             :   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      25             :   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      26             :   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      27             :   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      28             : */
      29             : #ifndef CEREAL_ARCHIVES_BINARY_HPP_
      30             : #define CEREAL_ARCHIVES_BINARY_HPP_
      31             : 
      32             : #include "cereal/cereal.hpp"
      33             : #include <sstream>
      34             : 
      35             : namespace cereal
      36             : {
      37             :   // ######################################################################
      38             :   //! An output archive designed to save data in a compact binary representation
      39             :   /*! This archive outputs data to a stream in an extremely compact binary
      40             :       representation with as little extra metadata as possible.
      41             : 
      42             :       This archive does nothing to ensure that the endianness of the saved
      43             :       and loaded data is the same.  If you need to have portability over
      44             :       architectures with different endianness, use PortableBinaryOutputArchive.
      45             : 
      46             :       When using a binary archive and a file stream, you must use the
      47             :       std::ios::binary format flag to avoid having your data altered
      48             :       inadvertently.
      49             : 
      50             :       \ingroup Archives */
      51             :   class BinaryOutputArchive : public OutputArchive<BinaryOutputArchive, AllowEmptyClassElision>
      52             :   {
      53             :     public:
      54             :       //! Construct, outputting to the provided stream
      55             :       /*! @param stream The stream to output to.  Can be a stringstream, a file stream, or
      56             :                         even cout! */
      57        3704 :       BinaryOutputArchive(std::ostream & stream) :
      58             :         OutputArchive<BinaryOutputArchive, AllowEmptyClassElision>(this),
      59        3704 :         itsStream(stream)
      60        3704 :       { }
      61             : 
      62        3704 :       ~BinaryOutputArchive() CEREAL_NOEXCEPT = default;
      63             : 
      64             :       //! Writes size bytes of data to the output stream
      65     2564755 :       void saveBinary( const void * data, std::streamsize size )
      66             :       {
      67     2564755 :         auto const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
      68             : 
      69     2564755 :         if(writtenSize != size)
      70           0 :           throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize));
      71     2564755 :       }
      72             : 
      73             :     private:
      74             :       std::ostream & itsStream;
      75             :   };
      76             : 
      77             :   // ######################################################################
      78             :   //! An input archive designed to load data saved using BinaryOutputArchive
      79             :   /*  This archive does nothing to ensure that the endianness of the saved
      80             :       and loaded data is the same.  If you need to have portability over
      81             :       architectures with different endianness, use PortableBinaryOutputArchive.
      82             : 
      83             :       When using a binary archive and a file stream, you must use the
      84             :       std::ios::binary format flag to avoid having your data altered
      85             :       inadvertently.
      86             : 
      87             :       \ingroup Archives */
      88             :   class BinaryInputArchive : public InputArchive<BinaryInputArchive, AllowEmptyClassElision>
      89             :   {
      90             :     public:
      91             :       //! Construct, loading from the provided stream
      92        3704 :       BinaryInputArchive(std::istream & stream) :
      93             :         InputArchive<BinaryInputArchive, AllowEmptyClassElision>(this),
      94        3704 :         itsStream(stream)
      95        3704 :       { }
      96             : 
      97        3704 :       ~BinaryInputArchive() CEREAL_NOEXCEPT = default;
      98             : 
      99             :       //! Reads size bytes of data from the input stream
     100     2563755 :       void loadBinary( void * const data, std::streamsize size )
     101             :       {
     102     2563755 :         auto const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
     103             : 
     104     2563755 :         if(readSize != size)
     105           0 :           throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));
     106     2563755 :       }
     107             : 
     108             :     private:
     109             :       std::istream & itsStream;
     110             :   };
     111             : 
     112             :   // ######################################################################
     113             :   // Common BinaryArchive serialization functions
     114             : 
     115             :   //! Saving for POD types to binary
     116             :   template<class T> inline
     117             :   typename std::enable_if<std::is_arithmetic<T>::value, void>::type
     118     2493206 :   CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive & ar, T const & t)
     119             :   {
     120     2493206 :     ar.saveBinary(std::addressof(t), sizeof(t));
     121     2493206 :   }
     122             : 
     123             :   //! Loading for POD types from binary
     124             :   template<class T> inline
     125             :   typename std::enable_if<std::is_arithmetic<T>::value, void>::type
     126     2492206 :   CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive & ar, T & t)
     127             :   {
     128     2492206 :     ar.loadBinary(std::addressof(t), sizeof(t));
     129     2492206 :   }
     130             : 
     131             :   //! Serializing NVP types to binary
     132             :   template <class Archive, class T> inline
     133             :   CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
     134             :   CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, NameValuePair<T> & t )
     135             :   {
     136             :     ar( t.value );
     137             :   }
     138             : 
     139             :   //! Serializing SizeTags to binary
     140             :   template <class Archive, class T> inline
     141             :   CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
     142      162698 :   CEREAL_SERIALIZE_FUNCTION_NAME( Archive & ar, SizeTag<T> & t )
     143             :   {
     144      162698 :     ar( t.size );
     145      162698 :   }
     146             : 
     147             :   //! Saving binary data
     148             :   template <class T> inline
     149       71549 :   void CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive & ar, BinaryData<T> const & bd)
     150             :   {
     151       71549 :     ar.saveBinary( bd.data, static_cast<std::streamsize>( bd.size ) );
     152       71549 :   }
     153             : 
     154             :   //! Loading binary data
     155             :   template <class T> inline
     156       71549 :   void CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive & ar, BinaryData<T> & bd)
     157             :   {
     158       71549 :     ar.loadBinary(bd.data, static_cast<std::streamsize>( bd.size ) );
     159       71549 :   }
     160             : } // namespace cereal
     161             : 
     162             : // register archives for polymorphic support
     163             : CEREAL_REGISTER_ARCHIVE(cereal::BinaryOutputArchive)
     164             : CEREAL_REGISTER_ARCHIVE(cereal::BinaryInputArchive)
     165             : 
     166             : // tie input and output archives together
     167             : CEREAL_SETUP_ARCHIVE_TRAITS(cereal::BinaryInputArchive, cereal::BinaryOutputArchive)
     168             : 
     169             : #endif // CEREAL_ARCHIVES_BINARY_HPP_

Generated by: LCOV version 1.14