Rev 1 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#ifndef STRING_BUILDER_INCLUDED#define STRING_BUILDER_INCLUDED#include <math.h>#include <string.h>#include "stream_base.h"template <class Ty>class string_builder_base : public mystream::stream_base{public:typedef mystream::stream_base base;typedef Ty value_type;typedef Ty* value_type_ptr;typedef const Ty* const_value_type_ptr;typedef size_t size_type;private:value_type_ptr m_buffer;size_type m_bufferSize;size_type m_stringSize;size_type m_growby;bool allocate(size_type newsize){if(allocated() < newsize) {value_type_ptr old=m_buffer;size_type oldsize=m_bufferSize;int c=(int)ceil((float)newsize / growby());m_bufferSize=c * growby();m_buffer=new value_type[m_bufferSize];if(m_buffer==NULL){setstate(failbit);m_buffer=old;m_bufferSize=oldsize;}else{memcpy(m_buffer, old, oldsize * sizeof(value_type));delete[] old;}}return (state() & failbit)==0;}void init(){m_buffer=0; m_bufferSize=m_stringSize=0;base::clear(badbit);}size_type strlen(const wchar_t *str) { return (size_type)::wcslen(str); }size_type strlen(const char *str) { return (size_type)::strlen(str); }public:string_builder_base() { init(); growby(0); }string_builder_base(const_value_type_ptr str){init(); growby(0);append(str);}string_builder_base(const string_builder_base& str){init(); growby(0);append(str);}bool reserve(size_type newsize) { return allocate(newsize); }size_type allocated() const { return m_bufferSize; }size_type size() const { return m_stringSize; }void size(size_type newsize) { m_stringSize=(newsize > allocated() ? allocated() : newsize); }size_type growby() const { return m_growby; }void growby(size_type newgrow) { if(newgrow==0) newgrow=100; m_growby=newgrow; }~string_builder_base() { delete[] m_buffer; }string_builder_base& append(const_value_type_ptr str){size_type s=strlen(str);size_type newsize=size() + s;if(allocate(newsize + 1)==false)return *this;memcpy(m_buffer + size(), str, (s + 1) * sizeof(value_type));size(newsize);base::clear(m_buffer ? goodbit : badbit);return *this;}string_builder_base& append(const string_builder_base& str){size_type newsize=size() + str.size();if(allocate(newsize + 1)==false)return *this;memcpy(m_buffer + size(), str, (str.size() + 1) * sizeof(value_type));size(newsize);base::clear(m_buffer ? goodbit : badbit);return *this;}string_builder_base& append(const value_type& ch){//if(!good()) return;size_type newsize=size() + 1;if(allocate(newsize + 1)==false)return *this;m_buffer[size()]=ch;m_buffer[size() + 1]=0;size(newsize);base::clear(m_buffer ? goodbit : badbit);return *this;}value_type_ptr getbuffer(){value_type_ptr b=m_buffer;init();return b;}void clear(){delete[] m_buffer;init();}const_value_type_ptr buffer() const { return m_buffer; }operator const_value_type_ptr () const { return m_buffer; }string_builder_base& operator = (const string_builder_base& other){if(other.m_buffer==0) {delete[] m_buffer;init();}else(*this)=other.m_buffer;return *this;}string_builder_base& operator = (const_value_type_ptr str){size(0);append(str);base::clear(m_buffer ? goodbit : badbit);return *this;}};class string_builder : public string_builder_base<char>{public:typedef string_builder_base<char> base;string_builder() : string_builder_base<char>() { }string_builder(const char *str) : string_builder_base<char>(str) { }string_builder& operator = (const_value_type_ptr str) { return (string_builder&)base::operator =(str); }};inline string_builder& operator << (string_builder& is, const char *str){is.append(str);return is;}inline string_builder& operator << (string_builder& is, char ch){is.append(ch);return is;}class wstring_builder : public string_builder_base<wchar_t>{public:wstring_builder() : string_builder_base<wchar_t>() { }wstring_builder(const wchar_t *str) : string_builder_base<wchar_t>(str) { }};inline wstring_builder& operator << (wstring_builder& is, const wchar_t *str){is.append(str);return is;}inline wstring_builder& operator << (wstring_builder& is, wchar_t ch){is.append(ch);return is;}inline wstring_builder& operator << (wstring_builder& is, int i){is.append((wstring_builder::value_type)i);return is;}#endif // !defined(STRING_BUILDER_INCLUDED)