Toshihiro Shimizu 890ddd
#include "igs_resource_msg_from_err.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------ localeを日本に設定し日本語を扱うことを指示
Toshihiro Shimizu 890ddd
(しないと日本語文字部分のみ処理しない)
Toshihiro Shimizu 890ddd
ただし数値カテゴリはC localeのままに
Toshihiro Shimizu 890ddd
(しないと3桁ごとにカンマが付く(1000-->1,000)) */
Toshihiro Shimizu 890ddd
void igs::resource::locale_to_jp(void)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::locale::global(
Toshihiro Shimizu 890ddd
		std::locale(std::locale(), "japanese", std::locale::ctype));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ マルチバイト文字列 --> ワイド文字文字列 ------*/
Toshihiro Shimizu 890ddd
void igs::resource::mbs_to_wcs(
Toshihiro Shimizu 890ddd
	const std::string &mbs, std::wstring &wcs, const UINT code_page)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/* 第4引数で -1 指定により終端文字を含む大きさを返す */
Toshihiro Shimizu 890ddd
	/*	int MultiByteToWideChar(
Toshihiro Shimizu 890ddd
 			UINT CodePage
Toshihiro Shimizu 890ddd
			,DWORD dwFlags
Toshihiro Shimizu 890ddd
			,LPCSTR lpMultiByteStr
Toshihiro Shimizu 890ddd
			,int cbMultiByte
Toshihiro Shimizu 890ddd
			,LPWSTR lpWideCharStr
Toshihiro Shimizu 890ddd
			,int cchWideChar        
Toshihiro Shimizu 890ddd
		);
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	int length = ::MultiByteToWideChar(
Toshihiro Shimizu 890ddd
		code_page, 0, mbs.c_str(), -1, 0, 0);
Toshihiro Shimizu 890ddd
	if (length <= 1) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	} /* 終端以外の文字がないなら何もしない */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/***	std::vector<wchar_t> buf(length);</wchar_t>
Toshihiro Shimizu 890ddd
	length = ::MultiByteToWideChar(
Toshihiro Shimizu 890ddd
		code_page ,0 ,mbs.c_str() ,-1
Toshihiro Shimizu 890ddd
		,&buf.at(0) ,static_cast<int>(buf.size())</int>
Toshihiro Shimizu 890ddd
	);***/
Toshihiro Shimizu 890ddd
	wcs.resize(length);
Toshihiro Shimizu 890ddd
	length = ::MultiByteToWideChar(
Toshihiro Shimizu 890ddd
		code_page, 0, mbs.c_str(), -1, const_cast<lpwstr>(wcs.data()), static_cast<int>(wcs.size()));</int></lpwstr>
Toshihiro Shimizu 890ddd
	if (0 == length) {
Toshihiro Shimizu 890ddd
		switch (::GetLastError()) {
Toshihiro Shimizu 890ddd
		case ERROR_INSUFFICIENT_BUFFER:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"MultiByteToWideChar():insufficient buffer");
Toshihiro Shimizu 890ddd
		case ERROR_INVALID_FLAGS:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"MultiByteToWideChar():invalid flags");
Toshihiro Shimizu 890ddd
		case ERROR_INVALID_PARAMETER:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"MultiByteToWideChar():invalid parameter");
Toshihiro Shimizu 890ddd
		case ERROR_NO_UNICODE_TRANSLATION:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"MultiByteToWideChar():no unicode translation");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//wcs = std::wstring(buf.begin() ,buf.end()-1); /* 終端以外を */
Toshihiro Shimizu 890ddd
	wcs.erase(wcs.end() - 1); /* 終端文字を消す。end()は終端より先位置 */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ ワイド文字文字列 --> マルチバイト文字列 ------*/
Toshihiro Shimizu 890ddd
void igs::resource::wcs_to_mbs(
Toshihiro Shimizu 890ddd
	const std::wstring &wcs, std::string &mbs, const UINT code_page)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/* 第4引数で -1 指定により終端文字を含む大きさを返す */
Toshihiro Shimizu 890ddd
	int length = ::WideCharToMultiByte(
Toshihiro Shimizu 890ddd
		code_page, 0, wcs.c_str(), -1, 0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	if (length <= 1) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	} /* 終端以外の文字がないなら何もしない */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/***	std::vector<char> buf(length);</char>
Toshihiro Shimizu 890ddd
	length = ::WideCharToMultiByte(
Toshihiro Shimizu 890ddd
		code_page ,0 ,wcs.c_str() ,-1
Toshihiro Shimizu 890ddd
		,&buf.at(0) ,static_cast<int>(buf.size()) ,0 ,NULL</int>
Toshihiro Shimizu 890ddd
	);***/
Toshihiro Shimizu 890ddd
	mbs.resize(length);
Toshihiro Shimizu 890ddd
	length = ::WideCharToMultiByte(
Toshihiro Shimizu 890ddd
		code_page, 0, wcs.c_str(), -1, const_cast<lpstr>(mbs.data()), static_cast<int>(mbs.size()), 0, NULL);</int></lpstr>
