Main Page   Class Hierarchy   Alphabetical List   Compound List   Examples  
streambufs.h
1 /***************************************************************************
2  copyright : (C) 2002-2008 by Stefano Barbato
3  email : stefano@codesink.org
4 
5  $Id: streambufs.h,v 1.7 2008-10-07 11:06:26 tat Exp $
6  ***************************************************************************/
7 #ifndef _MIMETIC_MIMESTREAMBUF_H_
8 #define _MIMETIC_MIMESTREAMBUF_H_
9 #include <iostream>
10 #include <string>
11 #include <mimetic/libconfig.h>
12 #include <mimetic/strutils.h>
13 
14 namespace mimetic
15 {
16 
17 
18 struct read_streambuf: public std::streambuf
19 {
20  enum { bufsz = 512 };
21  typedef unsigned int size_type;
22  read_streambuf()
23  : m_iBuf(new char_type[bufsz])
24  {
25  setg(m_iBuf, m_iBuf + bufsz, m_iBuf + bufsz);
26  }
27  virtual ~read_streambuf()
28  {
29  if(m_iBuf)
30  delete[] m_iBuf;
31  m_iBuf = 0;
32  }
33  int_type underflow()
34  {
35  int bread;
36 
37  if(gptr() < egptr())
38  return traits_type::to_int_type(*gptr());
39 
40  if((bread = read(eback(), bufsz)) == 0)
41  return traits_type::eof();
42  else
43  setg(eback(), eback(), eback() + bread);
44 
45  return traits_type::to_int_type(*gptr());
46  }
47  // must return number of bytes read or 0 on eof
48  virtual int_type read(char*, int) = 0;
49 private:
50  read_streambuf(const read_streambuf&);
51  read_streambuf& operator=(const read_streambuf&);
52  char_type* m_iBuf;
53 };
54 
55 
56 template<typename InputIt>
57 struct inputit_streambuf: public read_streambuf
58 {
59  inputit_streambuf(InputIt beg, InputIt end)
60  : m_beg(beg), m_end(end)
61  {
62  }
63  // returns number of bytes read or 0 on eof
64  int_type read(char* buf, int bufsz)
65  {
66  // fill buffer
67  int c;
68  for(c = 0; m_beg != m_end && c < bufsz; ++m_beg, ++buf, ++c)
69  *buf = *m_beg;
70  return c;
71  }
72 private:
73  InputIt m_beg, m_end;
74 };
75 
76 struct transform_streambuf: public std::streambuf
77 {
78  typedef unsigned int size_type;
79  transform_streambuf()
80  : m_oBuf(new char_type[512])
81  {
82  setp(m_oBuf, m_oBuf + 512);
83  }
84  virtual ~transform_streambuf()
85  {
86  if(m_oBuf)
87  {
88  sync();
89  delete[] m_oBuf;
90  }
91  }
92  int overflow(int meta = EOF)
93  {
94  if(sync() == -1)
95  return EOF;
96  if(meta != EOF)
97  {
98  *pptr() = meta;
99  pbump(1);
100  }
101  return meta;
102  }
103  int sync()
104  {
105  int toSend = pptr() - pbase();
106  if(toSend)
107  {
108  write(pbase(), pbase() + toSend);
109  setp(m_oBuf, epptr());
110  }
111  return 0;
112  }
113  virtual void write(const char_type* beg, const char_type* end)=0;
114 private:
115  transform_streambuf(const transform_streambuf&);
116  transform_streambuf& operator=(const transform_streambuf&);
117  char_type* m_oBuf;
118 };
119 
120 /*
121  * stream buffer that does nothing except counting character written into it.
122  * characters count is available through the size() method
123  */
124 struct count_streambuf: public transform_streambuf
125 {
126  count_streambuf()
127  : m_count(0)
128  {
129  }
130  void write(const char_type* beg, const char_type* end)
131  {
132  int toSend = end - beg;
133  if(toSend)
134  m_count += toSend;
135  }
136  size_type size()
137  {
138  return m_count;
139  }
140 private:
141  size_type m_count;
142 };
143 
144 
145 
146 /*
147  * stream buffer that count char written into it and copy every char to the
148  * output iterator passed as ctor parameter
149  * characters count is available through the size() method
150  */
151 template<typename OutputIt>
152 struct passthrough_streambuf: public transform_streambuf
153 {
154  typedef unsigned int size_type;
155  passthrough_streambuf(const OutputIt& out)
156  : m_out(out), m_count(0)
157  {
158  }
159  void write(const char_type* beg, const char_type* end)
160  {
161  int toSend = end - beg;
162  if(toSend)
163  {
164  m_count += toSend;
165  copy(beg, end, m_out);
166  }
167  }
168  size_type size()
169  {
170  return m_count;
171  }
172 private:
173  OutputIt m_out;
174  size_type m_count;
175 };
176 
177 
178 
179 struct crlftolf_streambuf: public transform_streambuf
180 {
181  typedef unsigned int size_type;
182  crlftolf_streambuf(std::streambuf* osbuf)
183  : m_osbuf(osbuf)
184  {
185  }
186  void write(const char_type* beg, const char_type* end)
187  {
188  enum { cr = 0xD, lf = 0xA };
189  char_type c;
190  bool got_cr = 0;
191  for(; beg != end; ++beg)
192  {
193  c = *beg;
194  if(got_cr)
195  {
196  if(c == lf)
197  m_osbuf->sputc(lf);
198  else {
199  m_osbuf->sputc(cr);
200  m_osbuf->sputc(c);
201  }
202  got_cr = 0;
203  } else if(c == cr) {
204  got_cr = 1;
205  continue;
206  } else
207  m_osbuf->sputc(c);
208  }
209  if(got_cr)
210  m_osbuf->sputc(c);
211  }
212 private:
213  std::streambuf* m_osbuf;
214 };
215 
216 
217 }
218 
219 #endif