OSDN Git Service

calLibraryのxml処理を共通化。
[tpi/lychee.git] / src / plugin / cuiWrapper / cuiWrapper.cpp
index 75f4346..675864b 100644 (file)
@@ -16,7 +16,7 @@
   with this library; if not, write to the Free Software Foundation, Inc.,\r
   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
 \r
-  $Id: cuiWrapper.cpp,v 1.26 2009/09/27 13:41:02 sirakaba Exp $\r
+  $Id$\r
 *******************************************************************************/\r
 \r
 //******************************************************************************\r
 #include "../../common/header/plugin.h"\r
 #include "../../common/header/plugin-extra.h"\r
 #include "../../common/library/library.h"\r
+#include "../../common/library/xmldoc.h"\r
 #include <wx/config.h>\r
-#include <wx/stdpaths.h>\r
-#include <wx/xml/xml.h>\r
 #include <wx/tokenzr.h>\r
-#include <windows.h>\r
 #include "cuiWrapper.h"\r
 \r
 //******************************************************************************\r
@@ -42,66 +40,51 @@ struct g_LibInfo
        wxString szExeFile;\r
        wxString szExeFileAlt;\r
        wxString szListCommand;\r
-       int nLibIndex;\r
+       wxULongLong_t nLibIndex;\r
        wxXmlNode node;\r
 }      g_LibInfo;\r
 \r
 TPI_PROC g_prProc;\r
-wxString g_szCurrentArchive;\r
-wxArrayString g_asOutput;\r
-\r
-//******************************************************************************\r
-//    Entry\r
-//******************************************************************************\r
-\r
-BOOL __stdcall DllMain(HMODULE, DWORD, void *)\r
-{\r
-       return TRUE;\r
-}\r
 \r
 //******************************************************************************\r
 //    Inside Functions\r
 //******************************************************************************\r
 \r
