/*---------------------------------------------------------------------------------------------- Convert UTF-8 to UTF-32--a single character's worth. Also pass back the number of 8-bit items consumed. ----------------------------------------------------------------------------------------------*/ utf32 GrCharStream::Utf8ToUtf32(utf8 * prgchs, int cchs, int * pcchsUsed) { if (cchs <= 0) { *pcchsUsed = 0; return 0; } long chlRet = DecodeUtf8(prgchs, cchs, pcchsUsed); Assert(chlRet > 0); if (chlRet == -1) { // Some error occurred. Just treat the UTF-8 as UTF-32. *pcchsUsed = 1; return (utf32)prgchs[0]; } else return chlRet; }
/* CESU-8 文字のチェック (組み合わせ文字列考慮なし) */ int CheckCesu8Char( const char* pS, const int nLen, ECharSet* peCharset, const int nOption ) { ECharSet echarset1, echarset2, eret_charset; int nclen1, nclen2, nret_clen; if( nLen < 1 ){ return 0; } // 1文字目のスキャン nclen1 = CheckUtf8Char( &pS[0], nLen, &echarset1, false, 0 ); // 文字長が3未満の場合 if( nclen1 < 3 ){ // echarset == BAINARY の場合は、からなず nclen1 < 3 eret_charset = echarset1; nret_clen = nclen1; }else // 文字長が3の場合 if( nclen1 == 3 ){ // 正常な3バイト文字があった。 // 2文字目のスキャン nclen2 = CheckUtf8Char( &pS[3], nLen-3, &echarset2, false, 0 ); // &pS[3]からの文字長が3でないか echarset2 が CHARSET_BINARY だった場合。 if( nclen2 != 3 || echarset2 == CHARSET_BINARY ){ // nclen1 と echarset1 を結果とする。 eret_charset = echarset1; nret_clen = nclen1; // &pS[0] から3バイトがサロゲート片だった場合。 if( IsUtf8SurrogHi(&pS[0]) || IsUtf8SurrogLow(&pS[0]) ){ eret_charset = CHARSET_BINARY; nret_clen = 1; } goto EndFunc; } // nclen1 == 3 && echarset1 != CHARSET_BINARY // && nclen2 == 3 && echarset2 != CHARSET_BINARY の場合。 // UTF-8版サロゲートペアを確認。 if( IsUtf8SurrogHi(&pS[0]) && IsUtf8SurrogLow(&pS[3]) ){ // CESU-8 であるかどうかをチェック eret_charset = CHARSET_UNI_SURROG; nret_clen = 6; // CESU-8 のサロゲートである }else // &pS[0] から3バイトがサロゲート片だった場合。 if( IsUtf8SurrogHi(&pS[0]) || IsUtf8SurrogLow(&pS[0]) ){ eret_charset = CHARSET_BINARY; nret_clen = 1; }else // 通常の3バイト文字 { eret_charset = echarset1; nret_clen = 3; } }else // 文字長が3より大きい場合 { // nclen1 == 4 // UTF-16 サロゲートに変換される領域 // 4バイトコードは禁止 eret_charset = CHARSET_BINARY; nret_clen = 1; } EndFunc:; // 非文字と予約コードポイントを確認 if( nOption != 0 && eret_charset != CHARSET_BINARY ){ wchar32_t wc32; if( nret_clen < 4 ){ wc32 = DecodeUtf8( reinterpret_cast<const unsigned char*>(pS), nret_clen ); if( (nOption & UC_NONCHARACTER) && IsUnicodeNoncharacter(wc32) ){ eret_charset = CHARSET_BINARY; nret_clen = 1; } }else if( nret_clen == 6 ){ wc32 = DecodeUtf16Surrog( static_cast<unsigned short>(DecodeUtf8(reinterpret_cast<const unsigned char*>(&pS[0]), 3) & 0x0000ffff), static_cast<unsigned short>(DecodeUtf8(reinterpret_cast<const unsigned char*>(&pS[3]), 3) & 0x0000ffff) ); if( (nOption & UC_NONCHARACTER) && IsUnicodeNoncharacter(wc32) ){ eret_charset = CHARSET_BINARY; nret_clen = 1; } }else{ // 保護コード eret_charset = CHARSET_BINARY; nret_clen = 1; } } if( peCharset ){ *peCharset = eret_charset; } return nret_clen; }
/*! UTF-8 文字をチェック (組み合わせ文字列考慮なし) @sa CheckSjisChar() @date 2008/11/01 syat UTF8ファイルで欧米の特殊文字が読み込めない不具合を修正 */ int CheckUtf8Char( const char *pS, const int nLen, ECharSet *peCharset, const bool bAllow4byteCode, const int nOption ) { unsigned char c0, c1, c2, c3; int ncwidth; ECharSet echarset; if( nLen < 1 ){ return 0; } echarset = CHARSET_UNI_NORMAL; c0 = pS[0]; if( c0 < 0x80 ){ // 第1バイトが 0aaabbbb の場合 ncwidth = 1; // 1バイトコードである goto EndFunc; }else if( 1 < nLen && (c0 & 0xe0) == 0xc0 ){ // 第1バイトが110aaabbの場合 c1 = pS[1]; // 第2バイトが10bbccccの場合 if( (c1 & 0xc0) == 0x80 ){ ncwidth = 2; // 2バイトコードである // 第1バイトがaaabb=0000xの場合(\u80未満に変換される) if( (c0 & 0x1e) == 0 ){ // デコードできない.(往復変換不可領域) echarset = CHARSET_BINARY; ncwidth = 1; } goto EndFunc; } }else if( 2 < nLen && (c0 & 0xf0) == 0xe0 ){ // 第1バイトが1110aaaaの場合 c1 = pS[1]; c2 = pS[2]; // 第2バイトが10bbbbcc、第3バイトが10ccddddの場合 if( (c1 & 0xc0) == 0x80 && (c2 & 0xc0) == 0x80 ){ ncwidth = 3; // 3バイトコードである // 第1バイトのaaaa=0000、第2バイトのbbbb=0xxxの場合(\u800未満に変換される) if( (c0 & 0x0f) == 0 && (c1 & 0x20) == 0 ){ // デコードできない.(往復変換不可領域) echarset = CHARSET_BINARY; ncwidth = 1; } //if( (c0 & 0x0f) == 0x0f && (c1 & 0x3f) == 0x3f && (c2 & 0x3e) == 0x3e ){ // // Unicode でない文字(U+FFFE, U+FFFF) // charset = CHARSET_BINARY; // ncwidth = 1; //} if( bAllow4byteCode == true && (c0 & 0x0f) == 0x0d && (c1 & 0x20) != 0 ){ // サロゲート領域 (U+D800 から U+DFFF) echarset = CHARSET_BINARY; ncwidth = 1; } goto EndFunc; } }else if( 3 < nLen && (c0 & 0xf8) == 0xf0 ){ // 第1バイトが11110abbの場合 c1 = pS[1]; c2 = pS[2]; c3 = pS[3]; // 第2バイトが10bbcccc、第3バイトが10ddddee、第4バイトが10ddddeeの場合 if( (c1 & 0xc0) == 0x80 && (c2 & 0xc0) == 0x80 && (c3 & 0xc0) == 0x80 ){ ncwidth = 4; // 4バイトコードである echarset = CHARSET_UNI_SURROG; // サロゲートペアの文字(初期化) // 第1バイトのabb=000、第2バイトのbb=00の場合(\u10000未満に変換される) if( (c0 & 0x07) == 0 && (c1 & 0x30) == 0 ){ // デコードできない.(往復変換不可領域) echarset = CHARSET_BINARY; ncwidth = 1; } // 1バイト目が 11110xxx=11110100のとき、 // かつ、1111 01xx : 10xx oooo の x のところに値があるとき if( (c0 & 0x04) != 0 && ((c0 & 0x03) != 0 || (c1 & 0x30) != 0) ){ // 値が大きすぎ(0x10ffffより大きい) echarset = CHARSET_BINARY; ncwidth = 1; } if( bAllow4byteCode == false ){ echarset = CHARSET_BINARY; ncwidth = 1; } goto EndFunc; } } // 規定外のフォーマット echarset = CHARSET_BINARY; ncwidth = 1; EndFunc: // 非文字と予約コードポイントをチェック if( nOption != 0 && echarset != CHARSET_BINARY ){ wchar32_t wc32; wc32 = DecodeUtf8( reinterpret_cast<const unsigned char*>(pS), ncwidth ); if( (nOption & UC_NONCHARACTER) && IsUnicodeNoncharacter(wc32) ){ echarset = CHARSET_BINARY; ncwidth = 1; }else{ // 保護コード echarset = CHARSET_BINARY; ncwidth = 1; } } if( peCharset ){ *peCharset = echarset; } return ncwidth; }
// 读取文件 vector<ST_ROADLINE> ReadMifMidFile(char *pMifName, char *pMidName) { char acLine[1024]; vector<string> vMidStrLst; vector<pair<double, double> > vCoorXYLst; vector<ST_ROADLINE> vecRoadLineLst; // 打开文件 ifstream fMifFile(pMifName, ios::in); ifstream fMidFile(pMidName, ios::in); if( !fMifFile.is_open() || !fMidFile.is_open() ) { return vecRoadLineLst; } // MIF文件偏移到数据部分 do { memset(acLine, 0, 1024 ); fMifFile.getline(acLine, 1024); } while( strcmp(acLine,"Data") != 0); // 读取MIF/MID文件 do { memset(acLine, 0, 1024 ); fMidFile.getline(acLine, 1024); // 读取一行MID文件 vMidStrLst.clear(); if( RET_FAILED == ReadMidLineFile( acLine, vMidStrLst)) { break; } // 读取一行MIF文件 vCoorXYLst.clear(); if( RET_FAILED == ReadMifOneElement( fMifFile, vCoorXYLst)) { break; } // 生成道路结构 ST_ROADLINE stLine; stLine.wstrRoadDirDes = DecodeUtf8(vMidStrLst[8]); stLine.iRLCD = StringToInt(vMidStrLst[9]); stLine.wstrRoadName = DecodeUtf8(vMidStrLst[6]); stLine.iShowLev = StringToInt(vMidStrLst[11]); stLine.iDrawLev = StringToInt(vMidStrLst[12]); stLine.iOrder = StringToInt(vMidStrLst[10]); vector<pair<double, double> >::iterator iter = vCoorXYLst.begin(); for (; iter != vCoorXYLst.end(); iter++) { stLine.vecPoints.push_back(iter->first); stLine.vecPoints.push_back(iter->second); } stLine.flag = 0; vecRoadLineLst.push_back(stLine); } while(true); return vecRoadLineLst; }