【发布时间】:2012-01-30 15:31:53
【问题描述】:
我想使用 ICU 实现codecvt facet,以便在内部从任何字符编码(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 编码。
我的问题是:
- 我应该像上面那样为“pivot”缓冲区指定
nullptr,还是提供我自己的? - 我不确定何时应该将
reset参数(目前是上面的第一个false)设置为true。 - 不清楚我如何知道何时将
flush参数(目前是上面的第二个false)设置为true,即,我如何知道何时到达输入的末尾。
有点帮助?
【问题讨论】:
-
您应该在打开文件之前灌输()您的文件流。如果文件已经打开,许多系统会默默地忽略 imbue()(这是因为有关对话的状态可能已经丢失)。
-
完成。剩下的有什么答案吗?