Subversion Repositories spk

Rev

Blame | Last modification | View Log | RSS feed

/*
  basic file stream class
*/

#ifndef BOB_DOM_FILESTREAM_INCLUDED
#define BOB_DOM_FILESTREAM_INCLUDED

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "stream.h"

/*
        obinaryfilestream - binary output stream
        otextfilestream - text output stream
*/


class filestream
{
        protected:
                char *m_name;
                
                void name(const char *pszName)
                {
                        delete[] m_name;
                        m_name = _strdup(pszName);
                }
                
        public:
                enum mode{
                        seekbof   =  1,
                        seekeof   =  2,
                        rdonly    =  4,
                        rdwr      =  8,
                        create    = 16,
                        typepck   = 32,
                        typeplain = 64
                };
                
                filestream() { m_name = _strdup(""); }
                filestream(const filestream& other) 
                { 
                        m_name = _strdup(other.name()); 
                }
                
                virtual ~filestream() { delete[] m_name; }
                
                const char *name() const { return m_name; }
                
                virtual bool open(const char *fileName, mode m = seekbof) = 0;
                virtual void close() = 0;
};

class obinaryfilestream : public ostream<char>, public filestream
{
        public:
                virtual size_t seek(int offset, seek_type origin)=0;
};

class otextfilestream : public ostream<char>, public filestream
{
        public:
                static const int bob_addsemicolon = 4;
                
};

class itextfilestream : public istream<char>, public filestream
{

};

class ibinaryfilestream : public istream<unsigned char>, public filestream
{

};

// binary input operators
inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, int& right)
{
        is.read((unsigned char*)&right, sizeof(right));
        right=be2le((unsigned int)right);
        return is;
}

inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, short& right)
{
        is.read((unsigned char*)&right, sizeof(right));
        right=be2le((unsigned short)right);
        return is;
}

inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, double& right)
{
        static const double MULTIPLIER=1.52587890625E-05; // == 1 / 65536
        
        int v;
        is >> v;
        right=v * MULTIPLIER;
        return is;
}

inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, float& right)
{
        static const double MULTIPLIER=1.52587890625E-05; // == 1 / 65536
        
        int v;
        is >> v;
        right=(float)(v * MULTIPLIER);
        return is;
}

inline
ibinaryfilestream& operator >> (ibinaryfilestream& is, char*& right)
{
        char *buff=0, *p;
        size_t size=250, readed;
        buff=new char[size];
        
        size_t start=is.tell();
        while(is.good()){
                readed=is.read((unsigned char*)buff, size);
                if(is.fail()) break;
                if(p=(char*)memchr(buff, 0, readed)) break;
        }
        
        if(p){
                size_t send=is.tell();
                size_t end=(send - readed) + (p - buff);
                
                delete buff;
                size=end - start + 1;
                buff=new char[size];
                is.advance( - ((int)send - (int)start));
                is.read((unsigned char*)buff, size);
        }
        else{
                delete buff;
                buff=0;
        }
        right=buff;
        
        return is;
}

/* binary output operators */
inline 
obinaryfilestream& operator << (obinaryfilestream& os, int right)
{
        right=be2le((unsigned int)right);
        os.write((obinaryfilestream::const_value_type_ptr)&right, sizeof(right));
        return os;
}

inline 
obinaryfilestream& operator << (obinaryfilestream& os, short right)
{
        right=be2le((unsigned short)right);
        os.write((obinaryfilestream::const_value_type_ptr)&right, sizeof(right));
        return os;
}

#include "conversion.h"

inline
obinaryfilestream& operator << (obinaryfilestream& os, double right)
{
        os << conversion::double2int(right);
        return os;
}

inline
obinaryfilestream& operator << (obinaryfilestream& os, float right)
{
        os << conversion::double2int(right);
        return os;
}

inline 
obinaryfilestream& operator << (obinaryfilestream& os, const char *right)
{
        os.write((obinaryfilestream::const_value_type_ptr)right, strlen(right) + 1);
        return os;
}

inline 
obinaryfilestream& operator << (obinaryfilestream& os, char *right)
{
        os << const_cast<const char*>(right);
        return os;
}

/* text output operators */
inline 
otextfilestream& operator << (otextfilestream& os, const char *right)
{
        os.write(right, strlen(right));
        if(os.flags() & otextfilestream::bob_addsemicolon)
                os.write("; ", 2);
        
        return os;
}

inline 
otextfilestream& operator << (otextfilestream& os, char *right)
{
        os << const_cast<const char*>(right);
        return os;
}


inline 
otextfilestream& operator << (otextfilestream& os, int right)
{
        char ch[20];
        if(os.flags() & otextfilestream::hex)
                sprintf(ch, "%X", right);
        else
                _itoa(right, ch, 10);
        os << ch;
        return os;
}

inline 
otextfilestream& operator << (otextfilestream& os, float right)
{
        char ch[20];
        sprintf(ch, "%f", right);
        os << ch;
        return os;
}

inline
otextfilestream& operator << (otextfilestream& os, double right)
{
        char ch[20];
        sprintf(ch, "%f", (float)right);
        os << ch;
        return os;
}

inline 
otextfilestream& operator << (otextfilestream& os, char right)
{
        os.put(right);
        return os;
}

inline 
otextfilestream& operator << (otextfilestream& os, short right)
{
        os << static_cast<int>(right);
        return os;
}

inline 
otextfilestream& operator << (otextfilestream& os, bool right)
{
        os << static_cast<int>(right);
        return os;
}

// text manipulators

inline
otextfilestream& endl(otextfilestream& os)
{
        os.put('\r');
        os.put('\n');
        return os;
}

inline 
otextfilestream& autoSemicolons(otextfilestream& os)
{
        os.setf(otextfilestream::bob_addsemicolon);
        return os;
}

inline 
otextfilestream& noSemicolons(otextfilestream& os)
{
        os.unsetf(otextfilestream::bob_addsemicolon);
        return os;
}

inline
otextfilestream& hex(otextfilestream& os)
{
        os.setf(otextfilestream::hex);
        return os;
}

inline
otextfilestream& dec(otextfilestream& os)
{
        os.unsetf(otextfilestream::hex);
        return os;
}

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

//************************

template <class Ty>
ibinaryfilestream& operator >> (ibinaryfilestream& is, Ty& o)
{
        o.load(is);
        return is;
}

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

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

//*************************

#endif // !defined(BOB_DOM_FILESTREAM_INCLUDED)