Boost.Nowide
boost/nowide/stackstring.hpp
00001 //
00002 //  Copyright (c) 2012 Artyom Beilis (Tonkikh)
00003 //
00004 //  Distributed under the Boost Software License, Version 1.0. (See
00005 //  accompanying file LICENSE_1_0.txt or copy at
00006 //  http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 #ifndef BOOST_NOWIDE_DETAILS_WIDESTR_H_INCLUDED
00009 #define BOOST_NOWIDE_DETAILS_WIDESTR_H_INCLUDED
00010 #include <boost/nowide/convert.hpp>
00011 #include <string.h>
00012 #include <algorithm>
00013 
00014 namespace boost {
00015 namespace nowide {
00016 
00024 template<typename CharOut=wchar_t,typename CharIn = char,size_t BufferSize = 256>
00025 class basic_stackstring {
00026 public:
00027    
00028     static const size_t buffer_size = BufferSize; 
00029     typedef CharOut output_char;
00030     typedef CharIn input_char;
00031 
00032     basic_stackstring(basic_stackstring const &other) : 
00033     mem_buffer_(0)
00034     {
00035         clear();
00036         if(other.mem_buffer_) {
00037             size_t len = 0;
00038             while(other.mem_buffer_[len])
00039                 len ++;
00040             mem_buffer_ = new output_char[len + 1];
00041             memcpy(mem_buffer_,other.mem_buffer_,sizeof(output_char) * (len+1));
00042         }
00043         else {
00044             memcpy(buffer_,other.buffer_,buffer_size * sizeof(output_char));
00045         }
00046     }
00047     
00048     void swap(basic_stackstring &other)
00049     {
00050         std::swap(mem_buffer_,other.mem_buffer_);
00051         for(size_t i=0;i<buffer_size;i++)
00052             std::swap(buffer_[i],other.buffer_[i]);
00053     }
00054     basic_stackstring &operator=(basic_stackstring const &other)
00055     {
00056         if(this != &other) {
00057             basic_stackstring tmp(other);
00058             swap(tmp);            
00059         }
00060         return *this;
00061     }
00062 
00063     basic_stackstring() : mem_buffer_(0)
00064     {
00065     }
00066     bool convert(input_char const *input)
00067     {
00068         return convert(input,details::basic_strend(input));
00069     }
00070     bool convert(input_char const *begin,input_char const *end)
00071     {
00072         clear();
00073 
00074         size_t space = get_space(sizeof(input_char),sizeof(output_char),end - begin) + 1;
00075         if(space <= buffer_size) {
00076             if(basic_convert(buffer_,buffer_size,begin,end))
00077                 return true;
00078             clear();
00079             return false;
00080         }
00081         else {
00082             mem_buffer_ = new output_char[space];
00083             if(!basic_convert(mem_buffer_,space,begin,end)) {
00084                 clear();
00085                 return false;
00086             }
00087             return true;
00088         }
00089 
00090     }
00091     output_char *c_str()
00092     {
00093         if(mem_buffer_)
00094             return mem_buffer_;
00095         return buffer_;
00096     }
00097     output_char const *c_str() const
00098     {
00099         if(mem_buffer_)
00100             return mem_buffer_;
00101         return buffer_;
00102     }
00103     void clear()
00104     {
00105         if(mem_buffer_) {
00106             delete [] mem_buffer_;
00107             mem_buffer_=0;
00108         }
00109         buffer_[0] = 0;
00110     }
00111     ~basic_stackstring()
00112     {
00113         clear();
00114     }
00115 private:
00116     static size_t get_space(size_t insize,size_t outsize,size_t in)
00117     {
00118         if(insize <= outsize)
00119             return in;
00120         else if(insize == 2 && outsize == 1) 
00121             return 3 * in;
00122         else if(insize == 4 && outsize == 1) 
00123             return 4 * in;
00124         else  // if(insize == 4 && outsize == 2) 
00125             return 2 * in;
00126     }
00127     output_char buffer_[buffer_size];
00128     output_char *mem_buffer_;
00129 };  //basic_stackstring
00130 
00134 typedef basic_stackstring<wchar_t,char,256> wstackstring;
00138 typedef basic_stackstring<char,wchar_t,256> stackstring;
00142 typedef basic_stackstring<wchar_t,char,16> wshort_stackstring;
00146 typedef basic_stackstring<char,wchar_t,16> short_stackstring;
00147 
00148 
00149 } // nowide
00150 } // namespace boost
00151 
00152 #endif
00153 
00154 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4