Changeset 15 for trunk/sample/guessutf8.cpp
- Timestamp:
- 12/21/11 11:46:25 (5 months ago)
- File:
-
- 1 edited
-
trunk/sample/guessutf8.cpp (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/sample/guessutf8.cpp
r6 r15 1 1 /** 2 2 @file guessutf8.cpp 3 @brief libiconv ðp¢½¶Zbg©®F¯ÌTv (àR[h UCS4 Å)3 @brief libiconv を用いた文字セット自動認識処理のサンプル (内部コード UCS4 版) 4 4 @author T.MURACHI (Toshiyuki Murayama) / (C)2010 Harapeko Inc. 5 5 */ … … 15 15 using namespace std; 16 16 17 /// ¶ðµ¤àR[h^17 /// 文字を扱う内部コード型 18 18 typedef uint32_t ucs4_t; 19 19 typedef basic_string<ucs4_t, char_traits<ucs4_t>, allocator<ucs4_t> > ucs4string; 20 20 21 21 /** 22 @brief fR[háONX22 @brief デコード時例外クラス 23 23 */ 24 24 class UcsDecoderException : public exception … … 35 35 36 36 /** 37 @brief GR[háONX37 @brief エンコード時例外クラス 38 38 */ 39 39 class UcsEncoderException : public exception … … 50 50 51 51 /** 52 @brief fR[_NX53 54 t@C©çÇÝñ¾¶ñf[^ðAàR[h̶ñÉÏ··éB55 Ï·ÉA³Ì¶ñf[^̶Zbgð©®F¯·éB52 @brief デコーダクラス 53 54 ファイルから読み込んだ文字列データを、内部コードの文字列に変換する。 55 変換時に、元の文字列データの文字セットを自動認識する。 56 56 */ 57 57 class UcsDecoder … … 61 61 size_t src_size; 62 62 63 // ftHgRXgN^ARs[RXgN^AãüZqÍgpÖ~63 // デフォルトコンストラクタ、コピーコンストラクタ、代入演算子は使用禁止 64 64 UcsDecoder(); 65 65 UcsDecoder(const UcsDecoder &); 66 66 UcsDecoder &operator =(const UcsDecoder &); 67 67 68 /// ¶R[hZbgÌXg68 /// 文字コードセットのリスト 69 69 static char const* const ENCODE_LIST[]; 70 70 … … 76 76 public: 77 77 /** 78 @brief RXgN^79 @param bytes (I) t@C©çÇÝñ¾¶ñf[^78 @brief コンストラクタ 79 @param bytes (I) ファイルから読み込んだ文字列データ 80 80 81 øÉn³ê½¶ñf[^̶Zbgðð͵A UCS4 ÌàR[h𶬷éB82 UCS4 eLXgÉÍ get() \bhÉÄANZXÅ«éB81 引数に渡された文字列データの文字セットを解析し、 UCS4 の内部コードを生成する。 82 UCS4 テキストには get() メソッドにてアクセスできる。 83 83 */ 84 84 UcsDecoder(char const* bytes) … … 98 98 99 99 /** 100 @brief àR[heLXgðæ¾·é101 @return àR[hÉÏ·³ê½eLXg̶ñIuWFNgB100 @brief 内部コードテキストを取得する 101 @return 内部コードに変換されたテキストの文字列オブジェクト。 102 102 */ 103 103 ucs4string const& get() const { return result; } … … 109 109 110 110 private: 111 // ¶ZbgððÍ·éB111 // 文字セットを解析する。 112 112 string guessEncodeType() const 113 113 { … … 126 126 for (;;) { 127 127 size_t ret = iconv(iconv_handle, &from_current, &from_left, &to_current, &to_left); 128 // G[³µ128 // エラー無し 129 129 if (ret != static_cast<size_t>(-1)) 130 130 break; 131 131 132 // }`oCg̺ÊINebhª¯Ä¢éêA133 // f[^\[Xͱ±ÅI¹µÄ¢é͸ÈÌÅAG[ÍJEg¹¸I¹B132 // マルチバイトの下位オクテッドが欠けている場合、 133 // データソースはここで終了しているはずなので、エラーはカウントせず終了。 134 134 if (errno == EINVAL) 135 135 break; … … 137 137 switch (errno) { 138 138 case E2BIG: 139 // oÍæobt@ÌTCYª«èÈ¢B140 // Ï·©ÌªÚIÅÍÈ¢ÌÅA±«Íã«·éB139 // 出力先バッファのサイズが足りない。 140 // 変換自体が目的ではないので、続きは上書きする。 141 141 to_current = reinterpret_cast<char *>(&buf[0]); 142 142 to_left = src_size * sizeof(ucs4_t); 143 143 break; 144 144 case EILSEQ: 145 // è¾È¢R[hªo»B146 // G[ðJEgµA±«©çÏ·ðp±·éB145 // あり得ないコードが出現。 146 // エラーをカウントし、続きから変換を継続する。 147 147 ill_seq_count++; 148 148 from_current++; … … 150 150 break; 151 151 case EBADF: 152 // ½ç©ÌRÉæèϷɸsBÊíÍ è¾È¢Í¸B152 // 何らかの理由により変換に失敗。通常はあり得ないはず。 153 153 iconv_close(iconv_handle); 154 154 throw UcsDecoderException("iconv faild"); 155 155 default: 156 // ¢è`ÌG[Ô156 // 未定義のエラー番号 157 157 iconv_close(iconv_handle); 158 158 throw UcsDecoderException("unknown error"); … … 161 161 iconv_close(iconv_handle); 162 162 163 // G[ªêÂàȯêÎmè163 // エラーが一つもなければ確定 164 164 if (ill_seq_count == 0) 165 165 return *encode_type; … … 167 167 ill_seq_count_map[*encode_type] = ill_seq_count; 168 168 } 169 // G[̪ÅàÈ¢àÌðóâÆµÄÔ·B169 // エラーの数が最も少ないものを候補として返す。 170 170 string guess_code; 171 171 int ill_seq_count = 0; … … 179 179 } 180 180 181 // ³f[^̶ZbgðwèµÄA UCS4 àR[heLXgÉÏ··éB181 // 元データの文字セットを指定して、 UCS4 内部コードテキストに変換する。 182 182 void decodeToUcs4(const string &encode_type) 183 183 { … … 193 193 for (;;) { 194 194 size_t ret = iconv(iconv_handle, &from_current, &from_left, &to_current, &to_left); 195 // G[³µ195 // エラー無し 196 196 if (ret != static_cast<size_t>(-1)) 197 197 break; 198 198 199 // }`oCg̺ÊINebhª¯Ä¢éêA200 // f[^\[Xͱ±ÅI¹µÄ¢é͸ÈÌÅA±±ÜÅÅI¹B199 // マルチバイトの下位オクテッドが欠けている場合、 200 // データソースはここで終了しているはずなので、ここまでで終了。 201 201 if (errno == EINVAL) 202 202 break; … … 204 204 switch (errno) { 205 205 case E2BIG: 206 // oÍæobt@ÌTCYª«èÈ¢B207 // obt@ðg£µAp±·éB206 // 出力先バッファのサイズが足りない。 207 // バッファを拡張し、継続する。 208 208 { 209 209 size_t pre_size = buf.size(); … … 214 214 break; 215 215 case EILSEQ: 216 // è¾È¢R[hªo»B217 // G[ðñðµA±«©çÏ·ðp±·éB216 // あり得ないコードが出現。 217 // エラーを回避し、続きから変換を継続する。 218 218 from_current++; 219 219 from_left--; 220 220 break; 221 221 case EBADF: 222 // ½ç©ÌRÉæèϷɸsBÊíÍ è¾È¢Í¸B222 // 何らかの理由により変換に失敗。通常はあり得ないはず。 223 223 iconv_close(iconv_handle); 224 224 throw UcsDecoderException("iconv faild"); 225 225 default: 226 // ¢è`ÌG[Ô226 // 未定義のエラー番号 227 227 iconv_close(iconv_handle); 228 228 throw UcsDecoderException("unknown error"); … … 249 249 250 250 /** 251 @brief GR[_NX252 253 àR[h̶ñðAUTF-8 `®Ì¶ñf[^ÉÏ··éB251 @brief エンコーダクラス 252 253 内部コードの文字列を、UTF-8 形式の文字列データに変換する。 254 254 */ 255 255 class UcsEncoder … … 258 258 vector<char> result_bytes; 259 259 260 // ftHgRXgN^ARs[RXgN^AãüZqÍgpÖ~260 // デフォルトコンストラクタ、コピーコンストラクタ、代入演算子は使用禁止 261 261 UcsEncoder(); 262 262 UcsEncoder(const UcsEncoder &); … … 265 265 public: 266 266 /** 267 @brief RXgN^268 @param src (I) UCS4 àR[h¶ñ267 @brief コンストラクタ 268 @param src (I) UCS4 内部コード文字列 269 269 270 øÉn³ê½ UCS4 àR[h¶ñðAUTF-8 `®Ì¶ñf[^ÉÏ··éB270 引数に渡された UCS4 内部コード文字列を、UTF-8 形式の文字列データに変換する。 271 271 */ 272 272 UcsEncoder(const ucs4string &src) : ucs_text(src), result_bytes(src.size() + 1, '\0') … … 275 275 } 276 276 /** 277 @brief UTF-8 `®Ì¶ñf[^ðæ¾·é278 @return UTF-8 `®Ì¶ñf[^ÖÌ|C^277 @brief UTF-8 形式の文字列データを取得する 278 @return UTF-8 形式の文字列データへのポインタ 279 279 */ 280 280 char const* get() const { return &result_bytes[0]; } 281 281 282 282 private: 283 // UCS4 àR[h¶ñð UTF-8 `®ÉÏ··é283 // UCS4 内部コード文字列を UTF-8 形式に変換する 284 284 void encodeFromUcs4() 285 285 { … … 293 293 for (;;) { 294 294 size_t ret = iconv(iconv_handle, &from_current, &from_left, &to_current, &to_left); 295 // G[³µ295 // エラー無し 296 296 if (ret != static_cast<size_t>(-1)) 297 297 break; 298 298 299 // }`oCg̺ÊINebhª¯Ä¢éêA300 // f[^\[Xͱ±ÅI¹µÄ¢é͸ÈÌÅA±±ÜÅÅI¹B301 // ¦ è¦È¢ªc299 // マルチバイトの下位オクテッドが欠けている場合、 300 // データソースはここで終了しているはずなので、ここまでで終了。 301 // ※ありえないが… 302 302 if (errno == EINVAL) 303 303 break; … … 305 305 switch (errno) { 306 306 case E2BIG: 307 // oÍæobt@ÌTCYª«èÈ¢B308 // obt@ðg£µAp±·éB307 // 出力先バッファのサイズが足りない。 308 // バッファを拡張し、継続する。 309 309 { 310 310 size_t pre_size = result_bytes.size(); … … 315 315 break; 316 316 case EILSEQ: 317 // è¾È¢R[hªo»B318 // G[ðñðµA±«©çÏ·ðp±·éB317 // あり得ないコードが出現。 318 // エラーを回避し、続きから変換を継続する。 319 319 from_current++; 320 320 from_left--; 321 321 break; 322 322 case EBADF: 323 // ½ç©ÌRÉæèϷɸsBÊíÍ è¾È¢Í¸B323 // 何らかの理由により変換に失敗。通常はあり得ないはず。 324 324 iconv_close(iconv_handle); 325 325 throw UcsEncoderException("iconv faild"); 326 326 default: 327 // ¢è`ÌG[Ô327 // 未定義のエラー番号 328 328 iconv_close(iconv_handle); 329 329 throw UcsEncoderException("unknown error"); … … 337 337 { 338 338 try { 339 // WüÍðêCÇÝc339 // 標準入力を一気読み… 340 340 vector<char> buf(32768, '\0'); 341 341 char * target = &buf[0]; … … 353 353 target = &buf[pre_size - 1]; 354 354 } 355 // fR[h355 // デコード 356 356 ucs4string text = UcsDecoder(&buf[0]).get(); 357 // uAvðu,vÉÏ··é357 // 「、」を「,」に変換する 358 358 for (size_t i = text.find_first_of(0x3001ul); i != ucs4string::npos; i = text.find_first_of(0x3001ul, i + 1)) 359 359 text[i] = 0x2cul; 360 // uBvðu.vÉÏ··é360 // 「。」を「.」に変換する 361 361 for (size_t i = text.find_first_of(0x3002ul); i != ucs4string::npos; i = text.find_first_of(0x3002ul, i + 1)) 362 362 text[i] = 0x2eul; 363 // GR[hµÄoÍ363 // エンコードして出力 364 364 fputs(UcsEncoder(text).get(), stdout); 365 365 }
Note: See TracChangeset
for help on using the changeset viewer.
