Subversion Repositories spk

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
  basic stream class - it's similar to STL streams
*/

#ifndef BOB_DOM_STREAM_INCLUDED
#define BOB_DOM_STREAM_INCLUDED

#include "../common/indian.h"
#include "../common/ext_stream.h"

/* 
        bob_dom_istream - input template stream
        bob_dom_ostream - output template stream
*/

template <class Ty>
class bob_istream : public ext::stream_base
{
        public:
                typedef size_t size_type;
                typedef int offset_type;
                typedef Ty value_type;
                typedef Ty* value_type_ptr;
                typedef ext::stream_base base;
                typedef const Ty* const_value_type_ptr;
                
                virtual size_type read(value_type_ptr buffer, size_type size)=0;
                virtual bool advance(offset_type off)=0;
                virtual size_type tell() const = 0;
};

template <class Ty>
class bob_dom_ibufferstream : public bob_istream<Ty>
{
        public:
                typedef bob_istream<Ty> base;
                typedef int offset_type;
                
        private:
                const_value_type_ptr m_buffer;
                const_value_type_ptr m_ptr;
                size_type m_size;
                size_type m_avail;
                
        public:
                bob_dom_ibufferstream() { rdbuff(0, 0); clear(); }
                bob_dom_ibufferstream(const_value_type_ptr *buffer, size_type size) { rdbuff(buffer, size); }
                
                const_value_type_ptr rdbuff() const { return m_ptr; }
                void rdbuff(const_value_type_ptr buffer, size_type size) 
                { 
                        m_buffer=m_ptr=buffer; 
                        m_avail=m_size=size;
                        clear();
                }
                
                void clear(state s=goodbit) 
                { 
                        base::clear(s);
                        setstate(m_buffer ? goodbit : badbit); 
                }

                
                size_type read(value_type_ptr buffer, size_type size);
                
                size_type tell() const { return m_ptr - m_buffer; }
                size_type size() const { return m_size; }
                size_type avail() const { return m_avail; }
                
                bool advance(offset_type offset)
                {
                        if((offset > (offset_type)avail()) || ((offset_type)tell() + offset < 0))
                                setstate(failbit);
                        else{
                                m_ptr+=offset;
                                m_avail-=offset;
                        }
                        if(avail()==0) 
                                setstate(eofbit);
                        else
                                clear((state)(rdstate() & ~eofbit));
                        return good();
                }
                
                void rewind()
                {
                        m_ptr=m_buffer;
                        m_avail=m_size;
                        clear();
                }               
                
                
                bob_dom_ibufferstream& operator ++()
                {
                        advance(1);
                        return *this;
                }
                
                bob_dom_ibufferstream& operator --()
                {
                        advance(-1);
                        return *this;
                }
                
                bob_dom_ibufferstream& operator +=(offset_type offset)
                {
                        advance(offset);
                        return *this;
                }
                
                bob_dom_ibufferstream& operator -=(offset_type offset)
                {
                        advance(offset * -1);
                        return *this;
                }
};

template <class Ty>
typename bob_dom_ibufferstream<Ty>::size_type bob_dom_ibufferstream<Ty>::read(value_type_ptr buffer, size_type s)
{
        if(!good()) return -1;
        if(avail() < s){
                setstate(failbit);
                return -1;
        }
        else{
                memcpy(buffer, rdbuff(), s);
                advance((offset_type)s);
                return s;
        }
}

typedef bob_dom_ibufferstream<unsigned char> bob_dom_ibytestream;

inline 
bob_dom_ibytestream& operator >> (bob_dom_ibytestream& is, int& right)
{
        is.read((bob_dom_ibytestream::value_type_ptr)&right, sizeof(right));
        right=be2le((unsigned int)right);
        return is;
}

inline
bob_dom_ibytestream& operator >> (bob_dom_ibytestream& is, short& right)
{
        is.read((bob_dom_ibytestream::value_type_ptr)&right, sizeof(right));
        right=be2le((unsigned short) right);
        return is;
}

#include <memory.h>

inline
bob_dom_ibytestream& operator >> (bob_dom_ibytestream& is, char*& right)
{
        bob_dom_ibytestream::const_value_type_ptr data=is.rdbuff();
        bob_dom_ibytestream::const_value_type_ptr pos=(bob_dom_ibytestream::const_value_type_ptr)memchr(data, 0, is.avail());
        if(pos){
                bob_dom_ibytestream::offset_type s=(bob_dom_ibytestream::offset_type)(pos - data + 1);
                right=new char[s];
                memcpy(right, data, s);
                is.advance(s);
        }
        else 
                right=0;
        return is;
}

template <class Ty>
class bob_ostream : public ext::stream_base
{
        public:
                typedef Ty value_type;
                typedef Ty* value_type_ptr;
                typedef const Ty const_value_type;
                typedef const Ty* const_value_type_ptr;
                typedef size_t size_type;
                
                // flags for formating output
                static const int hex=1;
                
                virtual size_type write(const_value_type_ptr data, size_type size)=0;
                virtual bool put(const_value_type &ch)=0;
                
                virtual size_t tell()=0;
};



#endif // !defined(BOB_DOM_STREAM_INCLUDED)