← index
JavaScript.Projects/source/apps/WebAssembly_Ports/ES3Shader/webmx/mx2/include/tee_stream.hpp
Source: JavaScript.Projects/source/apps/WebAssembly_Ports/ES3Shader/webmx/mx2/include/tee_stream.hpp
#ifndef MX_TSTREAM_H

#define MX_TSTREAM_H


#include <iostream>

#include <fstream>

#include <streambuf>

#include <stdexcept>

#include <memory>


namespace mx {

    class TeeBuf : public std::streambuf {
    public:
        TeeBuf(std::streambuf* buf1, std::streambuf* buf2) : buf1(buf1), buf2(buf2) {}

    protected:
        virtual int overflow(int c) override {
            if (buf1 == nullptr || buf2 == nullptr) {
                return traits_type::eof();
            }

            if (traits_type::eq_int_type(c, traits_type::eof())) {
                if (this->sync() == -1) {
                    return traits_type::eof();
                }
                return traits_type::not_eof(c);
            }

            const auto ch = traits_type::to_char_type(c);
            if (traits_type::eq_int_type(buf1->sputc(ch), traits_type::eof()) ||
                traits_type::eq_int_type(buf2->sputc(ch), traits_type::eof())) {
                return traits_type::eof();
            }

            return c;
        }

        virtual int sync() override {
            if (buf1 == nullptr || buf2 == nullptr) {
                return -1;
            }
            int res1 = buf1->pubsync();
            int res2 = buf2->pubsync();
            return (res1 == 0 && res2 == 0) ? 0 : -1;
        }

    private:
        std::streambuf* buf1 = nullptr;
        std::streambuf* buf2 = nullptr;
    };

    class TeeStream : public std::ostream {
    public:
        TeeStream(std::ostream& stream1, std::ostream& stream2)
            : std::ostream(&tbuf), tbuf(stream1.rdbuf(), stream2.rdbuf()) {}

    private:
        TeeBuf tbuf;
    };
    
    extern TeeStream system_out;
    extern TeeStream system_err;
    void redirect();
} 

#endif