Merge pull request #24470 from fuzzard/release_20.3
[xbmc.git] / xbmc / addons / VFSEntry.cpp
blob063ba2514beb9979ec82bc8b38b2c0d153c251fc
1 /*
2 * Copyright (C) 2013 Arne Morten Kvarving
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 * See LICENSES/README.md for more information.
6 */
8 #include "VFSEntry.h"
10 #include "ServiceBroker.h"
11 #include "URL.h"
12 #include "addons/AddonEvents.h"
13 #include "addons/AddonManager.h"
14 #include "addons/addoninfo/AddonInfo.h"
15 #include "addons/addoninfo/AddonType.h"
16 #include "addons/interfaces/Filesystem.h"
17 #include "network/ZeroconfBrowser.h"
18 #include "utils/StringUtils.h"
19 #include "utils/log.h"
21 #include <mutex>
22 #include <utility>
24 #if defined(TARGET_WINDOWS)
25 #ifndef S_IFLNK
26 #define S_IFLNK 0120000
27 #endif
28 #ifndef S_IFBLK
29 #define S_IFBLK 0
30 #endif
31 #ifndef S_IFSOCK
32 #define S_IFSOCK 0
33 #endif
34 #ifndef S_IFREG
35 #define S_IFREG _S_IFREG
36 #endif
37 #ifndef S_IFCHR
38 #define S_IFCHR _S_IFCHR
39 #endif
40 #ifndef S_IFDIR
41 #define S_IFDIR _S_IFDIR
42 #endif
43 #ifndef S_IFIFO
44 #define S_IFIFO _S_IFIFO
45 #endif
46 #endif
48 namespace ADDON
51 CVFSAddonCache::~CVFSAddonCache()
53 Deinit();
56 void CVFSAddonCache::Init()
58 CServiceBroker::GetAddonMgr().Events().Subscribe(this, &CVFSAddonCache::OnEvent);
60 // Load all available VFS addons during Kodi start
61 std::vector<AddonInfoPtr> addonInfos;
62 CServiceBroker::GetAddonMgr().GetAddonInfos(addonInfos, true, AddonType::VFS);
64 std::unique_lock<CCriticalSection> lock(m_critSection);
65 for (const auto& addonInfo : addonInfos)
67 VFSEntryPtr vfs = std::make_shared<CVFSEntry>(addonInfo);
68 vfs->Addon()->RegisterInformer(this);
70 m_addonsInstances.emplace_back(vfs);
72 if (!vfs->GetZeroconfType().empty())
73 CZeroconfBrowser::GetInstance()->AddServiceType(vfs->GetZeroconfType());
77 void CVFSAddonCache::Deinit()
79 CServiceBroker::GetAddonMgr().Events().Unsubscribe(this);
82 const std::vector<VFSEntryPtr> CVFSAddonCache::GetAddonInstances()
84 std::unique_lock<CCriticalSection> lock(m_critSection);
85 return m_addonsInstances;
88 VFSEntryPtr CVFSAddonCache::GetAddonInstance(const std::string& strId)
90 VFSEntryPtr addon;
92 std::unique_lock<CCriticalSection> lock(m_critSection);
94 const auto& itAddon = std::find_if(m_addonsInstances.begin(), m_addonsInstances.end(),
95 [&strId](const VFSEntryPtr& addon)
97 return addon->ID() == strId;
98 });
100 if (itAddon != m_addonsInstances.end())
101 addon = *itAddon;
103 return addon;
106 void CVFSAddonCache::OnEvent(const AddonEvent& event)
108 if (typeid(event) == typeid(AddonEvents::Disabled))
110 for (const auto& vfs : m_addonsInstances)
112 if (vfs->ID() == event.addonId && !vfs->GetZeroconfType().empty())
113 CZeroconfBrowser::GetInstance()->RemoveServiceType(vfs->GetZeroconfType());
117 if (typeid(event) == typeid(AddonEvents::Enabled) ||
118 typeid(event) == typeid(AddonEvents::Disabled) ||
119 typeid(event) == typeid(AddonEvents::ReInstalled))
121 if (CServiceBroker::GetAddonMgr().HasType(event.addonId, AddonType::VFS))
122 Update(event.addonId);
124 else if (typeid(event) == typeid(AddonEvents::UnInstalled))
126 Update(event.addonId);
130 bool CVFSAddonCache::IsInUse(const std::string& id)
132 std::unique_lock<CCriticalSection> lock(m_critSection);
134 const auto& itAddon = std::find_if(m_addonsInstances.begin(), m_addonsInstances.end(),
135 [&id](const VFSEntryPtr& addon) { return addon->ID() == id; });
136 if (itAddon != m_addonsInstances.end() && (*itAddon).use_count() > 1)
137 return true;
138 return false;
141 void CVFSAddonCache::Update(const std::string& id)
143 std::vector<VFSEntryPtr> addonmap;
145 // Stop used instance if present, otherwise the new becomes created on already created addon base one.
147 std::unique_lock<CCriticalSection> lock(m_critSection);
149 const auto& itAddon =
150 std::find_if(m_addonsInstances.begin(), m_addonsInstances.end(),
151 [&id](const VFSEntryPtr& addon) { return addon->ID() == id; });
153 if (itAddon != m_addonsInstances.end())
155 (*itAddon)->Addon()->RegisterInformer(nullptr);
156 m_addonsInstances.erase(itAddon);
160 // Create and init the new VFS addon instance
161 AddonInfoPtr addonInfo = CServiceBroker::GetAddonMgr().GetAddonInfo(id, AddonType::VFS);
162 if (addonInfo && !CServiceBroker::GetAddonMgr().IsAddonDisabled(id))
164 VFSEntryPtr vfs = std::make_shared<CVFSEntry>(addonInfo);
166 if (!vfs->GetZeroconfType().empty())
167 CZeroconfBrowser::GetInstance()->AddServiceType(vfs->GetZeroconfType());
169 std::unique_lock<CCriticalSection> lock(m_critSection);
170 m_addonsInstances.emplace_back(vfs);
174 class CVFSURLWrapper
176 public:
177 explicit CVFSURLWrapper(const CURL& url2)
179 m_strings.push_back(url2.Get());
180 m_strings.push_back(url2.GetDomain());
181 m_strings.push_back(url2.GetHostName());
182 m_strings.push_back(url2.GetFileName());
183 m_strings.push_back(url2.GetOptions());
184 m_strings.push_back(url2.GetUserName());
185 m_strings.push_back(url2.GetPassWord());
186 m_strings.push_back(url2.GetRedacted());
187 m_strings.push_back(url2.GetShareName());
188 m_strings.push_back(url2.GetProtocol());
190 url.url = m_strings[0].c_str();
191 url.domain = m_strings[1].c_str();
192 url.hostname = m_strings[2].c_str();
193 url.filename = m_strings[3].c_str();
194 url.port = url2.GetPort();
195 url.options = m_strings[4].c_str();
196 url.username = m_strings[5].c_str();
197 url.password = m_strings[6].c_str();
198 url.redacted = m_strings[7].c_str();
199 url.sharename = m_strings[8].c_str();
200 url.protocol = m_strings[9].c_str();
203 VFSURL url;
204 protected:
205 std::vector<std::string> m_strings;
208 CVFSEntry::ProtocolInfo::ProtocolInfo(const AddonInfoPtr& addonInfo)
209 : supportPath(addonInfo->Type(AddonType::VFS)->GetValue("@supportPath").asBoolean()),
210 supportUsername(addonInfo->Type(AddonType::VFS)->GetValue("@supportUsername").asBoolean()),
211 supportPassword(addonInfo->Type(AddonType::VFS)->GetValue("@supportPassword").asBoolean()),
212 supportPort(addonInfo->Type(AddonType::VFS)->GetValue("@supportPort").asBoolean()),
213 supportBrowsing(addonInfo->Type(AddonType::VFS)->GetValue("@supportBrowsing").asBoolean()),
214 supportWrite(addonInfo->Type(AddonType::VFS)->GetValue("@supportWrite").asBoolean()),
215 defaultPort(addonInfo->Type(AddonType::VFS)->GetValue("@defaultPort").asInteger()),
216 type(addonInfo->Type(AddonType::VFS)->GetValue("@protocols").asString()),
217 label(addonInfo->Type(AddonType::VFS)->GetValue("@label").asInteger())
221 CVFSEntry::CVFSEntry(const AddonInfoPtr& addonInfo)
222 : IAddonInstanceHandler(ADDON_INSTANCE_VFS, addonInfo),
223 m_protocols(addonInfo->Type(AddonType::VFS)->GetValue("@protocols").asString()),
224 m_extensions(addonInfo->Type(AddonType::VFS)->GetValue("@extensions").asString()),
225 m_zeroconf(addonInfo->Type(AddonType::VFS)->GetValue("@zeroconf").asString()),
226 m_files(addonInfo->Type(AddonType::VFS)->GetValue("@files").asBoolean()),
227 m_directories(addonInfo->Type(AddonType::VFS)->GetValue("@directories").asBoolean()),
228 m_filedirectories(addonInfo->Type(AddonType::VFS)->GetValue("@filedirectories").asBoolean()),
229 m_protocolInfo(addonInfo)
231 if (!addonInfo->Type(AddonType::VFS)->GetValue("@supportDialog").asBoolean())
232 m_protocolInfo.type.clear();
234 // Create "C" interface structures, used as own parts to prevent API problems on update
235 m_ifc.vfs = new AddonInstance_VFSEntry;
236 m_ifc.vfs->props = new AddonProps_VFSEntry();
237 m_ifc.vfs->toAddon = new KodiToAddonFuncTable_VFSEntry();
238 m_ifc.vfs->toKodi = new AddonToKodiFuncTable_VFSEntry();
240 m_ifc.vfs->toKodi->kodiInstance = this;
241 if (CreateInstance() != ADDON_STATUS_OK)
242 CLog::Log(LOGFATAL, "CVFSEntry - Couldn't create instance on add-on '{}'", addonInfo->Name());
245 CVFSEntry::~CVFSEntry()
247 DestroyInstance();
249 // Delete "C" interface structures
250 delete m_ifc.vfs->toAddon;
251 delete m_ifc.vfs->toKodi;
252 delete m_ifc.vfs->props;
253 delete m_ifc.vfs;
256 void* CVFSEntry::Open(const CURL& url)
258 if (!m_ifc.vfs->toAddon->open)
259 return nullptr;
261 CVFSURLWrapper url2(url);
262 return m_ifc.vfs->toAddon->open(m_ifc.vfs, &url2.url);
265 void* CVFSEntry::OpenForWrite(const CURL& url, bool bOverWrite)
267 if (!m_ifc.vfs->toAddon->open_for_write)
268 return nullptr;
270 CVFSURLWrapper url2(url);
271 return m_ifc.vfs->toAddon->open_for_write(m_ifc.vfs, &url2.url, bOverWrite);
274 bool CVFSEntry::Exists(const CURL& url)
276 if (!m_ifc.vfs->toAddon->exists)
277 return false;
279 CVFSURLWrapper url2(url);
280 return m_ifc.vfs->toAddon->exists(m_ifc.vfs, &url2.url);
283 int CVFSEntry::Stat(const CURL& url, struct __stat64* buffer)
285 int ret = -1;
286 if (!m_ifc.vfs->toAddon->stat)
287 return ret;
289 CVFSURLWrapper url2(url);
290 STAT_STRUCTURE statBuffer = {};
291 ret = m_ifc.vfs->toAddon->stat(m_ifc.vfs, &url2.url, &statBuffer);
293 *buffer = {};
294 buffer->st_dev = statBuffer.deviceId;
295 buffer->st_ino = statBuffer.fileSerialNumber;
296 buffer->st_size = statBuffer.size;
297 buffer->st_atime = statBuffer.accessTime;
298 buffer->st_mtime = statBuffer.modificationTime;
299 buffer->st_ctime = statBuffer.statusTime;
300 buffer->st_mode = 0;
301 if (statBuffer.isDirectory)
302 buffer->st_mode |= S_IFDIR;
303 if (statBuffer.isSymLink)
304 buffer->st_mode |= S_IFLNK;
305 if (statBuffer.isBlock)
306 buffer->st_mode |= S_IFBLK;
307 if (statBuffer.isCharacter)
308 buffer->st_mode |= S_IFCHR;
309 if (statBuffer.isFifo)
310 buffer->st_mode |= S_IFIFO;
311 if (statBuffer.isRegular)
312 buffer->st_mode |= S_IFREG;
313 if (statBuffer.isSocket)
314 buffer->st_mode |= S_IFSOCK;
316 return ret;
319 ssize_t CVFSEntry::Read(void* ctx, void* lpBuf, size_t uiBufSize)
321 if (!m_ifc.vfs->toAddon->read)
322 return 0;
324 return m_ifc.vfs->toAddon->read(m_ifc.vfs, ctx, static_cast<uint8_t*>(lpBuf), uiBufSize);
327 ssize_t CVFSEntry::Write(void* ctx, const void* lpBuf, size_t uiBufSize)
329 if (!m_ifc.vfs->toAddon->write)
330 return 0;
332 return m_ifc.vfs->toAddon->write(m_ifc.vfs, ctx, static_cast<const uint8_t*>(lpBuf), uiBufSize);
335 int64_t CVFSEntry::Seek(void* ctx, int64_t position, int whence)
337 if (!m_ifc.vfs->toAddon->seek)
338 return 0;
340 return m_ifc.vfs->toAddon->seek(m_ifc.vfs, ctx, position, whence);
343 int CVFSEntry::Truncate(void* ctx, int64_t size)
345 if (!m_ifc.vfs->toAddon->truncate)
346 return 0;
348 return m_ifc.vfs->toAddon->truncate(m_ifc.vfs, ctx, size);
351 void CVFSEntry::Close(void* ctx)
353 if (m_ifc.vfs->toAddon->close)
354 m_ifc.vfs->toAddon->close(m_ifc.vfs, ctx);
357 int64_t CVFSEntry::GetPosition(void* ctx)
359 if (!m_ifc.vfs->toAddon->get_position)
360 return 0;
362 return m_ifc.vfs->toAddon->get_position(m_ifc.vfs, ctx);
365 int CVFSEntry::GetChunkSize(void* ctx)
367 if (!m_ifc.vfs->toAddon->get_chunk_size)
368 return 0;
370 return m_ifc.vfs->toAddon->get_chunk_size(m_ifc.vfs, ctx);
373 int64_t CVFSEntry::GetLength(void* ctx)
375 if (!m_ifc.vfs->toAddon->get_length)
376 return 0;
378 return m_ifc.vfs->toAddon->get_length(m_ifc.vfs, ctx);
381 int CVFSEntry::IoControl(void* ctx, XFILE::EIoControl request, void* param)
383 switch (request)
385 case XFILE::EIoControl::IOCTRL_SEEK_POSSIBLE:
387 if (!m_ifc.vfs->toAddon->io_control_get_seek_possible)
388 return -1;
389 return m_ifc.vfs->toAddon->io_control_get_seek_possible(m_ifc.vfs, ctx) ? 1 : 0;
391 case XFILE::EIoControl::IOCTRL_CACHE_STATUS:
393 if (!m_ifc.vfs->toAddon->io_control_get_cache_status)
394 return -1;
396 XFILE::SCacheStatus* kodiData = static_cast<XFILE::SCacheStatus*>(param);
397 if (!kodiData)
398 return -1;
400 VFS_CACHE_STATUS_DATA status;
401 int ret = m_ifc.vfs->toAddon->io_control_get_cache_status(m_ifc.vfs, ctx, &status) ? 0 : -1;
402 if (ret >= 0)
404 kodiData->forward = status.forward;
405 kodiData->maxrate = status.maxrate;
406 kodiData->currate = status.currate;
407 kodiData->lowrate = status.lowrate;
409 return ret;
411 case XFILE::EIoControl::IOCTRL_CACHE_SETRATE:
413 if (!m_ifc.vfs->toAddon->io_control_set_cache_rate)
414 return -1;
416 uint32_t& iParam = *static_cast<uint32_t*>(param);
417 return m_ifc.vfs->toAddon->io_control_set_cache_rate(m_ifc.vfs, ctx, iParam) ? 1 : 0;
419 case XFILE::EIoControl::IOCTRL_SET_RETRY:
421 if (!m_ifc.vfs->toAddon->io_control_set_retry)
422 return -1;
424 bool& bParam = *static_cast<bool*>(param);
425 return m_ifc.vfs->toAddon->io_control_set_retry(m_ifc.vfs, ctx, bParam) ? 0 : -1;
428 // Not by addon supported io's
429 case XFILE::EIoControl::IOCTRL_SET_CACHE:
430 case XFILE::EIoControl::IOCTRL_NATIVE:
431 default:
432 break;
435 return -1;
438 bool CVFSEntry::Delete(const CURL& url)
440 if (!m_ifc.vfs->toAddon->delete_it)
441 return false;
443 CVFSURLWrapper url2(url);
444 return m_ifc.vfs->toAddon->delete_it(m_ifc.vfs, &url2.url);
447 bool CVFSEntry::Rename(const CURL& url, const CURL& url2)
449 if (!m_ifc.vfs->toAddon->rename)
450 return false;
452 CVFSURLWrapper url3(url);
453 CVFSURLWrapper url4(url2);
454 return m_ifc.vfs->toAddon->rename(m_ifc.vfs, &url3.url, &url4.url);
457 void CVFSEntry::ClearOutIdle()
459 if (m_ifc.vfs->toAddon->clear_out_idle)
460 m_ifc.vfs->toAddon->clear_out_idle(m_ifc.vfs);
463 void CVFSEntry::DisconnectAll()
465 if (m_ifc.vfs->toAddon->disconnect_all)
466 m_ifc.vfs->toAddon->disconnect_all(m_ifc.vfs);
469 bool CVFSEntry::DirectoryExists(const CURL& url)
471 if (!m_ifc.vfs->toAddon->directory_exists)
472 return false;
474 CVFSURLWrapper url2(url);
475 return m_ifc.vfs->toAddon->directory_exists(m_ifc.vfs, &url2.url);
478 bool CVFSEntry::RemoveDirectory(const CURL& url)
480 if (!m_ifc.vfs->toAddon->remove_directory)
481 return false;
483 CVFSURLWrapper url2(url);
484 return m_ifc.vfs->toAddon->remove_directory(m_ifc.vfs, &url2.url);
487 bool CVFSEntry::CreateDirectory(const CURL& url)
489 if (!m_ifc.vfs->toAddon->create_directory)
490 return false;
492 CVFSURLWrapper url2(url);
493 return m_ifc.vfs->toAddon->create_directory(m_ifc.vfs, &url2.url);
496 static void VFSDirEntriesToCFileItemList(int num_entries,
497 VFSDirEntry* entries,
498 CFileItemList& items)
500 for (int i=0;i<num_entries;++i)
502 CFileItemPtr item(new CFileItem());
503 item->SetLabel(entries[i].label);
504 item->SetPath(entries[i].path);
505 item->m_dwSize = entries[i].size;
506 item->m_dateTime = entries[i].date_time;
507 item->m_bIsFolder = entries[i].folder;
508 if (entries[i].title)
509 item->m_strTitle = entries[i].title;
510 for (unsigned int j=0;j<entries[i].num_props;++j)
512 if (StringUtils::CompareNoCase(entries[i].properties[j].name, "propmisusepreformatted") == 0)
514 if (StringUtils::CompareNoCase(entries[i].properties[j].name, "true") == 0)
515 item->SetLabelPreformatted(true);
516 else
517 item->SetLabelPreformatted(false);
518 } else
519 item->SetProperty(entries[i].properties[j].name,
520 entries[i].properties[j].val);
522 items.Add(item);
526 bool CVFSEntry::GetDirectory(const CURL& url, CFileItemList& items,
527 void* ctx)
529 if (!m_ifc.vfs->toAddon->get_directory || !m_ifc.vfs->toAddon->free_directory)
530 return false;
532 VFSGetDirectoryCallbacks callbacks;
533 callbacks.ctx = ctx;
534 callbacks.get_keyboard_input = CVFSEntryIDirectoryWrapper::DoGetKeyboardInput;
535 callbacks.set_error_dialog = CVFSEntryIDirectoryWrapper::DoSetErrorDialog;
536 callbacks.require_authentication = CVFSEntryIDirectoryWrapper::DoRequireAuthentication;
538 VFSDirEntry* entries = nullptr;
539 int num_entries = 0;
540 CVFSURLWrapper url2(url);
541 bool ret =
542 m_ifc.vfs->toAddon->get_directory(m_ifc.vfs, &url2.url, &entries, &num_entries, &callbacks);
543 if (ret)
545 VFSDirEntriesToCFileItemList(num_entries, entries, items);
546 m_ifc.vfs->toAddon->free_directory(m_ifc.vfs, entries, num_entries);
549 return ret;
552 bool CVFSEntry::ContainsFiles(const CURL& url, CFileItemList& items)
554 if (!m_ifc.vfs->toAddon->contains_files || !m_ifc.vfs->toAddon->free_directory)
555 return false;
557 VFSDirEntry* entries = nullptr;
558 int num_entries = 0;
560 CVFSURLWrapper url2(url);
561 char rootpath[ADDON_STANDARD_STRING_LENGTH];
562 rootpath[0] = 0;
563 bool ret =
564 m_ifc.vfs->toAddon->contains_files(m_ifc.vfs, &url2.url, &entries, &num_entries, rootpath);
565 if (!ret)
566 return false;
568 VFSDirEntriesToCFileItemList(num_entries, entries, items);
569 m_ifc.vfs->toAddon->free_directory(m_ifc.vfs, entries, num_entries);
570 if (strlen(rootpath))
571 items.SetPath(rootpath);
573 return true;
576 CVFSEntryIFileWrapper::CVFSEntryIFileWrapper(VFSEntryPtr ptr)
577 : m_context(nullptr), m_addon(std::move(ptr))
581 CVFSEntryIFileWrapper::~CVFSEntryIFileWrapper()
583 Close();
586 bool CVFSEntryIFileWrapper::Open(const CURL& url)
588 m_context = m_addon->Open(url);
589 return m_context != nullptr;
592 bool CVFSEntryIFileWrapper::OpenForWrite(const CURL& url, bool bOverWrite)
594 m_context = m_addon->OpenForWrite(url, bOverWrite);
595 return m_context != nullptr;
598 bool CVFSEntryIFileWrapper::Exists(const CURL& url)
600 return m_addon->Exists(url);
603 int CVFSEntryIFileWrapper::Stat(const CURL& url, struct __stat64* buffer)
605 return m_addon->Stat(url, buffer);
608 int CVFSEntryIFileWrapper::Truncate(int64_t size)
610 return m_addon->Truncate(m_context, size);
613 ssize_t CVFSEntryIFileWrapper::Read(void* lpBuf, size_t uiBufSize)
615 if (!m_context)
616 return 0;
618 return m_addon->Read(m_context, lpBuf, uiBufSize);
621 ssize_t CVFSEntryIFileWrapper::Write(const void* lpBuf, size_t uiBufSize)
623 if (!m_context)
624 return 0;
626 return m_addon->Write(m_context, lpBuf, uiBufSize);
629 int64_t CVFSEntryIFileWrapper::Seek(int64_t iFilePosition, int whence)
631 if (!m_context)
632 return 0;
634 return m_addon->Seek(m_context, iFilePosition, whence);
637 void CVFSEntryIFileWrapper::Close()
639 if (m_context)
641 m_addon->Close(m_context);
642 m_context = nullptr;
646 int64_t CVFSEntryIFileWrapper::GetPosition()
648 if (!m_context)
649 return 0;
651 return m_addon->GetPosition(m_context);
654 int CVFSEntryIFileWrapper::GetChunkSize()
656 if (!m_context)
657 return 0;
659 return m_addon->GetChunkSize(m_context);
662 int64_t CVFSEntryIFileWrapper::GetLength()
664 if (!m_context)
665 return 0;
667 return m_addon->GetLength(m_context);
670 int CVFSEntryIFileWrapper::IoControl(XFILE::EIoControl request, void* param)
672 if (!m_context)
673 return 0;
675 return m_addon->IoControl(m_context, request, param);
678 bool CVFSEntryIFileWrapper::Delete(const CURL& url)
680 return m_addon->Delete(url);
683 bool CVFSEntryIFileWrapper::Rename(const CURL& url, const CURL& url2)
685 return m_addon->Rename(url, url2);
688 CVFSEntryIDirectoryWrapper::CVFSEntryIDirectoryWrapper(VFSEntryPtr ptr) : m_addon(std::move(ptr))
692 bool CVFSEntryIDirectoryWrapper::Exists(const CURL& url)
694 return m_addon->DirectoryExists(url);
697 bool CVFSEntryIDirectoryWrapper::Remove(const CURL& url)
699 return m_addon->RemoveDirectory(url);
702 bool CVFSEntryIDirectoryWrapper::Create(const CURL& url)
704 return m_addon->CreateDirectory(url);
707 bool CVFSEntryIDirectoryWrapper::GetDirectory(const CURL& url,
708 CFileItemList& items)
710 return m_addon->GetDirectory(url, items, this);
713 bool CVFSEntryIDirectoryWrapper::DoGetKeyboardInput(void* ctx,
714 const char* heading,
715 char** input,
716 bool hidden_input)
718 return static_cast<CVFSEntryIDirectoryWrapper*>(ctx)->GetKeyboardInput2(heading, input, hidden_input);
721 bool CVFSEntryIDirectoryWrapper::GetKeyboardInput2(const char* heading,
722 char** input,
723 bool hidden_input)
725 std::string inp;
726 bool result;
727 if ((result=GetKeyboardInput(CVariant(std::string(heading)), inp, hidden_input)))
728 *input = strdup(inp.c_str());
730 return result;
733 void CVFSEntryIDirectoryWrapper::DoSetErrorDialog(void* ctx, const char* heading,
734 const char* line1,
735 const char* line2,
736 const char* line3)
738 static_cast<CVFSEntryIDirectoryWrapper*>(ctx)->SetErrorDialog2(heading, line1,
739 line2, line3);
742 void CVFSEntryIDirectoryWrapper::SetErrorDialog2(const char* heading,
743 const char* line1,
744 const char* line2,
745 const char* line3)
747 CVariant l2=0, l3=0;
748 if (line2)
749 l2 = std::string(line2);
750 if (line3)
751 l3 = std::string(line3);
752 if (m_flags & XFILE::DIR_FLAG_ALLOW_PROMPT)
753 SetErrorDialog(CVariant(std::string(heading)),
754 CVariant(std::string(line1)), l2, l3);
757 void CVFSEntryIDirectoryWrapper::DoRequireAuthentication(void* ctx,
758 const char* url)
760 static_cast<CVFSEntryIDirectoryWrapper*>(ctx)->RequireAuthentication2(CURL(url));
763 void CVFSEntryIDirectoryWrapper::RequireAuthentication2(const CURL& url)
765 if (m_flags & XFILE::DIR_FLAG_ALLOW_PROMPT)
766 RequireAuthentication(url);
769 } /*namespace ADDON*/