[Fedora-i18n-list] Re: iconv help required
Mustafa Jamil
mustafa_jamil at yahoo.com
Fri Sep 8 19:21:37 UTC 2006
Um, never mind. I have the from/to encodings
reversed. :(
--- Mustafa Jamil <mustafa_jamil at yahoo.com> wrote:
> 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
>
__________________________________________________
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