Lars Gullik Bjønnes wrote:
Angus Leeming <[EMAIL PROTECTED]> writes:
| In fact, when I look at your code, why don't you make iconv_convert a
| template and return a vector of the correct type directly. All that's
| needed is a change to the last couple of lines of iconv_convert where
| you fill outvec:
|
| int const bytes = 1000 - outbytesleft;
| std::size_t length_outvec = bytes * sizeof(char) / sizeof(T);
| ASSERT(length_outvec * sizeof(T) / sizeof(char) == bytes);
|
| std::vector<T> outvec(length_outvec);
| std::memcpy(&outvec[0], out, bytes);
| return outvec;
|
| I think that the only assumption is that "ucs-4-internal" is a valid
| flag to pass to iconv itself and that iconv will then do the right
| thing when filling the char* buffer.
|
| What do I miss?
converting to utf-8.
Sorry, don't follow.
std::vector<char>
ucs4_to_utf8(std::vector<boost::uint32_t> const & ucs4str)
{
// ucs4str has a machine-specific byte order, but that
// doesn't actually matter because *we* generated it in
// the first place, passing "UCS-4-INTERNAL" to iconv.
std::vector<char> in(ucs4str.size() * 4);
std::memcpy(&in[0], &ucs4str[0], ucs4str.size() * 4);
return iconv_convert<char>("UTF-8", "UCS-4-INTERNAL", in);
}
std::vector<boost::uint32_t>
utf8_to_ucs4(std::vector<char> const & utf8str)
{
return iconv_convert<boost::uint32_t>(
"UCS-4-INTERNAL", "UTF-8", utf8str);
}
template <typename T>
std::vector<T>
iconv_convert(
std::string const & tocode,
std::string const & fromcode,
std::vector const & indata)
{
char outdata[1000] = { 0 };
int const bytes = icon_fill_buffer(
tocode, fromcode, indata, outdata);
// conversion failed.
if (bytes == 0)
return std::vector<T>();
std::size_t length_outvec = bytes * sizeof(char) / sizeof(T);
ASSERT(length_outvec * sizeof(T) / sizeof(char) == bytes);
std::vector<T> outvec(length_outvec);
std::memcpy(&outvec[0], outdata, bytes);
return outvec;
}
template <char>
std::vector<char>
iconv_convert(
std::string const & tocode,
std::string const & fromcode,
std::vector const & indata)
{
// specialize the copying to outvec for char.
// No need for anything more complicated that the
// existing code at the tail of the existing iconv_convert.
...
}
// returns the number of bytes converted.
// (0 if conversion failed.)
int iconv_fill_buffer(
std::string const & tocode,
std::string const & fromcode,
std::vector const & indata,
char* outdata)
{
// The existing iconv_convert goes here.
// Just move out the final copying of outdata
// to vector<char>.
...
}