#ifndef INCLUDED_BOBCAT_SHAREDSTREAMBUF_
#define INCLUDED_BOBCAT_SHAREDSTREAMBUF_

#include <ios>
#include <streambuf>

#include <bobcat/sharedmemory>

namespace FBB
{

class SharedStreambuf: public std::streambuf, public virtual SharedEnum__
{
    std::ios::openmode d_openMode;
    std::ios::openmode d_currentMode;       // initially openMode, thereafter
                                            // either ::in or ::out
    SharedMemory d_memory;

    public:
        SharedStreambuf();                                      // 1

        SharedStreambuf(
                size_t maxSize, SizeUnit sizeUnit,              // 2
                std::ios::openmode openMode = std::ios::in | std::ios::out,
                size_t access = 0600);

        SharedStreambuf(                                        // 3
                int id,
                std::ios::openmode openMode = std::ios::in | std::ios::out);

        virtual ~SharedStreambuf();

        int id() const;                 // id of the shared Memory segment

        void kill();                    // kill all shared segments w/o locks
                                        // the object is unusable hereafter

        void remove();                  // remove all shared segments.
                                        // the object is unusable hereafter

        void clear();                   // clear all existing data and reduce
                                        // until only the segment at 
                                        // d_sharedData

        void setMemory(SharedMemory &&tmp);

        void memInfo(std::ostream &out) const;

    protected:
        void setOpenMode(std::ios::openmode openMode);        
        
    private:
        bool mode(std::ios::openmode flag);

        int pbackfail(int ch) override;
        std::streamsize showmanyc() override;
        int underflow() override;
        std::streamsize xsgetn(char *buf, std::streamsize n) override;
  
        int overflow(int c) override;
        std::streamsize xsputn(char const *buf, std::streamsize n) override;

        std::ios::pos_type seekoff(
            std::ios::off_type offset, 
            std::ios::seekdir way = std::ios::beg,
            std::ios::openmode mode = std::ios::in | std::ios::out) override;

        std::ios::pos_type seekpos(
            std::ios::pos_type offset, 
            std::ios::openmode mode = std::ios::in | std::ios::out) override;
};

#include "setopenmode.f"
#include "id.f"
#include "remove.f"
#include "kill.f"
#include "clear.f"
#include "setmemory.f"
#include "meminfo.f"

} // FBB        
#endif
