C++でC風ライブラリを作る(UTF-16またはUTF-32からUTF-8への変換編2)
高木です。おはようございます。
最近は本当に当サイトのブログが活気づいています。
前回の投稿は探さないと見つからなくなってしまいました。
ブログが活気づくのはいいことなので、うれしい悲鳴といったところでしょうか。
昨年4月の状況を振り返ると、1ヶ月間で105件もの投稿がありました。
おそらく「君ブロ」が佳境を迎えていたからだと思います。
それに比べれば今月の状況はまだおとなしいぐらいです。
余談はこれぐらいにして、本題に入りましょう。
今取り組んでいるUTF-16またはUTF-32からUTF-8への変換編は、かれこれ1ヶ月ほどかけて連載しています。
この辺りでそろそろ完結させたいですね。
今まではchar16_t
型またはchar32_t
型の値からUTF-8の多バイト文字列に変換するというものでした。
実際のコードではwchar_t
型を使うこともあると思いますので、まずはctrtomb
関数をwchar_t
型に対応させることにしましょう。
あまりクソ真面目な対応はやめ、wchar_t
型はchar16_t
型またはchar32_t
型のどちらかと同じサイズ、同じ内部表現であると仮定することにします。
1 2 3 4 5 6 7 8 9 | namespace cloverfield { inline std::size_t ctrtomb(char* s, wchar_t wc, mbstate_t* ps) { if (sizeof(wchar_t) == sizeof(char16_t)) return ctrtomb(s, static_cast<char16_t>(wc), ps); return ctrtomb(s, static_cast<char32_t>(wc), ps); } } |
これでctrtomb
関数は一応の完成をみました。
次は、後回しにしていたcttomb
関数の実装を再開することにしましょう。
以前作ったものはいったん捨て、ctrtomb
関数を使って再実装することにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace cloverfield { inline int cttomb(char* s, char16_t c16) { return static_cast<int>(ctrtomb(s, c16, nullptr)); } inline int cttomb(char* s, char32_t c32) { return static_cast<int>(ctrtomb(s, c32, nullptr)); } inline int cttomb(char* s, wchar_t wc) { return static_cast<int>(ctrtomb(s, wc, nullptr)); } } |
これでcttomb
関数も完成です。
厳密なことをいうと、std::size_t
型からint
型への変換はオーバーフローを発生させるのでよくありません。
ただ、現実の処理系ではまず問題になることはないので、こういう簡易な実装を行いました。
まだまだブラッシュアップの余地はあるのですが、いったんはこの辺りで締めたいと思います。
次回からは、今回の逆、すなわちUTF-8からUTF-16やUTF-32への変換を扱いたいと考えています。