00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _MIMETIC_MIMESTREAMBUF_H_
00017 #define _MIMETIC_MIMESTREAMBUF_H_
00018 #include <iostream>
00019 #include <string>
00020 #include <mimetic/libconfig.h>
00021 #include <mimetic/strutils.h>
00022
00023 namespace mimetic
00024 {
00025
00026
00027 struct read_streambuf: public std::streambuf
00028 {
00029 enum { bufsz = 512 };
00030 typedef unsigned int size_type;
00031 read_streambuf()
00032 : m_iBuf(new char_type[bufsz])
00033 {
00034 setg(m_iBuf, m_iBuf + bufsz, m_iBuf + bufsz);
00035 }
00036 virtual ~read_streambuf()
00037 {
00038 if(m_iBuf)
00039 delete[] m_iBuf;
00040 m_iBuf = 0;
00041 }
00042 int_type underflow()
00043 {
00044 int bread;
00045
00046 if(gptr() < egptr())
00047 return traits_type::to_int_type(*gptr());
00048
00049 if((bread = read(eback(), bufsz)) == 0)
00050 return traits_type::eof();
00051 else
00052 setg(eback(), eback(), eback() + bread);
00053
00054 return traits_type::to_int_type(*gptr());
00055 }
00056
00057 virtual int_type read(char*, int) = 0;
00058 private:
00059 read_streambuf(const read_streambuf&);
00060 read_streambuf& operator=(const read_streambuf&);
00061 char_type* m_iBuf;
00062 };
00063
00064
00065 template<typename InputIt>
00066 struct inputit_streambuf: public read_streambuf
00067 {
00068 inputit_streambuf(InputIt beg, InputIt end)
00069 : m_beg(beg), m_end(end)
00070 {
00071 }
00072
00073 int_type read(char* buf, int bufsz)
00074 {
00075
00076 int c;
00077 for(c = 0; m_beg != m_end && c < bufsz; ++m_beg, ++buf, ++c)
00078 *buf = *m_beg;
00079 return c;
00080 }
00081 private:
00082 InputIt m_beg, m_end;
00083 };
00084
00085 struct transform_streambuf: public std::streambuf
00086 {
00087 typedef unsigned int size_type;
00088 transform_streambuf()
00089 : m_oBuf(new char_type[512])
00090 {
00091 setp(m_oBuf, m_oBuf + 512);
00092 }
00093 virtual ~transform_streambuf()
00094 {
00095 if(m_oBuf)
00096 {
00097 sync();
00098 delete[] m_oBuf;
00099 }
00100 }
00101 int overflow(int meta = EOF)
00102 {
00103 if(sync() == -1)
00104 return EOF;
00105 if(meta != EOF)
00106 {
00107 *pptr() = meta;
00108 pbump(1);
00109 }
00110 return meta;
00111 }
00112 int sync()
00113 {
00114 int toSend = pptr() - pbase();
00115 if(toSend)
00116 {
00117 write(pbase(), pbase() + toSend);
00118 setp(m_oBuf, epptr());
00119 }
00120 return 0;
00121 }
00122 virtual void write(const char_type* beg, const char_type* end)=0;
00123 private:
00124 transform_streambuf(const transform_streambuf&);
00125 transform_streambuf& operator=(const transform_streambuf&);
00126 char_type* m_oBuf;
00127 };
00128
00129
00130
00131
00132
00133 struct count_streambuf: public transform_streambuf
00134 {
00135 count_streambuf()
00136 : m_count(0)
00137 {
00138 }
00139 void write(const char_type* beg, const char_type* end)
00140 {
00141 int toSend = end - beg;
00142 if(toSend)
00143 m_count += toSend;
00144 }
00145 size_type size()
00146 {
00147 return m_count;
00148 }
00149 private:
00150 size_type m_count;
00151 };
00152
00153
00154
00155
00156
00157
00158
00159
00160 template<typename OutputIt>
00161 struct passthrough_streambuf: public transform_streambuf
00162 {
00163 typedef unsigned int size_type;
00164 passthrough_streambuf(const OutputIt& out)
00165 : m_out(out), m_count(0)
00166 {
00167 }
00168 void write(const char_type* beg, const char_type* end)
00169 {
00170 int toSend = end - beg;
00171 if(toSend)
00172 {
00173 m_count += toSend;
00174 copy(beg, end, m_out);
00175 }
00176 }
00177 size_type size()
00178 {
00179 return m_count;
00180 }
00181 private:
00182 OutputIt m_out;
00183 size_type m_count;
00184 };
00185
00186
00187
00188 struct crlftolf_streambuf: public transform_streambuf
00189 {
00190 typedef unsigned int size_type;
00191 crlftolf_streambuf(std::streambuf* osbuf)
00192 : m_osbuf(osbuf)
00193 {
00194 }
00195 void write(const char_type* beg, const char_type* end)
00196 {
00197 enum { cr = 0xD, lf = 0xA };
00198 char_type c;
00199 bool got_cr = 0;
00200 for(; beg != end; ++beg)
00201 {
00202 c = *beg;
00203 if(got_cr)
00204 {
00205 if(c == lf)
00206 m_osbuf->sputc(lf);
00207 else {
00208 m_osbuf->sputc(cr);
00209 m_osbuf->sputc(c);
00210 }
00211 got_cr = 0;
00212 } else if(c == cr) {
00213 got_cr = 1;
00214 continue;
00215 } else
00216 m_osbuf->sputc(c);
00217 }
00218 if(got_cr)
00219 m_osbuf->sputc(c);
00220 }
00221 private:
00222 std::streambuf* m_osbuf;
00223 };
00224
00225
00226 }
00227
00228 #endif