我想使用ICU实现codecvt
方面,以便在内部将任何字符编码(ICU支持)转换为UTF-8。我知道codecvt_byname
存在,并且它可用于执行我想要的部分内容,如this example所示。该示例的问题在于它(1)使用宽字符流(我想使用“常规”,面向字节的流)和(2)需要2个流来执行转换。相反,我想要一个像:
locale loc( locale(), new icu_codecvt( "ISO-8859-1" ) );
ifstream ifs;
ifs.imbue( loc );
ifs.open( "/path/to/some/file.txt" );
// data read from ifs here will have been converted from ISO-8859-1 to UTF-8
因此,我想做一个像this这样的实现,但是使用ICU而不是iconv
。
鉴于此,我对do_in()
的实施是:
icu_codecvt::result icu_codecvt::do_in( state_type &state,
extern_type const *from, extern_type const *from_end,
extern_type const *&from_next, intern_type *to,
intern_type *to_end, intern_type *&to_next ) const {
from_next = from;
to_next = to;
if ( always_noconv_ )
return noconv;
our_state *const s = state_store_.get( state );
UErrorCode err = U_ZERO_ERROR;
ucnv_convertEx(
s->utf8_conv_, s->extern_conv_, &to_next, to_end, &from_next, from_end,
nullptr, nullptr, nullptr, nullptr, false, false, &err
);
if ( err == U_TRUNCATED_CHAR_FOUND )
return partial;
return U_SUCCESS( err ) ? ok : error;
}
our_state
对象维护两个UConverter*
指针,一个用于“外部”编码(在本例中为ISO-8859-1),另一个用于UTF-8编码。
我的问题是:
nullptr
,还是提供我自己的?{/ li>
reset
参数(目前是上面的第一个false
)设置为true
。flush
参数(目前是上面的第二个false
)设置为true
,即我怎么知道输入结束的时间已经到达。一点帮助?
答案 0 :(得分:0)
codecvt方面不旨在在不同编码之间进行转换。相反,它从外部编码转换,其中一个字符可能使用多个外部字(通常为字节)编码为内部表示,其中每个字符由一个字(例如char,wchar_t,char16_t等)表示。
从这个角度来看,“结束”内部字符序列是没有意义的。如果没有可用的外部单词,则转换完成,如果最后一个字符仍未完成,则这是转移中的错误。因此,不需要指示转换是完整的,并且相应地,没有指示接口。这应该澄清“冲洗”论证确实应该总是“假”。
我意识到UTF-8并不适合让一个单词代表一个字符。但是,这将困扰您使用标准类型处理字符串来使用UTF-8处理。只要你不清楚syring修改,通常情况下工作正常。
“reset”参数可能用于处理流中的搜索。我认为filebuf应该在搜索时提供一个新的state_type对象。这可能表明ICU内部需要重置。但是,我不知道ICU接口。因此,我也不知道您是否想要提供数据透视缓冲区。