-DWORD myExecute(wxString szCommandLine, wxString * szOutput, wxString szCwd, bool bCheckExist = false)\r
+int myExecute(const wxString & szCommandLine, wxString * szOutput, const wxString & szCwd, bool fWine)\r
 {\r
 #ifdef __LINUX__\r
        wxString sz = ::wxGetCwd();\r
        ::wxSetWorkingDirectory(szCwd);\r
-       FILE * fp = popen(szCommandLine.char_str(), "r");\r
+       FILE * fp = popen(fWine ? (wxT("wine ") + szCommandLine).ToUTF8() : szCommandLine.ToUTF8(), "r");\r
        ::wxSetWorkingDirectory(sz);\r
        if (fp == NULL)\r
        {\r
-//             wxMessageBox(wxString::Format(wxT("Error :\n\nCommandLine:\n%s"), szCommandLine.c_str()));\r
+               wxLogError(L"Error :\n\nCommandLine:\n%s", szCommandLine.c_str());\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
 \r
-       if (bCheckExist)\r
-       {\r
-               return TPI_ERROR_SUCCESS;\r
-       }\r
-\r
        if (szOutput != NULL)\r
        {\r
                char sz[32769];\r
-               memset(sz, 0, sizeof(sz));\r
                while (! feof(fp))\r
                {\r
+                       memset(sz, 0, sizeof(sz));\r
                        fread(sz, sizeof(char), sizeof(sz) - 1, fp);\r
-                       * szOutput += MB2String(sz);\r
+                       * szOutput += UTF82String(sz);\r
                }\r
 //             ::wxMessageBox(* szOutput);\r
        }\r
 \r
-       pclose(fp);\r
-       return TPI_ERROR_SUCCESS;\r
+       // 127を返した場合はコマンドが存在しない。\r
+       int nErrorCode = pclose(fp);\r
+       return (WIFEXITED(nErrorCode) && WEXITSTATUS(nErrorCode) != 127) ? TPI_ERROR_SUCCESS : TPI_ERROR_U_USE_LIBRARY;\r
 #else\r
        SECURITY_ATTRIBUTES sa;\r
        memset(& sa, 0, sizeof(SECURITY_ATTRIBUTES));\r
        sa.bInheritHandle = TRUE;\r
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
        HANDLE hRead, hWrite;\r
-       if (! ::CreatePipe(& hRead, & hWrite, & sa, 65537))\r
+       if (! ::CreatePipe(& hRead, & hWrite, & sa, 0))\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
@@ -116,58 +99,59 @@ DWORD myExecute(wxString szCommandLine, wxString * szOutput, wxString szCwd, boo
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
-\r
-       ::WaitForInputIdle(pi.hProcess, INFINITE);\r
-       ::WaitForSingleObject(pi.hProcess, INFINITE);\r
-\r
-       DWORD nErrorCode = 0;\r
-       ::GetExitCodeProcess(pi.hProcess, & nErrorCode);\r
        ::CloseHandle(pi.hThread);\r
-       ::CloseHandle(pi.hProcess);\r
-\r
-       if (bCheckExist)\r
-       {\r
-               return TPI_ERROR_SUCCESS;\r
-       }\r
 \r
        if (szOutput != NULL)\r
        {\r
-               DWORD dwSize = 0;\r
-               char sz[32769];\r
-               memset(sz, 0, sizeof(sz));\r
-               for (wxULongLong llSize = 0; llSize < ::GetFileSize(hRead, NULL); llSize += dwSize)\r
+               char sz[32768];\r
+               while (true)\r
                {\r
-                       dwSize = 0;\r
-                       ::ReadFile(hRead, sz, sizeof(sz) - 1, & dwSize, NULL);\r
-                       * szOutput += MB2String(sz);\r
-//                     ::MessageBoxA(NULL, sz, NULL, 0);\r
+                       DWORD dwSize = 0;\r
+                       if (! ::PeekNamedPipe(hRead, NULL, 0, NULL, & dwSize, NULL))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (dwSize > 0)\r
+                       {\r
+                               memset(sz, 0, sizeof(sz));\r
+                               ::ReadFile(hRead, & sz, sizeof(sz), & dwSize, NULL);\r
+                               * szOutput += wxString(sz);\r
+                               // UTF-8以外の文字コードだと、UTF82Stringを使うと書庫が開けなくなる。データの切り出しにも影響。\r
+//                             * szOutput += UTF82String(sz);\r
+//                             ::MessageBoxA(NULL, sz, NULL, 0);\r
+                       }\r
+                       else if (::WaitForSingleObject(pi.hProcess, 0) == WAIT_OBJECT_0)\r
+                       {\r
+                               break;\r
+                       }\r
                }\r
        }\r
+\r
+       ::CloseHandle(pi.hProcess);\r
        ::CloseHandle(hRead);\r
        ::CloseHandle(hWrite);\r
-\r
-       return nErrorCode == 0 ? TPI_ERROR_SUCCESS : TPI_ERROR_UNDEFINED;\r
+       return TPI_ERROR_SUCCESS;\r
 #endif\r
 }\r
 \r
-PosInfo MakePosInfo(wxString szPrefix)\r
+PosInfo MakePosInfo(const wxString & szPrefix)\r
 {\r
        PosInfo pi;\r
-       g_LibInfo.node.GetPropVal(wxT("list-") + szPrefix + wxT("-s"), wxEmptyString).ToULong(& pi.nStart);\r
-       g_LibInfo.node.GetPropVal(wxT("list-") + szPrefix + wxT("-c"), wxEmptyString).ToULong(& pi.nCount);\r
-       g_LibInfo.node.GetPropVal(wxT("list-") + szPrefix + wxT("-l"), wxT("0")).ToULong(& pi.nLine);\r
+       pi.nStart = myGetAttributeInt(& g_LibInfo.node, wxT("list-") + szPrefix + wxT("-s"));\r
+       pi.nCount = myGetAttributeInt(& g_LibInfo.node, wxT("list-") + szPrefix + wxT("-c"));\r
+       pi.nLine  = myGetAttributeInt(& g_LibInfo.node, wxT("list-") + szPrefix + wxT("-l"));\r
        return pi;\r
 }\r
 \r
-wxULongLong GetSize(PosInfo & pi, size_t uCurrent, wxArrayString & as)\r
+wxULongLong_t GetSize(const PosInfo & pi, wxULongLong_t nCurrent, const wxArrayString & as)\r
 {\r
        if (pi.nStart == 0 && pi.nCount == 0)\r
        {\r
                return 0;\r
        }\r
 \r
-       wxULongLong_t nTemp;\r
-       size_t nPos = uCurrent + pi.nLine;\r
+       wxULongLong_t nTemp = 0, nPos = nCurrent + pi.nLine;\r
        wxString sz = pi.nCount == 0 ? as[nPos].Mid(pi.nStart) : as[nPos].Mid(pi.nStart, pi.nCount);\r
        sz.ToULongLong(& nTemp);\r
        return nTemp;\r
@@ -185,7 +169,7 @@ extern "C"
 int __stdcall GetPluginInformation\r
 (\r
        unsigned int _uInfoId,\r
-       wxULongLong,\r
+       wxULongLong_t,\r
        void * _pPtr\r
 )\r
 {\r
@@ -193,7 +177,7 @@ int __stdcall GetPluginInformation
        {\r
                return TPI_ERROR_D_PARAMETER;\r
        }\r
-       switch (LOWORD(_uInfoId))\r
+       switch (_uInfoId)\r
        {\r
        case TPI_INFO_VERSION_MAJOR:\r
        case TPI_INFO_VERSION_MINOR:\r
@@ -210,95 +194,87 @@ int __stdcall GetPluginInformation
 \r
 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
 {\r
-       static unsigned int s_uFileID;\r
-       wxStandardPaths p;\r
-       wxXmlDocument config(wxPathOnly(p.GetExecutablePath()) + wxT("/lib/cuiWrapper.xml"));\r
-       // \88ê\8bC\82É\90æ\93ª\82Ì\83\89\83C\83u\83\89\83\8a\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B\r
-       wxXmlNode * xmlLibrary = config.GetRoot()->GetChildren();\r
-\r
+       static wxULongLong_t s_nFileId;\r
+       static wxXmlDocument xmlDoc(myMakeXMLName(wxT("cuiWrapper")));\r
+       static wxXmlNode * xmlLibrary;\r
        if (_bFirst)\r
        {\r
-               // xml\89ð\90Í\8aJ\8en\81B\r
-               s_uFileID = 0;\r
+               // xml解析開始。\r
+               s_nFileId = 0;\r
+               xmlLibrary = myGetFirstLib(& xmlDoc);\r
        }\r
        else\r
        {\r
-               for (unsigned int i = 0; i < s_uFileID && xmlLibrary != NULL; i++)\r
-               {\r
-                       xmlLibrary = xmlLibrary->GetNext();\r
-               }\r
+               xmlLibrary = myGetNextLib(xmlLibrary);\r
        }\r
-\r
-       if (xmlLibrary == NULL || xmlLibrary->GetName() != wxT("library"))\r
+       if (xmlLibrary == NULL)\r
        {\r
-               // xml\95\96@\83G\83\89\81[\81B\r
-               return TPI_ERROR_UNDEFINED;\r
+               // データの終端に達した場合。\r
+               return TPI_ERROR_S_ENDOFDATA;\r
        }\r
 \r
-       MakeFormatInfo(wxT("cuiWrapper"), _fiInfo, xmlLibrary, s_uFileID++);\r
-       if (myExecute(xmlLibrary->GetPropVal(wxT("name"), wxEmptyString), NULL, wxEmptyString, true) != TPI_ERROR_SUCCESS)\r
+       MakeFormatInfo(xmlLibrary, wxT("cuiWrapper"), _fiInfo, s_nFileId++);\r
+       wxString szExeFile = xmlLibrary->GetAttribute(wxT("name"), wxEmptyString);\r
+       if (myExecute(szExeFile, NULL, wxEmptyString, szExeFile.Find(wxT('.')) != wxNOT_FOUND && szExeFile.AfterLast(wxT('.')) == wxT("exe")) != TPI_ERROR_SUCCESS)\r
        {\r
-               _fiInfo->llSupportedCommand = 0;\r
+               _fiInfo->eSupportedCommand = 0;\r
        }\r
-\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall LoadPlugin\r
 (\r
        const wxString & _szArcName,\r
-       wxULongLong _llSubOption\r
+       wxULongLong_t _nTypeId\r
 )\r
 {\r
-       // xml\89ð\90Í\8aJ\8en\81B\r
-       wxStandardPaths p;\r
-       wxXmlDocument config(wxPathOnly(p.GetExecutablePath()) + wxT("/lib/cuiWrapper.xml"));\r
-       if (! config.IsOk())\r
-       {\r
-               return TPI_ERROR_UNDEFINED;\r
-       }\r
-       // \88ê\8bC\82É\90æ\93ª\82Ì\83\89\83C\83u\83\89\83\8a\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B\r
-       wxXmlNode * xmlLibrary = config.GetRoot()->GetChildren();\r
+       // xml解析開始。\r
+       wxXmlDocument xmlDoc(myMakeXMLName(wxT("cuiWrapper")));\r
+       wxXmlNode * xmlLibrary;\r
 \r
-       // \91Î\8fÛ\82ª\91\8dÝ\82·\82é\82È\82ç\82Î\91Î\89\9e\82·\82é\83\89\83C\83u\83\89\83\8a\82ð\92²\8d¸\81A\r
-       // \91Î\8fÛ\82ª\91\8dÝ\82µ\82È\82¢\82È\82ç\82Î\8ew\8e¦\82³\82ê\82½\83\89\83C\83u\83\89\83\8a\82ð\83\8d\81[\83h\81B\r
+       // 対象が存在するならば対応するライブラリを調査、\r
+       // 対象が存在しないならば指示されたライブラリをロード。\r
        if (! ::wxFileExists(_szArcName))\r
        {\r
-               // \93K\93\96\82È\88Ê\92u\82Ü\82Å\88Ú\93®\81B\r
-               for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < _llSubOption && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\r
+               xmlLibrary = myGetFirstLib(& xmlDoc, _nTypeId);\r
+               if (xmlLibrary == NULL)\r
                {\r
-                       xmlLibrary = xmlLibrary->GetNext();\r
-               }\r
-               if (xmlLibrary == NULL || xmlLibrary->GetName() != wxT("library"))\r
-               {\r
-                       // xml\95\96@\83G\83\89\81[\81B\r
+                       // xml文法エラー。\r
                        return TPI_ERROR_UNDEFINED;\r
                }\r
-               g_LibInfo.szExeFile = xmlLibrary->GetPropVal(wxT("name"), wxEmptyString);\r
-               g_LibInfo.szExeFileAlt = xmlLibrary->GetPropVal(wxT("name-alt"), wxEmptyString);\r
+               g_LibInfo.szExeFile = xmlLibrary->GetAttribute(wxT("name"), wxEmptyString);\r
+               g_LibInfo.szExeFileAlt = xmlLibrary->GetAttribute(wxT("name-alt"), wxEmptyString);\r
                g_LibInfo.node = * xmlLibrary;\r
-\r
+               g_LibInfo.nLibIndex = _nTypeId;\r
                return TPI_ERROR_SUCCESS;\r
        }\r
 \r
-       // \96³\8cÀ\83\8b\81[\83v\82É\8a×\82ç\82È\82¢\82æ\82¤\8fã\8cÀ\82ð\90Ý\92è\81B\r
+       // 無限ループに陥らないよう上限を設定。\r
+       xmlLibrary = myGetFirstLib(& xmlDoc);\r
        for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < 300 && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\r
        {\r
-               // \83\89\83C\83u\83\89\83\8a\82ð\83\8d\81[\83h\81B\r
-               g_LibInfo.szExeFile = xmlLibrary->GetPropVal(wxT("name"), wxEmptyString);\r
-               g_LibInfo.szExeFileAlt = xmlLibrary->GetPropVal(wxT("name-alt"), wxEmptyString);\r
-               g_LibInfo.node = * xmlLibrary;\r
-\r
-               // \8f\91\8cÉ\82É\91Î\89\9e\82µ\82Ä\82¢\82é\82©\83`\83F\83b\83N\81B\r
-               if (CheckArchive(_szArcName, NULL) == TPI_ERROR_SUCCESS)\r
+               // 書庫に対応しているかチェック。\r
+               wxFileName fnArchive(_szArcName);\r
+               wxArrayString asExt = ::wxStringTokenize(xmlLibrary->GetAttribute(wxT("suffix"), wxEmptyString), wxT(";"));\r
+               if (xmlLibrary->HasAttribute(wxT("list")))\r
                {\r
-                       // \91Î\89\9e\82µ\82Ä\82¢\82ê\82Î\8f\88\97\9d\82ð\8fI\97¹\81B\r
-                       return TPI_ERROR_SUCCESS;\r
+                       for (size_t i = 0; i < asExt.GetCount(); i++)\r
+                       {\r
+                               // .tar.XXXなど二重判定への対応。\r
+//                             if (asExt[i].IsSameAs(fnArchive.GetExt(), false))\r
+                               if (fnArchive.GetFullName().EndsWith(wxT('.') + asExt[i]))\r
+                               {\r
+                                       // ライブラリをロード。\r
+                                       g_LibInfo.szExeFile = xmlLibrary->GetAttribute(wxT("name"), wxEmptyString);\r
+                                       g_LibInfo.szExeFileAlt = xmlLibrary->GetAttribute(wxT("name-alt"), wxEmptyString);\r
+                                       g_LibInfo.node = * xmlLibrary;\r
+                                       g_LibInfo.nLibIndex = _nTypeId;\r
+                                       return TPI_ERROR_SUCCESS;\r
+                               }\r
+                       }\r
                }\r
-\r
-               xmlLibrary = xmlLibrary->GetNext();\r
+               xmlLibrary = myGetNextLib(xmlLibrary);\r
        }\r
-\r
        return TPI_ERROR_U_LOAD_LIBRARY;\r
 }\r
 \r
@@ -310,62 +286,26 @@ int __stdcall FreePlugin
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
-int __stdcall CheckArchive\r
-(\r
-       const wxString & _szArcName,\r
-       int * _nFileCount\r
-)\r
-{\r
-       wxFileName fnArchive(_szArcName);\r
-       wxArrayString asExt = ::wxStringTokenize(g_LibInfo.node.GetPropVal(wxT("suffix"), wxEmptyString), wxT(";"));\r
-       if (! g_LibInfo.node.HasProp(wxT("list")))\r
-       {\r
-               return TPI_ERROR_ARC_UNSUPPORTED;\r
-       }\r
-\r
-       for (size_t i = 0; i < asExt.GetCount(); i++)\r
-       {\r
-               // .tar.XXX\82È\82Ç\93ñ\8fd\94»\92è\82Ö\82Ì\91Î\89\9e\81B\r
-//             if (asExt[i].IsSameAs(fnArchive.GetExt(), false))\r
-               if (fnArchive.GetFullName().EndsWith(wxT('.') + asExt[i]))\r
-               {\r
-                       // \8aJ\82¢\82Ä\8am\94F\81B\90æ\8ds\82µ\82Ä\83f\81[\83^\82ð\8eæ\93¾\82µ\82Ä\82¨\82­\81B\r
-                       int nErrorCode = OpenArchive(_szArcName, NULL);\r
-\r
-                       // \91Î\89\9e\81B\r
-                       if (_nFileCount != NULL)\r
-                       {\r
-                               // \83t\83@\83C\83\8b\90\94\82Í\91½\82ß\82É\8eæ\82Á\82Ä\82¨\82­\81B\r
-                               * _nFileCount = g_asOutput.Count();\r
-                       }\r
-                       return nErrorCode;\r
-               }\r
-       }\r
-\r
-       return TPI_ERROR_ARC_UNSUPPORTED;\r
-}\r
-\r
 int __stdcall OpenArchive\r
 (\r
        const wxString & _szArcName,\r
-       void * * _hArchive\r
+       void * * _hArchive,\r
+       wxULongLong_t * _nFileCount\r
 )\r
 {\r
-       if (g_szCurrentArchive != _szArcName)\r
+       wxString szOutput;\r
+       if (myExecute(g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetAttribute(wxT("list"), wxEmptyString), _szArcName), & szOutput, wxEmptyString, g_LibInfo.szExeFile.Find(wxT('.')) != wxNOT_FOUND && g_LibInfo.szExeFile.AfterLast(wxT('.')) == wxT("exe")) != TPI_ERROR_SUCCESS)\r
        {\r
-               wxString szOutput;\r
-               if (myExecute(g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetPropVal(wxT("list"), wxEmptyString), _szArcName, NULL, NULL, wxEmptyString), & szOutput, wxEmptyString) != TPI_ERROR_SUCCESS)\r
-               {\r
-                       return TPI_ERROR_U_USE_LIBRARY;\r
-               }\r
-               g_szCurrentArchive = _szArcName;\r
-               g_asOutput = ::wxStringTokenize(szOutput, wxT("\r\n"));\r
+               return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
-       if (_hArchive != NULL)\r
+       wxArrayString * as = new wxArrayString(::wxStringTokenize(szOutput, wxT("\r\n")));\r
+       * _hArchive = (void *) as;\r
+       as->Shrink();\r
+       if (_nFileCount != NULL)\r
        {\r
-               * _hArchive = & g_asOutput;\r
+               * _nFileCount = as->GetCount();\r
        }\r
-       return g_asOutput.Count() == 0 ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;\r
+       return as->IsEmpty() ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall CloseArchive\r
@@ -373,7 +313,9 @@ int __stdcall CloseArchive
        void * _hArchive\r
 )\r
 {\r
-       ((wxArrayString *) _hArchive)->Clear();\r
+       wxArrayString * as = (wxArrayString *) _hArchive;\r
+       as->Clear();\r
+       delete as;\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -384,75 +326,73 @@ int __stdcall GetFileInformation
        bool _bFirst\r
 )\r
 {\r
-       static size_t s_uCurrentLine;\r
-       static wxULongLong s_llFileID;\r
+       static size_t s_nCurrentLine;\r
+       static wxULongLong_t s_nFileId;\r
        if (_hArchive == NULL)\r
        {\r
                return TPI_ERROR_UNDEFINED;\r
        }\r
        wxArrayString asOutput = * (wxArrayString *) _hArchive;\r
 \r
-       // XML\82©\82ç\82Ì\93Ç\82Ý\8d\9e\82Ý\82Í\8f\89\89ñ\82É\8ds\82¤\81B\r
+       // XMLからの読み込みは初回に行う。\r
        static wxString szEndLine, szDateFormat;\r
-       static unsigned long nProcessPerLine;\r
+       static wxULongLong_t nProcessPerLine;\r
        static PosInfo piFName, piPSize, piUSize, piDate;\r
        if (_bFirst)\r
        {\r
-               s_llFileID = 0;\r
-               wxString szStartLine = g_LibInfo.node.GetPropVal(wxT("list-line-s"), wxEmptyString);\r
+               s_nFileId = 0;\r
+               wxString szStartLine = g_LibInfo.node.GetAttribute(wxT("list-line-s"), wxEmptyString);\r
                if (! szStartLine.IsEmpty())\r
                {\r
-                       for (s_uCurrentLine = 0; s_uCurrentLine < asOutput.Count(); s_uCurrentLine++)\r
+                       // 開始行の次の行にセット。\r
+                       s_nCurrentLine = asOutput.Index(szStartLine) + 1;\r
+                       if (s_nCurrentLine == wxNOT_FOUND + 1)\r
                        {\r
-                               if (asOutput[s_uCurrentLine] == szStartLine)\r
-                               {\r
-                                       // \8e\9f\82Ì\8ds\82Ö\90i\82ñ\82Å\8fI\97¹\81B\r
-                                       s_uCurrentLine++;\r
-                                       break;\r
-                               }\r
+                               // 書庫が読み込めなかった?\r
+                               return TPI_ERROR_ARC_UNSUPPORTED;\r
                        }\r
                }\r
 \r
-               // \8f\89\8aú\90Ý\92è\81B\r
-               g_LibInfo.node.GetPropVal(wxT("list-line-c"), wxT("1")).ToULong(& nProcessPerLine);\r
-               szEndLine = g_LibInfo.node.GetPropVal(wxT("list-line-e"), szStartLine);\r
-               szDateFormat = g_LibInfo.node.GetPropVal(wxT("list-date-f"), wxDefaultDateTimeFormat);\r
+               // 初期設定。\r
+               nProcessPerLine = myGetAttributeInt(& g_LibInfo.node, wxT("list-line-c"), 1);\r
+               szEndLine = g_LibInfo.node.GetAttribute(wxT("list-line-e"), szStartLine);\r
+               szDateFormat = g_LibInfo.node.GetAttribute(wxT("list-date-f"), wxDefaultDateTimeFormat);\r
                piFName = MakePosInfo(wxT("fname"));\r
                piPSize = MakePosInfo(wxT("psize"));\r
                piUSize = MakePosInfo(wxT("usize"));\r
-               piDate = MakePosInfo(wxT("date"));\r
+               piDate  = MakePosInfo(wxT("date"));\r
        }\r
 \r
-       if (s_uCurrentLine >= asOutput.Count())\r
+       if (s_nCurrentLine >= asOutput.GetCount())\r
        {\r
-               // \8f\91\8cÉ\82ª\93Ç\82Ý\8d\9e\82ß\82È\82©\82Á\82½\81H\r
-               return TPI_ERROR_ARC_UNSUPPORTED;\r
+               // 空行で終わるとき以外はエラーとする。\r
+               return szEndLine.IsEmpty() ? TPI_ERROR_S_ENDOFDATA : TPI_ERROR_ARC_UNSUPPORTED;\r
        }\r
 \r
-       // \8dÅ\8fI\8ds\82©\82Ç\82¤\82©\8am\94F\81B\r
-       if (asOutput[s_uCurrentLine] == szEndLine)\r
+       // 最終行かどうか確認。\r
+       if (asOutput[s_nCurrentLine] == szEndLine)\r
        {\r
-               return TPI_ERROR_UNDEFINED;\r
+               return TPI_ERROR_S_ENDOFDATA;\r
        }\r
 \r
-       // \83t\83@\83C\83\8b\96¼\82ð\8eæ\93¾\81B\r
-       _fiInfo->szStoredName = piFName.nCount == 0 ? asOutput[s_uCurrentLine + piFName.nLine].Mid(piFName.nStart) : asOutput[s_uCurrentLine + piFName.nLine].Mid(piFName.nStart, piFName.nCount);\r
+       // ファイル名を取得。\r
+       _fiInfo->szStoredName = piFName.nCount == 0 ? asOutput[s_nCurrentLine + piFName.nLine].Mid(piFName.nStart) : asOutput[s_nCurrentLine + piFName.nLine].Mid(piFName.nStart, piFName.nCount);\r
        _fiInfo->szStoredName.Trim();\r
-       _fiInfo->fnFileName = wxFileName::wxFileName(_fiInfo->szStoredName);\r
+       _fiInfo->fnFileName = wxFileName(_fiInfo->szStoredName, wxPATH_DOS);\r
 \r
-       // \83T\83C\83Y\8eæ\93¾\81B\r
-       _fiInfo->llPackedSize   = GetSize(piPSize, s_uCurrentLine, asOutput);\r
-       _fiInfo->llUnpackedSize = GetSize(piUSize, s_uCurrentLine, asOutput);\r
+       // サイズ取得。\r
+       _fiInfo->nPackedSize   = GetSize(piPSize, s_nCurrentLine, asOutput);\r
+       _fiInfo->nUnpackedSize = GetSize(piUSize, s_nCurrentLine, asOutput);\r
 \r
-       // \8dX\90V\8e\9e\8d\8f\8eæ\93¾\81B\r
+       // 更新時刻取得。\r
        if (piDate.nStart != 0 || piDate.nCount != 0)\r
        {\r
-               _fiInfo->tmModified.ParseFormat(piDate.nCount == 0 ? asOutput[s_uCurrentLine + piDate.nLine].Mid(piDate.nStart) : asOutput[s_uCurrentLine + piDate.nLine].Mid(piDate.nStart, piDate.nCount), szDateFormat);\r
+               _fiInfo->tmModified.ParseFormat(piDate.nCount == 0 ? asOutput[s_nCurrentLine + piDate.nLine].Mid(piDate.nStart) : asOutput[s_nCurrentLine + piDate.nLine].Mid(piDate.nStart, piDate.nCount), szDateFormat);\r
        }\r
 \r
-       // \8dÅ\8cã\82É\8e\9f\82Ì\8ds\82Ö\90i\82ß\82Ä\82¨\82­\81B\r
-       _fiInfo->llFileID = s_llFileID++;\r
-       s_uCurrentLine += nProcessPerLine;\r
+       // 最後に次の行へ進めておく。\r
+       _fiInfo->nFileId = s_nFileId++;\r
+       s_nCurrentLine += nProcessPerLine;\r
 \r
        return TPI_ERROR_SUCCESS;\r
 }\r
@@ -463,44 +403,46 @@ int __stdcall GetArchiveInformation
        TPI_ARCHIVEINFO * _aiInfo\r
 )\r
 {\r
-       // \8c`\8e®\82É\8aÖ\82·\82é\8fî\95ñ\82ð\8eæ\93¾\81B\r
-       MakeFormatInfo(wxT("calLibrary"), & _aiInfo->fiInfo, & g_LibInfo.node, 0);\r
+       // 形式に関する情報を取得。\r
+       MakeFormatInfo(& g_LibInfo.node, wxT("cuiWrapper"), & _aiInfo->fiInfo, 0);\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall Command\r
 (\r
-       unsigned int _uCommand,\r
+       wxULongLong_t _eCommand,\r
        TPI_SWITCHES * _swInfo,\r
        const wxString & _szArcName,\r
        const wxArrayString & _szFiles\r
 )\r
 {\r
-       // xml\82©\82ç\83R\83}\83\93\83h\83\89\83C\83\93\82ð\8eæ\93¾\81B\r
+       // xmlからコマンドラインを取得。\r
        wxString szPath, szCommandLine;\r
 \r
-       // API\83A\83h\83\8c\83X\8eæ\93¾\81B\r
-       if (! g_LibInfo.node.GetPropVal(\r
-                       _uCommand == TPI_COMMAND_ADD     ? wxT("add") :\r
-                       _uCommand == TPI_COMMAND_EXTRACT ? wxT("extract") : \r
-                       _uCommand == TPI_COMMAND_DELETE  ? wxT("delete") : \r
-                       _uCommand == TPI_COMMAND_UPDATE  ? wxT("update") : \r
-                       _uCommand == TPI_COMMAND_TEST    ? wxT("test") : \r
-                       _uCommand == TPI_COMMAND_REPAIR  ? wxT("repair") : \r
-                       _uCommand == TPI_COMMAND_MOVE    ? wxT("move") : \r
-                       _uCommand == TPI_COMMAND_SFX     ? wxT("sfx") : \r
-                       _uCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx") : wxEmptyString, & szCommandLine))\r
+       // APIアドレス取得。\r
+       if (! g_LibInfo.node.GetAttribute(\r
+                       _eCommand == TPI_COMMAND_CREATE  ? wxT("create") :\r
+                       _eCommand == TPI_COMMAND_ADD     ? wxT("add") :\r
+                       _eCommand == TPI_COMMAND_EXTRACT ? wxT("extract") : \r
+                       _eCommand == TPI_COMMAND_DELETE  ? wxT("delete") : \r
+                       _eCommand == TPI_COMMAND_UPDATE  ? wxT("update") : \r
+                       _eCommand == TPI_COMMAND_TEST    ? wxT("test") : \r
+                       _eCommand == TPI_COMMAND_REPAIR  ? wxT("repair") : \r
+                       _eCommand == TPI_COMMAND_MOVE    ? wxT("move") : \r
+                       _eCommand == TPI_COMMAND_SFX     ? wxT("sfx") : \r
+                       _eCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx") : wxEmptyString, & szCommandLine))\r
        {\r
-               g_LibInfo.node.GetPropVal(\r
-                       _uCommand == TPI_COMMAND_ADD     ? wxT("add-alt") :\r
-                       _uCommand == TPI_COMMAND_EXTRACT ? wxT("extract-alt") : \r
-                       _uCommand == TPI_COMMAND_DELETE  ? wxT("delete-alt") : \r
-                       _uCommand == TPI_COMMAND_UPDATE  ? wxT("update-alt") : \r
-                       _uCommand == TPI_COMMAND_TEST    ? wxT("test-alt") : \r
-                       _uCommand == TPI_COMMAND_REPAIR  ? wxT("repair-alt") : \r
-                       _uCommand == TPI_COMMAND_MOVE    ? wxT("move-alt") : \r
-                       _uCommand == TPI_COMMAND_SFX     ? wxT("sfx-alt") : \r
-                       _uCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx-alt") : wxEmptyString, & szCommandLine);\r
+               g_LibInfo.node.GetAttribute(\r
+                       _eCommand == TPI_COMMAND_CREATE  ? wxT("create-alt") :\r
+                       _eCommand == TPI_COMMAND_ADD     ? wxT("add-alt") :\r
+                       _eCommand == TPI_COMMAND_EXTRACT ? wxT("extract-alt") : \r
+                       _eCommand == TPI_COMMAND_DELETE  ? wxT("delete-alt") : \r
+                       _eCommand == TPI_COMMAND_UPDATE  ? wxT("update-alt") : \r
+                       _eCommand == TPI_COMMAND_TEST    ? wxT("test-alt") : \r
+                       _eCommand == TPI_COMMAND_REPAIR  ? wxT("repair-alt") : \r
+                       _eCommand == TPI_COMMAND_MOVE    ? wxT("move-alt") : \r
+                       _eCommand == TPI_COMMAND_SFX     ? wxT("sfx-alt") : \r
+                       _eCommand == TPI_COMMAND_UNSFX   ? wxT("unsfx-alt") : wxEmptyString, & szCommandLine);\r
        }\r
 \r
        if (szCommandLine.IsEmpty())\r
@@ -508,25 +450,21 @@ int __stdcall Command
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
 \r
-       // \83R\83}\83\93\83h\83\89\83C\83\93\81E\83\8c\83X\83|\83\93\83X\83t\83@\83C\83\8b\8dì\90¬\81B\r
+       // コマンドライン・レスポンスファイル作成。\r
        wxString\r
-               szResponceFileName = MakeResponceFile(_szFiles, g_LibInfo.node.GetPropVal(wxT("quote-resp"), wxT("1")) == wxT("1")),\r
+               szResponceFileName = MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfo.node, wxT("quote-resp"), true)),\r
                szCommandLineSend  = MakeCommandLineSend(szCommandLine, _szArcName, _swInfo, _szFiles, szResponceFileName);\r
 \r
-       // \83R\83}\83\93\83h\83\89\83C\83\93\8eÀ\8ds\81B\r
+       // コマンドライン実行。\r
        wxString szOutput;\r
-       DWORD nErrorCode = myExecute(g_LibInfo.szExeFile + wxT(" ") + szCommandLineSend, & szOutput, _swInfo->fnDestinationDirectory.GetFullPath());\r
+       int nErrorCode = myExecute(g_LibInfo.szExeFile + wxT(" ") + szCommandLineSend, & szOutput, _swInfo->fnDestinationDirectory.GetFullPath(), g_LibInfo.szExeFile.Find(wxT('.')) != wxNOT_FOUND && g_LibInfo.szExeFile.AfterLast(wxT('.')) == wxT("exe"));\r
 \r
-       // \83\8c\83X\83|\83\93\83X\83t\83@\83C\83\8b\8dí\8f\9c\81B\r
+       // レスポンスファイル削除。\r
        ::wxRemoveFile(szResponceFileName);\r
 \r
        if (nErrorCode != TPI_ERROR_SUCCESS)\r
        {\r
-#ifdef __LINUX__\r
-               ::wxMessageBox(wxString::Format(wxT("Error :\n%d\n\nCommandLine:\n%s\n\nOutput:\n%s"), nErrorCode, szCommandLineSend.c_str(), szOutput.c_str()));\r
-#else\r
-               MessageBox(NULL, wxString::Format(wxT("Error :\n%d\n\nCommandLine:\n%s\n\nOutput:\n%s"), nErrorCode, szCommandLineSend.c_str(), szOutput.c_str()), NULL, 0);\r
-#endif\r
+               wxLogError(L"Error :\n%x\n\nCommandLine:\n%s\n\nOutput:\n%s", nErrorCode, szCommandLineSend.c_str(), szOutput.c_str());\r
        }\r
        return nErrorCode;\r
 }\r
@@ -536,7 +474,7 @@ int __stdcall SetCallbackProc
        TPI_PROC _prArcProc\r
 )\r
 {\r
-       // \83|\83C\83\93\83^\82ð\95Û\91\81B\r
+       // ポインタを保存。\r
        if (_prArcProc == NULL)\r
        {\r
                return TPI_ERROR_D_PARAMETER;\r