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
14namespace mimetic
15{
16
17
18struct 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;
49private:
50 read_streambuf(const read_streambuf&);
51 read_streambuf& operator=(const read_streambuf&);
52 char_type* m_iBuf;
53};
54
55
56template<typename InputIt>
57struct 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 }
72private:
73 InputIt m_beg, m_end;
74};
75
76struct 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;
114private:
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 */
124struct 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 }
140private:
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 */
151template<typename OutputIt>
152struct 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 }
172private:
173 OutputIt m_out;
174 size_type m_count;
175};
176
177
178
179struct 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 }
212private:
213 std::streambuf* m_osbuf;
214};
215
216
217}
218
219#endif
Definition body.h:18