Toshihiro Shimizu 890ddd
	if (0 == length) {
Toshihiro Shimizu 890ddd
		switch (::GetLastError()) {
Toshihiro Shimizu 890ddd
		case ERROR_INSUFFICIENT_BUFFER:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"WideCharToMultiByte():insufficient buffer");
Toshihiro Shimizu 890ddd
		case ERROR_INVALID_FLAGS:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"WideCharToMultiByte():invalid flags");
Toshihiro Shimizu 890ddd
		case ERROR_INVALID_PARAMETER:
Toshihiro Shimizu 890ddd
			throw std::domain_error(
Toshihiro Shimizu 890ddd
				"WideCharToMultiByte():invalid parameter");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//mbs = std::string(buf.begin() ,buf.end()-1); /* 終端以外を */
Toshihiro Shimizu 890ddd
	mbs.erase(mbs.end() - 1); /* 終端文字を消す。end()は終端より先位置 */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ UNICODE宣言ならマルチバイト文字列をワイド文字文字列に変換 ------*/
Toshihiro Shimizu 890ddd
const std::basic_string<tchar> igs::resource::ts_from_mbs(</tchar>
Toshihiro Shimizu 890ddd
	const std::string &mbs, const UINT code_page)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#if defined UNICODE
Toshihiro Shimizu 890ddd
	std::wstring wcs;
Toshihiro Shimizu 890ddd
	igs::resource::mbs_to_wcs(mbs, wcs, code_page);
Toshihiro Shimizu 890ddd
	return wcs;
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	code_page;
Toshihiro Shimizu 890ddd
	/* MBCSの場合のsize()は文字数ではなくchar(byte)数,2bytes文字は2 */
Toshihiro Shimizu 890ddd
	return mbs;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ UNICODE宣言ならワイド文字文字列をマルチバイト文字列に変換 ------*/
Toshihiro Shimizu 890ddd
const std::string igs::resource::mbs_from_ts(
Toshihiro Shimizu 890ddd
	const std::basic_string<tchar> &ts, const UINT code_page)</tchar>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#if defined UNICODE
Toshihiro Shimizu 890ddd
	std::string mbs;
Toshihiro Shimizu 890ddd
	igs::resource::wcs_to_mbs(ts, mbs, code_page);
Toshihiro Shimizu 890ddd
	return mbs;
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	code_page;
Toshihiro Shimizu 890ddd
	/* MBCSの場合のsize()は文字数ではなくchar(byte)数,2bytes文字は2 */
Toshihiro Shimizu 890ddd
	return ts;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ cp932を含む文字列をutf-8に変換(マルチバイト文字列) ------*/
Toshihiro Shimizu 890ddd
const std::string igs::resource::utf8_from_cp932_mb(const std::string &text)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::wstring wcs;
Toshihiro Shimizu 890ddd
	igs::resource::mbs_to_wcs(text, wcs);
Toshihiro Shimizu 890ddd
	std::string mbs;
Toshihiro Shimizu 890ddd
	igs::resource::wcs_to_mbs(wcs, mbs, CP_UTF8);
Toshihiro Shimizu 890ddd
	return mbs;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ utf-8を含む文字列をcp932に変換(マルチバイト文字列) ------*/
Toshihiro Shimizu 890ddd
const std::string igs::resource::cp932_from_utf8_mb(const std::string &text)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::wstring wcs;
Toshihiro Shimizu 890ddd
	igs::resource::mbs_to_wcs(text, wcs, CP_UTF8);
Toshihiro Shimizu 890ddd
	std::string mbs;
Toshihiro Shimizu 890ddd
	igs::resource::wcs_to_mbs(wcs, mbs, 932);
Toshihiro Shimizu 890ddd
	return mbs;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*------ エラーメッセージ表示の元関数、直接呼び出すことはしない ------*/
Toshihiro Shimizu 890ddd
#include <sstream></sstream>
Toshihiro Shimizu 890ddd
const std::string igs::resource::msg_from_err_(
Toshihiro Shimizu 890ddd
	const std::basic_string<tchar> &tit, const DWORD error_message_id, const std::basic_string<tchar> &file, const std::basic_string<tchar> &line, const std::basic_string<tchar> &funcsig, const std::basic_string<tchar> &comp_type, const std::basic_string<tchar> &msc_full_ver, const std::basic_string<tchar> &date, const std::basic_string<tchar> &time)</tchar></tchar></tchar></tchar></tchar></tchar></tchar></tchar>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
汎用データ型  ワイド文字(UNICODE)(※1)	マルチバイト文字(_MBCS)(※2)
Toshihiro Shimizu 890ddd
TCHAR	      wchar_t			char 
Toshihiro Shimizu 890ddd
LPTSTR	      wchar_t *			char * 
Toshihiro Shimizu 890ddd
LPCTSTR	      const wchar_t *		const char * 
Toshihiro Shimizu 890ddd
※1  1文字を16ビットのワイド文字として表すUnicode を使う方法
Toshihiro Shimizu 890ddd
	すべての文字が 16 ビットに固定されます。
