00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00016 #include <ders/buf_rdwr.hpp>
00017 #include <string.h>
00018
00019 namespace ders {
00020
00021 int buf_reader::read_impl()
00022 {
00023 assert(it==lim);
00024
00025 int rc=rd.read(buf, bsz);
00026 switch (rc) {
00027 case -1:
00028 case 0: return -1;
00029 }
00030
00031 it=1;
00032 lim=rc;
00033
00034 return buf[0];
00035 }
00036
00037 buf_reader::buf_reader(mem_pool& m, readable& rdbl, int bufsz) :
00038 mp(m), rd(rdbl), bsz(bufsz)
00039 {
00040 assert(bsz>0);
00041
00042 buf=static_cast<unsigned char*>(mp.allocate(bsz));
00043 reset();
00044 }
00045
00046 int buf_reader::read(void* b, int n)
00047 {
00048 assert(n>=0);
00049
00050 if (n==0) return 0;
00051
00052 if (it==lim) {
00053 int rc=rd.read(buf, bsz);
00054 switch (rc) {
00055 case -1: return -1;
00056 case 0: return 0;
00057 }
00058
00059 it=0;
00060 lim=rc;
00061 }
00062
00063 if (n<=lim-it) {
00064 memcpy(b, buf, n);
00065 it+=n;
00066
00067 return n;
00068 }
00069
00070
00071 int rdn=lim-it;
00072 memcpy(b, buf, rdn);
00073 reset();
00074
00075 b=static_cast<unsigned char*>(b)+rdn;
00076 n-=rdn;
00077
00078 int rc=rd.read(b, n);
00079 return (rc!=-1) ? rdn+rc : rdn;
00080 }
00081
00082 int buf_reader::read(sh_text& buf, int n)
00083 {
00084 assert(n>=0);
00085
00086 buf->clear();
00087 buf->reserve(n);
00088
00089 int rc=read(buf->begin(), n);
00090 assert(rc<=n);
00091 if (rc!=-1) buf->uninitialized_resize(rc);
00092
00093 return rc;
00094 }
00095
00096 bool buf_reader::read_line(sh_text& line, bool noendl)
00097 {
00098 line->clear();
00099
00100 for (int ch; ; ) {
00101 if ((ch=read())==-1) return line->size()!=0;
00102
00103 if (ch!='\n') line->append(ch);
00104 else {
00105 if (!noendl) line->append(ch);
00106 else {
00107 if (line->size()>0 && line->back()=='\r')
00108 line->uninitialized_resize(line->size()-1);
00109 }
00110
00111 break;
00112 }
00113 }
00114
00115 return true;
00116 }
00117
00118 int buf_writer::write_impl(char ch)
00119 {
00120 assert(it==bsz);
00121
00122 int rc=wr.write(buf, it);
00123 switch (rc) {
00124 case -1:
00125 case 0: return -1;
00126 }
00127
00128 if (it==rc) {
00129 it=1;
00130 return buf[0]=ch;
00131 }
00132
00133 it-=rc;
00134 memmove(buf, buf+rc, it);
00135 return buf[it++]=ch;
00136 }
00137
00138 buf_writer::buf_writer(mem_pool& m, writable& wrbl, int bufsz) :
00139 mp(m), wr(wrbl), bsz(bufsz)
00140 {
00141 assert(bsz>0);
00142
00143 buf=static_cast<unsigned char*>(mp.allocate(bsz));
00144 reset();
00145 }
00146
00147 buf_writer::~buf_writer()
00148 {
00149 flush();
00150 mp.deallocate(buf, bsz);
00151 }
00152
00153 int buf_writer::write(const void* b, int n)
00154 {
00155 assert(n>=0);
00156
00157 if (n==0) return 0;
00158
00159 int wrn=bsz-it;
00160 if (n<=wrn) {
00161 memcpy(buf+it, b, n);
00162 it+=n;
00163
00164 return n;
00165 }
00166
00167
00168 memcpy(buf+it, b, wrn);
00169 it=bsz;
00170
00171 if (!flush()) return wrn;
00172
00173 b=static_cast<const char*>(b)+wrn;
00174 n-=wrn;
00175
00176 int rc=wr.write(b, n);
00177 return (rc!=-1) ? wrn+rc : wrn;
00178 }
00179
00180 bool buf_writer::flush()
00181 {
00182 if (it==0) return true;
00183
00184 int rc=wr.write(buf, it);
00185 if (rc==-1) return false;
00186
00187 memmove(buf, buf+rc, it-rc);
00188 it-=rc;
00189
00190 return it==0;
00191 }
00192
00193 }
00194