OSDN Git Service

refactor
[winmerge-jp/winmerge-jp.git] / Src / Merge7zFormatMergePluginImpl.cpp
1 /** 
2  * @file  Merge7zFormatMergePluginImpl.cpp
3  *
4  * @brief Implementation file for Merge7zFormatMergePluginImpl class
5  */
6 #include "pch.h"
7 #include "Merge7zFormatMergePluginImpl.h"
8 #include "paths.h"
9 #include "Plugins.h"
10 #include "Merge7zFormatRegister.h"
11 #include "OptionsMgr.h"
12 #include "OptionsDef.h"
13 #include "MergeApp.h"
14 #include "Environment.h"
15 #include "7zCommon.h"
16 #include <list>
17 #include <Poco/Mutex.h>
18
19 static Merge7zFormatRegister g_autoregister(&Merge7zFormatMergePluginImpl::GuessFormat);
20 static __declspec(thread) Merge7zFormatMergePluginImpl *g_pluginformat;
21 static std::list<std::unique_ptr<Merge7zFormatMergePluginImpl> > g_pluginformat_list;
22 static Poco::FastMutex g_mutex;
23
24 static Merge7zFormatMergePluginImpl *GetInstance()
25 {
26         if (g_pluginformat == nullptr)
27         {
28                 g_pluginformat = new Merge7zFormatMergePluginImpl();
29                 Poco::FastMutex::ScopedLock lock(g_mutex);
30                 g_pluginformat_list.emplace_back(g_pluginformat);
31         }
32         return g_pluginformat;
33 }
34
35 Merge7z::Format *Merge7zFormatMergePluginImpl::GuessFormat(const String& path)
36 {
37         if (!GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED))
38                 return nullptr;
39         Merge7zFormatMergePluginImpl *format = GetInstance();
40         Merge7z::Format* formatChild = nullptr;
41         PluginInfo* URLHandler = nullptr;
42         PluginInfo *plugin = nullptr;
43         String dummypath = path;
44         bool isfolder = false;
45         if (paths::IsURL(path))
46         {
47                 URLHandler = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"URL_PACK_UNPACK", path);
48                 if (!URLHandler)
49                         return nullptr;
50                 isfolder = plugin::InvokeIsFolder(path, URLHandler->m_lpDispatch);
51                 if (!isfolder)
52                 {
53                         dummypath = paths::ConcatPath(env::GetTemporaryPath(), _T("tmp"));
54                         String ext = URLHandler->m_ext;
55                         if (!ext.empty())
56                                 dummypath += ext;
57                         else
58                                 dummypath += paths::FindExtension(path);
59                 }
60         }
61         if (!isfolder)
62         {
63                 if (format->m_infoUnpacker.GetPluginPipeline().find(_T("<Automatic>")) != String::npos)
64                         plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_FOLDER_PACK_UNPACK", dummypath);
65                 else if (!format->m_infoUnpacker.GetPluginPipeline().empty())
66                         plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_FOLDER_PACK_UNPACK", format->m_infoUnpacker.GetPluginPipeline());
67                 if (plugin == nullptr)
68                 {
69                         if (URLHandler == nullptr)
70                                 return nullptr;
71                         formatChild = ArchiveGuessFormat(dummypath);
72                         if (formatChild == nullptr)
73                                 return nullptr;
74                 }
75                 if (plugin)
76                 {
77                         if (!plugin::InvokeIsFolder(dummypath, plugin->m_lpDispatch))
78                                 return nullptr;
79                 }
80         }
81         format->m_plugin = plugin;
82         format->m_URLHandler = URLHandler;
83         format->m_format = formatChild;
84         return format;
85 }
86
87 HRESULT Merge7zFormatMergePluginImpl::DeCompressArchive(HWND, LPCTSTR path, LPCTSTR folder)
88 {
89         int nChanged = 0;
90         int subcode = 0;
91         if (m_URLHandler == nullptr && m_plugin == nullptr && m_format == nullptr)
92                 return E_FAIL;
93         String srcpath = path;
94         paths::CreateIfNeeded(folder);
95         if (m_URLHandler != nullptr && m_plugin == nullptr && m_format == nullptr)
96                 return plugin::InvokeUnpackFolder(srcpath, folder, nChanged, m_URLHandler->m_lpDispatch, subcode) ? S_OK : E_FAIL;
97         if (m_URLHandler)
98         {
99                 String ext = m_URLHandler->m_ext;
100                 String dstpath = env::GetTemporaryFileName(env::GetTemporaryPath(), _T("URL"))
101                         + (!ext.empty() ? ext : paths::FindExtension(path));
102                 if (!plugin::InvokeUnpackFile(srcpath, dstpath, nChanged, m_URLHandler->m_lpDispatch, subcode))
103                         return E_FAIL;
104                 srcpath = dstpath;
105         }
106         if (m_plugin)
107         {
108                 HRESULT hr = plugin::InvokeUnpackFolder(srcpath, folder, nChanged, m_plugin->m_lpDispatch, subcode) ? S_OK : E_FAIL;
109                 if (m_URLHandler != nullptr)
110                         DeleteFile(srcpath.c_str());
111                 return hr;
112         }
113         else if (m_format)
114         {
115                 HRESULT hr = m_format->DeCompressArchive(nullptr, srcpath.c_str(), folder);
116                 if (m_URLHandler != nullptr)
117                         DeleteFile(srcpath.c_str());
118                 return hr;
119         }
120         return E_FAIL;
121 }
122
123 HRESULT Merge7zFormatMergePluginImpl::CompressArchive(HWND, LPCTSTR path, Merge7z::DirItemEnumerator *)
124 {
125         return E_FAIL;
126 }
127
128 Merge7z::Format::Inspector *Merge7zFormatMergePluginImpl::Open(HWND, LPCTSTR) { return nullptr; }
129 Merge7z::Format::Updater *Merge7zFormatMergePluginImpl::Update(HWND, LPCTSTR) { return nullptr; }
130 HRESULT Merge7zFormatMergePluginImpl::GetHandlerProperty(HWND, PROPID, PROPVARIANT *, VARTYPE) { return E_FAIL; }
131 BSTR Merge7zFormatMergePluginImpl::GetHandlerName(HWND) { return nullptr; }
132 BSTR Merge7zFormatMergePluginImpl::GetHandlerClassID(HWND) { return nullptr; }
133 BSTR Merge7zFormatMergePluginImpl::GetHandlerExtension(HWND) { return nullptr; }
134 BSTR Merge7zFormatMergePluginImpl::GetHandlerAddExtension(HWND) { return nullptr; }
135 VARIANT_BOOL Merge7zFormatMergePluginImpl::GetHandlerUpdate(HWND) { return VARIANT_FALSE; }
136 VARIANT_BOOL Merge7zFormatMergePluginImpl::GetHandlerKeepName(HWND) { return VARIANT_FALSE; }
137
138 BSTR Merge7zFormatMergePluginImpl::GetDefaultName(HWND, LPCTSTR path)
139 {
140         return SysAllocString(L"");
141 }
142
143 void Merge7zFormatMergePluginImpl::SetPackingInfo(const PackingInfo* infoUnpacker)
144 {
145         GetInstance()->m_infoUnpacker = infoUnpacker ? *infoUnpacker : PackingInfo();
146 }
147
148 PackingInfo *Merge7zFormatMergePluginImpl::GetPackingInfo()
149 {
150         return &GetInstance()->m_infoUnpacker;
151 }