summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2017-07-23 16:59:43 +0200
committermanuel <manuel@mausz.at>2017-07-23 16:59:43 +0200
commit4c3251ec645c8b71820dab7e51e612e5919d4e75 (patch)
tree9533268a93e58fc2e16de1b8ee3fafe3784e5225 /xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h
parentf44ecaa4f27e7538ddcad66d40e543bffa2d2d86 (diff)
downloadkodi-pvr-build-4c3251ec645c8b71820dab7e51e612e5919d4e75.tar.gz
kodi-pvr-build-4c3251ec645c8b71820dab7e51e612e5919d4e75.tar.bz2
kodi-pvr-build-4c3251ec645c8b71820dab7e51e612e5919d4e75.zip
sync with upstream
Diffstat (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h')
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h622
1 files changed, 622 insertions, 0 deletions
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h
new file mode 100644
index 0000000..4bb3e69
--- /dev/null
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/VFS.h
@@ -0,0 +1,622 @@
1#pragma once
2/*
3 * Copyright (C) 2015 Team Kodi
4 *
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Kodi; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include "../AddonBase.h"
22#include "../Filesystem.h"
23
24#ifdef BUILD_KODI_ADDON
25#include "../IFileTypes.h"
26#else
27#include "filesystem/IFileTypes.h"
28#include "PlatformDefs.h"
29#endif
30
31namespace kodi { namespace addon { class CInstanceVFS; }}
32
33extern "C"
34{
35
36 struct VFSURL
37 {
38 const char* url;
39 const char* domain;
40 const char* hostname;
41 const char* filename;
42 unsigned int port;
43 const char* options;
44 const char* username;
45 const char* password;
46 const char* redacted;
47 const char* sharename;
48 };
49
50 typedef struct VFSGetDirectoryCallbacks /* internal */
51 {
52 bool (__cdecl* get_keyboard_input)(void* ctx, const char* heading, char** input, bool hidden_input);
53 void (__cdecl* set_error_dialog)(void* ctx, const char* heading, const char* line1, const char* line2, const char* line3);
54 void (__cdecl* require_authentication)(void* ctx, const char* url);
55 void* ctx;
56 } VFSGetDirectoryCallbacks;
57
58 typedef struct AddonProps_VFSEntry /* internal */
59 {
60 int dummy;
61 } AddonProps_VFSEntry;
62
63 typedef struct AddonToKodiFuncTable_VFSEntry /* internal */
64 {
65 KODI_HANDLE kodiInstance;
66 } AddonToKodiFuncTable_VFSEntry;
67
68 struct AddonInstance_VFSEntry;
69 typedef struct KodiToAddonFuncTable_VFSEntry /* internal */
70 {
71 kodi::addon::CInstanceVFS* addonInstance;
72
73 void* (__cdecl* open) (const AddonInstance_VFSEntry* instance, const VFSURL* url);
74 void* (__cdecl* open_for_write) (const AddonInstance_VFSEntry* instance, const VFSURL* url, bool overwrite);
75 ssize_t (__cdecl* read) (const AddonInstance_VFSEntry* instance, void* context, void* buffer, size_t buf_size);
76 ssize_t (__cdecl* write) (const AddonInstance_VFSEntry* instance, void* context, const void* buffer, size_t buf_size);
77 int64_t (__cdecl* seek) (const AddonInstance_VFSEntry* instance, void* context, int64_t position, int whence);
78 int (__cdecl* truncate) (const AddonInstance_VFSEntry* instance, void* context, int64_t size);
79 int64_t (__cdecl* get_length) (const AddonInstance_VFSEntry* instance, void* context);
80 int64_t (__cdecl* get_position) (const AddonInstance_VFSEntry* instance, void* context);
81 int (__cdecl* get_chunk_size) (const AddonInstance_VFSEntry* instance, void* context);
82 int (__cdecl* io_control) (const AddonInstance_VFSEntry* instance, void* context, XFILE::EIoControl request, void* param);
83 int (__cdecl* stat) (const AddonInstance_VFSEntry* instance, const VFSURL* url, struct __stat64* buffer);
84 bool (__cdecl* close) (const AddonInstance_VFSEntry* instance, void* context);
85 bool (__cdecl* exists) (const AddonInstance_VFSEntry* instance, const VFSURL* url);
86 void (__cdecl* clear_out_idle) (const AddonInstance_VFSEntry* instance);
87 void (__cdecl* disconnect_all) (const AddonInstance_VFSEntry* instance);
88 bool (__cdecl* delete_it) (const AddonInstance_VFSEntry* instance, const VFSURL* url);
89 bool (__cdecl* rename) (const AddonInstance_VFSEntry* instance, const VFSURL* url, const VFSURL* url2);
90 bool (__cdecl* directory_exists) (const AddonInstance_VFSEntry* instance, const VFSURL* url);
91 bool (__cdecl* remove_directory) (const AddonInstance_VFSEntry* instance, const VFSURL* url);
92 bool (__cdecl* create_directory) (const AddonInstance_VFSEntry* instance, const VFSURL* url);
93 bool (__cdecl* get_directory) (const AddonInstance_VFSEntry* instance,
94 const VFSURL* url,
95 VFSDirEntry** entries,
96 int* num_entries,
97 VFSGetDirectoryCallbacks* callbacks);
98 bool (__cdecl* contains_files) (const AddonInstance_VFSEntry* instance,
99 const VFSURL* url,
100 VFSDirEntry** entries,
101 int* num_entries,
102 char* rootpath);
103 void (__cdecl* free_directory) (const AddonInstance_VFSEntry* instance, VFSDirEntry* entries, int num_entries);
104 } KodiToAddonFuncTable_VFSEntry;
105
106 typedef struct AddonInstance_VFSEntry /* internal */
107 {
108 AddonProps_VFSEntry props;
109 AddonToKodiFuncTable_VFSEntry toKodi;
110 KodiToAddonFuncTable_VFSEntry toAddon;
111 } AddonInstance_VFSEntry;
112
113} /* extern "C" */
114
115namespace kodi
116{
117namespace addon
118{
119 class CInstanceVFS : public IAddonInstance
120 {
121 public:
122 CInstanceVFS(KODI_HANDLE instance)
123 : IAddonInstance(ADDON_INSTANCE_VFS)
124 {
125 if (CAddonBase::m_interface->globalSingleInstance != nullptr)
126 throw std::logic_error("kodi::addon::CInstanceVFS: Creation of multiple together with single instance way is not allowed!");
127
128 SetAddonStruct(instance);
129 }
130
131 ~CInstanceVFS() override = default;
132
133 /// @brief Open a file for input
134 ///
135 /// @param[in] url The URL of the file
136 /// @return Context for the opened file
137 virtual void* Open(const VFSURL& url) { return nullptr; }
138
139 /// @brief Open a file for output
140 ///
141 /// @param[in] url The URL of the file
142 /// @param[in] overWrite Whether or not to overwrite an existing file
143 /// @return Context for the opened file
144 ///
145 virtual void* OpenForWrite(const VFSURL& url, bool overWrite) { return nullptr; }
146
147 /// @brief Read from a file
148 ///
149 /// @param[in] context The context of the file
150 /// @param[out] buffer The buffer to read data into
151 /// @param[in] uiBufSize Number of bytes to read
152 /// @return Number of bytes read
153 ///
154 virtual ssize_t Read(void* context, void* buffer, size_t uiBufSize) { return -1; }
155
156 /// @brief Write to a file
157 ///
158 /// @param[in] context The context of the file
159 /// @param[in] buffer The buffer to read data from
160 /// @param[in] uiBufSize Number of bytes to write
161 /// @return Number of bytes written
162 ///
163 virtual ssize_t Write(void* context, const void* buffer, size_t uiBufSize) { return -1; }
164
165 /// @brief Seek in a file
166 ///
167 /// @param[in] context The context of the file
168 /// @param[in] position The position to seek to
169 /// @param[in] whence Position in file 'position' is relative to (SEEK_CUR, SEEK_SET, SEEK_END)
170 /// @return Offset in file after seek
171 ///
172 virtual int64_t Seek(void* context, int64_t position, int whence) { return -1; }
173
174 /// @brief Truncate a file
175 ///
176 /// @param[in] context The context of the file
177 /// @param[in] size The size to truncate the file to
178 /// @return 0 on success, -1 on error
179 ///
180 virtual int Truncate(void* context, int64_t size) { return -1; }
181
182 /// @brief Get total size of a file
183 ///
184 /// @param[in] context The context of the file
185 /// @return Total file size
186 ///
187 virtual int64_t GetLength(void* context) { return 0; }
188
189 /// @brief Get current position in a file
190 ///
191 /// @param[in] context The context of the file
192 /// @return Current position
193 ///
194 virtual int64_t GetPosition(void* context) { return 0; }
195
196 /// @brief Get chunk size of a file
197 ///
198 /// @param[in] context The context of the file
199 /// @return Chunk size
200 ///
201 virtual int GetChunkSize(void* context) { return 1; }
202
203 /// @brief Perform an IO-control on the file
204 ///
205 /// @param[in] context The context of the file
206 /// @param[in] request The requested IO-control
207 /// @param[in] param Parameter attached to the IO-control
208 /// @return -1 on error, >= 0 on success
209 ///
210 virtual int IoControl(void* context, XFILE::EIoControl request, void* param) { return -1; }
211
212 /// @brief Close a file
213 ///
214 /// @param[in] context The context of the file
215 /// @return True on success, false on failure
216 ///
217 virtual bool Close(void* context) { return false; }
218
219 /// @brief Stat a file
220 ///
221 /// @param[in] url The URL of the file
222 /// @param[in] buffer The buffer to store results in
223 /// @return -1 on error, 0 otherwise
224 ///
225 virtual int Stat(const VFSURL& url, struct __stat64* buffer) { return 0; }
226
227 /// @brief Check for file existence
228 ///
229 /// @param[in] url The URL of the file
230 /// @return True if file exists, false otherwise
231 ///
232 virtual bool Exists(const VFSURL& url) { return false; }
233
234 /// @brief Clear out any idle connections
235 ///
236 virtual void ClearOutIdle() { }
237
238 /// @brief Disconnect all connections
239 ///
240 virtual void DisconnectAll() { }
241
242 /// @brief Delete a file
243 ///
244 /// @param[in] url The URL of the file
245 /// @return True if deletion was successful, false otherwise
246 ///
247 virtual bool Delete(const VFSURL& url) { return false; }
248
249 /// @brief Rename a file
250 ///
251 /// @param[in] url The URL of the source file
252 /// @param[in] url2 The URL of the destination file
253 /// @return True if deletion was successful, false otherwise
254 ///
255 virtual bool Rename(const VFSURL& url, const VFSURL& url2) { return false; }
256
257 /// @brief Check for directory existence
258 ///
259 /// @param[in] url The URL of the file
260 /// @return True if directory exists, false otherwise
261 ///
262 virtual bool DirectoryExists(const VFSURL& url) { return false; }
263
264 /// @brief Remove a directory
265 ///
266 /// @param[in] url The URL of the directory
267 /// @return True if removal was successful, false otherwise
268 ///
269 virtual bool RemoveDirectory(const VFSURL& url) { return false; }
270
271 /// @brief Create a directory
272 ///
273 /// @param[in] url The URL of the file
274 /// @return True if creation was successful, false otherwise
275 ///
276 virtual bool CreateDirectory(const VFSURL& url) { return false; }
277
278 /// @brief Callback functions on GetDirectory()
279 ///
280 /// This functions becomes available during call of GetDirectory() from
281 /// Kodi.
282 ///
283 /// If GetDirectory() returns false becomes the parts from here used on
284 /// next call of the function.
285 ///
286 /// **Example:**
287 /// ~~~~~~~~~~~~~{.cpp}
288 ///
289 /// #include <kodi/addon-instance/VFS.h>
290 ///
291 /// ...
292 ///
293 /// bool CMyFile::GetDirectory(const VFSURL& url, std::vector<kodi::vfs::CDirEntry>& items, CVFSCallbacks callbacks)
294 /// {
295 /// std::string neededString;
296 /// callbacks.GetKeyboardInput("Test", neededString, true);
297 /// if (neededString.empty())
298 /// return false;
299 ///
300 /// /* Do the work */
301 /// ...
302 /// return true;
303 /// }
304 /// ~~~~~~~~~~~~~
305 ///
306 //@{
307 class CVFSCallbacks
308 {
309 public:
310 /// @brief Require keyboard input
311 ///
312 /// Becomes called if GetDirectory() returns false and GetDirectory()
313 /// becomes after entry called again.
314 ///
315 /// @param[in] heading The heading of the keyboard dialog
316 /// @param[out] input The resulting string. Returns string after
317 /// second call!
318 /// @param[in] hiddenInput To show input only as "*" on dialog
319 /// @return True if input was received, false otherwise
320 ///
321 bool GetKeyboardInput(const std::string& heading, std::string& input, bool hiddenInput = false)
322 {
323 char* cInput = nullptr;
324 bool ret = m_cb->get_keyboard_input(m_cb->ctx, heading.c_str(), &cInput, hiddenInput);
325 if (cInput)
326 {
327 input = cInput;
328 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, cInput);
329 }
330 return ret;
331 }
332
333 /// @brief Display an error dialog
334 ///
335 /// @param[in] heading The heading of the error dialog
336 /// @param[in] line1 The first line of the error dialog
337 /// @param[in] line2 [opt] The second line of the error dialog
338 /// @param[in] line3 [opt] The third line of the error dialog
339 ///
340 void SetErrorDialog(const std::string& heading, const std::string& line1, const std::string& line2 = "", const std::string& line3 = "")
341 {
342 m_cb->set_error_dialog(m_cb->ctx, heading.c_str(), line1.c_str(), line2.c_str(), line3.c_str());
343 }
344
345 /// @brief Prompt the user for authentication of a URL
346 ///
347 /// @param[in] url The URL
348 void RequireAuthentication(const std::string& url)
349 {
350 m_cb->require_authentication(m_cb->ctx, url.c_str());
351 }
352
353 CVFSCallbacks(const VFSGetDirectoryCallbacks* cb) : m_cb(cb) { }
354
355 private:
356 const VFSGetDirectoryCallbacks* m_cb;
357 };
358 //@}
359
360 /// @brief List a directory
361 ///
362 /// @param[in] url The URL of the directory
363 /// @param[out] entries The entries in the directory
364 /// @param[in] callbacks A callback structure
365 /// @return Context for the directory listing
366 ///
367 virtual bool GetDirectory(const VFSURL& url,
368 std::vector<kodi::vfs::CDirEntry>& entries,
369 CVFSCallbacks callbacks) { return false; }
370
371 /// @brief Check if file should be presented as a directory (multiple streams)
372 ///
373 /// @param[in] url The URL of the file
374 /// @param[out] entries The entries in the directory
375 /// @param[out] rootPath Path to root directory if multiple entries
376 /// @return Context for the directory listing
377 ///
378 virtual bool ContainsFiles(const VFSURL& url,
379 std::vector<kodi::vfs::CDirEntry>& entries,
380 std::string& rootPath) { return false; }
381
382 private:
383 void SetAddonStruct(KODI_HANDLE instance)
384 {
385 if (instance == nullptr)
386 throw std::logic_error("kodi::addon::CInstanceVFS: Creation with empty addon structure not allowed, table must be given from Kodi!");
387
388 m_instanceData = static_cast<AddonInstance_VFSEntry*>(instance);
389 m_instanceData->toAddon.addonInstance = this;
390 m_instanceData->toAddon.open = ADDON_Open;
391 m_instanceData->toAddon.open_for_write = ADDON_OpenForWrite;
392 m_instanceData->toAddon.read = ADDON_Read;
393 m_instanceData->toAddon.write = ADDON_Write;
394 m_instanceData->toAddon.seek = ADDON_Seek;
395 m_instanceData->toAddon.truncate = ADDON_Truncate;
396 m_instanceData->toAddon.get_length = ADDON_GetLength;
397 m_instanceData->toAddon.get_position = ADDON_GetPosition;
398 m_instanceData->toAddon.get_chunk_size = ADDON_GetChunkSize;
399 m_instanceData->toAddon.io_control = ADDON_IoControl;
400 m_instanceData->toAddon.stat = ADDON_Stat;
401 m_instanceData->toAddon.close = ADDON_Close;
402 m_instanceData->toAddon.exists = ADDON_Exists;
403 m_instanceData->toAddon.clear_out_idle = ADDON_ClearOutIdle;
404 m_instanceData->toAddon.disconnect_all = ADDON_DisconnectAll;
405 m_instanceData->toAddon.delete_it = ADDON_Delete;
406 m_instanceData->toAddon.rename = ADDON_Rename;
407 m_instanceData->toAddon.directory_exists = ADDON_DirectoryExists;
408 m_instanceData->toAddon.remove_directory = ADDON_RemoveDirectory;
409 m_instanceData->toAddon.create_directory = ADDON_CreateDirectory;
410 m_instanceData->toAddon.get_directory = ADDON_GetDirectory;
411 m_instanceData->toAddon.free_directory = ADDON_FreeDirectory;
412 m_instanceData->toAddon.contains_files = ADDON_ContainsFiles;
413 }
414
415 inline static void* ADDON_Open(const AddonInstance_VFSEntry* instance, const VFSURL* url)
416 {
417 return instance->toAddon.addonInstance->Open(*url);
418 }
419
420 inline static void* ADDON_OpenForWrite(const AddonInstance_VFSEntry* instance, const VFSURL* url, bool overWrite)
421 {
422 return instance->toAddon.addonInstance->OpenForWrite(*url, overWrite);
423 }
424
425 inline static ssize_t ADDON_Read(const AddonInstance_VFSEntry* instance, void* context, void* buffer, size_t uiBufSize)
426 {
427 return instance->toAddon.addonInstance->Read(context, buffer, uiBufSize);
428 }
429
430 inline static ssize_t ADDON_Write(const AddonInstance_VFSEntry* instance, void* context, const void* buffer, size_t uiBufSize)
431 {
432 return instance->toAddon.addonInstance->Write(context, buffer, uiBufSize);
433 }
434
435 inline static int64_t ADDON_Seek(const AddonInstance_VFSEntry* instance, void* context, int64_t position, int whence)
436 {
437 return instance->toAddon.addonInstance->Seek(context, position, whence);
438 }
439
440 inline static int ADDON_Truncate(const AddonInstance_VFSEntry* instance, void* context, int64_t size)
441 {
442 return instance->toAddon.addonInstance->Truncate(context, size);
443 }
444
445 inline static int64_t ADDON_GetLength(const AddonInstance_VFSEntry* instance, void* context)
446 {
447 return instance->toAddon.addonInstance->GetLength(context);
448 }
449
450 inline static int64_t ADDON_GetPosition(const AddonInstance_VFSEntry* instance, void* context)
451 {
452 return instance->toAddon.addonInstance->GetPosition(context);
453 }
454
455 inline static int ADDON_GetChunkSize(const AddonInstance_VFSEntry* instance, void* context)
456 {
457 return instance->toAddon.addonInstance->GetChunkSize(context);
458 }
459
460 inline static int ADDON_IoControl(const AddonInstance_VFSEntry* instance, void* context, XFILE::EIoControl request, void* param)
461 {
462 return instance->toAddon.addonInstance->IoControl(context, request, param);
463 }
464
465 inline static int ADDON_Stat(const AddonInstance_VFSEntry* instance, const VFSURL* url, struct __stat64* buffer)
466 {
467 return instance->toAddon.addonInstance->Stat(*url, buffer);
468 }
469
470 inline static bool ADDON_Close(const AddonInstance_VFSEntry* instance, void* context)
471 {
472 return instance->toAddon.addonInstance->Close(context);
473 }
474
475 inline static bool ADDON_Exists(const AddonInstance_VFSEntry* instance, const VFSURL* url)
476 {
477 return instance->toAddon.addonInstance->Exists(*url);
478 }
479
480 inline static void ADDON_ClearOutIdle(const AddonInstance_VFSEntry* instance)
481 {
482 return instance->toAddon.addonInstance->ClearOutIdle();
483 }
484
485 inline static void ADDON_DisconnectAll(const AddonInstance_VFSEntry* instance)
486 {
487 return instance->toAddon.addonInstance->DisconnectAll();
488 }
489
490 inline static bool ADDON_Delete(const AddonInstance_VFSEntry* instance, const VFSURL* url)
491 {
492 return instance->toAddon.addonInstance->Delete(*url);
493 }
494
495 inline static bool ADDON_Rename(const AddonInstance_VFSEntry* instance, const VFSURL* url, const VFSURL* url2)
496 {
497 return instance->toAddon.addonInstance->Rename(*url, *url2);
498 }
499
500 inline static bool ADDON_DirectoryExists(const AddonInstance_VFSEntry* instance, const VFSURL* url)
501 {
502 return instance->toAddon.addonInstance->DirectoryExists(*url);
503 }
504
505 inline static bool ADDON_RemoveDirectory(const AddonInstance_VFSEntry* instance, const VFSURL* url)
506 {
507 return instance->toAddon.addonInstance->RemoveDirectory(*url);
508 }
509
510 inline static bool ADDON_CreateDirectory(const AddonInstance_VFSEntry* instance, const VFSURL* url)
511 {
512 return instance->toAddon.addonInstance->CreateDirectory(*url);
513 }
514
515 inline static bool ADDON_GetDirectory(const AddonInstance_VFSEntry* instance,
516 const VFSURL* url,
517 VFSDirEntry** retEntries,
518 int* num_entries,
519 VFSGetDirectoryCallbacks* callbacks)
520 {
521 std::vector<kodi::vfs::CDirEntry> addonEntries;
522 bool ret = instance->toAddon.addonInstance->GetDirectory(*url, addonEntries, callbacks);
523 if (ret)
524 {
525 VFSDirEntry* entries = static_cast<VFSDirEntry*>(malloc(sizeof(VFSDirEntry) * addonEntries.size()));
526 for (unsigned int i = 0; i < addonEntries.size(); ++i)
527 {
528 entries[i].label = strdup(addonEntries[i].Label().c_str());
529 entries[i].title = strdup(addonEntries[i].Title().c_str());
530 entries[i].path = strdup(addonEntries[i].Path().c_str());
531 entries[i].folder = addonEntries[i].IsFolder();
532 entries[i].size = addonEntries[i].Size();
533
534 entries[i].num_props = 0;
535 const std::map<std::string, std::string>& props = addonEntries[i].GetProperties();
536 if (!props.empty())
537 {
538 entries[i].properties = static_cast<VFSProperty*>(malloc(sizeof(VFSProperty)*props.size()));
539 for (const auto& prop : props)
540 {
541 entries[i].properties[entries[i].num_props].name = strdup(prop.first.c_str());
542 entries[i].properties[entries[i].num_props].val = strdup(prop.second.c_str());
543 ++entries[i].num_props;
544 }
545 }
546 else
547 entries[i].properties = nullptr;
548 }
549 *retEntries = entries;
550 *num_entries = addonEntries.size();
551 }
552 return ret;
553 }
554
555 inline static void ADDON_FreeDirectory(const AddonInstance_VFSEntry* instance, VFSDirEntry* entries, int num_entries)
556 {
557 for (int i = 0; i < num_entries; ++i)
558 {
559 if (entries[i].properties)
560 {
561 for (unsigned int j = 0; j < entries[i].num_props; ++j)
562 {
563 free(entries[i].properties[j].name);
564 free(entries[i].properties[j].val);
565 }
566 free(entries[i].properties);
567 }
568 free(entries[i].label);
569 free(entries[i].title);
570 free(entries[i].path);
571 }
572 free(entries);
573 }
574
575 inline static bool ADDON_ContainsFiles(const AddonInstance_VFSEntry* instance,
576 const VFSURL* url,
577 VFSDirEntry** retEntries,
578 int* num_entries,
579 char* rootpath)
580 {
581 std::string cppRootPath;
582 std::vector<kodi::vfs::CDirEntry> addonEntries;
583 bool ret = instance->toAddon.addonInstance->ContainsFiles(*url, addonEntries, cppRootPath);
584 if (ret)
585 {
586 strncpy(rootpath, cppRootPath.c_str(), ADDON_STANDARD_STRING_LENGTH);
587
588 VFSDirEntry* entries = static_cast<VFSDirEntry*>(malloc(sizeof(VFSDirEntry) * addonEntries.size()));
589 for (unsigned int i = 0; i < addonEntries.size(); ++i)
590 {
591 entries[i].label = strdup(addonEntries[i].Label().c_str());
592 entries[i].title = strdup(addonEntries[i].Title().c_str());
593 entries[i].path = strdup(addonEntries[i].Path().c_str());
594 entries[i].folder = addonEntries[i].IsFolder();
595 entries[i].size = addonEntries[i].Size();
596
597 entries[i].num_props = 0;
598 const std::map<std::string, std::string>& props = addonEntries[i].GetProperties();
599 if (!props.empty())
600 {
601 entries[i].properties = static_cast<VFSProperty*>(malloc(sizeof(VFSProperty)*props.size()));
602 for (const auto& prop : props)
603 {
604 entries[i].properties[entries[i].num_props].name = strdup(prop.first.c_str());
605 entries[i].properties[entries[i].num_props].val = strdup(prop.second.c_str());
606 ++entries[i].num_props;
607 }
608 }
609 else
610 entries[i].properties = nullptr;
611 }
612 *retEntries = entries;
613 *num_entries = addonEntries.size();
614 }
615 return ret;
616 }
617
618 AddonInstance_VFSEntry* m_instanceData;
619 };
620
621} /* namespace addon */
622} /* namespace kodi */