CppCMS
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 <stdio.h>
14 #include <string>
15 #include <string.h>
16 #include <stdlib.h>
17 
18 namespace cppcms {
19 namespace util {
20 
31  template<size_t OnStackSize = 128>
32  class stackbuf : public std::streambuf {
33  stackbuf(stackbuf const &);
34  void operator=(stackbuf const &);
35  public:
39  char *begin()
40  {
41  return pbase();
42  }
46  char *end()
47  {
48  return pptr();
49  }
53  char *c_str()
54  {
55  *pptr() = 0;
56  return begin();
57  }
61  std::string str()
62  {
63  return std::string(begin(),size_t(end()-begin()));
64  }
65  stackbuf()
66  {
67  init();
68  }
69  ~stackbuf()
70  {
71  free(on_heap_);
72  }
73  protected:
74 
75  int overflow(int c)
76  {
77  size_t current_size;
78  size_t new_size;
79  if(pbase() == on_stack_) {
80  current_size = OnStackSize;
81  new_size = OnStackSize * 2;
82  on_heap_ = (char *)malloc(new_size + 1);
83  if(!on_heap_)
84  throw std::bad_alloc();
85  memcpy(on_heap_,on_stack_,current_size);
86  }
87  else {
88  current_size = pptr() - pbase();
89  new_size = current_size * 2;
90  char *new_ptr = (char *)realloc(on_heap_,new_size + 1);
91  if(!new_ptr)
92  throw std::bad_alloc();
93  on_heap_ = new_ptr;
94 
95  }
96  setp(on_heap_,on_heap_ + new_size);
97  pbump(current_size);
98  if(c!=EOF)
99  sputc(c);
100  return 0;
101  }
102  private:
103  void init()
104  {
105  on_heap_ = 0;
106  setp(on_stack_,on_stack_+OnStackSize);
107  }
108  char *on_heap_;
109  char on_stack_[OnStackSize + 1];
110  };
111 
112 
125  template<size_t Size = 128>
126  class steal_buffer : public stackbuf<Size> {
127  public:
131  steal_buffer(std::ostream &out)
132  {
133  stolen_ = 0;
134  stream_ = 0;
135  steal(out);
136  }
141  {
142  stolen_ = 0;
143  stream_ = 0;
144  }
148  void steal(std::ostream &out)
149  {
150  release();
151  stolen_ = out.rdbuf(this);
152  stream_ = &out;
153  }
158  void release()
159  {
160  if(stream_ && stolen_) {
161  stream_->rdbuf(stolen_);
162  }
163  stream_ = 0;
164  stolen_ = 0;
165  }
166  ~steal_buffer()
167  {
168  release();
169  }
170  private:
171  std::streambuf *stolen_;
172  std::ostream *stream_;
173  };
174 
182  template<size_t Size = 128>
183  class stackstream : public std::ostream {
184  public:
188  stackstream() : std::ostream(0)
189  {
190  rdbuf(&buf_);
191  }
195  char *begin()
196  {
197  return buf_.begin();
198  }
202  char *end()
203  {
204  return buf_.end();
205  }
209  char *c_str()
210  {
211  return buf_.c_str();
212  }
216  std::string str()
217  {
218  return buf_.str();
219  }
220  private:
221  stackbuf<Size> buf_;
222  };
223 
224 } // util
225 } // cppcms
226 
227 #endif
char * end()
Definition: steal_buf.h:46
char * begin()
Definition: steal_buf.h:39
char * begin()
Definition: steal_buf.h:195
void steal(std::ostream &out)
Definition: steal_buf.h:148
char * c_str()
Definition: steal_buf.h:209
std::string str()
Definition: steal_buf.h:61
char * end()
Definition: steal_buf.h:202
stackstream()
Definition: steal_buf.h:188
Fast output stream object.
Definition: steal_buf.h:183
This is a special buffer that allows to "steal" some chunk of text from the output stream...
Definition: steal_buf.h:126
char * c_str()
Definition: steal_buf.h:53
std::string str()
Definition: steal_buf.h:216
steal_buffer(std::ostream &out)
Definition: steal_buf.h:131
Very simple output stream buffer that uses stack for small chunks of text and then allocates memory o...
Definition: steal_buf.h:32
void release()
Definition: steal_buf.h:158
steal_buffer()
Definition: steal_buf.h:140