encoding_converter: overload for C strings

This commit is contained in:
Frédéric Mangano-Tarumi 2018-12-09 12:17:10 -05:00
parent ebc8347c9e
commit bb548f51d3
2 changed files with 10 additions and 7 deletions

View File

@ -153,7 +153,9 @@ public:
* abort the processing. If some character could not be converted perfectly, keep converting
* the string and finally return #st::information_lost.
*/
status operator()(const std::string& in, std::string& out);
status operator()(const std::string& in, std::string& out)
{ return (*this)(in.data(), in.size(), out); }
status operator()(const char* in, size_t n, std::string& out);
private:
iconv_t cd; /**< conversion descriptor */
};

View File

@ -63,13 +63,13 @@ ot::encoding_converter::~encoding_converter()
iconv_close(cd);
}
ot::status ot::encoding_converter::operator()(const std::string& in, std::string& out)
ot::status ot::encoding_converter::operator()(const char* in, size_t n, std::string& out)
{
iconv(cd, nullptr, nullptr, nullptr, nullptr);
out.clear();
out.reserve(in.size());
char* in_cursor = const_cast<char*>(in.data());
size_t in_left = in.size();
out.reserve(n);
char* in_cursor = const_cast<char*>(in);
size_t in_left = n;
constexpr size_t chunk_size = 1024;
char chunk[chunk_size];
bool lost_information = false;
@ -79,7 +79,8 @@ ot::status ot::encoding_converter::operator()(const std::string& in, std::string
size_t rc = iconv(cd, &in_cursor, &in_left, &out_cursor, &out_left);
if (rc == (size_t) -1 && errno != E2BIG)
return {ot::st::badly_encoded,
"Could not convert string '" + in + "': " + strerror(errno)};
"Could not convert string '" + std::string(in, n) + "': " +
strerror(errno)};
if (rc != 0)
lost_information = true;
out.append(chunk, out_cursor - chunk);
@ -91,6 +92,6 @@ ot::status ot::encoding_converter::operator()(const std::string& in, std::string
if (lost_information)
return {ot::st::information_lost,
"Some characters could not be converted into the target encoding "
"in string '" + in + "'."};
"in string '" + std::string(in, n) + "'."};
return ot::st::ok;
}