#ifndef INCLUDED_BOBCAT_MEMORYBRIDGE_
#define INCLUDED_BOBCAT_MEMORYBRIDGE_

#include <iosfwd>

#include <bobcat/exception>
#include <bobcat/memoryaccess>

namespace FBB
{

class MemoryBridge
{
    MemoryAccess *d_accessPtr;          // points to the attached shared
                                        // memory. This is NOT a pointer
                                        // to dynamically allocated memory
                                        // but a static_cast pointer to
                                        // the attached shared data segment
    bool d_erase;

    size_t d_offset;

    MemoryAccess *(MemoryBridge::*d_access)() const;

    public:
        MemoryBridge();                                                 // 1.

        MemoryBridge(MemoryBridge &&tmp);                               // 2.

        MemoryBridge(std::string const &bufSize, bool erase,           // 3.
                     size_t access = 0600);

        MemoryBridge(int id, bool erase);                              // 4. 

        ~MemoryBridge();        // detach all data from MemoryAccess,
                                // then detach MemoryAccess itself.
                                // to eventually erase the shared data
                                // segments themself a separate 'erase'
                                // facility is needed.

        MemoryBridge &operator=(MemoryBridge &&tmp) = default;

        char *beginPtr();                                               // .f

        std::streamsize blockBegin() const;                             // .f
        std::streamsize blockEnd() const;                               // .f
        std::streamsize blockSize() const;                              // .f

        void bufLimits();                                               // .f

        char *endPtr();                                                 // .f
        char *endReadPtr();                                             // .f

        void extend();      // extend the memory size to the current    // .f
                            // d_blockEnd

        int id() const;                 // MemoryAccess's id            // .f
        void info(std::ostream &out) const;

        bool load();                                                    // .f

        std::streamsize maxEnd() const;                                 // .f

        std::streamsize offset() const;                                 // 1.f
        void offset(std::streamsize pos);                               // 2.f
        char *offsetPtr();                                              // .f

                                        // read len chars, return nRead    .f
        size_t read(char *dest, std::streamsize len);

        void setErase(bool erase);                                      // .f

        std::streamsize showmanyc() const;                              // .f

        void swap(MemoryBridge &other);

        void truncate(std::streamsize size);                            // .f

        size_t write(char const *dest, std::streamsize len);            // .f

        std::streamsize writtenUntil() const; // last written byte offset  1.f
        void writtenUntil(std::streamsize offset);                       //2.f

    private:
        MemoryAccess *available() const;           // returns *d_accessPtr
        MemoryAccess &requireAccess() const;                            // .f
        MemoryAccess *unavailable() const;         // throws: no d_accessPtr
};

#include "memorybridge.f"

} // FBB

#endif


