Транскодирование символов на лету с использованием iostreams и ICU

Я хотел бы перекодировать кодировку символов на лету. Я хотел бы использовать iostreams и мое собственное транскодирование streambufНапример:

xcoder_streambuf xbuf( "UTF-8", "ISO-8859-1", cout.rdbuf() );
cout.rdbuf( &xbuf );

char *utf8_s;    // pointer to buffer containing UTF-8 encoded characters
// ...
cout << utf8_s;  // characters are written in ISO-8859-1

Реализация xcoder_streambuf будет использовать API конвертеров ICU. Это будет принимать данные, поступающие (в этом случае от utf8_s), перекодируйте его и запишите, используя оригинал iostream steambuf,

Это разумный путь? Если нет, то что будет лучше?

1 ответ

Это разумный путь?

Да, но это не то, что от вас ожидают в современном (как в 1997 году) iostream.

Поведение вывода через basic_streambuf<> определяется overflow(int_type c) виртуальная функция.

Описание basic_filebuf<>::overflow(int_type c = traits::eof()) включает в себя a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end); где a_codecvt определяется как:

const codecvt<charT,char,typename traits::state_type>& a_codecvt 
     = use_facet<codecvt<charT,char,typename traits::state_type> >(getloc());

так что вы должны imbue locale с соответствующими codecvt<charT,char,typename traits::state_type> конвертер.

Класс codecvt<internT,externT,stateT> предназначен для использования при преобразовании одной кодировки символов в другую, например, из широких символов в многобайтовые символы или между кодировками широких символов, такими как Unicode и EUC.

Поддержка стандартной библиотеки Unicode достигла определенного прогресса с 1997 года:

код специализации конвертирует между схемами кодирования UTF-32 и UTF-8.

Это, кажется, то, что вы хотите (коды ISO-8859-1 - это коды USC-4 = UTF-32).

Если нет, то что будет лучше?

Я бы представил другой тип для UTF8, например:

struct utf8 {
    символ без знака d; // d для данных
};

struct latin1 {
    беззнаковый символ c; // c для персонажа 
};

Таким образом, вы не можете случайно пройти UTF8 там, где ожидается ISO-8859-*. Но тогда вам придется написать некоторый код интерфейса, и тип ваших потоков не будет istream / ostream,

Отказ от ответственности: я никогда не делал ничего подобного, поэтому я не знаю, возможно ли это на практике.

Другие вопросы по тегам