mirror of
https://github.com/boostorg/nowide.git
synced 2026-02-21 15:12:30 +00:00
Merge pull request #61 from Flamefire/simplify_convert
Move basic_convert to detail namespace and rename
This commit is contained in:
@@ -8,114 +8,11 @@
|
||||
#ifndef BOOST_NOWIDE_CONVERT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_CONVERT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/detail/utf.hpp>
|
||||
#include <boost/nowide/replacement.hpp>
|
||||
#include <iterator>
|
||||
#include <boost/nowide/detail/convert.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
///
|
||||
/// \brief Template function that converts a buffer of UTF sequences in range [source_begin,source_end)
|
||||
/// to the output \a buffer of size \a buffer_size.
|
||||
///
|
||||
/// In case of success a NULL terminated string is returned (buffer), otherwise 0 is returned.
|
||||
///
|
||||
/// If there is not enough room in the buffer 0 is returned, and the content of the buffer is undefined.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
CharOut* basic_convert(CharOut* buffer, size_t buffer_size, const CharIn* source_begin, const CharIn* source_end)
|
||||
{
|
||||
CharOut* rv = buffer;
|
||||
if(buffer_size == 0)
|
||||
return 0;
|
||||
buffer_size--;
|
||||
while(source_begin != source_end)
|
||||
{
|
||||
using namespace detail::utf;
|
||||
code_point c = utf_traits<CharIn>::template decode<const CharIn*>(source_begin, source_end);
|
||||
if(c == illegal || c == incomplete)
|
||||
{
|
||||
c = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
size_t width = utf_traits<CharOut>::width(c);
|
||||
if(buffer_size < width)
|
||||
{
|
||||
rv = NULL;
|
||||
break;
|
||||
}
|
||||
buffer = utf_traits<CharOut>::template encode<CharOut*>(c, buffer);
|
||||
buffer_size -= width;
|
||||
}
|
||||
*buffer++ = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Template function that converts a buffer of UTF sequences in range [source_begin,source_end) and returns a string containing
|
||||
/// converted value
|
||||
///
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> basic_convert(const CharIn* begin, const CharIn* end)
|
||||
{
|
||||
std::basic_string<CharOut> result;
|
||||
result.reserve(end - begin);
|
||||
typedef std::back_insert_iterator<std::basic_string<CharOut> > inserter_type;
|
||||
inserter_type inserter(result);
|
||||
using namespace detail::utf;
|
||||
code_point c;
|
||||
while(begin != end)
|
||||
{
|
||||
c = utf_traits<CharIn>::template decode<const CharIn*>(begin, end);
|
||||
if(c == illegal || c == incomplete)
|
||||
{
|
||||
c = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
utf_traits<CharOut>::template encode<inserter_type>(c, inserter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \cond INTERNAL
|
||||
namespace detail {
|
||||
//
|
||||
// wcslen defined only in C99... So we will not use it
|
||||
//
|
||||
template<typename Char>
|
||||
const Char* basic_strend(const Char* s)
|
||||
{
|
||||
while(*s)
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
///
|
||||
/// \brief Template function that converts a string \a s from one type of UTF to another UTF and returns a string containing converted
|
||||
/// value
|
||||
///
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> basic_convert(std::basic_string<CharIn> const& s)
|
||||
{
|
||||
return basic_convert<CharOut>(s.c_str(), s.c_str() + s.size());
|
||||
}
|
||||
///
|
||||
/// \brief Template function that converts a string \a s from one type of UTF to another UTF and returns a string containing converted
|
||||
/// value
|
||||
///
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> basic_convert(const CharIn* s)
|
||||
{
|
||||
return basic_convert<CharOut>(s, detail::basic_strend(s));
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert NULL terminated UTF source string to NULL terminated \a output string of size at
|
||||
@@ -126,7 +23,7 @@ namespace nowide {
|
||||
///
|
||||
inline char* narrow(char* output, size_t output_size, const wchar_t* source)
|
||||
{
|
||||
return basic_convert(output, output_size, source, detail::basic_strend(source));
|
||||
return detail::convert_buffer(output, output_size, source, detail::strend(source));
|
||||
}
|
||||
///
|
||||
/// Convert UTF text in range [begin,end) to NULL terminated \a output string of size at
|
||||
@@ -137,7 +34,7 @@ namespace nowide {
|
||||
///
|
||||
inline char* narrow(char* output, size_t output_size, const wchar_t* begin, const wchar_t* end)
|
||||
{
|
||||
return basic_convert(output, output_size, begin, end);
|
||||
return detail::convert_buffer(output, output_size, begin, end);
|
||||
}
|
||||
///
|
||||
/// Convert NULL terminated UTF source string to NULL terminated \a output string of size at
|
||||
@@ -148,7 +45,7 @@ namespace nowide {
|
||||
///
|
||||
inline wchar_t* widen(wchar_t* output, size_t output_size, const char* source)
|
||||
{
|
||||
return basic_convert(output, output_size, source, detail::basic_strend(source));
|
||||
return detail::convert_buffer(output, output_size, source, detail::strend(source));
|
||||
}
|
||||
///
|
||||
/// Convert UTF text in range [begin,end) to NULL terminated \a output string of size at
|
||||
@@ -159,7 +56,7 @@ namespace nowide {
|
||||
///
|
||||
inline wchar_t* widen(wchar_t* output, size_t output_size, const char* begin, const char* end)
|
||||
{
|
||||
return basic_convert(output, output_size, begin, end);
|
||||
return detail::convert_buffer(output, output_size, begin, end);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -169,7 +66,7 @@ namespace nowide {
|
||||
///
|
||||
inline std::string narrow(const wchar_t* s)
|
||||
{
|
||||
return basic_convert<char>(s);
|
||||
return detail::convert_string<char>(s, detail::strend(s));
|
||||
}
|
||||
///
|
||||
/// Convert between UTF-8 and UTF-16 string
|
||||
@@ -178,7 +75,7 @@ namespace nowide {
|
||||
///
|
||||
inline std::wstring widen(const char* s)
|
||||
{
|
||||
return basic_convert<wchar_t>(s);
|
||||
return detail::convert_string<wchar_t>(s, detail::strend(s));
|
||||
}
|
||||
///
|
||||
/// Convert between Wide - UTF-16/32 string and UTF-8 string
|
||||
@@ -187,7 +84,7 @@ namespace nowide {
|
||||
///
|
||||
inline std::string narrow(const std::wstring& s)
|
||||
{
|
||||
return basic_convert<char>(s);
|
||||
return detail::convert_string<char>(s.c_str(), s.c_str() + s.size());
|
||||
}
|
||||
///
|
||||
/// Convert between UTF-8 and UTF-16 string
|
||||
@@ -196,7 +93,7 @@ namespace nowide {
|
||||
///
|
||||
inline std::wstring widen(const std::string& s)
|
||||
{
|
||||
return basic_convert<wchar_t>(s);
|
||||
return detail::convert_string<wchar_t>(s.c_str(), s.c_str() + s.size());
|
||||
}
|
||||
|
||||
} // namespace nowide
|
||||
|
||||
99
include/boost/nowide/detail/convert.hpp
Normal file
99
include/boost/nowide/detail/convert.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef BOOST_NOWIDE_DETAIL_CONVERT_HPP_INCLUDED
|
||||
#define BOOST_NOWIDE_DETAIL_CONVERT_HPP_INCLUDED
|
||||
|
||||
#include <boost/nowide/detail/utf.hpp>
|
||||
#include <boost/nowide/replacement.hpp>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace nowide {
|
||||
/// \cond INTERNAL
|
||||
namespace detail {
|
||||
///
|
||||
/// Convert a buffer of UTF sequences in the range [source_begin, source_end) from \tparam CharIn to \tparam CharOut
|
||||
/// to the output \a buffer of size \a buffer_size.
|
||||
///
|
||||
/// \return original buffer containing the NULL terminated string or NULL
|
||||
///
|
||||
/// If there is not enough room in the buffer NULL is returned, and the content of the buffer is undefined.
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
CharOut* convert_buffer(CharOut* buffer, size_t buffer_size, const CharIn* source_begin, const CharIn* source_end)
|
||||
{
|
||||
CharOut* rv = buffer;
|
||||
if(buffer_size == 0)
|
||||
return 0;
|
||||
buffer_size--;
|
||||
while(source_begin != source_end)
|
||||
{
|
||||
using namespace detail::utf;
|
||||
code_point c = utf_traits<CharIn>::template decode<const CharIn*>(source_begin, source_end);
|
||||
if(c == illegal || c == incomplete)
|
||||
{
|
||||
c = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
size_t width = utf_traits<CharOut>::width(c);
|
||||
if(buffer_size < width)
|
||||
{
|
||||
rv = NULL;
|
||||
break;
|
||||
}
|
||||
buffer = utf_traits<CharOut>::template encode<CharOut*>(c, buffer);
|
||||
buffer_size -= width;
|
||||
}
|
||||
*buffer++ = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
///
|
||||
/// Convert the UTF sequences in range [begin, end) from \tparam CharIn to \tparam CharOut
|
||||
/// and return it as a string
|
||||
///
|
||||
/// Any illegal sequences are replaced with the replacement character, see #BOOST_NOWIDE_REPLACEMENT_CHARACTER
|
||||
///
|
||||
template<typename CharOut, typename CharIn>
|
||||
std::basic_string<CharOut> convert_string(const CharIn* begin, const CharIn* end)
|
||||
{
|
||||
std::basic_string<CharOut> result;
|
||||
result.reserve(end - begin);
|
||||
typedef std::back_insert_iterator<std::basic_string<CharOut> > inserter_type;
|
||||
inserter_type inserter(result);
|
||||
using namespace detail::utf;
|
||||
code_point c;
|
||||
while(begin != end)
|
||||
{
|
||||
c = utf_traits<CharIn>::template decode<const CharIn*>(begin, end);
|
||||
if(c == illegal || c == incomplete)
|
||||
{
|
||||
c = BOOST_NOWIDE_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
utf_traits<CharOut>::template encode<inserter_type>(c, inserter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return the pointer to the first NULL value encountered by increasing s
|
||||
/// Equivalent to `return s + strlen(s)` but more generic
|
||||
template<typename Char>
|
||||
const Char* strend(const Char* s)
|
||||
{
|
||||
while(*s)
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
} // namespace nowide
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -93,7 +93,7 @@ namespace nowide {
|
||||
output_char* convert(const input_char* input)
|
||||
{
|
||||
if(input)
|
||||
return convert(input, detail::basic_strend(input));
|
||||
return convert(input, detail::strend(input));
|
||||
clear();
|
||||
return get();
|
||||
}
|
||||
@@ -107,11 +107,11 @@ namespace nowide {
|
||||
if(space <= buffer_size)
|
||||
{
|
||||
data_ = buffer_;
|
||||
basic_convert(buffer_, buffer_size, begin, end);
|
||||
detail::convert_buffer(buffer_, buffer_size, begin, end);
|
||||
} else
|
||||
{
|
||||
data_ = new output_char[space];
|
||||
basic_convert(data_, space, begin, end);
|
||||
detail::convert_buffer(data_, space, begin, end);
|
||||
}
|
||||
}
|
||||
return get();
|
||||
|
||||
Reference in New Issue
Block a user