Toshihiro Shimizu 890ddd
	マルチバイト文字に比べ、メモリ効率は低下しますが処理速度は向上します
Toshihiro Shimizu 890ddd
※2  1文字を複数のバイトで表すマルチバイト文字
Toshihiro Shimizu 890ddd
	MBCS(Multibyte Character Set) と呼ばれる文字集合を使う方法
Toshihiro Shimizu 890ddd
	可変長だが、事実上、サポートされているのは 2 バイト文字までなので、
Toshihiro Shimizu 890ddd
	マルチバイト文字の 1 文字は 1 バイトまたは 2 バイトとなります。
Toshihiro Shimizu 890ddd
	Windows 2000 以降、Windows は内部で Unicode を使用しているため、
Toshihiro Shimizu 890ddd
	マルチバイト文字を使用すると内部で文字列の変換が発生するため
Toshihiro Shimizu 890ddd
	オーバーヘッドが発生します。
Toshihiro Shimizu 890ddd
	UNICODEも_MBCSも未定義のときはこちらになる。
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	std::basic_string<tchar> errmsg;</tchar>
Toshihiro Shimizu 890ddd
	errmsg += TEXT('\"');
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* makefile-vc2008mdAMD64等でコンパイルすると
Toshihiro Shimizu 890ddd
	フルパスで入ってくるのでファイル名だけにする
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	std::basic_string<tchar>::size_type index =</tchar>
Toshihiro Shimizu 890ddd
		file.find_last_of(TEXT("/\\"));
Toshihiro Shimizu 890ddd
	if (std::basic_string<tchar>::npos != index) {</tchar>
Toshihiro Shimizu 890ddd
		errmsg += file.substr(index + 1);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		errmsg += file;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
	errmsg += line;
Toshihiro Shimizu 890ddd
	errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
	errmsg += comp_type;
Toshihiro Shimizu 890ddd
	errmsg += TEXT(":");
Toshihiro Shimizu 890ddd
	errmsg += msc_full_ver;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		std::basic_istringstream<tchar> ist(date);</tchar>
Toshihiro Shimizu 890ddd
		std::basic_string<tchar> month, day, year;</tchar>
Toshihiro Shimizu 890ddd
		ist >> month;
Toshihiro Shimizu 890ddd
		ist >> day;
Toshihiro Shimizu 890ddd
		ist >> year;
Toshihiro Shimizu 890ddd
		errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
		errmsg += year;
Toshihiro Shimizu 890ddd
		errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
		errmsg += month;
Toshihiro Shimizu 890ddd
		errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
		errmsg += day;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
	errmsg += time;
Toshihiro Shimizu 890ddd
	errmsg += TEXT('\"');
Toshihiro Shimizu 890ddd
	errmsg += TEXT(' ');
Toshihiro Shimizu 890ddd
	errmsg += TEXT('\"');
Toshihiro Shimizu 890ddd
	errmsg += funcsig;
Toshihiro Shimizu 890ddd
	errmsg += TEXT('\"');
Toshihiro Shimizu 890ddd
	errmsg += TEXT(' ');
Toshihiro Shimizu 890ddd
	errmsg += TEXT('\"');
Toshihiro Shimizu 890ddd
	if (0 < tit.size()) {
Toshihiro Shimizu 890ddd
		errmsg += tit;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (NO_ERROR != error_message_id) {
Toshihiro Shimizu 890ddd
		errmsg += TEXT(':');
Toshihiro Shimizu 890ddd
		LPTSTR lpMsgBuf = 0;
Toshihiro Shimizu 890ddd
		if (0 < ::FormatMessage(
Toshihiro Shimizu 890ddd
					FORMAT_MESSAGE_ALLOCATE_BUFFER |
Toshihiro Shimizu 890ddd
						FORMAT_MESSAGE_FROM_SYSTEM |
Toshihiro Shimizu 890ddd
						FORMAT_MESSAGE_IGNORE_INSERTS,
Toshihiro Shimizu 890ddd
					NULL, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) /* 既定言語 */
Toshihiro Shimizu 890ddd
					,
Toshihiro Shimizu 890ddd
					reinterpret_cast<lptstr>(&lpMsgBuf), 0, NULL)) { /* --- 成功 --- */</lptstr>
Toshihiro Shimizu 890ddd
			errmsg += lpMsgBuf;
Toshihiro Shimizu 890ddd
			::LocalFree(lpMsgBuf);
Toshihiro Shimizu 890ddd
			std::string::size_type index =
Toshihiro Shimizu 890ddd
				errmsg.find_first_of(TEXT("\r\n"));
Toshihiro Shimizu 890ddd
			if (std::string::npos != index) {
Toshihiro Shimizu 890ddd
				errmsg.erase(index);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else { /* エラー */
Toshihiro Shimizu 890ddd
			errmsg += TEXT("FormatMessage() can not get (error)message");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	errmsg += TEXT('\"');
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* MBCSで返す */
Toshihiro Shimizu 890ddd
	return igs::resource::mbs_from_ts(errmsg);
Toshihiro Shimizu 890ddd
}