#ifndef _INCLUDED_BOBCAT_OFDSTREAMBUF_
#define _INCLUDED_BOBCAT_OFDSTREAMBUF_

#include <streambuf>

namespace FBB
{    
    class OFdStreambuf: public std::streambuf
    {
        public:
                // Mode defines what to do with the file descriptor at
                // destruction-time or when the default open is
                // called. CLOSE_FD will close the fd, KEEP_FD will leave the
                // fd as-is. When open is called with a Mode argument, then
                // the provided argument is used for the actual fd. The Mode
                // specified at the constructor is therefore only used for the
                // mode-less open() call and for the destructor.
            enum Mode
            {
                CLOSE_FD,
                KEEP_FD,
            };

        private:
            Mode        d_mode;
            size_t    d_n;
            int         d_fd;
            char       *d_buffer;

        public:
            OFdStreambuf()
            :
                d_mode(CLOSE_FD),          // comply with old default
                d_n(0),
                d_buffer(0)
            {}
            OFdStreambuf(Mode mode)
            :
                d_mode(mode),
                d_n(0),
                d_buffer(0)
            {}
            OFdStreambuf(int fd, size_t n = 1)
            :
                d_mode(CLOSE_FD),
                d_buffer(0)
            {
                open(fd, CLOSE_FD, n);
            }
            OFdStreambuf(int fd, Mode mode, size_t n = 1)
            :
                d_mode(mode),
                d_buffer(0)
            {
                open(fd, CLOSE_FD, n);
            }
    
            ~OFdStreambuf()
            {
                cleanup(d_mode);
            }
    
            void open(int fd, Mode mode, size_t n = 1);

            void open(int fd, size_t n = 1)
            {
                open(fd, d_mode, n);
            }

            int sync();
            int overflow(int c);

        private:
            OFdStreambuf(OFdStreambuf const &other);              // NI
            OFdStreambuf &operator=(OFdStreambuf const &other);   // NI

            void cleanup(Mode mode);
    };
}

#endif
