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