OSDN Git Service

TPI内部でのパスのハードコーディングを撤廃。
[tpi/lychee.git] / src / plugin / cuiWrapper / cuiWrapper.cpp
index 2a32490..1ee4032 100644 (file)
 //    Includes\r
 //******************************************************************************\r
 \r
+#define MYUSE_LIBPATH 1\r
 #include "../../common/header/plugin.h"\r
 #include "../../common/header/plugin-extra.h"\r
 #include "../../common/library/library.h"\r
-#include <wx/config.h>\r
-#include <wx/stdpaths.h>\r
-#include <wx/xml/xml.h>\r
+#include "../../common/library/xmldoc.h"\r
 #include <wx/tokenzr.h>\r
 #include "cuiWrapper.h"\r
+#define min(a, b) ((a) < (b) ? (a) : (b))\r
 \r
 //******************************************************************************\r
 //    Global varients\r
@@ -51,12 +51,12 @@ TPI_PROC g_prProc;
 //    Inside Functions\r
 //******************************************************************************\r
 \r
-int myExecute(const wxString & szCommandLine, wxString * szOutput, const wxString & szCwd)\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.ToUTF8(), "r");\r
+       FILE * fp = popen(fWine ? (wxT("wine ") + szCommandLine).ToUTF8() : szCommandLine.ToUTF8(), "r");\r
        ::wxSetWorkingDirectory(sz);\r
        if (fp == NULL)\r
        {\r
@@ -85,7 +85,7 @@ int myExecute(const wxString & szCommandLine, wxString * szOutput, const wxStrin
        sa.bInheritHandle = TRUE;\r
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
        HANDLE hRead, hWrite;\r
-       if (! ::CreatePipe(& hRead, & hWrite, & sa, 0))\r
+       if (! ::CreatePipe(& hRead, & hWrite, & sa, 4096))\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
@@ -104,27 +104,25 @@ int myExecute(const wxString & szCommandLine, wxString * szOutput, const wxStrin
 \r
        if (szOutput != NULL)\r
        {\r
-               char sz[32768];\r
-               while (true)\r
+               bool bSignal;\r
+               do\r
                {\r
                        DWORD dwSize = 0;\r
-                       if (! ::PeekNamedPipe(hRead, NULL, 0, NULL, & dwSize, NULL))\r
-                       {\r
-                               continue;\r
-                       }\r
-\r
-                       if (dwSize > 0)\r
+                       bSignal = ::WaitForSingleObject(pi.hProcess, 100) == WAIT_OBJECT_0;\r
+                       ::PeekNamedPipe(hRead, NULL, 0, NULL, & dwSize, NULL);\r
+                       while (dwSize > 0)\r
                        {\r
+                               char sz[4097];\r
                                memset(sz, 0, sizeof(sz));\r
-                               ::ReadFile(hRead, & sz, sizeof(sz), & dwSize, NULL);\r
-                               * szOutput += UTF82String(sz);\r
+                               ::ReadFile(hRead, & sz, sizeof(sz) - 1, & 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
+                               ::PeekNamedPipe(hRead, NULL, 0, NULL, & dwSize, NULL);\r
                        }\r
                }\r
+               while (! bSignal);\r
        }\r
 \r
        ::CloseHandle(pi.hProcess);\r
@@ -137,9 +135,9 @@ int myExecute(const wxString & szCommandLine, wxString * szOutput, const wxStrin
 PosInfo MakePosInfo(const wxString & szPrefix)\r
 {\r
        PosInfo pi;\r
-       g_LibInfo.node.GetAttribute(wxT("list-") + szPrefix + wxT("-s"), wxEmptyString).ToULongLong(& pi.nStart);\r
-       g_LibInfo.node.GetAttribute(wxT("list-") + szPrefix + wxT("-c"), wxEmptyString).ToULongLong(& pi.nCount);\r
-       g_LibInfo.node.GetAttribute(wxT("list-") + szPrefix + wxT("-l"), wxT("0")).ToULongLong(& 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
@@ -185,6 +183,9 @@ int __stdcall GetPluginInformation
        case TPI_INFO_VERSION_API:\r
                * (int *) _pPtr = 2;\r
                break;\r
+       case TPI_INFO_HANDLE_ON_COMMAND:\r
+               * (int *) _pPtr = 0;\r
+               break;\r
        default:\r
                return TPI_ERROR_D_UNSUPPORTED;\r
        }\r
@@ -194,65 +195,56 @@ int __stdcall GetPluginInformation
 int __stdcall GetFormatInformation(TPI_FORMATINFO * _fiInfo, bool _bFirst)\r
 {\r
        static wxULongLong_t s_nFileId;\r
-       wxStandardPaths p;\r
-       wxXmlDocument config(wxPathOnly(p.GetExecutablePath()) + wxT("/lib/cuiWrapper.xml"));\r
-       // 一気に先頭のライブラリの情報を取得。\r
-       wxXmlNode * xmlLibrary = config.GetRoot()->GetChildren();\r
-\r
+       static wxXmlDocument xmlDoc(myMakeXMLName(wxT("cuiWrapper")));\r
+       static wxXmlNode * xmlLibrary;\r
        if (_bFirst)\r
        {\r
                // xml解析開始。\r
                s_nFileId = 0;\r
+               xmlLibrary = myGetFirstLib(& xmlDoc);\r
        }\r
        else\r
        {\r
-               for (wxULongLong_t i = 0; i < s_nFileId && 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
                // データの終端に達した場合。\r
                return TPI_ERROR_S_ENDOFDATA;\r
        }\r
 \r
-       MakeFormatInfo(wxT("cuiWrapper"), _fiInfo, xmlLibrary, s_nFileId++);\r
-       if (myExecute(xmlLibrary->GetAttribute(wxT("name"), wxEmptyString), NULL, wxEmptyString) != 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.MakeLower().EndsWith(wxT(".exe"))) != TPI_ERROR_SUCCESS)\r
        {\r
                _fiInfo->eSupportedCommand = 0;\r
        }\r
-\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall LoadPlugin\r
 (\r
        const wxString & _szArcName,\r
-       wxULongLong_t _llTypeId\r
+       TPI_PROC _prProc,\r
+       wxULongLong_t _nTypeId\r
 )\r
 {\r
        // xml解析開始。\r
-       wxStandardPaths p;\r
-       wxXmlDocument config(wxPathOnly(p.GetExecutablePath()) + wxT("/lib/cuiWrapper.xml"));\r
-       if (! config.IsOk())\r
+       wxXmlDocument xmlDoc(myMakeXMLName(wxT("cuiWrapper")));\r
+       wxXmlNode * xmlLibrary;\r
+\r
+       // コールバック関数を設定。\r
+       if (_prProc != NULL)\r
        {\r
-               return TPI_ERROR_UNDEFINED;\r
+               g_prProc = * _prProc;\r
        }\r
-       // 一気に先頭のライブラリの情報を取得。\r
-       wxXmlNode * xmlLibrary = config.GetRoot()->GetChildren();\r
 \r
        // 対象が存在するならば対応するライブラリを調査、\r
        // 対象が存在しないならば指示されたライブラリをロード。\r
        if (! ::wxFileExists(_szArcName))\r
        {\r
-               // 適当な位置まで移動。\r
-               for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < _llTypeId && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\r
-               {\r
-                       xmlLibrary = xmlLibrary->GetNext();\r
-               }\r
-               if (xmlLibrary == NULL || xmlLibrary->GetName() != wxT("library"))\r
+               xmlLibrary = myGetFirstLib(& xmlDoc, _nTypeId);\r
+               if (xmlLibrary == NULL)\r
                {\r
                        // xml文法エラー。\r
                        return TPI_ERROR_UNDEFINED;\r
@@ -260,40 +252,36 @@ int __stdcall LoadPlugin
                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
        // 無限ループに陥らないよう上限を設定。\r
+       xmlLibrary = myGetFirstLib(& xmlDoc);\r
        for (g_LibInfo.nLibIndex = 0; g_LibInfo.nLibIndex < 300 && xmlLibrary != NULL; g_LibInfo.nLibIndex++)\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
-\r
                // 書庫に対応しているかチェック。\r
                wxFileName fnArchive(_szArcName);\r
-               wxArrayString asExt = ::wxStringTokenize(g_LibInfo.node.GetAttribute(wxT("suffix"), wxEmptyString), wxT(";"));\r
-               if (! g_LibInfo.node.HasAttribute(wxT("list")))\r
-               {\r
-                       xmlLibrary = xmlLibrary->GetNext();\r
-                       continue;\r
-               }\r
-\r
-               for (size_t i = 0; i < asExt.GetCount(); i++)\r
+               wxArrayString asExt = ::wxStringTokenize(xmlLibrary->GetAttribute(wxT("suffix"), wxEmptyString), wxT(";"));\r
+               if (xmlLibrary->HasAttribute(wxT("list")))\r
                {\r
-                       // .tar.XXXなど二重判定への対応。\r
-//                     if (asExt[i].IsSameAs(fnArchive.GetExt(), false))\r
-                       if (fnArchive.GetFullName().EndsWith(wxT('.') + asExt[i]))\r
+                       for (size_t i = 0; i < asExt.GetCount(); i++)\r
                        {\r
-                               return TPI_ERROR_SUCCESS;\r
+                               // .tar.XXXなど二重判定への対応。\r
+//                             if (asExt[i].IsSameAs(fnArchive.GetExt(), false))\r
+                               if (fnArchive.GetFullName().MakeLower().EndsWith(wxT('.') + asExt[i].MakeLower()))\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
@@ -313,7 +301,9 @@ int __stdcall OpenArchive
 )\r
 {\r
        wxString szOutput;\r
-       if (myExecute(g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetAttribute(wxT("list"), wxEmptyString), _szArcName), & szOutput, wxEmptyString) != TPI_ERROR_SUCCESS)\r
+       TPI_SWITCHES swInfo;\r
+       swInfo.szArcName = _szArcName;\r
+       if (myExecute(g_LibInfo.szExeFile + wxT(" ") + MakeCommandLineSend(g_LibInfo.node.GetAttribute(wxT("list"), wxEmptyString), & swInfo), & szOutput, wxEmptyString, g_LibInfo.szExeFile.MakeLower().EndsWith(wxT(".exe"))) != TPI_ERROR_SUCCESS)\r
        {\r
                return TPI_ERROR_U_USE_LIBRARY;\r
        }\r
@@ -324,7 +314,16 @@ int __stdcall OpenArchive
        {\r
                * _nFileCount = as->GetCount();\r
        }\r
-       return as->IsEmpty() ? TPI_ERROR_UNDEFINED : TPI_ERROR_SUCCESS;\r
+\r
+       wxString szStartLine = g_LibInfo.node.GetAttribute(wxT("list-line-s"), wxEmptyString);\r
+       if ((! szStartLine.IsEmpty() && as->Index(szStartLine) == wxNOT_FOUND) || as->IsEmpty())\r
+       {\r
+               // 書庫が読み込めなかった?\r
+               delete as;\r
+               return TPI_ERROR_ARC_UNSUPPORTED;\r
+       }\r
+\r
+       return TPI_ERROR_SUCCESS;\r
 }\r
 \r
 int __stdcall CloseArchive\r
@@ -363,17 +362,12 @@ int __stdcall GetFileInformation
                wxString szStartLine = g_LibInfo.node.GetAttribute(wxT("list-line-s"), wxEmptyString);\r
                if (! szStartLine.IsEmpty())\r
                {\r
-                       // 開始行の次の行にセット。\r
+                       // 開始行の次の行にセット。エラーはOpenArchiveでチェック済み。\r
                        s_nCurrentLine = asOutput.Index(szStartLine) + 1;\r
-                       if (s_nCurrentLine == wxNOT_FOUND + 1)\r
-                       {\r
-                               // 書庫が読み込めなかった?\r
-                               return TPI_ERROR_ARC_UNSUPPORTED;\r
-                       }\r
                }\r
 \r
                // 初期設定。\r
-               g_LibInfo.node.GetAttribute(wxT("list-line-c"), wxT("1")).ToULongLong(& nProcessPerLine);\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
@@ -397,7 +391,7 @@ int __stdcall GetFileInformation
        // ファイル名を取得。\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
        // サイズ取得。\r
        _fiInfo->nPackedSize   = GetSize(piPSize, s_nCurrentLine, asOutput);\r
@@ -406,7 +400,7 @@ int __stdcall GetFileInformation
        // 更新時刻取得。\r
        if (piDate.nStart != 0 || piDate.nCount != 0)\r
        {\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
+               _fiInfo->tmModify.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
        // 最後に次の行へ進めておく。\r
@@ -423,7 +417,7 @@ int __stdcall GetArchiveInformation
 )\r
 {\r
        // 形式に関する情報を取得。\r
-       MakeFormatInfo(wxT("cuiWrapper"), & _aiInfo->fiInfo, & g_LibInfo.node, 0);\r
+       MakeFormatInfo(& g_LibInfo.node, wxT("cuiWrapper"), & _aiInfo->fiInfo, 0);\r
        return TPI_ERROR_SUCCESS;\r
 }\r
 \r
@@ -431,7 +425,7 @@ int __stdcall Command
 (\r
        wxULongLong_t _eCommand,\r
        TPI_SWITCHES * _swInfo,\r
-       const wxString & _szArcName,\r
+       void *,// _hArchive,\r
        const wxArrayString & _szFiles\r
 )\r
 {\r
@@ -471,12 +465,12 @@ int __stdcall Command
 \r
        // コマンドライン・レスポンスファイル作成。\r
        wxString\r
-               szResponceFileName = MakeResponceFile(_szFiles, g_LibInfo.node.GetAttribute(wxT("quote-resp"), wxT("1")) == wxT("1")),\r
-               szCommandLineSend  = MakeCommandLineSend(szCommandLine, _szArcName, _swInfo, _szFiles, szResponceFileName);\r
+               szResponceFileName = MakeResponceFile(_szFiles, myGetAttributeBool(& g_LibInfo.node, wxT("quote-resp"), true)),\r
+               szCommandLineSend  = MakeCommandLineSend(szCommandLine, _swInfo, _szFiles, szResponceFileName);\r
 \r
        // コマンドライン実行。\r
        wxString szOutput;\r
-       int 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.MakeLower().EndsWith(wxT(".exe")));\r
 \r
        // レスポンスファイル削除。\r
        ::wxRemoveFile(szResponceFileName);\r
@@ -488,21 +482,6 @@ int __stdcall Command
        return nErrorCode;\r
 }\r
 \r
-int __stdcall SetCallbackProc\r
-(\r
-       TPI_PROC _prArcProc\r
-)\r
-{\r
-       // ポインタを保存。\r
-       if (_prArcProc == NULL)\r
-       {\r
-               return TPI_ERROR_D_PARAMETER;\r
-       }\r
-       g_prProc = * _prArcProc;\r
-\r
-       return TPI_ERROR_SUCCESS;\r
-}\r
-\r
 #ifdef __cplusplus\r
 }\r
 #endif\r