2
0
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:
Alexander Grund
2020-01-24 10:20:07 +01:00
committed by GitHub
3 changed files with 111 additions and 115 deletions

View File

@@ -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

View 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

View File

@@ -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();