[Fedora-i18n-list] iconv help required
Mustafa Jamil
mustafa_jamil at yahoo.com
Fri Sep 8 19:09:01 UTC 2006
Hey.
I'm trying to write a simple C++ string converter that
takes ISO-8859-1-encoded strings and converts them to
UTF8-encoded strings.
Unfortunately, iconv is dying with EILSEQ, and I don't
know why. I'd appreciate any ideas you may have.
Here's my test program (you can run it with 'g++
main.cpp; ./a.out'):
-- START --
#include <string>
#include <vector>
#include <iostream>
#include "errno.h"
using namespace std;
struct i18nError {
i18nError(const std::string &m) : message(m) {
}
const std::string message;
};
std::string
ConvertString(const std::string& input,
const std::string& from,
const std::string& to)
{
cout << "DEBUG: Input string = " << input <<
endl;
size_t input_bytes_to_read = input.size();
//returns the byte size
cout << "DEBUG: input_bytes_to_read = " <<
input_bytes_to_read << endl;
char *input_pointer = (char *)input.c_str();
//cast away the const
size_t output_buffer_size =
(input_bytes_to_read * 4) + 1;
cout << "DEBUG: output_buffer_size = " <<
output_buffer_size << endl;
size_t output_bytes_left = output_buffer_size;
std::vector<char>
output_buffer(output_bytes_left);
char *output_buffer_pointer =
&output_buffer[0];
iconv_t cd = iconv_open(from.c_str(),
to.c_str());
if (cd == (iconv_t) -1) {
// Could not get suitable conversion
descriptor
if (errno == EINVAL) {
throw i18nError("Conversion
from " + from + " to " + to + " is not available");
} else {
throw i18nError("iconv_open
failed");
}
}
size_t nconv = iconv(cd,
&input_pointer,
&input_bytes_to_read,
&output_buffer_pointer,
&output_bytes_left);
if (nconv == (size_t) -1) {
std::string msg = "iconv failed, errno
= ";
if (errno == E2BIG) {
msg += "E2BIG";
} else if (errno == EILSEQ) {
msg += "EILSEQ";
} else if (errno == EINVAL) {
msg += "EINVAL";
} else {
msg += "Unknown";
}
throw i18nError(msg);
}
if (iconv_close(cd) != 0) {
throw i18nError("iconv_close failed");
}
cout << "DEBUG: input_bytes_to_read = " <<
input_bytes_to_read << endl;
cout << "DEBUG: nconv = " << nconv << endl;
cout << "DEBUG: output_bytes_left = " <<
output_bytes_left << endl;
size_t output_bytes_written =
output_buffer_size - output_bytes_left;
cout << "DEBUG: output_bytes_written = " <<
output_bytes_written
<< endl;
if (output_bytes_written < output_buffer_size)
{
*output_buffer_pointer = '\0'; //
explicitly null-terminate
}
std::string retVal =
std::string(&output_buffer[0],
output_buffer.size());
cout << "DEBUG: Output string = " << retVal <<
endl;
cout << "DEBUG: Output string size = " <<
retVal.size() << endl;
return (retVal);
}
main()
{
try {
cout <<
"------------------------------------" << endl;
std::string bar = ConvertString("Hello
world", "ISO-8859-1", "UTF8");
cout <<
"------------------------------------" << endl;
std::string baz =
ConvertString("\xA2", "ISO-8859-1", "UTF8");
cout <<
"------------------------------------" << endl;
} catch (i18nError e) {
cout << e.message << endl;
}
}
-- END --
And here's the output:
------------------------------------
DEBUG: Input string = Hello world
DEBUG: input_bytes_to_read = 11
DEBUG: output_buffer_size = 45
DEBUG: input_bytes_to_read = 0
DEBUG: nconv = 0
DEBUG: output_bytes_left = 34
DEBUG: output_bytes_written = 11
DEBUG: Output string = Hello world
DEBUG: Output string size = 45
------------------------------------
DEBUG: Input string = �
DEBUG: input_bytes_to_read = 1
DEBUG: output_buffer_size = 5
iconv failed, errno = EILSEQ
I'd appreciate any help you can offer.
Thanks!
Mustafa
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
More information about the Fedora-i18n-list
mailing list