IAP GITLAB

Skip to content
Snippets Groups Projects
BufferedSink.h 2.10 KiB

/*
 * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
 *
 * See file AUTHORS for a list of contributors.
 *
 * This software is distributed under the terms of the GNU General Public
 * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
 * the license.
 */

#ifndef _include_BufferedSink_h_
#define _include_BufferedSink_h_

namespace corsika::logging {

  namespace sink {

    /**
       Output buffer template. NoBuffer does nothingk.
    */
    /*
    struct NoBuffer {
      inline bool Test(const std::string&) const { return false; }
      inline std::string GetString() const { return std::string(""); }
      inline void Clear() {}
      inline void Add(const std::string&) {}
    };
    */
    /**
       Output buffer template. StdBuffer records fSize characters in
       local memeory before passing it on to further output stages.
    */

    struct StdBuffer {
      StdBuffer(const int size)
          : fSize(size) {}
      inline bool Test(const std::string& s) {
        return int(fBuffer.tellp()) + s.length() < fSize;
      }
      inline std::string GetString() const { return fBuffer.str(); }
      inline void Clear() { fBuffer.str(""); }
      inline void Add(const std::string& s) { fBuffer << s; }

    private:
      unsigned int fSize;
      std::ostringstream fBuffer;
    };

    /**
       Definition of Sink for log output.
    */
    template <typename TStream, typename TBuffer = StdBuffer>
    class BufferedSink {
    public:
      BufferedSink(TStream& out, TBuffer buffer = {})
          : fOutput(out)
          , fBuffer(std::move(buffer)) {}
      void operator<<(const std::string& msg) {
        if (!fBuffer.Test(msg)) {
          fOutput << fBuffer.GetString();
          fBuffer.Clear();
        }
        if (!fBuffer.Test(msg))
          fOutput << msg;
        else
          fBuffer.Add(msg);
      }
      void Close() { fOutput << fBuffer.GetString(); }
    private:
      TStream& fOutput;
      TBuffer fBuffer;
    };

    typedef BufferedSink<std::ostream, StdBuffer> BufferedSinkStream;

  } // namespace sink
} // namespace corsika::logging

#endif