我想实现codecvt
方面使用ICU从任何字符编码(ICU支持)转换为UTF-8内部。我知道codecvt_byname
存在,它可以用来做我想要的一部分,如this example所示。这个例子的问题是它(1)使用宽字符流(我想使用“常规”,面向字节的流)和(2)需要2个流来执行转换。相反,我要像一个单一的数据流:使用ICU实现我自己的编码方面
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
为“支点”为上述缓冲液,或提供自己的? - 我不确定何时,如果有的话,我应该将
reset
参数(现在是第一个false
以上)设置为true
。 - 我不知道如何知道何时将
flush
参数(当前是第二个false
)设置为true
,即我如何知道何时已达到输入的结尾。
有一点帮助吗?
您应该在打开文件之前灌注()您的文件流。如果文件已经打开,很多系统会默默地忽略imbue()(这是因为关于对话的状态可能已经丢失)。 – 2011-12-30 15:54:15
完成。其余的答案? – 2011-12-30 16:01:59