用流来封装SOCKET通信的一种方法
aits::off_type off_type;
typedef traits traits_type;
streambufadaptor(Rw& rw,ios_base::openmode mode = ios_base::in | ios_base::out | ios_base::binary): _rw(rw),_out(0),_out_len(0),_in(0),_in_len(0){
setg(_in,_in,_in);
setp(_out,_out + _out_len);
basic_streambuf::mode_ = mode;
}
~streambufadaptor()
{
if(_out) free_out_buf();
if(_in) free_in_buf();
}
private:
void init_out_buf()
{
_out_len = 512;
_out = new charT[_out_len];
setp(_out,_out + _out_len);
}
void free_out_buf()
{
delete [] _out;
_out = 0;
_out_len = 0;
setp(0,0);
}
void init_in_buf()
{
_in_len = 512;
_in = new charT[_in_len];
setg(_in,_in,_in);
}
void free_in_buf()
{
delete [] _in;
_in = 0;
_in_len = 0;
setg(_in,_in,_in);
}
protected:
virtual int_type overflow(int_type c)
{
if((basic_streambuf::mode_ & ios_base::out) == 0) {
return traits::eof();
}
sync();
if(traits::eq_int_type(c,traits::eof()) )
return traits::not_eof(c);
else
{
if(pptr() == 0) init_out_buf();
return sputc(c);
}
}
virtual int_type underflow()
{
if((basic_streambuf::mode_ & ios_base::in) == 0) {
return traits::eof();
}
if(egptr() == 0)
init_in_buf();
if(egptr() == _in + _in_len)
setg(_in,_in,_in);
int tmp = _rw.read(egptr(),_in + _in_len - egptr());
if(tmp < 1) return traits::eof();
setg(eback(),egptr(),egptr() + tmp);
return traits::to_int_type(*gptr());
}
virtual int sync()
{
if(pptr() > pbase()){
int tmp = pptr() - pbase();
int tmp1 = _rw.write(pbase(),tmp);
if(tmp1 < 1)
return -1;
if(tmp1 < tmp)
{
memcpy(pbase(),pbase() + tmp1, tmp - tmp1);
setp(pbase(),epptr());
pbump(tmp1);
}else
setp(pbase(),epptr());
}
return 0;
}
};
class streamadaptor_base{};
typedef const streamadaptor_base& StreamAdaptor;
template
class streamadaptor: public streamadaptor_base
{
public:
typedef typename stream::char_type char_type;
typedef typename stream::traits_type traits_type;
private:
basic_ios& _stream ;
streambufadaptor _buff;
basic_streambuf* _oldbuf;
public:
streamadaptor(stream& s,Rw& rw):_stream(s),_buff(rw){
_oldbuf = _stream.rdbuf(&_buff);
}
~streamadaptor(){
_stream.rdbuf(_oldbuf);
}
operator stream&(){ return _stream; }
stream& get() { return _stream; }
};
template
streamadaptor MakeStreamAdaptor(Stream& s,Rw& rw)
{
return streamadaptor(s,rw);
}
#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#define STREAM_ADAPTOR StreamAdaptor ANONYMOUS_VARIABLE(streamAdaptor) = MakeStreamAdaptor
}

