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)