00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
#include "pl_streambuf.h"
00037
00038
00039
using namespace PLearn;
00040
using namespace std;
00041
00042
00043
00044
00045
00047 pl_streambuf::pl_streambuf(
streambuf& _original_buf,
int _inbuflen)
00048 :original_buf(_original_buf), inbuf(0), inbuflen(_inbuflen), first_marker(0)
00049 {
00050
00051
if(inbuflen < pback_size+1)
00052 inbuflen= min_buf_size + pback_size;
00053
00054 inbuf=
new char[inbuflen];
00055 setg(inbuf+pback_size, inbuf+pback_size, inbuf+pback_size);
00056 }
00057
00059 pl_streambuf::~pl_streambuf()
00060 {
00061
if(
inbuf)
00062
delete[]
inbuf;
00063 }
00064
00067 pl_streambuf::int_type pl_streambuf::underflow()
00068 {
00069
00070
if(
first_marker == 0 && gptr() == egptr())
00071 {
00072
00073
if(
inbuflen >
min_buf_size +
pback_size)
00074 {
00075
delete[]
inbuf;
00076
inbuflen=
min_buf_size +
pback_size;
00077
inbuf=
new char[
inbuflen];
00078 setg(
inbuf+pback_size,
inbuf+pback_size,
inbuf+pback_size);
00079 }
00080
return original_buf.sgetc();
00081 }
00082
00083
00084
00085
00086
if(gptr() < egptr())
00087
return *gptr();
00088
00089
int oldbuflen= egptr()-
inbuf;
00090
00091
if(egptr() == inbuf+
inbuflen)
00092 {
00093
00094
int newbuflen=
inbuflen*2;
00095
char* newbuf=
new char[newbuflen];
00096
00097
00098
for(
int i= 0; i < inbuflen; ++i)
00099 newbuf[i]= inbuf[i];
00100
00101
00102 setg(newbuf+
pback_size, newbuf+(gptr()-inbuf), newbuf+inbuflen);
00103
delete[] inbuf;
00104 inbuf= newbuf;
00105 inbuflen= newbuflen;
00106 }
00107
00108
char* the_egptr= 0;
00109
00110
00111
for(
int i= oldbuflen; i <
inbuflen; ++i)
00112
if(
original_buf.sgetc() != pl_streambuf::eof &&
original_buf.in_avail() || i == oldbuflen)
00113 inbuf[i]=
original_buf.sbumpc();
00114
else
00115 {
00116 the_egptr= inbuf+i;
00117
break;
00118 }
00119
00120
if(the_egptr == 0)
00121 the_egptr= inbuf + inbuflen;
00122
00123
00124 setg(eback(), gptr(), the_egptr);
00125
if(gptr() < egptr())
00126
return *gptr();
00127
return pl_streambuf::eof;
00128 }
00129
00130
00131 pl_streambuf::int_type pl_streambuf::uflow()
00132 {
00133
int c=
underflow();
00134
if(
first_marker == 0 && gptr() == egptr())
00135
original_buf.sbumpc();
00136
else
00137 gbump(1);
00138
return c;
00139 }
00140
00141 streamsize pl_streambuf::xsgetn(char_type* s, streamsize n)
00142 {
00143 int_type c=
uflow();
00144
int i;
00145
for(i= 0; i < n && c != pl_streambuf::eof; ++i)
00146 {
00147 s[i]= static_cast<char_type>(c);
00148 c=
uflow();
00149 }
00150
return i;
00151 }
00152
00153 streamsize pl_streambuf::xsputn(
const char_type* s, streamsize n)
00154 {
00155
int_type c = 1;
00156
int i;
00157
for(i= 0; i < n && c != pl_streambuf::eof; ++i)
00158 c=
overflow(static_cast<int_type>(s[i]));
00159
return i;
00160 }
00161
00162
00163 pl_streambuf::int_type pl_streambuf::overflow(
int_type meta)
00164 {
return original_buf.sputc(meta); }
00165
00166 void pl_streambuf::seekmark(
const pl_streammarker& mark)
00167 { setg(eback(),
inbuf+mark.
pos, egptr()); }
00168
00169 pl_streambuf::int_type pl_streambuf::sync()
00170 {
00171
#if __GNUC__ < 3 && !defined(WIN32)
00172
return original_buf.sync();
00173
#else
00174
return original_buf.pubsync();
00175
#endif
00176
}
00177
00178 pl_streambuf::int_type pl_streambuf::pbackfail(
int_type c)
00179 {
return original_buf.sungetc(); }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 pl_streammarker::pl_streammarker(
pl_streambuf* _buf)
00190 :buf(_buf), next_marker(buf->first_marker), pos(buf->curpos())
00191 {
buf->
first_marker=
this; }
00192
00193
00194 pl_streammarker::pl_streammarker(
streambuf* _buf)
00195 :buf(dynamic_cast<
pl_streambuf*>(_buf))
00196 {
00197
if(
buf == 0)
00198
PLERROR(
"Cannot put a pl_streammarker on a streambuf that is not a pl_streambuf...");
00199
next_marker=
buf->
first_marker;
00200
pos=
buf->
curpos();
00201
00202
buf->
first_marker=
this;
00203 }
00204
00205
00206 pl_streammarker::~pl_streammarker()
00207 {
00208
pl_streammarker* prev= 0;
00209
for(
pl_streammarker* it=
buf->
first_marker; it != 0; prev= it, it!=0?it= it->
next_marker:it= 0)
00210
if(it ==
this)
00211 {
00212
if(prev == 0)
00213
buf->
first_marker= it->
next_marker;
00214
else
00215 prev->
next_marker= it->
next_marker;
00216 it= 0;
00217 }
00218 }