Boost.Nowide
boost/nowide/convert.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_CONVERT_H_INCLUDED
00009 #define BOOST_NOWIDE_CONVERT_H_INCLUDED
00010 
00011 #include <string>
00012 #include <boost/locale/encoding_utf.hpp>
00013 
00014 namespace boost {
00015 namespace nowide {
00025     template<typename CharOut,typename CharIn>
00026     CharOut *basic_convert(CharOut *buffer,size_t buffer_size,CharIn const *source_begin,CharIn const *source_end)
00027     {
00028         CharOut *rv = buffer;
00029         if(buffer_size == 0)
00030             return 0;
00031         buffer_size --;
00032         while(source_begin!=source_end) {
00033             using namespace boost::locale::utf;
00034             code_point c = utf_traits<CharIn>::template decode<CharIn const *>(source_begin,source_end);
00035             if(c==illegal || c==incomplete) {
00036                 rv = 0;
00037                 break;
00038             }
00039             size_t width = utf_traits<CharOut>::width(c);
00040             if(buffer_size < width) {
00041                 rv=0;
00042                 break;
00043             }
00044             buffer = utf_traits<CharOut>::template encode<CharOut *>(c,buffer);
00045             buffer_size -= width;
00046         }
00047         *buffer++ = 0;
00048         return rv;
00049     }
00050 
00052     namespace details {
00053         //
00054         // wcslen defined only in C99... So we will not use it
00055         //
00056         template<typename Char>
00057         Char const *basic_strend(Char const *s)
00058         {
00059             while(*s)
00060                 s++;
00061             return s;
00062         }
00063     }
00065 
00073     inline char *narrow(char *output,size_t output_size,wchar_t const *source)
00074     {
00075         return basic_convert(output,output_size,source,details::basic_strend(source));
00076     }
00084     inline char *narrow(char *output,size_t output_size,wchar_t const *begin,wchar_t const *end)
00085     {
00086         return basic_convert(output,output_size,begin,end);
00087     }
00095     inline wchar_t *widen(wchar_t *output,size_t output_size,char const *source)
00096     {
00097         return basic_convert(output,output_size,source,details::basic_strend(source));
00098     }
00106     inline wchar_t *widen(wchar_t *output,size_t output_size,char const *begin,char const *end)
00107     {
00108         return basic_convert(output,output_size,begin,end);
00109     }
00110 
00111 
00117     inline std::string narrow(wchar_t const *s)
00118     {
00119         return boost::locale::conv::utf_to_utf<char>(s);
00120     }
00126     inline std::wstring widen(char const *s)
00127     {
00128         return boost::locale::conv::utf_to_utf<wchar_t>(s);
00129     }
00135     inline std::string narrow(std::wstring const &s) 
00136     {
00137         return boost::locale::conv::utf_to_utf<char>(s);
00138     }
00144     inline std::wstring widen(std::string const &s) 
00145     {
00146         return boost::locale::conv::utf_to_utf<wchar_t>(s);
00147     }
00148 
00149 } // nowide
00150 } // namespace boost
00151 
00152 #endif
00153 
00154 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4