steal_buf.h
//
// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
//
// See accompanying file COPYING.TXT file for licensing details.
//
#ifndef CPPCMS_STEAL_BUF_H
#define CPPCMS_STEAL_BUF_H
#include <streambuf>
#include <ostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <stdlib.h>
namespace cppcms {
namespace util {
template<size_t OnStackSize = 128>
class stackbuf : public std::streambuf {
stackbuf(stackbuf const &);
void operator=(stackbuf const &);
public:
char *begin()
{
return pbase();
}
char *end()
{
return pptr();
}
char *c_str()
{
*pptr() = 0;
return begin();
}
std::string str()
{
return std::string(begin(),size_t(end()-begin()));
}
stackbuf()
{
init();
}
~stackbuf()
{
free(on_heap_);
}
protected:
int overflow(int c)
{
size_t current_size;
size_t new_size;
if(pbase() == on_stack_) {
current_size = OnStackSize;
new_size = OnStackSize * 2;
on_heap_ = (char *)malloc(new_size + 1);
if(!on_heap_)
throw std::bad_alloc();
memcpy(on_heap_,on_stack_,current_size);
}
else {
current_size = pptr() - pbase();
new_size = current_size * 2;
char *new_ptr = (char *)realloc(on_heap_,new_size + 1);
if(!new_ptr)
throw std::bad_alloc();
on_heap_ = new_ptr;
}
setp(on_heap_,on_heap_ + new_size);
pbump(current_size);
if(c!=EOF)
sputc(c);
return 0;
}
private:
void init()
{
on_heap_ = 0;
setp(on_stack_,on_stack_+OnStackSize);
}
char *on_heap_;
char on_stack_[OnStackSize + 1];
};
template<size_t Size = 128>
class steal_buffer : public stackbuf<Size> {
public:
steal_buffer(std::ostream &out)
{
stolen_ = 0;
stream_ = 0;
steal(out);
}
steal_buffer()
{
stolen_ = 0;
stream_ = 0;
}
void steal(std::ostream &out)
{
release();
stolen_ = out.rdbuf(this);
stream_ = &out;
}
void release()
{
if(stream_ && stolen_) {
stream_->rdbuf(stolen_);
}
stream_ = 0;
stolen_ = 0;
}
~steal_buffer()
{
release();
}
private:
std::streambuf *stolen_;
std::ostream *stream_;
};
template<size_t Size = 128>
class stackstream : public std::ostream {
public:
stackstream() : std::ostream(0)
{
rdbuf(&buf_);
}
char *begin()
{
return buf_.begin();
}
char *end()
{
return buf_.end();
}
char *c_str()
{
return buf_.c_str();
}
std::string str()
{
return buf_.str();
}
private:
stackbuf<Size> buf_;
};
} // util
} // cppcms
#endif
cppcms::util::stackbuf::end
char * end()
Definition: steal_buf.h:46
cppcms::util::stackbuf::begin
char * begin()
Definition: steal_buf.h:39
cppcms::util::stackstream::begin
char * begin()
Definition: steal_buf.h:195
cppcms::util::steal_buffer::steal
void steal(std::ostream &out)
Definition: steal_buf.h:148
cppcms::util::stackstream::c_str
char * c_str()
Definition: steal_buf.h:209
cppcms::util::stackbuf::str
std::string str()
Definition: steal_buf.h:61
cppcms::util::stackstream::end
char * end()
Definition: steal_buf.h:202
cppcms::util::stackstream::stackstream
stackstream()
Definition: steal_buf.h:188
cppcms::util::stackstream
Fast output stream object.
Definition: steal_buf.h:183
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:126
cppcms::util::stackbuf::c_str
char * c_str()
Definition: steal_buf.h:53
cppcms::util::stackstream::str
std::string str()
Definition: steal_buf.h:216
cppcms::util::steal_buffer::steal_buffer
steal_buffer(std::ostream &out)
Definition: steal_buf.h:131
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:32
cppcms::util::steal_buffer::release
void release()
Definition: steal_buf.h:158
cppcms::util::steal_buffer::steal_buffer
steal_buffer()
Definition: steal_buf.h:140