CppCMS

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

steal_buf.h
1 //
3 // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
4 //
5 // See accompanying file COPYING.TXT file for licensing details.
6 //
8 #ifndef CPPCMS_STEAL_BUF_H
9 #define CPPCMS_STEAL_BUF_H
10
11 #include <streambuf>
12 #include <ostream>
13 #include <istream>
14 #include <stdio.h>
15 #include <string>
16 #include <string.h>
17 #include <stdlib.h>
18
19 namespace cppcms {
20 namespace util {
21
26
27 class const_char_buf : public std::streambuf {
28 public:
32 const_char_buf()
33 {
34 range(0,0);
35 }
39 const_char_buf(char const *begin,char const *end)
40 {
41 range(begin,end);
42 }
46 void range(char const *cbegin,char const *cend)
47 {
48 char *begin = const_cast<char*>(cbegin);
49 char *end = const_cast<char*>(cend);
50 setg(begin,begin,end);
51 }
55 char const *begin() const
56 {
57 return eback();
58 }
62 char const *end() const
63 {
64 return egptr();
65 }
66 };
67
72 class const_char_istream : public std::istream {
73 public:
77 const_char_istream() : std::istream(0)
78 {
79 init(&buf_);
80 }
84 const_char_istream(char const *begin,char const *end) : std::istream(0)
85 {
86 buf_.range(begin,end);
87 init(&buf_);
88 }
92 char const *begin() const
93 {
94 return buf_.begin();
95 }
99 char const *end() const
100 {
101 return buf_.end();
102 }
106 void range(char const *begin,char const *end)
107 {
108 buf_.range(begin,end);
109 clear();
110 }
111 private:
112 const_char_buf buf_;
113 };
114
125 template<size_t OnStackSize = 128>
126 class stackbuf : public std::streambuf {
127 stackbuf(stackbuf const &);
128 void operator=(stackbuf const &);
129 public:
133 char *begin()
134 {
135 return pbase();
136 }
140 char *end()
141 {
142 return pptr();
143 }
147 char *c_str()
148 {
149 *pptr() = 0;
150 return begin();
151 }
155 std::string str()
156 {
157 return std::string(begin(),size_t(end()-begin()));
158 }
159 stackbuf()
160 {
161 init();
162 }
163 ~stackbuf()
164 {
165 free(on_heap_);
166 }
167 protected:
168
169 int overflow(int c)
170 {
171 size_t current_size;
172 size_t new_size;
173 if(pbase() == on_stack_) {
174 current_size = OnStackSize;
175 new_size = OnStackSize * 2;
176 on_heap_ = (char *)malloc(new_size + 1);
177 if(!on_heap_)
178 throw std::bad_alloc();
179 memcpy(on_heap_,on_stack_,current_size);
180 }
181 else {
182 current_size = pptr() - pbase();
183 new_size = current_size * 2;
184 char *new_ptr = (char *)realloc(on_heap_,new_size + 1);
185 if(!new_ptr)
186 throw std::bad_alloc();
187 on_heap_ = new_ptr;
188
189 }
190 setp(on_heap_,on_heap_ + new_size);
191 pbump(current_size);
192 if(c!=EOF)
193 sputc(c);
194 return 0;
195 }
196 private:
197 void init()
198 {
199 on_heap_ = 0;
200 setp(on_stack_,on_stack_+OnStackSize);
201 }
202 char *on_heap_;
203 char on_stack_[OnStackSize + 1];
204 };
205
206
219 template<size_t Size = 128>
220 class steal_buffer : public stackbuf<Size> {
221 public:
225 steal_buffer(std::ostream &out)
226 {
227 stolen_ = 0;
228 stream_ = 0;
229 steal(out);
230 }
234 steal_buffer()
235 {
236 stolen_ = 0;
237 stream_ = 0;
238 }
242 void steal(std::ostream &out)
243 {
244 release();
245 stolen_ = out.rdbuf(this);
246 stream_ = &out;
247 }
252 void release()
253 {
254 if(stream_ && stolen_) {
255 stream_->rdbuf(stolen_);
256 }
257 stream_ = 0;
258 stolen_ = 0;
259 }
260 ~steal_buffer()
261 {
262 release();
263 }
264 private:
265 std::streambuf *stolen_;
266 std::ostream *stream_;
267 };
268
276 template<size_t Size = 128>
277 class stackstream : public std::ostream {
278 public:
282 stackstream() : std::ostream(0)
283 {
284 rdbuf(&buf_);
285 }
289 char *begin()
290 {
291 return buf_.begin();
292 }
296 char *end()
297 {
298 return buf_.end();
299 }
303 char *c_str()
304 {
305 return buf_.c_str();
306 }
310 std::string str()
311 {
312 return buf_.str();
313 }
314 private:
315 stackbuf<Size> buf_;
316 };
317
318 template<typename Filter,int BufferSize=128>
319 class filterbuf : public std::streambuf {
320 public:
321 filterbuf() : output_(0), output_stream_(0)
322 {
323 setp(buffer_,buffer_+BufferSize);
324 }
325 filterbuf(std::ostream &out) : output_(0), output_stream_(0)
326 {
327 setp(buffer_,buffer_+BufferSize);
328 steal(out);
329 }
330 ~filterbuf()
331 {
332 try {
333 release();
334 }
335 catch(...) {}
336 }
337 void steal(std::ostream &out)
338 {
339 release();
340 output_stream_ = &out;
341 output_ = out.rdbuf(this);
342 }
343 int release()
344 {
345 int r=0;
346 if(output_stream_) {
347 if(write()!=0)
348 r=-1;
349 output_stream_->rdbuf(output_);
350 output_=0;
351 output_stream_=0;
352 }
353 return r;
354 }
355 protected:
356 int overflow(int c)
357 {
358 if(write()!=0)
359 return -1;
360 if(c!=EOF) {
361 *pptr()=c;
362 pbump(1);
363 }
364 return 0;
365 }
366 private:
367 int write()
368 {
369 if(static_cast<Filter*>(this)->convert(pbase(),pptr(),output_)!=0) {
370 output_stream_->setstate(std::ios_base::failbit);
371 return -1;
372 }
373 setp(buffer_,buffer_ + BufferSize);
374 return 0;
375 }
376 char buffer_[BufferSize];
377 std::streambuf *output_;
378 std::ostream *output_stream_;
379 };
380
381 template<typename Filter>
382 class filterbuf<Filter,0> : public std::streambuf {
383 public:
384 filterbuf() : output_(0), output_stream_(0)
385 {
386 }
387 filterbuf(std::ostream &out) : output_(0), output_stream_(0)
388 {
389 steal(out);
390 }
391 ~filterbuf()
392 {
393 release();
394 }
395 void steal(std::ostream &out)
396 {
397 release();
398 output_stream_ = &out;
399 output_ = out.rdbuf(this);
400 }
401 int release()
402 {
403 int r=0;
404 if(output_stream_) {
405 output_stream_->rdbuf(output_);
406 output_=0;
407 output_stream_=0;
408 }
409 return r;
410 }
411 protected:
412 int overflow(int c)
413 {
414 if(c!=EOF) {
415 char tmp=c;
416 if(write(&tmp,&tmp+1)!=0)
417 return -1;
418 }
419 return 0;
420 }
421 std::streamsize xsputn(char const *s,std::streamsize size)
422 {
423 if(write(s,s+size)!=0)
424 return -1;
425 return size;
426 }
427 private:
428 int write(char const *begin,char const *end)
429 {
430 if(static_cast<Filter*>(this)->convert(begin,end,output_)!=0) {
431 output_stream_->setstate(std::ios_base::failbit);
432 return -1;
433 }
434 return 0;
435 }
436 std::streambuf *output_;
437 std::ostream *output_stream_;
438 };
439
440 } // util
441 } // cppcms
442
443 #endif
cppcms::util::const_char_istream::range
void range(char const *begin, char const *end)
Definition: steal_buf.h:106
cppcms::util::stackbuf::end
char * end()
Definition: steal_buf.h:140
cppcms::util::const_char_istream::end
char const * end() const
Definition: steal_buf.h:99
cppcms::util::const_char_istream
Definition: steal_buf.h:72
cppcms::util::stackbuf::begin
char * begin()
Definition: steal_buf.h:133
cppcms::util::stackstream::begin
char * begin()
Definition: steal_buf.h:289
cppcms::util::steal_buffer::steal
void steal(std::ostream &out)
Definition: steal_buf.h:242
cppcms
This is the namespace where all CppCMS functionality is placed.
Definition: application.h:19
cppcms::util::const_char_buf::const_char_buf
const_char_buf()
Definition: steal_buf.h:32
cppcms::util::stackstream::c_str
char * c_str()
Definition: steal_buf.h:303
cppcms::util::const_char_istream::const_char_istream
const_char_istream()
Definition: steal_buf.h:77
cppcms::util::stackbuf::str
std::string str()
Definition: steal_buf.h:155
cppcms::util::const_char_buf::end
char const * end() const
Definition: steal_buf.h:62
cppcms::util::stackstream::end
char * end()
Definition: steal_buf.h:296
cppcms::util::stackstream::stackstream
stackstream()
Definition: steal_buf.h:282
cppcms::util::const_char_buf::range
void range(char const *cbegin, char const *cend)
Definition: steal_buf.h:46
cppcms::util::stackstream
Fast output stream object.
Definition: steal_buf.h:277
cppcms::util::const_char_istream::const_char_istream
const_char_istream(char const *begin, char const *end)
Definition: steal_buf.h:84
cppcms::util::const_char_buf
Definition: steal_buf.h:27
cppcms::util::filterbuf
Definition: steal_buf.h:319
cppcms::util::steal_buffer
This is a special buffer that allows to "steal" some chunk of text from the output stream...
Definition: steal_buf.h:220
cppcms::util::stackbuf::c_str
char * c_str()
Definition: steal_buf.h:147
cppcms::util::stackstream::str
std::string str()
Definition: steal_buf.h:310
cppcms::util::const_char_buf::begin
char const * begin() const
Definition: steal_buf.h:55
cppcms::util::steal_buffer::steal_buffer
steal_buffer(std::ostream &out)
Definition: steal_buf.h:225
cppcms::util::stackbuf
Very simple output stream buffer that uses stack for small chunks of text and then allocates memory o...
Definition: steal_buf.h:126
cppcms::util::const_char_istream::begin
char const * begin() const
Definition: steal_buf.h:92
cppcms::util::steal_buffer::release
void release()
Definition: steal_buf.h:252
cppcms::util::const_char_buf::const_char_buf
const_char_buf(char const *begin, char const *end)
Definition: steal_buf.h:39
cppcms::util::steal_buffer::steal_buffer
steal_buffer()
Definition: steal_buf.h:234