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