Subversion Repositories spk

Rev

Blame | Last modification | View Log | RSS feed


#ifndef BOB_X2FILE_STREAM_INCLUDED
#define BOB_X2FILE_STREAM_INCLUDED

#include "../common/file_stream.h"
#include "../filedriver/x2fd.h"

/*
        bob_dom_obinaryX2file - output binary stream (x2 filesystem files)
        bob_dom_otextX2file - output text stream (x2 filesystem files)
*/

template <class Ty>
class x2buffer : public mystream::basic_buffer<Ty>
{
        private:
                static const size_t buffer_size=5000;
                
                X2FILE m_hFile;
                unsigned char m_buffer[buffer_size];
                unsigned char *m_bufferPos;
                unsigned char *m_bufferEnd;
                
                bool m_bExternalHandle;
                
                size_t availBuffer() const { return m_bufferEnd - m_bufferPos; }
                
        public:
                virtual operator bool() const { return m_hFile!=0; }
                virtual bool eof() const { return X2FD_EOF(m_hFile)!=0; }
                
                x2buffer() 
                { 
                        m_hFile=0; m_bExternalHandle=false; 
                        m_bufferPos=m_buffer; m_bufferEnd=m_buffer + buffer_size; 
                }
                
                ~x2buffer() { close(); }
                
                bool open(const char *fileName, mystream::filestream_base::OpenMode m)
                {
                        return false;
                }
                
                void changeSize() { X2FD_SetEndOfFile(m_hFile); }
                
                bool open(X2FILE hFile)
                {
                        close();
                        m_hFile=hFile;
                        m_bExternalHandle=true;
                        return hFile!=0;
                }
                
                virtual void close() 
                { 
                        if(m_hFile){
                                flush();
                                X2FD_SetEndOfFile(m_hFile);
                                if(m_bExternalHandle==false)
                                        X2FD_CloseFile(m_hFile);
                                m_hFile=0; 
                                m_bExternalHandle=false;
                        }
                }
                
                bool flush() 
                {
                        size_t s=m_bufferPos - m_buffer;
                        if(s > 0){
                                if(X2FD_WriteFile(m_hFile, m_buffer, (unsigned int)s)!=(unsigned int)s) 
                                        return false;
                                m_bufferPos=m_buffer;
                        }
                        return true;
                }
                
                virtual size_type read(value_type_ptr buffer, size_type size) { return -1; }
                
                virtual size_type write(const_value_type_ptr data, size_type size)
                {
                        size_type res=0;
                        if(size > availBuffer())
                                flush();
                        
                        if(size > availBuffer()){
                                res=X2FD_WriteFile(m_hFile, data, (unsigned int)size);
                        }
                        else{
                                memcpy(m_bufferPos, data, size);
                                m_bufferPos+=size;
                                res=size;
                        }
                        return res;
                }
                
                virtual size_type tellp() const { return tellg(); }
                virtual size_type tellg() const { return X2FD_FileTell(m_hFile); }
                virtual size_type seekp(int offset, mystream::stream_base::seek_type origin) { return seekg(offset, origin); }
                virtual size_type seekg(int offset, mystream::stream_base::seek_type origin) 
                { 
                        int o;
                        size_t res;
                        flush();
                        
                        switch(origin){
                                case mystream::stream_base::seek_begin:
                                        o=X2FD_SEEK_SET;
                                        break;
                                case mystream::stream_base::seek_end:
                                        o=X2FD_SEEK_END;
                                        break;
                                case mystream::stream_base::seek_current:
                                        o=X2FD_SEEK_CUR;
                                        break;
                                default:        
                                        o=-1;
                        }
                        if(o!=-1)
                                res=X2FD_SeekFile(m_hFile, offset, o);
                        else
                                res=0;
                        
                        return res;
                }
};

/*
        doesn't work with new mystream::stream stuff
        
        change mystream::file_stream to be indenpedent (move open to buffer)
        
        change ox2filestream to be buffer for mystream::file_stream 
        
        otextX2file = file_stream<stream<char>, x2buffer<char> >
*/

// these 2 lines added just to lessen number of errors
//typedef mystream::stream<unsigned char *> obinaryfilestream;
//typedef mystream::stream<char *> otextfilestream;

typedef mystream::stream<unsigned char> obinaryfilestream;
typedef mystream::stream<char> otextfilestream;

typedef mystream::file_stream<obinaryfilestream, x2buffer<char> > obinaryX2file;
//typedef mystream::file_stream<otextfilestream, x2buffer<char> > otextX2file;

class otextX2file : public mystream::file_stream<otextfilestream, x2buffer<char> > 
{
        private:
        
        public:
                typedef mystream::file_stream<otextfilestream, x2buffer<char> > base;
                
                bool open(X2FILE hFile)
                {
                        bool res=m_buffer.open(hFile);
                        clear();
                        return res;
                }
};

inline
otextfilestream& operator << (otextfilestream& os, const char *str)
{
        os.write(str, strlen(str));
        return os;
}

inline
otextfilestream& operator << (otextfilestream& os, char ch)
{
        os.write(&ch, 1);
        return os;
}

inline
otextfilestream& operator << (otextfilestream& os, int i)
{
        static char buff[20];
        itoa(i, buff, 10);
        os << buff;
        return os;
}

inline
otextfilestream& endl(otextfilestream& os)
{
        os.write("\r\n", 2);
        return os;
}

inline
otextfilestream& operator << (otextfilestream& os, otextfilestream& f(otextfilestream& os))
{
        return f(os);
}

template <class Ty>
otextfilestream& operator << (otextfilestream& os, Ty &o)
{
        o.toFile(os);
        return os;
}

#endif // !defined(BOB_X2FILE_STREAM_INCLUDED)