Toshihiro Shimizu 890ddd
#include "igs_resource_msg_from_err.h"
e280ae
#include <locale></locale>
e280ae
#include <stdexcept></stdexcept>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
rim 26a2b2
#if defined UNICODE
Toshihiro Shimizu 890ddd
/*------ ワイド文字文字列 --> マルチバイト文字列 ------*/
rim 26a2b2
static void 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
#endif
Toshihiro Shimizu 890ddd
/*------ UNICODE宣言ならワイド文字文字列をマルチバイト文字列に変換 ------*/
rim 26a2b2
static const std::string mbs_from_ts(const std::basic_string<tchar> &ts) {</tchar>
Toshihiro Shimizu 890ddd
#if defined UNICODE
Shinya Kitaoka 120a6e
  std::string mbs;
rim 26a2b2
  wcs_to_mbs(ts, mbs, CP_THREAD_ACP);
Shinya Kitaoka 120a6e
  return mbs;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  /* MBCSの場合のsize()は文字数ではなくchar(byte)数,2bytes文字は2 */
Shinya Kitaoka 120a6e
  return ts;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
rim 26a2b2
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で返す */
rim 26a2b2
  return mbs_from_ts(errmsg);
Toshihiro Shimizu 890ddd
}