Rev 1 | 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)