예제 #1
0
int CEuc::UniToEucjp( const wchar_t* pSrc, const int nSrcLen, char* pDst, bool* pbError )
{
	int nclen;
	const unsigned short *pr, *pr_end;
	unsigned char* pw;
	bool berror=false, berror_tmp;
	ECharSet echarset;

	pr = reinterpret_cast<const unsigned short*>(pSrc);
	pr_end = reinterpret_cast<const unsigned short*>(pSrc + nSrcLen);
	pw = reinterpret_cast<unsigned char*>(pDst);

	while( (nclen = CheckUtf16leChar(reinterpret_cast<const wchar_t*>(pr), pr_end-pr, &echarset, 0)) > 0 ){
		// 保護コード
		switch( echarset ){
		case CHARSET_UNI_NORMAL:
			nclen = 1;
			break;
		case CHARSET_UNI_SURROG:
			nclen = 2;
			break;
		default:
			echarset = CHARSET_BINARY;
			nclen = 1;
		}
		if( echarset != CHARSET_BINARY ){
			pw += _UniToEucjp_char( pr, pw, echarset, &berror_tmp );
			// 保護コード
			if( berror_tmp == true ){
				berror = true;
			}
			pr += nclen;
		}else{
			if( nclen == 1 && IsBinaryOnSurrogate(static_cast<wchar_t>(*pr)) ){
				*pw = static_cast<unsigned char>( TextToBin(*pr) & 0x00ff );
				++pw;
			}else{
				// 保護コード
				berror = true;
				*pw = '?';
				++pw;
			}
			++pr;
		}
	}

	if( pbError ){
		*pbError = berror;
	}

	return pw - reinterpret_cast<unsigned char*>(pDst);
}
예제 #2
0
/*!
	UTF-7 セットBの文字列か

	@return セットB文字列の長さ

	@param[out] ppNextChar 次のブロック(UTF-7セットD部分)の先頭文字のポインタが格納される(文字'-'を飛ばす)

	@note この関数の前に CheckUtf7DPart() が実行される必要がある。
*/
int CheckUtf7BPart( const char *pS, const int nLen, char **ppNextChar, bool *pbError, const int nOption )
{
	const char *pr, *pr_end;
	bool berror_found, bminus_found;
	int nchecklen;

	wchar_t* pdata;
	int ndatalen, nret;
	ECharSet echarset;
	CMemory cmbuffer;


	if( nLen < 1 ){
		if( pbError ){
			*pbError = false;
		}
		*ppNextChar = const_cast<char*>( pS );
		return 0;
	}

	berror_found = false;
	bminus_found = false;
	pr = pS;
	pr_end = pS + nLen;

	for( ; pr < pr_end; ++pr ){
		// セットBの文字でなくなるまでループ
		if( !IsBase64(*pr) ){
			if( *pr == '-' ){
				bminus_found= true;
			}else{
				bminus_found = false;
			}
			break;
		}
	}

	nchecklen = pr - pS;

	// 保護コード
	if( nchecklen < 1 ){
		nchecklen = 0;
	}


	/*
	◆ デコード後のデータ長の確認

	調査してきたデータ長 nchecklen(= pr - pS) を8で割ってみる.
	その余りの値から考えられるビット列は…

	             |----------------------------- Base64 表現 --------------------------------------------|
	             第1バイト  第2バイト  第3バイト  第4バイト  第5バイト  第6バイト  第7バイト  第8バイト
	残り1文字   00xx xxxx  00xx xxxx  00xx xx00     ---        ---        ---        ---        ---
	残り2文字   00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx 0000     ---        ---
	残り3文字   00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx

	上記3通りのいづれにも当てはまらない場合は全データを落とす(不正バイトとする).
	*/
	const char *pr_ = pr - 1;
	switch( nchecklen % 8 ){
	case 0:
		break;
	case 3:
		if( Base64ToVal(pr_[0]) & 0x03 ){
			berror_found = true;
		}
		break;
	case 6:
		if( Base64ToVal(pr_[0]) & 0x0f ){
			berror_found = true;
		}
		break;
	case 8:
		// nchecklen == 0 の場合
		break;
	default:
		berror_found = true;
	}

	if( UC_LOOSE == (nOption & UC_LOOSE) ){
		goto EndFunc;
	}

	// UTF-7文字列 "+-" のチェック

	if( pr < pr_end && (nchecklen < 1 && bminus_found != true) ){
		// 読み取りポインタがデータの終端を指していなくて
		// 確認できた Set B 文字列の長さがゼロの場合は、
		// 必ず終端文字 '-' が存在していることを確認する。
		berror_found = true;
	}

	// 実際にデコードして内容を確認する。

	if( berror_found == true || nchecklen < 1 ){
		goto EndFunc;
	}

	cmbuffer.AllocBuffer( nchecklen );
	pdata = reinterpret_cast<wchar_t*>( cmbuffer.GetRawPtr() );
	if( pdata == NULL ){
		goto EndFunc;
	}
	ndatalen = _DecodeBase64(pS, nchecklen, reinterpret_cast<char*>(pdata)) / sizeof(wchar_t);
	CMemory::SwapHLByte( reinterpret_cast<char*>(pdata), ndatalen*sizeof(wchar_t) );
	for( int i = 0; i < ndatalen; i += nret ){
		nret = CheckUtf16leChar( &pdata[i], ndatalen - i, &echarset, nOption & UC_NONCHARACTER );
		if( echarset == CHARSET_BINARY ){
			berror_found = true;
			goto EndFunc;
		}
		if( nret == 1 && IsUtf7SetD(pdata[i]) ){
			berror_found = true;
			goto EndFunc;
		}
	}

EndFunc:;

	if( pbError ){
		*pbError = berror_found;
	}

	if( (berror_found == false || UC_LOOSE == (nOption & UC_LOOSE)) && (pr < pr_end && bminus_found == true) ){
		// '-' をスキップ。
		*ppNextChar = const_cast<char*>(pr) + 1;
	}else{
		*ppNextChar = const_cast<char*>(pr);
	}

	return nchecklen;
}