buf_rdwr.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2008-2009.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00016 #include <ders/buf_rdwr.hpp>
00017 #include <string.h>
00018 
00019 namespace ders {  // ::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  // n>lim-it
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  // n>wrn
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 }  // namespace ::ders
00194 

Generated on Tue Dec 8 11:35:32 2009 for derslib by  doxygen 1.5.5