summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h')
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h3472
1 files changed, 2079 insertions, 1393 deletions
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h
index 3df6cec..2054ce6 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/Filesystem.h
@@ -9,1627 +9,2313 @@
9#pragma once 9#pragma once
10 10
11#include "AddonBase.h" 11#include "AddonBase.h"
12#include "c-api/filesystem.h"
12 13
14#ifdef __cplusplus
15
16#include <cstring>
13#include <map> 17#include <map>
14#include <vector> 18#include <vector>
15 19
16#if !defined(_WIN32) 20namespace kodi
17 #include <sys/stat.h> 21{
18 #if !defined(__stat64) 22namespace vfs
19 #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD)
20 #define __stat64 stat
21 #else
22 #define __stat64 stat64
23 #endif
24 #endif
25#endif
26#ifdef _WIN32 // windows
27#ifndef _SSIZE_T_DEFINED
28 typedef intptr_t ssize_t;
29 #define _SSIZE_T_DEFINED
30#endif // !_SSIZE_T_DEFINED
31#endif
32
33#ifndef S_ISDIR
34 #define S_ISDIR(mode) ((((mode)) & 0170000) == (0040000))
35#endif
36
37#ifndef S_ISLNK
38 #define S_ISLNK(mode) ((((mode)) & 0170000) == (0120000))
39#endif
40
41/*
42 * For interface between add-on and kodi.
43 *
44 * This structure defines the addresses of functions stored inside Kodi which
45 * are then available for the add-on to call
46 *
47 * All function pointers there are used by the C++ interface functions below.
48 * You find the set of them on xbmc/addons/interfaces/General.cpp
49 *
50 * Note: For add-on development itself this is not needed
51 */
52extern "C"
53{ 23{
54 24
55 struct VFSProperty 25//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
56 { 26// Main page text for filesystem group by Doxygen.
57 char* name; 27//{{{
58 char* val;
59 };
60
61 struct VFSDirEntry
62 {
63 char* label; //!< item label
64 char* title; //!< item title
65 char* path; //!< item path
66 unsigned int num_props; //!< Number of properties attached to item
67 VFSProperty* properties; //!< Properties
68 time_t date_time; //!< file creation date & time
69 bool folder; //!< Item is a folder
70 uint64_t size; //!< Size of file represented by item
71 };
72
73 typedef struct AddonToKodiFuncTable_kodi_filesystem
74 {
75 bool (*can_open_directory)(void* kodiBase, const char* url);
76 bool (*create_directory)(void* kodiBase, const char* path);
77 bool (*remove_directory)(void* kodiBase, const char* path);
78 bool (*directory_exists)(void* kodiBase, const char* path);
79 bool (*get_directory)(void* kodiBase, const char* path, const char* mask, VFSDirEntry** items, unsigned int* num_items);
80 void (*free_directory)(void* kodiBase, VFSDirEntry* items, unsigned int num_items);
81
82 bool (*file_exists)(void* kodiBase, const char *filename, bool useCache);
83 int (*stat_file)(void* kodiBase, const char *filename, struct __stat64* buffer);
84 bool (*delete_file)(void* kodiBase, const char *filename);
85 bool (*rename_file)(void* kodiBase, const char *filename, const char *newFileName);
86 bool (*copy_file)(void* kodiBase, const char *filename, const char *dest);
87
88 char* (*get_file_md5)(void* kodiBase, const char* filename);
89 char* (*get_cache_thumb_name)(void* kodiBase, const char* filename);
90 char* (*make_legal_filename)(void* kodiBase, const char* filename);
91 char* (*make_legal_path)(void* kodiBase, const char* path);
92 char* (*translate_special_protocol)(void* kodiBase, const char *strSource);
93
94 void* (*open_file)(void* kodiBase, const char* filename, unsigned int flags);
95 void* (*open_file_for_write)(void* kodiBase, const char* filename, bool overwrite);
96 ssize_t (*read_file)(void* kodiBase, void* file, void* ptr, size_t size);
97 bool (*read_file_string)(void* kodiBase, void* file, char *szLine, int iLineLength);
98 ssize_t (*write_file)(void* kodiBase, void* file, const void* ptr, size_t size);
99 void (*flush_file)(void* kodiBase, void* file);
100 int64_t (*seek_file)(void* kodiBase, void* file, int64_t position, int whence);
101 int (*truncate_file)(void* kodiBase, void* file, int64_t size);
102 int64_t (*get_file_position)(void* kodiBase, void* file);
103 int64_t (*get_file_length)(void* kodiBase, void* file);
104 double (*get_file_download_speed)(void* kodiBase, void* file);
105 void (*close_file)(void* kodiBase, void* file);
106 int (*get_file_chunk_size)(void* kodiBase, void* file);
107 char** (*get_property_values)(void* kodiBase, void* file, int type, const char *name, int *numValues);
108
109 void* (*curl_create)(void* kodiBase, const char* url);
110 bool (*curl_add_option)(void* kodiBase, void* file, int type, const char* name, const char* value);
111 bool (*curl_open)(void* kodiBase, void* file, unsigned int flags);
112 } AddonToKodiFuncTable_kodi_filesystem;
113
114} /* extern "C" */
115 28
116//============================================================================== 29//==============================================================================
117/// 30///
118/// \defgroup cpp_kodi_vfs Interface - kodi::vfs 31/// @defgroup cpp_kodi_vfs Interface - kodi::vfs
119/// \ingroup cpp 32/// @ingroup cpp
120/// @brief **Virtual filesystem functions** 33/// @brief **Virtual filesystem functions**\n
34/// Offers classes and functions for access to the Virtual File Server (VFS)
35/// which you can use to manipulate files and folders.
121/// 36///
37/// This system allow the use of ["Special Protocol"](https://kodi.wiki/view/Special_protocol)
38/// where is Kodi's solution to platform dependent directories. Common directory
39/// names are assigned a <b>`special://[name]`</b> path which is passed around
40/// inside Kodi and then translated to the platform specific path before the
41/// operating system sees it. This helps keep most of the platform mess
42/// centralized in the code.\n
43/// To become a correct path back can be @ref TranslateSpecialProtocol() used.
122/// 44///
123/// It has the header \ref Filesystem.h "#include <kodi/Filesystem.h>" be 45/// It has the header @ref Filesystem.h "#include <kodi/Filesystem.h>" be
124/// included to enjoy it. 46/// included to enjoy it.
125/// 47///
126//------------------------------------------------------------------------------ 48//------------------------------------------------------------------------------
127 49
128//============================================================================== 50//==============================================================================
129/// \defgroup cpp_kodi_vfs_Defs Definitions, structures and enumerators 51/// @defgroup cpp_kodi_vfs_Defs Definitions, structures and enumerators
130/// \ingroup cpp_kodi_vfs 52/// @ingroup cpp_kodi_vfs
131/// @brief **Virtual file Server definition values** 53/// @brief **Virtual file Server definition values**\n
54/// All to VFS system functions associated data structures.
55///
132//------------------------------------------------------------------------------ 56//------------------------------------------------------------------------------
133 57
134//============================================================================== 58//==============================================================================
59/// @defgroup cpp_kodi_vfs_Directory 1. Directory functions
60/// @ingroup cpp_kodi_vfs
61/// @brief **Globally available directories related functions**\n
62/// Used to perform typical operations with it.
135/// 63///
136/// @ingroup cpp_kodi_vfs_Defs 64//------------------------------------------------------------------------------
137/// Flags to define way how file becomes opened with kodi::vfs::CFile::OpenFile() 65
66//==============================================================================
67/// @defgroup cpp_kodi_vfs_File 2. File functions
68/// @ingroup cpp_kodi_vfs
69/// @brief **Globally available file related functions**\n
70/// Used to perform typical operations with it.
138/// 71///
139/// The values can be used together, e.g. <b>`file.Open("myfile", READ_TRUNCATED | READ_CHUNKED);`</b> 72//------------------------------------------------------------------------------
73
74//==============================================================================
75/// @defgroup cpp_kodi_vfs_General 3. General functions
76/// @ingroup cpp_kodi_vfs
77/// @brief **Other globally available functions**\n
78/// Used to perform typical operations with it.
140/// 79///
141typedef enum OpenFileFlags 80//------------------------------------------------------------------------------
81
82//}}}
83
84//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
85// "C++" related filesystem definitions
86//{{{
87
88//==============================================================================
89/// @defgroup cpp_kodi_vfs_Defs_FileStatus class FileStatus
90/// @ingroup cpp_kodi_vfs_Defs
91/// @brief **File information status**\n
92/// Used on kodi::vfs::StatFile() to get detailed information about a file.
93///
94//@{
95class ATTRIBUTE_HIDDEN FileStatus : public kodi::addon::CStructHdl<FileStatus, STAT_STRUCTURE>
142{ 96{
143 /// indicate that caller can handle truncated reads, where function returns 97public:
144 /// before entire buffer has been filled 98 /*! \cond PRIVATE */
145 READ_TRUNCATED = 0x01, 99 FileStatus() { memset(m_cStructure, 0, sizeof(STAT_STRUCTURE)); }
100 FileStatus(const FileStatus& channel) : CStructHdl(channel) {}
101 FileStatus(const STAT_STRUCTURE* channel) : CStructHdl(channel) {}
102 FileStatus(STAT_STRUCTURE* channel) : CStructHdl(channel) {}
103 /*! \endcond */
104
105 /// @defgroup cpp_kodi_vfs_Defs_FileStatus_Help *Value Help*
106 /// @ingroup cpp_kodi_vfs_Defs_FileStatus
107 /// ----------------------------------------------------------------------------
108 ///
109 /// <b>The following table contains values that can be set with @ref cpp_kodi_vfs_Defs_FileStatus :</b>
110 /// | Name | Type | Set call | Get call
111 /// |------|------|----------|----------
112 /// | **ID of device containing file** | `uint32_t` | @ref FileStatus::SetDeviceId "SetDeviceId" | @ref FileStatus::GetDeviceId "GetDeviceId"
113 /// | **Total size, in bytes** | `uint64_t` | @ref FileStatus::SetSize "SetSize" | @ref FileStatus::GetSize "GetSize"
114 /// | **Time of last access** | `time_t` | @ref FileStatus::SetAccessTime "SetAccessTime" | @ref FileStatus::GetAccessTime "GetAccessTime"
115 /// | **Time of last modification** | `time_t` | @ref FileStatus::SetModificationTime "SetModificationTime" | @ref FileStatus::GetModificationTime "GetModificationTime"
116 /// | **Time of last status change** | `time_t` | @ref FileStatus::SetStatusTime "SetStatusTime" | @ref FileStatus::GetStatusTime "GetStatusTime"
117 /// | **Stat url is a directory** | `bool` | @ref FileStatus::SetIsDirectory "SetIsDirectory" | @ref FileStatus::GetIsDirectory "GetIsDirectory"
118 /// | **Stat url as a symbolic link** | `bool` | @ref FileStatus::SetIsSymLink "SetIsSymLink" | @ref FileStatus::GetIsSymLink "GetIsSymLink"
119 ///
120
121 /// @addtogroup cpp_kodi_vfs_Defs_FileStatus
122 /// @copydetails cpp_kodi_vfs_Defs_FileStatus_Help
123 //@{
146 124
147 /// indicate that that caller support read in the minimum defined chunk size, 125 /// @brief Set ID of device containing file.
148 /// this disables internal cache then 126 void SetDeviceId(uint32_t deviceId) { m_cStructure->deviceId = deviceId; }
149 READ_CHUNKED = 0x02,
150 127
151 /// use cache to access this file 128 /// @brief Get ID of device containing file.
152 READ_CACHED = 0x04, 129 uint32_t GetDeviceId() const { return m_cStructure->deviceId; }
153 130
154 /// open without caching. regardless to file type 131 /// @brief Set total size, in bytes.
155 READ_NO_CACHE = 0x08, 132 void SetSize(uint64_t size) { m_cStructure->size = size; }
133
134 /// @brief Get total size, in bytes.
135 uint64_t GetSize() const { return m_cStructure->size; }
136
137 /// @brief Set time of last access.
138 void SetAccessTime(time_t accessTime) { m_cStructure->accessTime = accessTime; }
139
140 /// @brief Get time of last access.
141 time_t GetAccessTime() const { return m_cStructure->accessTime; }
142
143 /// @brief Set time of last modification.
144 void SetModificationTime(time_t modificationTime)
145 {
146 m_cStructure->modificationTime = modificationTime;
147 }
156 148
157 /// calcuate bitrate for file while reading 149 /// @brief Get time of last modification.
158 READ_BITRATE = 0x10, 150 time_t GetModificationTime() const { return m_cStructure->modificationTime; }
159 151
160 /// indicate to the caller we will seek between multiple streams in the file 152 /// @brief Set time of last status change.
161 /// frequently 153 void SetStatusTime(time_t statusTime) { m_cStructure->statusTime = statusTime; }
162 READ_MULTI_STREAM = 0x20,
163 154
164 /// indicate to the caller file is audio and/or video (and e.g. may grow) 155 /// @brief Get time of last status change.
165 READ_AUDIO_VIDEO = 0x40, 156 time_t GetStatusTime() const { return m_cStructure->statusTime; }
166 157
167 /// indicate that caller will do write operations before reading 158 /// @brief Set the stat url is a directory.
168 READ_AFTER_WRITE = 0x80, 159 void SetIsDirectory(bool isDirectory) { m_cStructure->isDirectory = isDirectory; }
169 160
170 /// indicate that caller want to reopen a file if its already open 161 /// @brief The stat url is a directory if returns true.
171 READ_REOPEN = 0x100 162 bool GetIsDirectory() const { return m_cStructure->isDirectory; }
172} OpenFileFlags; 163
164 /// @brief Set stat url as a symbolic link.
165 void SetIsSymLink(bool isSymLink) { m_cStructure->isSymLink = isSymLink; }
166
167 /// @brief Get stat url is a symbolic link.
168 bool GetIsSymLink() const { return m_cStructure->isSymLink; }
169
170 //@}
171};
172//@}
173//------------------------------------------------------------------------------ 173//------------------------------------------------------------------------------
174 174
175//============================================================================== 175//==============================================================================
176/// \ingroup cpp_kodi_vfs_Defs 176/// @defgroup cpp_kodi_vfs_Defs_CacheStatus class CacheStatus
177/// @brief CURL message types 177/// @ingroup cpp_kodi_vfs_Defs
178/// 178/// @brief **Cache information status**\n
179/// Used on kodi::vfs::CFile::CURLAddOption() 179/// Used on kodi::vfs::CFile::IoControlGetCacheStatus() to get running cache
180/// status of proccessed stream.
180/// 181///
181typedef enum CURLOptiontype 182//@{
183class ATTRIBUTE_HIDDEN CacheStatus
184 : public kodi::addon::CStructHdl<CacheStatus, VFS_CACHE_STATUS_DATA>
182{ 185{
183 /// Set a general option 186public:
184 ADDON_CURL_OPTION_OPTION, 187 /*! \cond PRIVATE */
185 188 CacheStatus() { memset(m_cStructure, 0, sizeof(VFS_CACHE_STATUS_DATA)); }
186 /// Set a protocol option 189 CacheStatus(const CacheStatus& channel) : CStructHdl(channel) {}
187 /// 190 CacheStatus(const VFS_CACHE_STATUS_DATA* channel) : CStructHdl(channel) {}
188 /// The following names for *ADDON_CURL_OPTION_PROTOCOL* are possible: 191 CacheStatus(VFS_CACHE_STATUS_DATA* channel) : CStructHdl(channel) {}
189 /// 192 /*! \endcond */
190 /// | Option name | Description 193
191 /// |---------------------------:|:---------------------------------------------------------- 194 /// @defgroup cpp_kodi_vfs_Defs_CacheStatus_Help *Value Help*
192 /// | accept-charset | Set the "accept-charset" header 195 /// @ingroup cpp_kodi_vfs_Defs_CacheStatus
193 /// | acceptencoding or encoding | Set the "accept-encoding" header 196 /// ----------------------------------------------------------------------------
194 /// | active-remote | Set the "active-remote" header 197 ///
195 /// | auth | Set the authentication method. Possible values: any, anysafe, digest, ntlm 198 /// <b>The following table contains values that can be set with @ref cpp_kodi_vfs_Defs_CacheStatus :</b>
196 /// | connection-timeout | Set the connection timeout in seconds 199 /// | Name | Type | Set call | Get call
197 /// | cookie | Set the "cookie" header 200 /// |------|------|----------|----------
198 /// | customrequest | Set a custom HTTP request like DELETE 201 /// | **Number of bytes cached** | `uint64_t` | @ref CacheStatus::SetForward "SetForward" | @ref CacheStatus::GetForward "GetForward"
199 /// | noshout | Set to true if kodi detects a stream as shoutcast by mistake. 202 /// | **Maximum number of bytes per second** | `unsigned int` | @ref CacheStatus::SetMaxRate "SetMaxRate" | @ref CacheStatus::GetMaxRate "GetMaxRate"
200 /// | postdata | Set the post body (value needs to be base64 encoded). (Implicitly sets the request to POST) 203 /// | **Average read rate from source file** | `unsigned int` | @ref CacheStatus::SetCurrentRate "SetCurrentRate" | @ref CacheStatus::GetCurrentRate "GetCurrentRate"
201 /// | referer | Set the "referer" header 204 /// | **Cache low speed condition detected** | `bool` | @ref CacheStatus::SetLowspeed "SetLowspeed" | @ref CacheStatus::GetLowspeed "GetLowspeed"
202 /// | user-agent | Set the "user-agent" header 205 ///
203 /// | seekable | Set the stream seekable. 1: enable, 0: disable 206
204 /// | sslcipherlist | Set list of accepted SSL ciphers. 207 /// @addtogroup cpp_kodi_vfs_Defs_CacheStatus
205 /// 208 /// @copydetails cpp_kodi_vfs_Defs_CacheStatus_Help
206 ADDON_CURL_OPTION_PROTOCOL, 209 //@{
207 210
208 /// Set User and password 211 /// @brief Set number of bytes cached forward of current position.
209 ADDON_CURL_OPTION_CREDENTIALS, 212 void SetForward(uint64_t forward) { m_cStructure->forward = forward; }
210 213
211 /// Add a Header 214 /// @brief Get number of bytes cached forward of current position.
212 ADDON_CURL_OPTION_HEADER 215 uint64_t GetForward() { return m_cStructure->forward; }
213} CURLOptiontype; 216
217 /// @brief Set maximum number of bytes per second cache is allowed to fill.
218 void SetMaxRate(unsigned int maxrate) { m_cStructure->maxrate = maxrate; }
219
220 /// @brief Set maximum number of bytes per second cache is allowed to fill.
221 unsigned int GetMaxRate() { return m_cStructure->maxrate; }
222
223 /// @brief Set average read rate from source file since last position change.
224 void SetCurrentRate(unsigned int currate) { m_cStructure->currate = currate; }
225
226 /// @brief Get average read rate from source file since last position change.
227 unsigned int GetCurrentRate() { return m_cStructure->currate; }
228
229 /// @brief Set cache low speed condition detected.
230 void SetLowspeed(bool lowspeed) { m_cStructure->lowspeed = lowspeed; }
231
232 /// @brief Get cache low speed condition detected.
233 bool GetLowspeed() { return m_cStructure->lowspeed; }
234
235 //@}
236};
237//@}
214//------------------------------------------------------------------------------ 238//------------------------------------------------------------------------------
215 239
216//============================================================================== 240//==============================================================================
217/// \ingroup cpp_kodi_vfs_Defs 241/// @defgroup cpp_kodi_vfs_Defs_HttpHeader class HttpHeader
218/// @brief CURL message types 242/// @ingroup cpp_kodi_vfs_Defs
243/// @brief **HTTP header information**\n
244/// The class used to access HTTP header information and get his information.
219/// 245///
220/// Used on kodi::vfs::CFile::GetPropertyValue() and kodi::vfs::CFile::GetPropertyValues() 246/// Used on @ref kodi::vfs::GetHttpHeader().
221/// 247///
222typedef enum FilePropertyTypes 248/// ----------------------------------------------------------------------------
223{
224 /// Get protocol response line
225 ADDON_FILE_PROPERTY_RESPONSE_PROTOCOL,
226 /// Get a response header
227 ADDON_FILE_PROPERTY_RESPONSE_HEADER,
228 /// Get file content type
229 ADDON_FILE_PROPERTY_CONTENT_TYPE,
230 /// Get file content charset
231 ADDON_FILE_PROPERTY_CONTENT_CHARSET,
232 /// Get file mime type
233 ADDON_FILE_PROPERTY_MIME_TYPE,
234 /// Get file effective URL (last one if redirected)
235 ADDON_FILE_PROPERTY_EFFECTIVE_URL
236} FilePropertyTypes;
237//------------------------------------------------------------------------------
238
239//============================================================================
240///
241/// \ingroup cpp_kodi_vfs_Defs
242/// @brief File information status
243/// 249///
244/// Used on kodi::vfs::StatFile(), all of these calls return a this stat 250/// @copydetails cpp_kodi_vfs_Defs_HttpHeader_Help
245/// structure, which contains the following fields:
246/// 251///
247struct STAT_STRUCTURE 252///@{
253class ATTRIBUTE_HIDDEN HttpHeader
248{ 254{
249 /// ID of device containing file 255public:
250 uint32_t deviceId; 256 //==========================================================================
251 /// Total size, in bytes 257 /// @brief Http header parser class constructor.
252 uint64_t size; 258 ///
253#ifdef TARGET_WINDOWS 259 HttpHeader()
254 /// Time of last access 260 {
255 __time64_t accessTime; 261 using namespace ::kodi::addon;
256 /// Time of last modification
257 __time64_t modificationTime;
258 /// Time of last status change
259 __time64_t statusTime;
260#else
261 /// Time of last access
262 timespec accessTime;
263 /// Time of last modification
264 timespec modificationTime;
265 /// Time of last status change
266 timespec statusTime;
267#endif
268 /// The stat url is a directory
269 bool isDirectory;
270 /// The stat url is a symbolic link
271 bool isSymLink;
272};
273//------------------------------------------------------------------------------
274 262
275namespace kodi 263 CAddonBase::m_interface->toKodi->kodi_filesystem->http_header_create(
276{ 264 CAddonBase::m_interface->toKodi->kodiBase, &m_handle);
277namespace vfs 265 }
278{ 266 //--------------------------------------------------------------------------
279 267
280 //============================================================================ 268 //==========================================================================
269 /// @brief Class destructor.
281 /// 270 ///
282 /// \defgroup cpp_kodi_vfs_CDirEntry class CDirEntry 271 ~HttpHeader()
283 /// \ingroup cpp_kodi_vfs 272 {
273 using namespace ::kodi::addon;
274
275 CAddonBase::m_interface->toKodi->kodi_filesystem->http_header_free(
276 CAddonBase::m_interface->toKodi->kodiBase, &m_handle);
277 }
278 //--------------------------------------------------------------------------
279
280 /// @defgroup cpp_kodi_vfs_Defs_HttpHeader_Help *Value Help*
281 /// @ingroup cpp_kodi_vfs_Defs_HttpHeader
284 /// 282 ///
285 /// @brief **Virtual file server directory entry** 283 /// <b>The following table contains values that can be get with @ref cpp_kodi_vfs_Defs_HttpHeader :</b>
284 /// | Description | Type | Get call
285 /// |-------------|------|------------
286 /// | **Get the value associated with this parameter of these HTTP headers** | `std::string` | @ref HttpHeader::GetValue "GetValue"
287 /// | **Get the values as list associated with this parameter of these HTTP headers** | `std::vector<std::string>` | @ref HttpHeader::GetValues "GetValues"
288 /// | **Get the full header string associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetHeader "GetHeader"
289 /// | **Get the mime type associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetMimeType "GetMimeType"
290 /// | **Get the charset associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetCharset "GetCharset"
291 /// | **The protocol line associated with these HTTP headers** | `std::string` | @ref HttpHeader::GetProtoLine "GetProtoLine"
286 /// 292 ///
287 /// This class is used as an entry for files and folders in 293
288 /// kodi::vfs::GetDirectory(). 294 /// @addtogroup cpp_kodi_vfs_Defs_HttpHeader
295 ///@{
296
297 //==========================================================================
298 /// @brief Get the value associated with this parameter of these HTTP
299 /// headers.
289 /// 300 ///
301 /// @param[in] param The name of the parameter a value is required for
302 /// @return The value found
290 /// 303 ///
291 /// ------------------------------------------------------------------------ 304 std::string GetValue(const std::string& param) const
305 {
306 using namespace ::kodi::addon;
307
308 if (!m_handle.handle)
309 return "";
310
311 std::string protoLine;
312 char* string = m_handle.get_value(CAddonBase::m_interface->toKodi->kodiBase, m_handle.handle,
313 param.c_str());
314 if (string != nullptr)
315 {
316 protoLine = string;
317 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
318 string);
319 }
320 return protoLine;
321 }
322 //--------------------------------------------------------------------------
323
324 //==========================================================================
325 /// @brief Get the values as list associated with this parameter of these
326 /// HTTP headers.
292 /// 327 ///
293 /// **Example:** 328 /// @param[in] param The name of the parameter values are required for
294 /// ~~~~~~~~~~~~~{.cpp} 329 /// @return The values found
295 /// #include <kodi/Filesystem.h>
296 /// 330 ///
297 /// ... 331 std::vector<std::string> GetValues(const std::string& param) const
332 {
333 using namespace kodi::addon;
334
335 if (!m_handle.handle)
336 return std::vector<std::string>();
337
338 int numValues = 0;
339 char** res(m_handle.get_values(CAddonBase::m_interface->toKodi->kodiBase, m_handle.handle,
340 param.c_str(), &numValues));
341 if (res)
342 {
343 std::vector<std::string> vecReturn;
344 for (int i = 0; i < numValues; ++i)
345 {
346 vecReturn.emplace_back(res[i]);
347 }
348 CAddonBase::m_interface->toKodi->free_string_array(CAddonBase::m_interface->toKodi->kodiBase,
349 res, numValues);
350 return vecReturn;
351 }
352 return std::vector<std::string>();
353 }
354 //--------------------------------------------------------------------------
355
356 //==========================================================================
357 /// @brief Get the full header string associated with these HTTP headers.
298 /// 358 ///
299 /// std::vector<kodi::vfs::CDirEntry> items; 359 /// @return The header as a string
300 /// kodi::vfs::GetDirectory("special://temp", "", items);
301 /// 360 ///
302 /// fprintf(stderr, "Directory have %lu entries\n", items.size()); 361 std::string GetHeader() const
303 /// for (unsigned long i = 0; i < items.size(); i++) 362 {
304 /// { 363 using namespace ::kodi::addon;
305 /// char buff[20]; 364
306 /// time_t now = items[i].DateTime(); 365 if (!m_handle.handle)
307 /// strftime(buff, 20, "%Y-%m-%d %H:%M:%S", gmtime(&now)); 366 return "";
308 /// fprintf(stderr, " - %04lu -- Folder: %s -- Name: %s -- Path: %s -- Time: %s\n", 367
309 /// i+1, 368 std::string header;
310 /// items[i].IsFolder() ? "yes" : "no ", 369 char* string = m_handle.get_header(CAddonBase::m_interface->toKodi->kodiBase, m_handle.handle);
311 /// items[i].Label().c_str(), 370 if (string != nullptr)
312 /// items[i].Path().c_str(), 371 {
313 /// buff); 372 header = string;
314 /// } 373 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
315 /// ~~~~~~~~~~~~~ 374 string);
375 }
376 return header;
377 }
378 //--------------------------------------------------------------------------
379
380 //==========================================================================
381 /// @brief Get the mime type associated with these HTTP headers.
316 /// 382 ///
317 /// It has the header \ref Filesystem.h "#include <kodi/Filesystem.h>" be included 383 /// @return The mime type
318 /// to enjoy it.
319 /// 384 ///
320 //@{ 385 std::string GetMimeType() const
321 class CDirEntry 386 {
387 using namespace ::kodi::addon;
388
389 if (!m_handle.handle)
390 return "";
391
392 std::string protoLine;
393 char* string =
394 m_handle.get_mime_type(CAddonBase::m_interface->toKodi->kodiBase, m_handle.handle);
395 if (string != nullptr)
396 {
397 protoLine = string;
398 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
399 string);
400 }
401 return protoLine;
402 }
403 //--------------------------------------------------------------------------
404
405 //==========================================================================
406 /// @brief Get the charset associated with these HTTP headers.
407 ///
408 /// @return The charset
409 ///
410 std::string GetCharset() const
411 {
412 using namespace ::kodi::addon;
413
414 if (!m_handle.handle)
415 return "";
416
417 std::string protoLine;
418 char* string = m_handle.get_charset(CAddonBase::m_interface->toKodi->kodiBase, m_handle.handle);
419 if (string != nullptr)
420 {
421 protoLine = string;
422 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
423 string);
424 }
425 return protoLine;
426 }
427 //--------------------------------------------------------------------------
428
429 //==========================================================================
430 /// @brief The protocol line associated with these HTTP headers.
431 ///
432 /// @return The protocol line
433 ///
434 std::string GetProtoLine() const
322 { 435 {
323 public: 436 using namespace ::kodi::addon;
324 //============================================================================ 437
325 /// 438 if (!m_handle.handle)
326 /// @ingroup cpp_kodi_vfs_CDirEntry 439 return "";
327 /// @brief Constructor for VFS directory entry 440
328 /// 441 std::string protoLine;
329 /// @param[in] label [opt] Name to use for entry 442 char* string =
330 /// @param[in] path [opt] Used path of the entry 443 m_handle.get_proto_line(CAddonBase::m_interface->toKodi->kodiBase, m_handle.handle);
331 /// @param[in] folder [opt] If set entry used as folder 444 if (string != nullptr)
332 /// @param[in] size [opt] If used as file, his size defined there
333 ///
334 CDirEntry(const std::string& label = "",
335 const std::string& path = "",
336 bool folder = false,
337 int64_t size = -1) :
338 m_label(label),
339 m_path(path),
340 m_folder(folder),
341 m_size(size)
342 { 445 {
446 protoLine = string;
447 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
448 string);
343 } 449 }
344 //---------------------------------------------------------------------------- 450 return protoLine;
345 451 }
346 //============================================================================ 452 //--------------------------------------------------------------------------
347 // @note Not for addon development itself needed, thats why below is 453
348 // disabled for doxygen! 454 ///@}
349 // 455
350 // @ingroup cpp_kodi_vfs_CDirEntry 456 KODI_HTTP_HEADER m_handle;
351 // @brief Constructor to create own copy 457};
352 // 458///@}
353 // @param[in] dirEntry pointer to own class type 459//----------------------------------------------------------------------------
354 // 460
355 explicit CDirEntry(const VFSDirEntry& dirEntry) : 461//==============================================================================
356 m_label(dirEntry.label ? dirEntry.label : ""), 462/// @defgroup cpp_kodi_vfs_CDirEntry class CDirEntry
463/// @ingroup cpp_kodi_vfs_Defs
464///
465/// @brief **Virtual file server directory entry**\n
466/// This class is used as an entry for files and folders in
467/// kodi::vfs::GetDirectory().
468///
469///
470/// ------------------------------------------------------------------------
471///
472/// **Example:**
473/// ~~~~~~~~~~~~~{.cpp}
474/// #include <kodi/Filesystem.h>
475///
476/// ...
477///
478/// std::vector<kodi::vfs::CDirEntry> items;
479/// kodi::vfs::GetDirectory("special://temp", "", items);
480///
481/// fprintf(stderr, "Directory have %lu entries\n", items.size());
482/// for (unsigned long i = 0; i < items.size(); i++)
483/// {
484/// char buff[20];
485/// time_t now = items[i].DateTime();
486/// strftime(buff, 20, "%Y-%m-%d %H:%M:%S", gmtime(&now));
487/// fprintf(stderr, " - %04lu -- Folder: %s -- Name: %s -- Path: %s -- Time: %s\n",
488/// i+1,
489/// items[i].IsFolder() ? "yes" : "no ",
490/// items[i].Label().c_str(),
491/// items[i].Path().c_str(),
492/// buff);
493/// }
494/// ~~~~~~~~~~~~~
495///
496/// It has the header @ref Filesystem.h "#include <kodi/Filesystem.h>" be included
497/// to enjoy it.
498///
499//@{
500class ATTRIBUTE_HIDDEN CDirEntry
501{
502public:
503 //============================================================================
504 /// @ingroup cpp_kodi_vfs_CDirEntry
505 /// @brief Constructor for VFS directory entry
506 ///
507 /// @param[in] label [opt] Name to use for entry
508 /// @param[in] path [opt] Used path of the entry
509 /// @param[in] folder [opt] If set entry used as folder
510 /// @param[in] size [opt] If used as file, his size defined there
511 /// @param[in] dateTime [opt] Date time of the entry
512 ///
513 CDirEntry(const std::string& label = "",
514 const std::string& path = "",
515 bool folder = false,
516 int64_t size = -1,
517 time_t dateTime = 0)
518 : m_label(label), m_path(path), m_folder(folder), m_size(size), m_dateTime(dateTime)
519 {
520 }
521 //----------------------------------------------------------------------------
522
523 //============================================================================
524 // @note Not for addon development itself needed, thats why below is
525 // disabled for doxygen!
526 //
527 // @ingroup cpp_kodi_vfs_CDirEntry
528 // @brief Constructor to create own copy
529 //
530 // @param[in] dirEntry pointer to own class type
531 //
532 explicit CDirEntry(const VFSDirEntry& dirEntry)
533 : m_label(dirEntry.label ? dirEntry.label : ""),
357 m_path(dirEntry.path ? dirEntry.path : ""), 534 m_path(dirEntry.path ? dirEntry.path : ""),
358 m_folder(dirEntry.folder), 535 m_folder(dirEntry.folder),
359 m_size(dirEntry.size), 536 m_size(dirEntry.size),
360 m_dateTime(dirEntry.date_time) 537 m_dateTime(dirEntry.date_time)
361 { 538 {
362 } 539 }
363 //----------------------------------------------------------------------------
364
365 //============================================================================
366 ///
367 /// @ingroup cpp_kodi_vfs_CDirEntry
368 /// @brief Get the directory entry name
369 ///
370 /// @return Name of the entry
371 ///
372 const std::string& Label(void) const { return m_label; }
373 //----------------------------------------------------------------------------
374
375 //============================================================================
376 ///
377 /// @ingroup cpp_kodi_vfs_CDirEntry
378 /// @brief Get the optional title of entry
379 ///
380 /// @return Title of the entry, if exists
381 ///
382 const std::string& Title(void) const { return m_title; }
383 //----------------------------------------------------------------------------
384
385 //============================================================================
386 ///
387 /// @ingroup cpp_kodi_vfs_CDirEntry
388 /// @brief Get the path of the entry
389 ///
390 /// @return File system path of the entry
391 ///
392 const std::string& Path(void) const { return m_path; }
393 //----------------------------------------------------------------------------
394
395 //============================================================================
396 ///
397 /// @ingroup cpp_kodi_vfs_CDirEntry
398 /// @brief Used to check entry is folder
399 ///
400 /// @return true if entry is a folder
401 ///
402 bool IsFolder(void) const { return m_folder; }
403 //----------------------------------------------------------------------------
404
405 //============================================================================
406 ///
407 /// @ingroup cpp_kodi_vfs_CDirEntry
408 /// @brief If file, the size of the file
409 ///
410 /// @return Defined file size
411 ///
412 int64_t Size(void) const { return m_size; }
413 //----------------------------------------------------------------------------
414
415 //============================================================================
416 ///
417 /// @ingroup cpp_kodi_vfs_CDirEntry
418 /// @brief Get file time and date for a new entry
419 ///
420 /// @return The with time_t defined date and time of file
421 ///
422 time_t DateTime() { return m_dateTime; }
423 //----------------------------------------------------------------------------
424
425 //============================================================================
426 ///
427 /// @ingroup cpp_kodi_vfs_CDirEntry
428 /// @brief Set the label name
429 ///
430 /// @param[in] label name of entry
431 ///
432 void SetLabel(const std::string& label) { m_label = label; }
433 //----------------------------------------------------------------------------
434
435 //============================================================================
436 ///
437 /// @ingroup cpp_kodi_vfs_CDirEntry
438 /// @brief Set the title name
439 ///
440 /// @param[in] title title name of entry
441 ///
442 void SetTitle(const std::string& title) { m_title = title; }
443 //----------------------------------------------------------------------------
444
445 //============================================================================
446 ///
447 /// @ingroup cpp_kodi_vfs_CDirEntry
448 /// @brief Set the path of the entry
449 ///
450 /// @param[in] path path of entry
451 ///
452 void SetPath(const std::string& path) { m_path = path; }
453 //----------------------------------------------------------------------------
454
455 //============================================================================
456 ///
457 /// @ingroup cpp_kodi_vfs_CDirEntry
458 /// @brief Set the entry defined as folder
459 ///
460 /// @param[in] folder If true becomes entry defined as folder
461 ///
462 void SetFolder(bool folder) { m_folder = folder; }
463 //----------------------------------------------------------------------------
464
465 //============================================================================
466 ///
467 /// @ingroup cpp_kodi_vfs_CDirEntry
468 /// @brief Set a file size for a new entry
469 ///
470 /// @param[in] size Size to set for dir entry
471 ///
472 void SetSize(int64_t size) { m_size = size; }
473 //----------------------------------------------------------------------------
474
475 //============================================================================
476 ///
477 /// @ingroup cpp_kodi_vfs_CDirEntry
478 /// @brief Set file time and date for a new entry
479 ///
480 /// @param[in] dateTime The with time_t defined date and time of file
481 ///
482 void SetDateTime(time_t dateTime) { m_dateTime = dateTime; }
483 //----------------------------------------------------------------------------
484
485 //============================================================================
486 ///
487 /// @ingroup cpp_kodi_vfs_CDirEntry
488 /// @brief Add a by string defined property entry to directory entry
489 ///
490 /// @note A property can be used to add some special information about a file
491 /// or directory entry, this can be used on other places to do the right work
492 /// of them.
493 ///
494 /// @param[in] id Identification name of property
495 /// @param[in] value The property value to add by given id
496 ///
497 void AddProperty(const std::string& id, const std::string& value) { m_properties[id] = value; }
498 //----------------------------------------------------------------------------
499
500 //============================================================================
501 ///
502 /// @ingroup cpp_kodi_vfs_CDirEntry
503 /// @brief Clear all present properties
504 ///
505 void ClearProperties() { m_properties.clear(); }
506 //----------------------------------------------------------------------------
507
508 //============================================================================
509 ///
510 /// @ingroup cpp_kodi_vfs_CDirEntry
511 /// @brief Get the present properties list on directory entry
512 ///
513 /// @return map with all present properties
514 ///
515 const std::map<std::string, std::string>& GetProperties() const { return m_properties; }
516 //----------------------------------------------------------------------------
517
518 private:
519 std::string m_label;
520 std::string m_title;
521 std::string m_path;
522 std::map<std::string, std::string> m_properties;
523 bool m_folder;
524 int64_t m_size;
525 time_t m_dateTime;
526 };
527 //@}
528 //---------------------------------------------------------------------------- 540 //----------------------------------------------------------------------------
529 541
530 //============================================================================ 542 /// @defgroup cpp_kodi_vfs_CDirEntry_Help *Value Help*
543 /// @ingroup cpp_kodi_vfs_CDirEntry
544 /// --------------------------------------------------------------------------
531 /// 545 ///
532 /// @ingroup cpp_kodi_vfs 546 /// <b>The following table contains values that can be set with @ref cpp_kodi_vfs_CDirEntry :</b>
533 /// @brief Make a directory 547 /// | Name | Type | Set call | Get call | Clear call |
548 /// |------|------|----------|----------|------------|
549 /// | **Directory entry name** | `std::string` | @ref CDirEntry::SetLabel "SetLabel" | @ref CDirEntry::Label "Label" | |
550 /// | **Title of entry** | `std::string` | @ref CDirEntry::SetTitle "SetTitle" | @ref CDirEntry::Title "Title" | |
551 /// | **Path of the entry** | `std::string` | @ref CDirEntry::SetPath "SetPath" | @ref CDirEntry::Path "Path" | |
552 /// | **Entry is folder** | `bool` | @ref CDirEntry::SetFolder "SetFolder" | @ref CDirEntry::IsFolder "IsFolder" | |
553 /// | **The size of the file** | `int64_t` | @ref CDirEntry::SetSize "SetSize" | @ref CDirEntry::Size "Size" | |
554 /// | **File time and date** | `time_t` | @ref CDirEntry::SetDateTime "SetDateTime" | @ref CDirEntry::DateTime "DateTime" | |
555 /// | **Property entries** | `std::string, std::string` | @ref CDirEntry::AddProperty "AddProperty" | @ref CDirEntry::GetProperties "GetProperties" | @ref CDirEntry::ClearProperties "ClearProperties"
534 /// 556 ///
535 /// The kodi::vfs::CreateDirectory() function shall create a 557
536 /// new directory with name path. 558 /// @addtogroup cpp_kodi_vfs_CDirEntry
537 /// 559 /// @copydetails cpp_kodi_vfs_CDirEntry_Help
538 /// The newly created directory shall be an empty directory. 560 //@{
539 /// 561
540 /// @param[in] path Path to the directory. 562 //============================================================================
541 /// @return Upon successful completion, CreateDirectory() shall return true. 563 /// @brief Get the directory entry name.
542 /// Otherwise false shall be returned, no directory shall be created.
543 /// 564 ///
565 /// @return Name of the entry
544 /// 566 ///
545 /// ------------------------------------------------------------------------- 567 const std::string& Label(void) const { return m_label; }
568 //----------------------------------------------------------------------------
569
570 //============================================================================
571 /// @brief Get the optional title of entry.
546 /// 572 ///
547 /// **Example:** 573 /// @return Title of the entry, if exists
548 /// ~~~~~~~~~~~~~{.cpp}
549 /// #include <kodi/Filesystem.h>
550 /// ...
551 /// std::string directory = "C:\\my_dir";
552 /// bool ret = kodi::vfs::CreateDirectory(directory);
553 /// fprintf(stderr, "Directory '%s' successfull created: %s\n", directory.c_str(), ret ? "yes" : "no");
554 /// ...
555 /// ~~~~~~~~~~~~~
556 /// 574 ///
557 inline bool CreateDirectory(const std::string& path) 575 const std::string& Title(void) const { return m_title; }
558 {
559 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->create_directory(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
560 }
561 //---------------------------------------------------------------------------- 576 //----------------------------------------------------------------------------
562 577
563 //============================================================================ 578 //============================================================================
579 /// @brief Get the path of the entry.
564 /// 580 ///
565 /// @ingroup cpp_kodi_vfs 581 /// @return File system path of the entry
566 /// @brief Verifying the Existence of a Directory
567 /// 582 ///
568 /// The kodi::vfs::DirectoryExists() method determines whether 583 const std::string& Path(void) const { return m_path; }
569 /// a specified folder exists. 584 //----------------------------------------------------------------------------
570 /// 585
571 /// @param[in] path Path to the directory. 586 //============================================================================
572 /// @return True when it exists, false otherwise. 587 /// @brief Used to check entry is folder.
573 /// 588 ///
589 /// @return true if entry is a folder
574 /// 590 ///
575 /// ------------------------------------------------------------------------- 591 bool IsFolder(void) const { return m_folder; }
592 //----------------------------------------------------------------------------
593
594 //============================================================================
595 /// @brief If file, the size of the file.
576 /// 596 ///
577 /// **Example:** 597 /// @return Defined file size
578 /// ~~~~~~~~~~~~~{.cpp}
579 /// #include <kodi/Filesystem.h>
580 /// ...
581 /// std::string directory = "C:\\my_dir";
582 /// bool ret = kodi::vfs::DirectoryExists(directory);
583 /// fprintf(stderr, "Directory '%s' present: %s\n", directory.c_str(), ret ? "yes" : "no");
584 /// ...
585 /// ~~~~~~~~~~~~~
586 /// 598 ///
587 inline bool DirectoryExists(const std::string& path) 599 int64_t Size(void) const { return m_size; }
588 {
589 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->directory_exists(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
590 }
591 //---------------------------------------------------------------------------- 600 //----------------------------------------------------------------------------
592 601
593 //============================================================================ 602 //============================================================================
603 /// @brief Get file time and date for a new entry.
594 /// 604 ///
595 /// @ingroup cpp_kodi_vfs 605 /// @return The with time_t defined date and time of file
596 /// @brief Removes a directory.
597 /// 606 ///
598 /// The kodi::vfs::RemoveDirectory() function shall remove a 607 time_t DateTime() { return m_dateTime; }
599 /// directory whose name is given by path. 608 //----------------------------------------------------------------------------
600 /// 609
601 /// @param[in] path Path to the directory. 610 //============================================================================
602 /// @return Upon successful completion, the function RemoveDirectory() shall 611 /// @brief Set the label name.
603 /// return true. Otherwise, false shall be returned, and errno set
604 /// to indicate the error. If false is returned, the named directory
605 /// shall not be changed.
606 /// 612 ///
613 /// @param[in] label name of entry
607 /// 614 ///
608 /// ------------------------------------------------------------------------- 615 void SetLabel(const std::string& label) { m_label = label; }
616 //----------------------------------------------------------------------------
617
618 //============================================================================
619 /// @brief Set the title name.
609 /// 620 ///
610 /// **Example:** 621 /// @param[in] title title name of entry
611 /// ~~~~~~~~~~~~~{.cpp}
612 /// #include <kodi/Filesystem.h>
613 /// ...
614 /// bool ret = kodi::vfs::RemoveDirectory("C:\\my_dir");
615 /// ...
616 /// ~~~~~~~~~~~~~
617 /// 622 ///
618 inline bool RemoveDirectory(const std::string& path) 623 void SetTitle(const std::string& title) { m_title = title; }
619 {
620 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->remove_directory(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
621 }
622 //---------------------------------------------------------------------------- 624 //----------------------------------------------------------------------------
623 625
624 //============================================================================ 626 //============================================================================
627 /// @brief Set the path of the entry.
625 /// 628 ///
626 /// @ingroup cpp_kodi_vfs 629 /// @param[in] path path of entry
627 /// @brief Lists a directory.
628 /// 630 ///
629 /// Return the list of files and directories which have been found in the 631 void SetPath(const std::string& path) { m_path = path; }
630 /// specified directory and which respect the given constraint. 632 //----------------------------------------------------------------------------
631 /// 633
632 /// It can handle the normal OS dependent paths and also the special virtual 634 //============================================================================
633 /// filesystem from Kodi what starts with \b special://. 635 /// @brief Set the entry defined as folder.
634 /// 636 ///
635 /// @param[in] path The path in which the files and directories are located. 637 /// @param[in] folder If true becomes entry defined as folder
636 /// @param[in] mask Mask to filter out requested files, e.g. "*.avi|*.mpg" to
637 /// files with this ending.
638 /// @param[out] items The returned list directory entries.
639 /// @return True if listing was successful, false otherwise.
640 /// 638 ///
639 void SetFolder(bool folder) { m_folder = folder; }
640 //----------------------------------------------------------------------------
641
642 //============================================================================
643 /// @brief Set a file size for a new entry.
641 /// 644 ///
642 /// ------------------------------------------------------------------------- 645 /// @param[in] size Size to set for dir entry
643 /// 646 ///
644 /// **Example:** 647 void SetSize(int64_t size) { m_size = size; }
645 /// ~~~~~~~~~~~~~{.cpp} 648 //----------------------------------------------------------------------------
646 /// #include <kodi/Filesystem.h> 649
650 //============================================================================
651 /// @brief Set file time and date for a new entry.
647 /// 652 ///
648 /// std::vector<kodi::vfs::CDirEntry> items; 653 /// @param[in] dateTime The with time_t defined date and time of file
649 /// kodi::vfs::GetDirectory("special://temp", "", items);
650 /// 654 ///
651 /// fprintf(stderr, "Directory have %lu entries\n", items.size()); 655 void SetDateTime(time_t dateTime) { m_dateTime = dateTime; }
652 /// for (unsigned long i = 0; i < items.size(); i++)
653 /// {
654 /// fprintf(stderr, " - %04lu -- Folder: %s -- Name: %s -- Path: %s\n",
655 /// i+1,
656 /// items[i].IsFolder() ? "yes" : "no ",
657 /// items[i].Label().c_str(),
658 /// items[i].Path().c_str());
659 /// }
660 /// ~~~~~~~~~~~~~
661 inline bool GetDirectory(const std::string& path, const std::string& mask, std::vector<CDirEntry>& items)
662 {
663 VFSDirEntry* dir_list = nullptr;
664 unsigned int num_items = 0;
665 if (::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_directory(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, path.c_str(), mask.c_str(), &dir_list, &num_items))
666 {
667 if (dir_list)
668 {
669 for (unsigned int i = 0; i < num_items; ++i)
670 items.push_back(CDirEntry(dir_list[i]));
671
672 ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->free_directory(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, dir_list, num_items);
673 }
674
675 return true;
676 }
677 return false;
678 }
679 //---------------------------------------------------------------------------- 656 //----------------------------------------------------------------------------
680 657
681 //============================================================================ 658 //============================================================================
659 /// @brief Add a by string defined property entry to directory entry.
682 /// 660 ///
683 /// @ingroup cpp_kodi_vfs 661 /// @note A property can be used to add some special information about a file
684 /// @brief Retrieve MD5sum of a file 662 /// or directory entry, this can be used on other places to do the right work
663 /// of them.
685 /// 664 ///
686 /// @param[in] path path to the file to MD5sum 665 /// @param[in] id Identification name of property
687 /// @return md5 sum of the file 666 /// @param[in] value The property value to add by given id
688 /// 667 ///
668 void AddProperty(const std::string& id, const std::string& value) { m_properties[id] = value; }
669 //----------------------------------------------------------------------------
670
671 //============================================================================
672 /// @brief Clear all present properties.
689 /// 673 ///
690 /// ------------------------------------------------------------------------- 674 void ClearProperties() { m_properties.clear(); }
675 //----------------------------------------------------------------------------
676
677 //============================================================================
678 /// @brief Get the present properties list on directory entry.
691 /// 679 ///
692 /// **Example:** 680 /// @return map with all present properties
693 /// ~~~~~~~~~~~~~{.cpp}
694 /// #include <kodi/Filesystem.h>
695 /// #include <kodi/gui/DialogFileBrowser.h>
696 /// ...
697 /// std::string md5;
698 /// std::string filename;
699 /// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "*.avi|*.mpg|*.mp4",
700 /// "Test File selection to get MD5",
701 /// filename))
702 /// {
703 /// md5 = kodi::vfs::GetFileMD5(filename);
704 /// fprintf(stderr, "MD5 of file '%s' is %s\n", md5.c_str(), filename.c_str());
705 /// }
706 /// ~~~~~~~~~~~~~
707 /// 681 ///
708 inline std::string GetFileMD5(const std::string& path) 682 const std::map<std::string, std::string>& GetProperties() const { return m_properties; }
683 //----------------------------------------------------------------------------
684
685 //@}
686
687private:
688 std::string m_label;
689 std::string m_title;
690 std::string m_path;
691 std::map<std::string, std::string> m_properties;
692 bool m_folder;
693 int64_t m_size;
694 time_t m_dateTime;
695};
696//@}
697//------------------------------------------------------------------------------
698
699//}}}
700
701//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
702// "C++" Directory related functions
703//{{{
704
705//==============================================================================
706/// @ingroup cpp_kodi_vfs_Directory
707/// @brief Make a directory.
708///
709/// The kodi::vfs::CreateDirectory() function shall create a
710/// new directory with name path.
711///
712/// The newly created directory shall be an empty directory.
713///
714/// @param[in] path Path to the directory.
715/// @return Upon successful completion, CreateDirectory() shall return true.
716/// Otherwise false shall be returned, no directory shall be created.
717///
718///
719/// -------------------------------------------------------------------------
720///
721/// **Example:**
722/// ~~~~~~~~~~~~~{.cpp}
723/// #include <kodi/Filesystem.h>
724/// ...
725/// std::string directory = "C:\\my_dir";
726/// bool ret = kodi::vfs::CreateDirectory(directory);
727/// fprintf(stderr, "Directory '%s' successfull created: %s\n", directory.c_str(), ret ? "yes" : "no");
728/// ...
729/// ~~~~~~~~~~~~~
730///
731inline bool ATTRIBUTE_HIDDEN CreateDirectory(const std::string& path)
732{
733 using namespace kodi::addon;
734
735 return CAddonBase::m_interface->toKodi->kodi_filesystem->create_directory(
736 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
737}
738//------------------------------------------------------------------------------
739
740//==============================================================================
741/// @ingroup cpp_kodi_vfs_Directory
742/// @brief Verifying the Existence of a Directory.
743///
744/// The kodi::vfs::DirectoryExists() method determines whether
745/// a specified folder exists.
746///
747/// @param[in] path Path to the directory.
748/// @return True when it exists, false otherwise.
749///
750///
751/// -------------------------------------------------------------------------
752///
753/// **Example:**
754/// ~~~~~~~~~~~~~{.cpp}
755/// #include <kodi/Filesystem.h>
756/// ...
757/// std::string directory = "C:\\my_dir";
758/// bool ret = kodi::vfs::DirectoryExists(directory);
759/// fprintf(stderr, "Directory '%s' present: %s\n", directory.c_str(), ret ? "yes" : "no");
760/// ...
761/// ~~~~~~~~~~~~~
762///
763inline bool ATTRIBUTE_HIDDEN DirectoryExists(const std::string& path)
764{
765 using namespace kodi::addon;
766
767 return CAddonBase::m_interface->toKodi->kodi_filesystem->directory_exists(
768 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
769}
770//------------------------------------------------------------------------------
771
772//==============================================================================
773/// @ingroup cpp_kodi_vfs_Directory
774/// @brief Removes a directory.
775///
776/// The kodi::vfs::RemoveDirectory() function shall remove a
777/// directory whose name is given by path.
778///
779/// @param[in] path Path to the directory.
780/// @return Upon successful completion, the function RemoveDirectory() shall
781/// return true. Otherwise, false shall be returned, and errno set
782/// to indicate the error. If false is returned, the named directory
783/// shall not be changed.
784///
785///
786/// -------------------------------------------------------------------------
787///
788/// **Example:**
789/// ~~~~~~~~~~~~~{.cpp}
790/// #include <kodi/Filesystem.h>
791/// ...
792/// bool ret = kodi::vfs::RemoveDirectory("C:\\my_dir");
793/// ...
794/// ~~~~~~~~~~~~~
795///
796inline bool ATTRIBUTE_HIDDEN RemoveDirectory(const std::string& path)
797{
798 using namespace kodi::addon;
799
800 return CAddonBase::m_interface->toKodi->kodi_filesystem->remove_directory(
801 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
802}
803//------------------------------------------------------------------------------
804
805//==============================================================================
806/// @ingroup cpp_kodi_vfs_Directory
807/// @brief Lists a directory.
808///
809/// Return the list of files and directories which have been found in the
810/// specified directory and which respect the given constraint.
811///
812/// It can handle the normal OS dependent paths and also the special virtual
813/// filesystem from Kodi what starts with \b special://.
814///
815/// @param[in] path The path in which the files and directories are located.
816/// @param[in] mask Mask to filter out requested files, e.g. "*.avi|*.mpg" to
817/// files with this ending.
818/// @param[out] items The returned list directory entries.
819/// @return True if listing was successful, false otherwise.
820///
821///
822/// -------------------------------------------------------------------------
823///
824/// **Example:**
825/// ~~~~~~~~~~~~~{.cpp}
826/// #include <kodi/Filesystem.h>
827///
828/// std::vector<kodi::vfs::CDirEntry> items;
829/// kodi::vfs::GetDirectory("special://temp", "", items);
830///
831/// fprintf(stderr, "Directory have %lu entries\n", items.size());
832/// for (unsigned long i = 0; i < items.size(); i++)
833/// {
834/// fprintf(stderr, " - %04lu -- Folder: %s -- Name: %s -- Path: %s\n",
835/// i+1,
836/// items[i].IsFolder() ? "yes" : "no ",
837/// items[i].Label().c_str(),
838/// items[i].Path().c_str());
839/// }
840/// ~~~~~~~~~~~~~
841inline bool ATTRIBUTE_HIDDEN GetDirectory(const std::string& path,
842 const std::string& mask,
843 std::vector<kodi::vfs::CDirEntry>& items)
844{
845 using namespace kodi::addon;
846
847 VFSDirEntry* dir_list = nullptr;
848 unsigned int num_items = 0;
849 if (CAddonBase::m_interface->toKodi->kodi_filesystem->get_directory(
850 CAddonBase::m_interface->toKodi->kodiBase, path.c_str(), mask.c_str(), &dir_list,
851 &num_items))
709 { 852 {
710 std::string strReturn; 853 if (dir_list)
711 char* strMd5 = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_md5(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
712 if (strMd5 != nullptr)
713 { 854 {
714 if (std::strlen(strMd5)) 855 for (unsigned int i = 0; i < num_items; ++i)
715 strReturn = strMd5; 856 items.emplace_back(dir_list[i]);
716 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, strMd5); 857
858 CAddonBase::m_interface->toKodi->kodi_filesystem->free_directory(
859 CAddonBase::m_interface->toKodi->kodiBase, dir_list, num_items);
717 } 860 }
718 return strReturn; 861
862 return true;
719 } 863 }
864 return false;
865}
866//------------------------------------------------------------------------------
867
868//}}}
869
870//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
871// "C++" File related functions
872//{{{
873
874//==============================================================================
875/// @ingroup cpp_kodi_vfs_File
876/// @brief Check if a file exists.
877///
878/// @param[in] filename The filename to check.
879/// @param[in] usecache Check in file cache.
880/// @return true if the file exists false otherwise.
881///
882///
883/// -------------------------------------------------------------------------
884///
885/// **Example:**
886/// ~~~~~~~~~~~~~{.cpp}
887/// #include <kodi/Filesystem.h>
888/// ...
889/// bool exists = kodi::vfs::FileExists("special://temp/kodi.log");
890/// fprintf(stderr, "Log file should be always present, is it present? %s\n", exists ? "yes" : "no");
891/// ~~~~~~~~~~~~~
892///
893inline bool ATTRIBUTE_HIDDEN FileExists(const std::string& filename, bool usecache = false)
894{
895 using namespace kodi::addon;
896
897 return CAddonBase::m_interface->toKodi->kodi_filesystem->file_exists(
898 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), usecache);
899}
900//------------------------------------------------------------------------------
901
902//==============================================================================
903/// @ingroup cpp_kodi_vfs_File
904/// @brief Get file status.
905///
906/// These function return information about a file. Execute (search)
907/// permission is required on all of the directories in path that
908/// lead to the file.
909///
910/// The call return a stat structure, which contains the on
911/// @ref cpp_kodi_vfs_Defs_FileStatus defined values.
912///
913/// @warning Not all of the OS file systems implement all of the time fields.
914///
915/// @param[in] filename The filename to read the status from.
916/// @param[out] buffer The file status is written into this buffer.
917/// @return On success, trur is returned. On error, false is returned
918///
919///
920/// @copydetails cpp_kodi_vfs_Defs_FileStatus_Help
921///
922/// -------------------------------------------------------------------------
923///
924/// **Example:**
925/// ~~~~~~~~~~~~~{.cpp}
926/// #include <kodi/Filesystem.h>
927/// ...
928/// kodi::vfs::FileStatus statFile;
929/// int ret = kodi::vfs::StatFile("special://temp/kodi.log", statFile);
930/// fprintf(stderr, "deviceId (ID of device containing file) = %u\n"
931/// "size (total size, in bytes) = %lu\n"
932/// "accessTime (time of last access) = %lu\n"
933/// "modificationTime (time of last modification) = %lu\n"
934/// "statusTime (time of last status change) = %lu\n"
935/// "isDirectory (The stat url is a directory) = %s\n"
936/// "isSymLink (The stat url is a symbolic link) = %s\n"
937/// "Return value = %i\n",
938/// statFile.GetDeviceId(),
939/// statFile.GetSize(),
940/// statFile.GetAccessTime(),
941/// statFile.GetModificationTime(),
942/// statFile.GetStatusTime(),
943/// statFile.GetIsDirectory() ? "true" : "false",
944/// statFile.GetIsSymLink() ? "true" : "false",
945/// ret);
946/// ~~~~~~~~~~~~~
947///
948inline bool ATTRIBUTE_HIDDEN StatFile(const std::string& filename, kodi::vfs::FileStatus& buffer)
949{
950 using namespace kodi::addon;
951
952 return CAddonBase::m_interface->toKodi->kodi_filesystem->stat_file(
953 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), buffer);
954}
955//------------------------------------------------------------------------------
956
957//==============================================================================
958/// @ingroup cpp_kodi_vfs_File
959/// @brief Deletes a file.
960///
961/// @param[in] filename The filename to delete.
962/// @return The file was successfully deleted.
963///
964///
965/// -------------------------------------------------------------------------
966///
967/// **Example:**
968/// ~~~~~~~~~~~~~{.cpp}
969/// #include <kodi/Filesystem.h>
970/// #include <kodi/gui/DialogFileBrowser.h>
971/// #include <kodi/gui/DialogOK.h>
972/// ...
973/// std::string filename;
974/// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "",
975/// "Test File selection and delete of them!",
976/// filename))
977/// {
978/// bool successed = kodi::vfs::DeleteFile(filename);
979/// if (!successed)
980/// kodi::gui::DialogOK::ShowAndGetInput("Error", "Delete of File", filename, "failed!");
981/// else
982/// kodi::gui::DialogOK::ShowAndGetInput("Information", "Delete of File", filename, "successfull done.");
983/// }
984/// ~~~~~~~~~~~~~
985///
986inline bool ATTRIBUTE_HIDDEN DeleteFile(const std::string& filename)
987{
988 using namespace kodi::addon;
989
990 return CAddonBase::m_interface->toKodi->kodi_filesystem->delete_file(
991 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str());
992}
993//------------------------------------------------------------------------------
994
995//==============================================================================
996/// @ingroup cpp_kodi_vfs_File
997/// @brief Rename a file name.
998///
999/// @param[in] filename The filename to copy.
1000/// @param[in] newFileName The new filename
1001/// @return true if successfully renamed
1002///
1003///
1004inline bool ATTRIBUTE_HIDDEN RenameFile(const std::string& filename, const std::string& newFileName)
1005{
1006 using namespace kodi::addon;
1007
1008 return CAddonBase::m_interface->toKodi->kodi_filesystem->rename_file(
1009 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), newFileName.c_str());
1010}
1011//------------------------------------------------------------------------------
1012
1013//==============================================================================
1014/// @ingroup cpp_kodi_vfs_File
1015/// @brief Copy a file from source to destination.
1016///
1017/// @param[in] filename The filename to copy.
1018/// @param[in] destination The destination to copy file to
1019/// @return true if successfully copied
1020///
1021///
1022inline bool ATTRIBUTE_HIDDEN CopyFile(const std::string& filename, const std::string& destination)
1023{
1024 using namespace kodi::addon;
1025
1026 return CAddonBase::m_interface->toKodi->kodi_filesystem->copy_file(
1027 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), destination.c_str());
1028}
1029//------------------------------------------------------------------------------
1030
1031//}}}
1032
1033//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
1034// "C++" General filesystem functions
1035//{{{
1036
1037//==============================================================================
1038/// @ingroup cpp_kodi_vfs_General
1039/// @brief Retrieve MD5sum of a file.
1040///
1041/// @param[in] path Path to the file to MD5sum
1042/// @return MD5 sum of the file
1043///
1044///
1045/// -------------------------------------------------------------------------
1046///
1047/// **Example:**
1048/// ~~~~~~~~~~~~~{.cpp}
1049/// #include <kodi/Filesystem.h>
1050/// #include <kodi/gui/DialogFileBrowser.h>
1051/// ...
1052/// std::string md5;
1053/// std::string filename;
1054/// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "*.avi|*.mpg|*.mp4",
1055/// "Test File selection to get MD5",
1056/// filename))
1057/// {
1058/// md5 = kodi::vfs::GetFileMD5(filename);
1059/// fprintf(stderr, "MD5 of file '%s' is %s\n", md5.c_str(), filename.c_str());
1060/// }
1061/// ~~~~~~~~~~~~~
1062///
1063inline std::string ATTRIBUTE_HIDDEN GetFileMD5(const std::string& path)
1064{
1065 using namespace kodi::addon;
1066
1067 std::string strReturn;
1068 char* strMd5 = CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_md5(
1069 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
1070 if (strMd5 != nullptr)
1071 {
1072 if (std::strlen(strMd5))
1073 strReturn = strMd5;
1074 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase, strMd5);
1075 }
1076 return strReturn;
1077}
1078//------------------------------------------------------------------------------
1079
1080//==============================================================================
1081/// @ingroup cpp_kodi_vfs_General
1082/// @brief Returns a thumb cache filename.
1083///
1084/// @param[in] filename Path to file
1085/// @return Cache filename
1086///
1087///
1088/// ------------------------------------------------------------------------
1089///
1090/// **Example:**
1091/// ~~~~~~~~~~~~~{.cpp}
1092/// #include <kodi/Filesystem.h>
1093/// #include <kodi/gui/DialogFileBrowser.h>
1094/// ...
1095/// std::string thumb;
1096/// std::string filename;
1097/// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "*.avi|*.mpg|*.mp4",
1098/// "Test File selection to get Thumnail",
1099/// filename))
1100/// {
1101/// thumb = kodi::vfs::GetCacheThumbName(filename);
1102/// fprintf(stderr, "Thumb name of file '%s' is %s\n", thumb.c_str(), filename.c_str());
1103/// }
1104/// ~~~~~~~~~~~~~
1105///
1106inline std::string ATTRIBUTE_HIDDEN GetCacheThumbName(const std::string& filename)
1107{
1108 using namespace kodi::addon;
1109
1110 std::string strReturn;
1111 char* strThumbName = CAddonBase::m_interface->toKodi->kodi_filesystem->get_cache_thumb_name(
1112 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str());
1113 if (strThumbName != nullptr)
1114 {
1115 if (std::strlen(strThumbName))
1116 strReturn = strThumbName;
1117 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1118 strThumbName);
1119 }
1120 return strReturn;
1121}
1122//------------------------------------------------------------------------------
1123
1124//==============================================================================
1125/// @ingroup cpp_kodi_vfs_General
1126/// @brief Make filename valid.
1127///
1128/// Function to replace not valid characters with '_'. It can be also
1129/// compared with original before in a own loop until it is equal
1130/// (no invalid characters).
1131///
1132/// @param[in] filename Filename to check and fix
1133/// @return The legal filename
1134///
1135///
1136/// ------------------------------------------------------------------------
1137///
1138/// **Example:**
1139/// ~~~~~~~~~~~~~{.cpp}
1140/// #include <kodi/Filesystem.h>
1141/// ...
1142/// std::string fileName = "///\\jk???lj????.mpg";
1143/// std::string legalName = kodi::vfs::MakeLegalFileName(fileName);
1144/// fprintf(stderr, "Legal name of '%s' is '%s'\n", fileName.c_str(), legalName.c_str());
1145///
1146/// /* Returns as legal: 'jk___lj____.mpg' */
1147/// ~~~~~~~~~~~~~
1148///
1149inline std::string ATTRIBUTE_HIDDEN MakeLegalFileName(const std::string& filename)
1150{
1151 using namespace kodi::addon;
1152
1153 std::string strReturn;
1154 char* strLegalFileName = CAddonBase::m_interface->toKodi->kodi_filesystem->make_legal_filename(
1155 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str());
1156 if (strLegalFileName != nullptr)
1157 {
1158 if (std::strlen(strLegalFileName))
1159 strReturn = strLegalFileName;
1160 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1161 strLegalFileName);
1162 }
1163 return strReturn;
1164}
1165//------------------------------------------------------------------------------
1166
1167//==============================================================================
1168/// @ingroup cpp_kodi_vfs_General
1169/// @brief Make directory name valid.
1170///
1171/// Function to replace not valid characters with '_'. It can be also
1172/// compared with original before in a own loop until it is equal
1173/// (no invalid characters).
1174///
1175/// @param[in] path Directory name to check and fix
1176/// @return The legal directory name
1177///
1178///
1179/// ------------------------------------------------------------------------
1180///
1181/// **Example:**
1182/// ~~~~~~~~~~~~~{.cpp}
1183/// #include <kodi/Filesystem.h>
1184/// ...
1185/// std::string path = "///\\jk???lj????\\hgjkg";
1186/// std::string legalPath = kodi::vfs::MakeLegalPath(path);
1187/// fprintf(stderr, "Legal name of '%s' is '%s'\n", path.c_str(), legalPath.c_str());
1188///
1189/// /* Returns as legal: '/jk___lj____/hgjkg' */
1190/// ~~~~~~~~~~~~~
1191///
1192inline std::string ATTRIBUTE_HIDDEN MakeLegalPath(const std::string& path)
1193{
1194 using namespace kodi::addon;
1195
1196 std::string strReturn;
1197 char* strLegalPath = CAddonBase::m_interface->toKodi->kodi_filesystem->make_legal_path(
1198 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
1199 if (strLegalPath != nullptr)
1200 {
1201 if (std::strlen(strLegalPath))
1202 strReturn = strLegalPath;
1203 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1204 strLegalPath);
1205 }
1206 return strReturn;
1207}
1208//------------------------------------------------------------------------------
1209
1210//==============================================================================
1211/// @ingroup cpp_kodi_vfs_General
1212/// @brief Returns the translated path.
1213///
1214/// @param[in] source String or unicode - Path to format
1215/// @return A human-readable string suitable for logging
1216///
1217/// @note Only useful if you are coding for both Linux and Windows. e.g.
1218/// Converts 'special://masterprofile/script_data' ->
1219/// '/home/user/.kodi/UserData/script_data' on Linux.
1220///
1221///
1222/// ------------------------------------------------------------------------
1223///
1224/// **Example:**
1225/// ~~~~~~~~~~~~~{.cpp}
1226/// #include <kodi/Filesystem.h>
1227/// ...
1228/// std::string path = kodi::vfs::TranslateSpecialProtocol("special://masterprofile/script_data");
1229/// fprintf(stderr, "Translated path is: %s\n", path.c_str());
1230/// ...
1231/// ~~~~~~~~~~~~~
1232/// or
1233/// ~~~~~~~~~~~~~{.cpp}
1234/// #include <kodi/Filesystem.h>
1235/// ...
1236/// fprintf(stderr, "Directory 'special://temp' is '%s'\n", kodi::vfs::TranslateSpecialProtocol("special://temp").c_str());
1237/// ...
1238/// ~~~~~~~~~~~~~
1239///
1240inline std::string ATTRIBUTE_HIDDEN TranslateSpecialProtocol(const std::string& source)
1241{
1242 using namespace kodi::addon;
1243
1244 std::string strReturn;
1245 char* protocol = CAddonBase::m_interface->toKodi->kodi_filesystem->translate_special_protocol(
1246 CAddonBase::m_interface->toKodi->kodiBase, source.c_str());
1247 if (protocol != nullptr)
1248 {
1249 if (std::strlen(protocol))
1250 strReturn = protocol;
1251 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1252 protocol);
1253 }
1254 return strReturn;
1255}
1256//------------------------------------------------------------------------------
1257
1258//==============================================================================
1259/// @ingroup cpp_kodi_vfs_General
1260/// @brief Retrieves information about the amount of space that is available on
1261/// a disk volume.
1262///
1263/// Path can be also with Kodi's special protocol.
1264///
1265/// @param[in] path Path for where to check
1266/// @param[out] capacity The total number of bytes in the file system
1267/// @param[out] free The total number of free bytes in the file system
1268/// @param[out] available The total number of free bytes available to a
1269/// non-privileged process
1270/// @return true if successfully done and set
1271///
1272/// @warning This only works with paths belonging to OS. If <b>"special://"</b>
1273/// is used, it must point to a place on your own OS.
1274///
1275///
1276/// ------------------------------------------------------------------------
1277///
1278/// **Example:**
1279/// ~~~~~~~~~~~~~{.cpp}
1280/// #include <climits> // for ULLONG_MAX
1281/// #include <kodi/Filesystem.h>
1282/// ...
1283/// std::string path = "special://temp";
1284/// uint64_t capacity = ULLONG_MAX;
1285/// uint64_t free = ULLONG_MAX;
1286/// uint64_t available = ULLONG_MAX;
1287/// kodi::vfs::GetDiskSpace(path, capacity, free, available);
1288/// fprintf(stderr, "Path '%s' sizes:\n", path.c_str());
1289/// fprintf(stderr, " - capacity: %lu MByte\n", capacity / 1024 / 1024);
1290/// fprintf(stderr, " - free: %lu MByte\n", free / 1024 / 1024);
1291/// fprintf(stderr, " - available: %lu MByte\n", available / 1024 / 1024);
1292/// ~~~~~~~~~~~~~
1293///
1294inline bool ATTRIBUTE_HIDDEN GetDiskSpace(const std::string& path,
1295 uint64_t& capacity,
1296 uint64_t& free,
1297 uint64_t& available)
1298{
1299 using namespace kodi::addon;
1300
1301 return CAddonBase::m_interface->toKodi->kodi_filesystem->get_disk_space(
1302 CAddonBase::m_interface->toKodi->kodiBase, path.c_str(), &capacity, &free, &available);
1303}
1304//------------------------------------------------------------------------------
1305
1306//==============================================================================
1307/// @ingroup cpp_kodi_vfs_General
1308/// @brief Return the file name from given complate path string.
1309///
1310/// @param[in] path The complete path include file and directory
1311/// @return Filename from path
1312///
1313///
1314/// ------------------------------------------------------------------------
1315///
1316/// **Example:**
1317/// ~~~~~~~~~~~~~{.cpp}
1318/// #include <kodi/Filesystem.h>
1319/// ...
1320/// std::string fileName = kodi::vfs::GetFileName("special://temp/kodi.log");
1321/// fprintf(stderr, "File name is '%s'\n", fileName.c_str());
1322/// ~~~~~~~~~~~~~
1323///
1324inline std::string ATTRIBUTE_HIDDEN GetFileName(const std::string& path)
1325{
1326 /* find the last slash */
1327 const size_t slash = path.find_last_of("/\\");
1328 return path.substr(slash + 1);
1329}
1330//------------------------------------------------------------------------------
1331
1332//==============================================================================
1333/// @ingroup cpp_kodi_vfs_General
1334/// @brief Return the directory name from given complate path string.
1335///
1336/// @param[in] path The complete path include file and directory
1337/// @return Directory name from path
1338///
1339///
1340/// ------------------------------------------------------------------------
1341///
1342/// **Example:**
1343/// ~~~~~~~~~~~~~{.cpp}
1344/// #include <kodi/Filesystem.h>
1345/// ...
1346/// std::string dirName = kodi::vfs::GetDirectoryName("special://temp/kodi.log");
1347/// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str());
1348/// ~~~~~~~~~~~~~
1349///
1350inline std::string ATTRIBUTE_HIDDEN GetDirectoryName(const std::string& path)
1351{
1352 // Will from a full filename return the directory the file resides in.
1353 // Keeps the final slash at end and possible |option=foo options.
1354
1355 size_t iPosSlash = path.find_last_of("/\\");
1356 if (iPosSlash == std::string::npos)
1357 return ""; // No slash, so no path (ignore any options)
1358
1359 size_t iPosBar = path.rfind('|');
1360 if (iPosBar == std::string::npos)
1361 return path.substr(0, iPosSlash + 1); // Only path
1362
1363 return path.substr(0, iPosSlash + 1) + path.substr(iPosBar); // Path + options
1364}
1365//------------------------------------------------------------------------------
1366
1367//==============================================================================
1368/// @ingroup cpp_kodi_vfs_General
1369/// @brief Remove the slash on given path name.
1370///
1371/// @param[in,out] path The complete path
1372///
1373///
1374/// ------------------------------------------------------------------------
1375///
1376/// **Example:**
1377/// ~~~~~~~~~~~~~{.cpp}
1378/// #include <kodi/Filesystem.h>
1379/// ...
1380/// std::string dirName = "special://temp/";
1381/// kodi::vfs::RemoveSlashAtEnd(dirName);
1382/// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str());
1383/// ~~~~~~~~~~~~~
1384///
1385inline void ATTRIBUTE_HIDDEN RemoveSlashAtEnd(std::string& path)
1386{
1387 if (!path.empty())
1388 {
1389 char last = path[path.size() - 1];
1390 if (last == '/' || last == '\\')
1391 path.erase(path.size() - 1);
1392 }
1393}
1394//------------------------------------------------------------------------------
1395
1396//==============================================================================
1397/// @ingroup cpp_kodi_vfs_General
1398/// @brief Return a size aligned to the chunk size at least as large as the
1399/// chunk size.
1400///
1401/// @param[in] chunk The chunk size
1402/// @param[in] minimum The minimum size (or maybe the minimum number of chunks?)
1403/// @return The aligned size
1404///
1405inline unsigned int ATTRIBUTE_HIDDEN GetChunkSize(unsigned int chunk, unsigned int minimum)
1406{
1407 if (chunk)
1408 return chunk * ((minimum + chunk - 1) / chunk);
1409 else
1410 return minimum;
1411}
1412//------------------------------------------------------------------------------
1413
1414//==============================================================================
1415/// @ingroup cpp_kodi_vfs_General
1416/// @brief Checks the given path contains a known internet protocol.
1417///
1418/// About following protocols are the path checked:
1419/// | Protocol | Return true condition | Protocol | Return true condition
1420/// |----------|-----------------------|----------|-----------------------
1421/// | **dav** | strictCheck = true | **rtmps** | always
1422/// | **davs** | strictCheck = true | **rtmpt** | always
1423/// | **ftp** | strictCheck = true | **rtmpte** | always
1424/// | **ftps** | strictCheck = true | **rtp** | always
1425/// | **http** | always | **rtsp** | always
1426/// | **https**| always | **sdp** | always
1427/// | **mms** | always | **sftp** | strictCheck = true
1428/// | **mmsh** | always | **stack** | always
1429/// | **mmst** | always | **tcp** | always
1430/// | **rtmp** | always | **udp** | always
1431/// | **rtmpe**| always | | |
1432///
1433/// @param[in] path To checked path/URL
1434/// @param[in] strictCheck [opt] If True the set of protocols used will be
1435/// extended to include ftp, ftps, dav, davs and sftp.
1436/// @return True if path is to a internet stream, false otherwise
1437///
1438///
1439/// ------------------------------------------------------------------------
1440///
1441/// **Example:**
1442/// ~~~~~~~~~~~~~{.cpp}
1443/// #include <kodi/Filesystem.h>
1444/// ...
1445/// // Check should return false
1446/// fprintf(stderr, "File name 1 is internet stream '%s' (should no)\n",
1447/// kodi::vfs::IsInternetStream("D:/my-file.mkv") ? "yes" : "no");
1448///
1449/// // Check should return true
1450/// fprintf(stderr, "File name 2 is internet stream '%s' (should yes)\n",
1451/// kodi::vfs::IsInternetStream("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4") ? "yes" : "no");
1452///
1453/// // Check should return false
1454/// fprintf(stderr, "File name 1 is internet stream '%s' (should no)\n",
1455/// kodi::vfs::IsInternetStream("ftp://do-somewhere.com/the-file.mkv") ? "yes" : "no", false);
1456///
1457/// // Check should return true
1458/// fprintf(stderr, "File name 1 is internet stream '%s' (should yes)\n",
1459/// kodi::vfs::IsInternetStream("ftp://do-somewhere.com/the-file.mkv") ? "yes" : "no", true);
1460/// ~~~~~~~~~~~~~
1461///
1462inline bool ATTRIBUTE_HIDDEN IsInternetStream(const std::string& path, bool strictCheck = false)
1463{
1464 using namespace kodi::addon;
1465
1466 return CAddonBase::m_interface->toKodi->kodi_filesystem->is_internet_stream(
1467 CAddonBase::m_interface->toKodi->kodiBase, path.c_str(), strictCheck);
1468}
1469//------------------------------------------------------------------------------
1470
1471//==============================================================================
1472/// @ingroup cpp_kodi_vfs_General
1473/// @brief Checks whether the specified path refers to a local network.
1474///
1475/// In difference to @ref IsHostOnLAN() include this more deeper checks where
1476/// also handle Kodi's special protocol and stacks.
1477///
1478/// @param[in] path To checked path
1479/// @return True if path is on LAN, false otherwise
1480///
1481/// @note Check includes @ref IsHostOnLAN() too.
1482///
1483///
1484/// ------------------------------------------------------------------------
1485///
1486/// **Example:**
1487/// ~~~~~~~~~~~~~{.cpp}
1488/// #include <kodi/Filesystem.h>
1489/// ...
1490/// // Check should return true
1491/// bool lan = kodi::vfs::IsOnLAN("smb://path/to/file");
1492/// ~~~~~~~~~~~~~
1493///
1494inline bool ATTRIBUTE_HIDDEN IsOnLAN(const std::string& path)
1495{
1496 using namespace kodi::addon;
1497
1498 return CAddonBase::m_interface->toKodi->kodi_filesystem->is_on_lan(
1499 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
1500}
1501//------------------------------------------------------------------------------
1502
1503//==============================================================================
1504/// @ingroup cpp_kodi_vfs_General
1505/// @brief Checks specified path for external network.
1506///
1507/// @param[in] path To checked path
1508/// @return True if path is remote, false otherwise
1509///
1510/// @note This does not apply to the local network.
1511///
1512///
1513/// ------------------------------------------------------------------------
1514///
1515/// **Example:**
1516/// ~~~~~~~~~~~~~{.cpp}
1517/// #include <kodi/Filesystem.h>
1518/// ...
1519/// // Check should return true
1520/// bool remote = kodi::vfs::IsRemote("http://path/to/file");
1521/// ~~~~~~~~~~~~~
1522///
1523inline bool ATTRIBUTE_HIDDEN IsRemote(const std::string& path)
1524{
1525 using namespace kodi::addon;
1526
1527 return CAddonBase::m_interface->toKodi->kodi_filesystem->is_remote(
1528 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
1529}
1530//------------------------------------------------------------------------------
1531
1532//==============================================================================
1533/// @ingroup cpp_kodi_vfs_General
1534/// @brief Checks whether the given path refers to the own system.
1535///
1536/// @param[in] path To checked path
1537/// @return True if path is local, false otherwise
1538///
1539inline bool ATTRIBUTE_HIDDEN IsLocal(const std::string& path)
1540{
1541 using namespace kodi::addon;
1542
1543 return CAddonBase::m_interface->toKodi->kodi_filesystem->is_local(
1544 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
1545}
1546//------------------------------------------------------------------------------
1547
1548//==============================================================================
1549/// @ingroup cpp_kodi_vfs_General
1550/// @brief Checks specified path is a regular URL, e.g. "someprotocol://path/to/file"
1551///
1552/// @return True if file item is URL, false otherwise
1553///
1554///
1555/// ------------------------------------------------------------------------
1556///
1557/// **Example:**
1558/// ~~~~~~~~~~~~~{.cpp}
1559/// #include <kodi/Filesystem.h>
1560/// ...
1561///
1562/// bool isURL;
1563/// // Check should return true
1564/// isURL = kodi::vfs::IsURL("someprotocol://path/to/file");
1565///
1566/// // Check should return false
1567/// isURL = kodi::vfs::IsURL("/path/to/file");
1568/// ~~~~~~~~~~~~~
1569///
1570inline bool ATTRIBUTE_HIDDEN IsURL(const std::string& path)
1571{
1572 using namespace kodi::addon;
1573
1574 return CAddonBase::m_interface->toKodi->kodi_filesystem->is_url(
1575 CAddonBase::m_interface->toKodi->kodiBase, path.c_str());
1576}
1577//--------------------------------------------------------------------------
1578
1579//============================================================================
1580/// @ingroup cpp_kodi_vfs_General
1581/// @brief To get HTTP header information.
1582///
1583/// @param[in] url URL source of the data
1584/// @param[out] header The @ref cpp_kodi_vfs_Defs_HttpHeader
1585/// @return true if successfully done, otherwise false
1586///
1587///
1588/// ------------------------------------------------------------------------
1589///
1590/// @copydetails cpp_kodi_vfs_Defs_HttpHeader_Help
1591///
1592/// ------------------------------------------------------------------------
1593///
1594/// **Example:**
1595/// ~~~~~~~~~~~~~{.cpp}
1596/// #include <kodi/Filesystem.h>
1597/// ...
1598/// kodi::vfs::HttpHeader header;
1599/// bool ret = kodi::vfs::GetHttpHeader(url, header);
1600/// ...
1601/// ~~~~~~~~~~~~~
1602///
1603inline bool ATTRIBUTE_HIDDEN GetHttpHeader(const std::string& url, HttpHeader& header)
1604{
1605 using namespace ::kodi::addon;
1606
1607 return CAddonBase::m_interface->toKodi->kodi_filesystem->get_http_header(
1608 CAddonBase::m_interface->toKodi->kodiBase, url.c_str(), &header.m_handle);
1609}
1610//----------------------------------------------------------------------------
1611
1612//============================================================================
1613/// @ingroup cpp_kodi_vfs_General
1614/// @brief Get file mime type.
1615///
1616/// @param[in] url URL source of the data
1617/// @param[out] mimeType the mime type of the URL
1618/// @param[in] useragent to be used when retrieving the MimeType [opt]
1619/// @return true if successfully done, otherwise false
1620///
1621///
1622/// ------------------------------------------------------------------------
1623///
1624/// **Example:**
1625/// ~~~~~~~~~~~~~{.cpp}
1626/// #include <kodi/Filesystem.h>
1627/// ...
1628/// std::string mimeType;.
1629/// if (kodi::vfs::GetMimeType(url, mimeType))
1630/// fprintf(stderr, "The mime type is '%s'\n", mimeType.c_str());
1631/// ...
1632/// ~~~~~~~~~~~~~
1633///
1634inline bool ATTRIBUTE_HIDDEN GetMimeType(const std::string& url,
1635 std::string& mimeType,
1636 const std::string& useragent = "")
1637{
1638 using namespace ::kodi::addon;
1639
1640 char* cMimeType = nullptr;
1641 bool ret = CAddonBase::m_interface->toKodi->kodi_filesystem->get_mime_type(
1642 CAddonBase::m_interface->toKodi->kodiBase, url.c_str(), &cMimeType, useragent.c_str());
1643 if (cMimeType != nullptr)
1644 {
1645 mimeType = cMimeType;
1646 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1647 cMimeType);
1648 }
1649 return ret;
1650}
1651//----------------------------------------------------------------------------
1652
1653//============================================================================
1654/// @ingroup cpp_kodi_vfs_General
1655/// @brief Get file content-type.
1656///
1657/// @param[in] url URL source of the data
1658/// @param[out] content The returned type
1659/// @param[in] useragent to be used when retrieving the MimeType [opt]
1660/// @return true if successfully done, otherwise false
1661///
1662///
1663/// ------------------------------------------------------------------------
1664///
1665/// **Example:**
1666/// ~~~~~~~~~~~~~{.cpp}
1667/// #include <kodi/Filesystem.h>
1668/// ...
1669/// std::string content;.
1670/// if (kodi::vfs::GetContentType(url, content))
1671/// fprintf(stderr, "The content type is '%s'\n", content.c_str());
1672/// ...
1673/// ~~~~~~~~~~~~~
1674///
1675inline bool ATTRIBUTE_HIDDEN GetContentType(const std::string& url,
1676 std::string& content,
1677 const std::string& useragent = "")
1678{
1679 using namespace ::kodi::addon;
1680
1681 char* cContent = nullptr;
1682 bool ret = CAddonBase::m_interface->toKodi->kodi_filesystem->get_content_type(
1683 CAddonBase::m_interface->toKodi->kodiBase, url.c_str(), &cContent, useragent.c_str());
1684 if (cContent != nullptr)
1685 {
1686 content = cContent;
1687 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1688 cContent);
1689 }
1690 return ret;
1691}
1692//----------------------------------------------------------------------------
1693
1694//============================================================================
1695/// @ingroup cpp_kodi_vfs_General
1696/// @brief Get cookies stored by CURL in RFC 2109 format.
1697///
1698/// @param[in] url URL source of the data
1699/// @param[out] cookies The text list of available cookies
1700/// @return true if successfully done, otherwise false
1701///
1702///
1703/// ------------------------------------------------------------------------
1704///
1705/// **Example:**
1706/// ~~~~~~~~~~~~~{.cpp}
1707/// #include <kodi/Filesystem.h>
1708/// ...
1709/// std::string url = "";
1710/// std::string cookies;
1711/// bool ret = kodi::vfs::GetCookies(url, cookies);
1712/// fprintf(stderr, "Cookies from URL '%s' are '%s' (return was %s)\n",
1713/// url.c_str(), cookies.c_str(), ret ? "true" : "false");
1714/// ...
1715/// ~~~~~~~~~~~~~
1716///
1717inline bool ATTRIBUTE_HIDDEN GetCookies(const std::string& url, std::string& cookies)
1718{
1719 using namespace ::kodi::addon;
1720
1721 char* cCookies = nullptr;
1722 bool ret = CAddonBase::m_interface->toKodi->kodi_filesystem->get_cookies(
1723 CAddonBase::m_interface->toKodi->kodiBase, url.c_str(), &cCookies);
1724 if (cCookies != nullptr)
1725 {
1726 cookies = cCookies;
1727 CAddonBase::m_interface->toKodi->free_string(CAddonBase::m_interface->toKodi->kodiBase,
1728 cCookies);
1729 }
1730 return ret;
1731}
1732//----------------------------------------------------------------------------
1733
1734//}}}
1735
1736//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
1737// "C++" CFile class
1738//{{{
1739
1740//==============================================================================
1741/// @defgroup cpp_kodi_vfs_CFile 4. class CFile
1742/// @ingroup cpp_kodi_vfs
1743///
1744/// @brief **Creatable class for virtual file server control**\n
1745/// To perform file read/write with Kodi's filesystem parts.
1746///
1747/// CFile is the class used for handling Files in Kodi. This class can be used
1748/// for creating, reading, writing and modifying files. It directly provides unbuffered, binary disk input/output services
1749///
1750/// It has the header @ref Filesystem.h "#include <kodi/Filesystem.h>" be included
1751/// to enjoy it.
1752///
1753///
1754/// ------------------------------------------------------------------------
1755///
1756/// **Example:**
1757/// ~~~~~~~~~~~~~{.cpp}
1758/// #include <kodi/Filesystem.h>
1759///
1760/// ...
1761///
1762/// /* Create the needed file handle class */
1763/// kodi::vfs::CFile myFile();
1764///
1765/// /* In this example we use the user path for the add-on */
1766/// std::string file = kodi::GetUserPath() + "/myFile.txt";
1767///
1768/// /* Now create and open the file or overwrite if present */
1769/// myFile.OpenFileForWrite(file, true);
1770///
1771/// const char* str = "I love Kodi!";
1772///
1773/// /* write string */
1774/// myFile.Write(str, sizeof(str));
1775///
1776/// /* On this way the Close() is not needed to call, becomes done from destructor */
1777///
1778/// ~~~~~~~~~~~~~
1779///
1780//@{
1781class ATTRIBUTE_HIDDEN CFile
1782{
1783public:
1784 //============================================================================
1785 /// @ingroup cpp_kodi_vfs_CFile
1786 /// @brief Construct a new, unopened file.
1787 ///
1788 CFile() = default;
720 //---------------------------------------------------------------------------- 1789 //----------------------------------------------------------------------------
721 1790
722 //============================================================================ 1791 //============================================================================
1792 /// @ingroup cpp_kodi_vfs_CFile
1793 /// @brief <b>`Close()`</b> is called from the destructor, so explicitly
1794 /// closing the file isn't required.
723 /// 1795 ///
724 /// @ingroup cpp_kodi_vfs 1796 virtual ~CFile() { Close(); }
725 /// @brief Returns a thumb cache filename 1797 //--------------------------------------------------------------------------
1798
1799 //==========================================================================
1800 /// @ingroup cpp_kodi_vfs_CFile
1801 /// @brief Open the file with filename via Kodi's @ref cpp_kodi_vfs_CFile
1802 /// "CFile". Needs to be closed by calling Close() when done.
726 /// 1803 ///
727 /// @param[in] filename path to file 1804 /// @param[in] filename The filename to open.
728 /// @return cache filename 1805 /// @param[in] flags [opt] The flags to pass, see @ref OpenFileFlags
1806 /// @return True on success or false on failure
729 /// 1807 ///
1808 bool OpenFile(const std::string& filename, unsigned int flags = 0)
1809 {
1810 using namespace kodi::addon;
1811
1812 Close();
1813 m_file = CAddonBase::m_interface->toKodi->kodi_filesystem->open_file(
1814 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), flags);
1815 return m_file != nullptr;
1816 }
1817 //--------------------------------------------------------------------------
1818
1819 //==========================================================================
1820 /// @ingroup cpp_kodi_vfs_CFile
1821 /// @brief Open the file with filename via Kodi's @ref cpp_kodi_vfs_CFile
1822 /// "CFile" in write mode. Needs to be closed by calling Close() when
1823 /// done.
730 /// 1824 ///
731 /// ------------------------------------------------------------------------ 1825 /// @note Related folders becomes created if not present.
732 /// 1826 ///
733 /// **Example:** 1827 /// @param[in] filename The filename to open.
734 /// ~~~~~~~~~~~~~{.cpp} 1828 /// @param[in] overwrite True to overwrite, false otherwise.
735 /// #include <kodi/Filesystem.h> 1829 /// @return True on success or false on failure
736 /// #include <kodi/gui/DialogFileBrowser.h>
737 /// ...
738 /// std::string thumb;
739 /// std::string filename;
740 /// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "*.avi|*.mpg|*.mp4",
741 /// "Test File selection to get Thumnail",
742 /// filename))
743 /// {
744 /// thumb = kodi::vfs::GetCacheThumbName(filename);
745 /// fprintf(stderr, "Thumb name of file '%s' is %s\n", thumb.c_str(), filename.c_str());
746 /// }
747 /// ~~~~~~~~~~~~~
748 /// 1830 ///
749 inline std::string GetCacheThumbName(const std::string& filename) 1831 bool OpenFileForWrite(const std::string& filename, bool overwrite = false)
750 { 1832 {
751 std::string strReturn; 1833 using namespace kodi::addon;
752 char* strThumbName = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_cache_thumb_name(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str()); 1834
753 if (strThumbName != nullptr) 1835 Close();
1836
1837 // Try to open the file. If it fails, check if we need to create the directory first
1838 // This way we avoid checking if the directory exists every time
1839 m_file = CAddonBase::m_interface->toKodi->kodi_filesystem->open_file_for_write(
1840 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), overwrite);
1841 if (!m_file)
754 { 1842 {
755 if (std::strlen(strThumbName)) 1843 std::string cacheDirectory = kodi::vfs::GetDirectoryName(filename);
756 strReturn = strThumbName; 1844 if (CAddonBase::m_interface->toKodi->kodi_filesystem->directory_exists(
757 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, strThumbName); 1845 CAddonBase::m_interface->toKodi->kodiBase, cacheDirectory.c_str()) ||
1846 CAddonBase::m_interface->toKodi->kodi_filesystem->create_directory(
1847 CAddonBase::m_interface->toKodi->kodiBase, cacheDirectory.c_str()))
1848 m_file = CAddonBase::m_interface->toKodi->kodi_filesystem->open_file_for_write(
1849 CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), overwrite);
758 } 1850 }
759 return strReturn; 1851 return m_file != nullptr;
760 } 1852 }
761 //---------------------------------------------------------------------------- 1853 //--------------------------------------------------------------------------
762 1854
763 //============================================================================ 1855 //==========================================================================
764 /// 1856 /// @ingroup cpp_kodi_vfs_CFile
765 /// @ingroup cpp_kodi_vfs 1857 /// @brief Check file is opened.
766 /// @brief Make filename valid
767 /// 1858 ///
768 /// Function to replace not valid characters with '_'. It can be also 1859 /// @return True on open or false on closed or failure
769 /// compared with original before in a own loop until it is equal
770 /// (no invalid characters).
771 /// 1860 ///
772 /// @param[in] filename Filename to check and fix 1861 bool IsOpen() const { return m_file != nullptr; }
773 /// @return The legal filename 1862 //--------------------------------------------------------------------------
1863
1864 //==========================================================================
1865 /// @ingroup cpp_kodi_vfs_CFile
1866 /// @brief Close an open file.
774 /// 1867 ///
1868 void Close()
1869 {
1870 using namespace kodi::addon;
1871
1872 if (!m_file)
1873 return;
1874 CAddonBase::m_interface->toKodi->kodi_filesystem->close_file(
1875 CAddonBase::m_interface->toKodi->kodiBase, m_file);
1876 m_file = nullptr;
1877 }
1878 //--------------------------------------------------------------------------
1879
1880 //==========================================================================
1881 /// @ingroup cpp_kodi_vfs_CFile
1882 /// @brief Create a Curl representation
775 /// 1883 ///
776 /// ------------------------------------------------------------------------ 1884 /// @param[in] url The URL of the Type.
1885 /// @return True on success or false on failure
777 /// 1886 ///
778 /// **Example:** 1887 bool CURLCreate(const std::string& url)
779 /// ~~~~~~~~~~~~~{.cpp} 1888 {
780 /// #include <kodi/Filesystem.h> 1889 using namespace kodi::addon;
781 /// ... 1890
782 /// std::string fileName = "///\\jk???lj????.mpg"; 1891 m_file = CAddonBase::m_interface->toKodi->kodi_filesystem->curl_create(
783 /// std::string legalName = kodi::vfs::MakeLegalFileName(fileName); 1892 CAddonBase::m_interface->toKodi->kodiBase, url.c_str());
784 /// fprintf(stderr, "Legal name of '%s' is '%s'\n", fileName.c_str(), legalName.c_str()); 1893 return m_file != nullptr;
1894 }
1895 //--------------------------------------------------------------------------
1896
1897 //==========================================================================
1898 /// @ingroup cpp_kodi_vfs_CFile
1899 /// @brief Add options to the curl file created with CURLCreate.
785 /// 1900 ///
786 /// /* Returns as legal: 'jk___lj____.mpg' */ 1901 /// @param[in] type Option type to set, see @ref CURLOptiontype
787 /// ~~~~~~~~~~~~~ 1902 /// @param[in] name Name of the option
1903 /// @param[in] value Value of the option
1904 /// @return True on success or false on failure
788 /// 1905 ///
789 inline std::string MakeLegalFileName(const std::string& filename) 1906 bool CURLAddOption(CURLOptiontype type, const std::string& name, const std::string& value)
790 { 1907 {
791 std::string strReturn; 1908 using namespace kodi::addon;
792 char* strLegalFileName = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->make_legal_filename(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str()); 1909
793 if (strLegalFileName != nullptr) 1910 if (!m_file)
794 { 1911 {
795 if (std::strlen(strLegalFileName)) 1912 kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before!");
796 strReturn = strLegalFileName; 1913 return false;
797 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, strLegalFileName);
798 } 1914 }
799 return strReturn; 1915 return CAddonBase::m_interface->toKodi->kodi_filesystem->curl_add_option(
1916 CAddonBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str(), value.c_str());
800 } 1917 }
801 //---------------------------------------------------------------------------- 1918 //--------------------------------------------------------------------------
802 1919
803 //============================================================================ 1920 //==========================================================================
804 /// 1921 /// @ingroup cpp_kodi_vfs_CFile
805 /// @ingroup cpp_kodi_vfs 1922 /// @brief Open the curl file created with CURLCreate.
806 /// @brief Make directory name valid
807 ///
808 /// Function to replace not valid characters with '_'. It can be also
809 /// compared with original before in a own loop until it is equal
810 /// (no invalid characters).
811 /// 1923 ///
812 /// @param[in] path Directory name to check and fix 1924 /// @param[in] flags [opt] The flags to pass, see @ref OpenFileFlags
813 /// @return The legal directory name 1925 /// @return True on success or false on failure
814 /// 1926 ///
815 /// 1927 bool CURLOpen(unsigned int flags = 0)
816 /// ------------------------------------------------------------------------
817 ///
818 /// **Example:**
819 /// ~~~~~~~~~~~~~{.cpp}
820 /// #include <kodi/Filesystem.h>
821 /// ...
822 /// std::string path = "///\\jk???lj????\\hgjkg";
823 /// std::string legalPath = kodi::vfs::MakeLegalPath(path);
824 /// fprintf(stderr, "Legal name of '%s' is '%s'\n", path.c_str(), legalPath.c_str());
825 ///
826 /// /* Returns as legal: '/jk___lj____/hgjkg' */
827 /// ~~~~~~~~~~~~~
828 ///
829 inline std::string MakeLegalPath(const std::string& path)
830 { 1928 {
831 std::string strReturn; 1929 using namespace kodi::addon;
832 char* strLegalPath = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->make_legal_path(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, path.c_str()); 1930
833 if (strLegalPath != nullptr) 1931 if (!m_file)
834 { 1932 {
835 if (std::strlen(strLegalPath)) 1933 kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before!");
836 strReturn = strLegalPath; 1934 return false;
837 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, strLegalPath);
838 } 1935 }
839 return strReturn; 1936 return CAddonBase::m_interface->toKodi->kodi_filesystem->curl_open(
1937 CAddonBase::m_interface->toKodi->kodiBase, m_file, flags);
840 } 1938 }
841 //---------------------------------------------------------------------------- 1939 //--------------------------------------------------------------------------
842 1940
843 //============================================================================ 1941 //==========================================================================
844 /// 1942 /// @ingroup cpp_kodi_vfs_CFile
845 /// @ingroup cpp_kodi_vfs 1943 /// @brief Read from an open file.
846 /// @brief Returns the translated path
847 /// 1944 ///
848 /// @param[in] source string or unicode - Path to format 1945 /// @param[in] ptr The buffer to store the data in.
849 /// @return A human-readable string suitable for logging 1946 /// @param[in] size The size of the buffer.
1947 /// @return number of successfully read bytes if any bytes were read and
1948 /// stored in buffer, zero if no bytes are available to read (end of
1949 /// file was reached) or undetectable error occur, -1 in case of any
1950 /// explicit error
850 /// 1951 ///
851 /// @note Only useful if you are coding for both Linux and Windows. 1952 ssize_t Read(void* ptr, size_t size)
852 /// e.g. Converts 'special://masterprofile/script_data' -> '/home/user/.kodi/UserData/script_data' 1953 {
853 /// on Linux. 1954 using namespace kodi::addon;
854 /// 1955
855 /// 1956 if (!m_file)
856 /// ------------------------------------------------------------------------ 1957 return -1;
1958 return CAddonBase::m_interface->toKodi->kodi_filesystem->read_file(
1959 CAddonBase::m_interface->toKodi->kodiBase, m_file, ptr, size);
1960 }
1961 //--------------------------------------------------------------------------
1962
1963 //==========================================================================
1964 /// @ingroup cpp_kodi_vfs_CFile
1965 /// @brief Read a string from an open file.
857 /// 1966 ///
858 /// **Example:** 1967 /// @param[out] line The buffer to store the data in.
859 /// ~~~~~~~~~~~~~{.cpp} 1968 /// @return True when a line was read, false otherwise.
860 /// #include <kodi/Filesystem.h>
861 /// ...
862 /// std::string path = kodi::vfs::TranslateSpecialProtocol("special://masterprofile/script_data");
863 /// fprintf(stderr, "Translated path is: %s\n", path.c_str());
864 /// ...
865 /// ~~~~~~~~~~~~~
866 /// or
867 /// ~~~~~~~~~~~~~{.cpp}
868 /// #include <kodi/Filesystem.h>
869 /// ...
870 /// fprintf(stderr, "Directory 'special://temp' is '%s'\n", kodi::vfs::TranslateSpecialProtocol("special://temp").c_str());
871 /// ...
872 /// ~~~~~~~~~~~~~
873 /// 1969 ///
874 inline std::string TranslateSpecialProtocol(const std::string& source) 1970 bool ReadLine(std::string& line)
875 { 1971 {
876 std::string strReturn; 1972 using namespace kodi::addon;
877 char* protocol = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->translate_special_protocol(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, source.c_str()); 1973
878 if (protocol != nullptr) 1974 line.clear();
1975 if (!m_file)
1976 return false;
1977 // TODO: Read 1024 chars into buffer. If file position advanced that many
1978 // chars, we didn't hit a newline. Otherwise, if file position is 1 or 2
1979 // past the number of bytes read, we read (and skipped) a newline sequence.
1980 char buffer[1025];
1981 if (CAddonBase::m_interface->toKodi->kodi_filesystem->read_file_string(
1982 CAddonBase::m_interface->toKodi->kodiBase, m_file, buffer, sizeof(buffer)))
879 { 1983 {
880 if (std::strlen(protocol)) 1984 line = buffer;
881 strReturn = protocol; 1985 return !line.empty();
882 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, protocol);
883 } 1986 }
884 return strReturn; 1987 return false;
885 } 1988 }
886 //---------------------------------------------------------------------------- 1989 //--------------------------------------------------------------------------
887 1990
888 //============================================================================ 1991 //==========================================================================
889 /// 1992 /// @ingroup cpp_kodi_vfs_CFile
890 /// @ingroup cpp_kodi_vfs 1993 /// @brief Write to a file opened in write mode.
891 /// @brief Return the file name from given complate path string
892 ///
893 /// @param[in] path The complete path include file and directory
894 /// @return Filename from path
895 ///
896 /// 1994 ///
897 /// ------------------------------------------------------------------------ 1995 /// @param[in] ptr Pointer to the data to write, converted to a <b>`const void*`</b>.
1996 /// @param[in] size Size of the data to write.
1997 /// @return number of successfully written bytes if any bytes were written,
1998 /// zero if no bytes were written and no detectable error occur,-1
1999 /// in case of any explicit error
898 /// 2000 ///
899 /// **Example:** 2001 ssize_t Write(const void* ptr, size_t size)
900 /// ~~~~~~~~~~~~~{.cpp}
901 /// #include <kodi/Filesystem.h>
902 /// ...
903 /// std::string fileName = kodi::vfs::GetFileName("special://temp/kodi.log");
904 /// fprintf(stderr, "File name is '%s'\n", fileName.c_str());
905 /// ~~~~~~~~~~~~~
906 ///
907 inline std::string GetFileName(const std::string& path)
908 { 2002 {
909 /* find the last slash */ 2003 using namespace kodi::addon;
910 const size_t slash = path.find_last_of("/\\"); 2004
911 return path.substr(slash+1); 2005 if (!m_file)
2006 return -1;
2007 return CAddonBase::m_interface->toKodi->kodi_filesystem->write_file(
2008 CAddonBase::m_interface->toKodi->kodiBase, m_file, ptr, size);
912 } 2009 }
913 //---------------------------------------------------------------------------- 2010 //--------------------------------------------------------------------------
914 2011
915 //============================================================================ 2012 //==========================================================================
916 /// 2013 /// @ingroup cpp_kodi_vfs_CFile
917 /// @ingroup cpp_kodi_vfs 2014 /// @brief Flush buffered data.
918 /// @brief Return the directory name from given complate path string
919 ///
920 /// @param[in] path The complete path include file and directory
921 /// @return Directory name from path
922 /// 2015 ///
2016 /// If the given stream was open for writing (or if it was open for updating
2017 /// and the last i/o operation was an output operation) any unwritten data
2018 /// in its output buffer is written to the file.
923 /// 2019 ///
924 /// ------------------------------------------------------------------------ 2020 /// The stream remains open after this call.
925 /// 2021 ///
926 /// **Example:** 2022 /// When a file is closed, either because of a call to close or because the
927 /// ~~~~~~~~~~~~~{.cpp} 2023 /// class is destructed, all the buffers associated with it are
928 /// #include <kodi/Filesystem.h> 2024 /// automatically flushed.
929 /// ...
930 /// std::string dirName = kodi::vfs::GetDirectoryName("special://temp/kodi.log");
931 /// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str());
932 /// ~~~~~~~~~~~~~
933 /// 2025 ///
934 inline std::string GetDirectoryName(const std::string& path) 2026 void Flush()
935 { 2027 {
936 // Will from a full filename return the directory the file resides in. 2028 using namespace kodi::addon;
937 // Keeps the final slash at end and possible |option=foo options.
938 2029
939 size_t iPosSlash = path.find_last_of("/\\"); 2030 if (!m_file)
940 if (iPosSlash == std::string::npos) 2031 return;
941 return ""; // No slash, so no path (ignore any options) 2032 CAddonBase::m_interface->toKodi->kodi_filesystem->flush_file(
942 2033 CAddonBase::m_interface->toKodi->kodiBase, m_file);
943 size_t iPosBar = path.rfind('|');
944 if (iPosBar == std::string::npos)
945 return path.substr(0, iPosSlash + 1); // Only path
946
947 return path.substr(0, iPosSlash + 1) + path.substr(iPosBar); // Path + options
948 } 2034 }
949 //---------------------------------------------------------------------------- 2035 //--------------------------------------------------------------------------
950 2036
951 2037 //==========================================================================
952 //============================================================================ 2038 /// @ingroup cpp_kodi_vfs_CFile
953 /// 2039 /// @brief Set the file's current position.
954 /// @ingroup cpp_kodi_vfs
955 /// @brief Remove the slash on given path name
956 /// 2040 ///
957 /// @param[in,out] path The complete path 2041 /// The whence argument is optional and defaults to SEEK_SET (0)
958 /// 2042 ///
2043 /// @param[in] position the position that you want to seek to
2044 /// @param[in] whence [optional] offset relative to You can set the value of
2045 /// whence to one of three things:
2046 /// | Value | int | Description |
2047 /// |:--------:|:---:|:----------------------------------------------------|
2048 /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
2049 /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
2050 /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
959 /// 2051 ///
960 /// ------------------------------------------------------------------------ 2052 /// @return Returns the resulting offset location as measured in bytes from
2053 /// the beginning of the file. On error, the value -1 is returned.
961 /// 2054 ///
962 /// **Example:** 2055 int64_t Seek(int64_t position, int whence = SEEK_SET)
963 /// ~~~~~~~~~~~~~{.cpp}
964 /// #include <kodi/Filesystem.h>
965 /// ...
966 /// std::string dirName = "special://temp/";
967 /// kodi::vfs::RemoveSlashAtEnd(dirName);
968 /// fprintf(stderr, "Directory name is '%s'\n", dirName.c_str());
969 /// ~~~~~~~~~~~~~
970 ///
971 inline void RemoveSlashAtEnd(std::string& path)
972 { 2056 {
973 if (!path.empty()) 2057 using namespace kodi::addon;
974 { 2058
975 char last = path[path.size() - 1]; 2059 if (!m_file)
976 if (last == '/' || last == '\\') 2060 return -1;
977 path.erase(path.size() - 1); 2061 return CAddonBase::m_interface->toKodi->kodi_filesystem->seek_file(
978 } 2062 CAddonBase::m_interface->toKodi->kodiBase, m_file, position, whence);
979 } 2063 }
980 //---------------------------------------------------------------------------- 2064 //--------------------------------------------------------------------------
981 2065
982 //============================================================================ 2066 //==========================================================================
2067 /// @ingroup cpp_kodi_vfs_CFile
2068 /// @brief Truncate a file to the requested size.
983 /// 2069 ///
984 /// @ingroup cpp_kodi_vfs 2070 /// @param[in] size The new max size.
985 /// @brief Return a size aligned to the chunk size at least as large as the chunk size. 2071 /// @return New size? On error, the value -1 is returned.
986 /// 2072 ///
987 /// @param[in] chunk The chunk size 2073 int Truncate(int64_t size)
988 /// @param[in] minimum The minimum size (or maybe the minimum number of chunks?)
989 /// @return The aligned size
990 ///
991 inline unsigned int GetChunkSize(unsigned int chunk, unsigned int minimum)
992 { 2074 {
993 if (chunk) 2075 using namespace kodi::addon;
994 return chunk * ((minimum + chunk - 1) / chunk); 2076
995 else 2077 if (!m_file)
996 return minimum; 2078 return -1;
2079 return CAddonBase::m_interface->toKodi->kodi_filesystem->truncate_file(
2080 CAddonBase::m_interface->toKodi->kodiBase, m_file, size);
997 } 2081 }
998 //---------------------------------------------------------------------------- 2082 //--------------------------------------------------------------------------
999 2083
1000 //============================================================================ 2084 //==========================================================================
1001 /// 2085 /// @ingroup cpp_kodi_vfs_CFile
1002 /// @ingroup cpp_kodi_vfs 2086 /// @brief The current offset in an open file.
1003 /// @brief Check if a file exists.
1004 /// 2087 ///
1005 /// @param[in] filename The filename to check. 2088 /// @return The requested offset. On error, the value -1 is returned.
1006 /// @param[in] usecache Check in file cache.
1007 /// @return true if the file exists false otherwise.
1008 /// 2089 ///
2090 int64_t GetPosition() const
2091 {
2092 using namespace kodi::addon;
2093
2094 if (!m_file)
2095 return -1;
2096 return CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_position(
2097 CAddonBase::m_interface->toKodi->kodiBase, m_file);
2098 }
2099 //--------------------------------------------------------------------------
2100
2101 //==========================================================================
2102 /// @ingroup cpp_kodi_vfs_CFile
2103 /// @brief Get the file size of an open file.
1009 /// 2104 ///
1010 /// ------------------------------------------------------------------------- 2105 /// @return The requested size. On error, the value -1 is returned.
1011 ///
1012 /// **Example:**
1013 /// ~~~~~~~~~~~~~{.cpp}
1014 /// #include <kodi/Filesystem.h>
1015 /// ...
1016 /// bool exists = kodi::vfs::FileExists("special://temp/kodi.log");
1017 /// fprintf(stderr, "Log file should be always present, is it present? %s\n", exists ? "yes" : "no");
1018 /// ~~~~~~~~~~~~~
1019 /// 2106 ///
1020 inline bool FileExists(const std::string& filename, bool usecache = false) 2107 int64_t GetLength() const
1021 { 2108 {
1022 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->file_exists(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), usecache); 2109 using namespace kodi::addon;
2110
2111 if (!m_file)
2112 return -1;
2113 return CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_length(
2114 CAddonBase::m_interface->toKodi->kodiBase, m_file);
1023 } 2115 }
1024 //---------------------------------------------------------------------------- 2116 //--------------------------------------------------------------------------
1025 2117
1026 //============================================================================ 2118 //==========================================================================
2119 /// @ingroup cpp_kodi_vfs_CFile
2120 /// @brief Checks the file access is on end position.
2121 ///
2122 /// @return If you've reached the end of the file, AtEnd() returns true.
1027 /// 2123 ///
1028 /// @ingroup cpp_kodi_vfs 2124 bool AtEnd() const
1029 /// @brief Get file status.
1030 ///
1031 /// These function return information about a file. Execute (search)
1032 /// permission is required on all of the directories in path that
1033 /// lead to the file.
1034 ///
1035 /// The call return a stat structure, which contains the on \ref STAT_STRUCTURE
1036 /// defined values.
1037 ///
1038 /// @warning Not all of the OS file systems implement all of the time fields.
1039 ///
1040 /// @param[in] filename The filename to read the status from.
1041 /// @param[out] buffer The file status is written into this buffer.
1042 /// @return On success, tru is returned. On error, fale is returned
1043 ///
1044 ///
1045 /// -------------------------------------------------------------------------
1046 ///
1047 /// **Example:**
1048 /// ~~~~~~~~~~~~~{.cpp}
1049 /// #include <kodi/Filesystem.h>
1050 /// ...
1051 /// STAT_STRUCTURE statFile;
1052 /// int ret = kodi::vfs::StatFile("special://temp/kodi.log", statFile);
1053 /// fprintf(stderr, "deviceId (ID of device containing file) = %u\n"
1054 /// "size (total size, in bytes) = %lu\n"
1055 /// "accessTime (time of last access) = %lu\n"
1056 /// "modificationTime (time of last modification) = %lu\n"
1057 /// "statusTime (time of last status change) = %lu\n"
1058 /// "isDirectory (The stat url is a directory) = %s\n"
1059 /// "isSymLink (The stat url is a symbolic link) = %s\n"
1060 /// "Return value = %i\n",
1061 /// statFile.deviceId,
1062 /// statFile.size,
1063 /// statFile.accessTime,
1064 /// statFile.modificationTime,
1065 /// statFile.statusTime,
1066 /// statFile.isDirectory ? "true" : "false",
1067 /// statFile.isSymLink ? "true" : "false",
1068 /// ret);
1069 /// ~~~~~~~~~~~~~
1070 ///
1071 inline bool StatFile(const std::string& filename, STAT_STRUCTURE& buffer)
1072 { 2125 {
1073 struct __stat64 frontendBuffer = { }; 2126 using namespace kodi::addon;
1074 if (::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->stat_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), &frontendBuffer)) 2127
1075 { 2128 if (!m_file)
1076 buffer.deviceId = frontendBuffer.st_dev;
1077 buffer.size = frontendBuffer.st_size;
1078#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD)
1079 buffer.accessTime = frontendBuffer.st_atimespec;
1080 buffer.modificationTime = frontendBuffer.st_mtimespec;
1081 buffer.statusTime = frontendBuffer.st_ctimespec;
1082#elif defined(TARGET_WINDOWS)
1083 buffer.accessTime = frontendBuffer.st_atime;
1084 buffer.modificationTime = frontendBuffer.st_mtime;
1085 buffer.statusTime = frontendBuffer.st_ctime;
1086#elif defined(TARGET_ANDROID)
1087 buffer.accessTime.tv_sec = frontendBuffer.st_atime;
1088 buffer.accessTime.tv_nsec = frontendBuffer.st_atime_nsec;
1089 buffer.modificationTime.tv_sec = frontendBuffer.st_mtime;
1090 buffer.modificationTime.tv_nsec = frontendBuffer.st_mtime_nsec;
1091 buffer.statusTime.tv_sec = frontendBuffer.st_ctime;
1092 buffer.statusTime.tv_nsec = frontendBuffer.st_ctime_nsec;
1093#else
1094 buffer.accessTime = frontendBuffer.st_atim;
1095 buffer.modificationTime = frontendBuffer.st_mtim;
1096 buffer.statusTime = frontendBuffer.st_ctim;
1097#endif
1098 buffer.isDirectory = S_ISDIR(frontendBuffer.st_mode);
1099 buffer.isSymLink = S_ISLNK(frontendBuffer.st_mode);
1100 return true; 2129 return true;
1101 } 2130 int64_t length = CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_length(
1102 return false; 2131 CAddonBase::m_interface->toKodi->kodiBase, m_file);
2132 int64_t position = CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_position(
2133 CAddonBase::m_interface->toKodi->kodiBase, m_file);
2134 return position >= length;
1103 } 2135 }
1104 //---------------------------------------------------------------------------- 2136 //--------------------------------------------------------------------------
1105 2137
1106 //============================================================================ 2138 //==========================================================================
2139 /// @ingroup cpp_kodi_vfs_CFile
2140 /// @brief Get the chunk size for an open file.
1107 /// 2141 ///
1108 /// @ingroup cpp_kodi_vfs 2142 /// @return The requested size. On error, the value -1 is returned.
1109 /// @brief Deletes a file. 2143 ///
1110 /// 2144 int GetChunkSize() const
1111 /// @param[in] filename The filename to delete.
1112 /// @return The file was successfully deleted.
1113 ///
1114 ///
1115 /// -------------------------------------------------------------------------
1116 ///
1117 /// **Example:**
1118 /// ~~~~~~~~~~~~~{.cpp}
1119 /// #include <kodi/Filesystem.h>
1120 /// #include <kodi/gui/DialogFileBrowser.h>
1121 /// #include <kodi/gui/DialogOK.h>
1122 /// ...
1123 /// std::string filename;
1124 /// if (kodi::gui::DialogFileBrowser::ShowAndGetFile("local", "",
1125 /// "Test File selection and delete of them!",
1126 /// filename))
1127 /// {
1128 /// bool successed = kodi::vfs::DeleteFile(filename);
1129 /// if (!successed)
1130 /// kodi::gui::DialogOK::ShowAndGetInput("Error", "Delete of File", filename, "failed!");
1131 /// else
1132 /// kodi::gui::DialogOK::ShowAndGetInput("Information", "Delete of File", filename, "successfull done.");
1133 /// }
1134 /// ~~~~~~~~~~~~~
1135 ///
1136 inline bool DeleteFile(const std::string& filename)
1137 { 2145 {
1138 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->delete_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str()); 2146 using namespace kodi::addon;
2147
2148 if (!m_file)
2149 return -1;
2150 return CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_chunk_size(
2151 CAddonBase::m_interface->toKodi->kodiBase, m_file);
1139 } 2152 }
1140 //---------------------------------------------------------------------------- 2153 //--------------------------------------------------------------------------
1141 2154
1142 //============================================================================ 2155 //==========================================================================
1143 /// 2156 /// @ingroup cpp_kodi_vfs_CFile
1144 /// @ingroup cpp_kodi_vfs 2157 /// @brief To check seek possible on current stream by file.
1145 /// @brief Rename a file name
1146 ///
1147 /// @param[in] filename The filename to copy.
1148 /// @param[in] newFileName The new filename
1149 /// @return true if successfully renamed
1150 /// 2158 ///
2159 /// @return true if seek possible, false if not
1151 /// 2160 ///
1152 inline bool RenameFile(const std::string& filename, const std::string& newFileName) 2161 bool IoControlGetSeekPossible() const
1153 { 2162 {
1154 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->rename_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), newFileName.c_str()); 2163 using namespace kodi::addon;
2164
2165 if (!m_file)
2166 return false;
2167 return CAddonBase::m_interface->toKodi->kodi_filesystem->io_control_get_seek_possible(
2168 CAddonBase::m_interface->toKodi->kodiBase, m_file);
1155 } 2169 }
1156 //---------------------------------------------------------------------------- 2170 //--------------------------------------------------------------------------
1157 2171
1158 //============================================================================ 2172 //==========================================================================
2173 /// @ingroup cpp_kodi_vfs_CFile
2174 /// @brief To check a running stream on file for state of his cache.
1159 /// 2175 ///
1160 /// @ingroup cpp_kodi_vfs 2176 /// @param[in] status Information about current cache status
1161 /// @brief Copy a file from source to destination 2177 /// @return true if successfull done, false otherwise
1162 /// 2178 ///
1163 /// @param[in] filename The filename to copy.
1164 /// @param[in] destination The destination to copy file to
1165 /// @return true if successfully copied
1166 /// 2179 ///
2180 /// @copydetails cpp_kodi_vfs_Defs_CacheStatus_Help
1167 /// 2181 ///
1168 inline bool CopyFile(const std::string& filename, const std::string& destination) 2182 bool IoControlGetCacheStatus(CacheStatus& status) const
1169 { 2183 {
1170 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->copy_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), destination.c_str()); 2184 using namespace kodi::addon;
2185
2186 if (!m_file)
2187 return false;
2188 return CAddonBase::m_interface->toKodi->kodi_filesystem->io_control_get_cache_status(
2189 CAddonBase::m_interface->toKodi->kodiBase, m_file, status);
1171 } 2190 }
1172 //---------------------------------------------------------------------------- 2191 //--------------------------------------------------------------------------
1173 2192
1174 //============================================================================ 2193 //==========================================================================
1175 /// 2194 /// @ingroup cpp_kodi_vfs_CFile
1176 /// \defgroup cpp_kodi_vfs_CFile class CFile 2195 /// @brief Unsigned int with speed limit for caching in bytes per second.
1177 /// \ingroup cpp_kodi_vfs
1178 ///
1179 /// @brief **Virtual file server control**
1180 ///
1181 /// CFile is the class used for handling Files in Kodi. This class can be used
1182 /// for creating, reading, writing and modifying files. It directly provides unbuffered, binary disk input/output services
1183 ///
1184 /// It has the header \ref Filesystem.h "#include <kodi/Filesystem.h>" be included
1185 /// to enjoy it.
1186 ///
1187 ///
1188 /// ------------------------------------------------------------------------
1189 /// 2196 ///
1190 /// **Example:** 2197 /// @param[in] rate Cache rate size to use
1191 /// ~~~~~~~~~~~~~{.cpp} 2198 /// @return true if successfull done, false otherwise
1192 /// #include <kodi/Filesystem.h>
1193 /// 2199 ///
1194 /// ... 2200 bool IoControlSetCacheRate(unsigned int rate)
1195 /// 2201 {
1196 /// /* Create the needed file handle class */ 2202 using namespace kodi::addon;
1197 /// kodi::vfs::CFile myFile(); 2203
1198 /// 2204 if (!m_file)
1199 /// /* In this example we use the user path for the add-on */ 2205 return false;
1200 /// std::string file = kodi::GetUserPath() + "/myFile.txt"; 2206 return CAddonBase::m_interface->toKodi->kodi_filesystem->io_control_set_cache_rate(
1201 /// 2207 CAddonBase::m_interface->toKodi->kodiBase, m_file, rate);
1202 /// /* Now create and open the file or overwrite if present */ 2208 }
1203 /// myFile.OpenFileForWrite(file, true); 2209 //--------------------------------------------------------------------------
1204 /// 2210
1205 /// const char* str = "I love Kodi!"; 2211 //==========================================================================
2212 /// @ingroup cpp_kodi_vfs_CFile
2213 /// @brief Enable/disable retry within the protocol handler (if supported).
1206 /// 2214 ///
1207 /// /* write string */ 2215 /// @param[in] retry To set the retry, true for use, false for not
1208 /// myFile.Write(str, sizeof(str)); 2216 /// @return true if successfull done, false otherwise
1209 /// 2217 ///
1210 /// /* On this way the Close() is not needed to call, becomes done from destructor */ 2218 bool IoControlSetRetry(bool retry)
2219 {
2220 using namespace kodi::addon;
2221
2222 if (!m_file)
2223 return false;
2224 return CAddonBase::m_interface->toKodi->kodi_filesystem->io_control_set_retry(
2225 CAddonBase::m_interface->toKodi->kodiBase, m_file, retry);
2226 }
2227 //--------------------------------------------------------------------------
2228
2229 //==========================================================================
2230 /// @ingroup cpp_kodi_vfs_CFile
2231 /// @brief Retrieve a file property.
1211 /// 2232 ///
1212 /// ~~~~~~~~~~~~~ 2233 /// @param[in] type The type of the file property to retrieve the value for
2234 /// @param[in] name The name of a named property value (e.g. Header)
2235 /// @return value of requested property, empty on failure / non-existance
1213 /// 2236 ///
1214 //@{ 2237 const std::string GetPropertyValue(FilePropertyTypes type, const std::string& name) const
1215 class CFile
1216 { 2238 {
1217 public: 2239 using namespace kodi::addon;
1218 //==========================================================================
1219 ///
1220 /// @ingroup cpp_kodi_vfs_CFile
1221 /// @brief Construct a new, unopened file
1222 ///
1223 CFile() = default;
1224 //--------------------------------------------------------------------------
1225
1226 //==========================================================================
1227 ///
1228 /// @ingroup cpp_kodi_vfs_CFile
1229 /// @brief Close() is called from the destructor, so explicitly closing the
1230 /// file isn't required
1231 ///
1232 virtual ~CFile() { Close(); }
1233 //--------------------------------------------------------------------------
1234
1235 //==========================================================================
1236 ///
1237 /// @ingroup cpp_kodi_vfs_CFile
1238 /// @brief Open the file with filename via Kodi's \ref cpp_kodi_vfs_CFile
1239 /// "CFile". Needs to be closed by calling Close() when done.
1240 ///
1241 /// @param[in] filename The filename to open.
1242 /// @param[in] flags [opt] The flags to pass, see \ref OpenFileFlags
1243 /// @return True on success or false on failure
1244 ///
1245 bool OpenFile(const std::string& filename, unsigned int flags = 0)
1246 {
1247 Close();
1248 m_file = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->open_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), flags);
1249 return m_file != nullptr;
1250 }
1251 //--------------------------------------------------------------------------
1252
1253 //==========================================================================
1254 ///
1255 /// @ingroup cpp_kodi_vfs_CFile
1256 /// @brief Open the file with filename via Kodi's \ref cpp_kodi_vfs_CFile
1257 /// "CFile" in write mode. Needs to be closed by calling Close() when
1258 /// done.
1259 ///
1260 /// @note Related folders becomes created if not present.
1261 ///
1262 /// @param[in] filename The filename to open.
1263 /// @param[in] overwrite True to overwrite, false otherwise.
1264 /// @return True on success or false on failure
1265 ///
1266 bool OpenFileForWrite(const std::string& filename, bool overwrite = false)
1267 {
1268 Close();
1269 2240
1270 // Try to open the file. If it fails, check if we need to create the directory first 2241 if (!m_file)
1271 // This way we avoid checking if the directory exists every time
1272 m_file = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->open_file_for_write(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), overwrite);
1273 if (!m_file)
1274 {
1275 std::string cacheDirectory = kodi::vfs::GetDirectoryName(filename);
1276 if (::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->directory_exists(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, cacheDirectory.c_str()) ||
1277 ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->create_directory(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, cacheDirectory.c_str()))
1278 m_file = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->open_file_for_write(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, filename.c_str(), overwrite);
1279 }
1280 return m_file != nullptr;
1281 }
1282 //--------------------------------------------------------------------------
1283
1284 //==========================================================================
1285 ///
1286 /// @ingroup cpp_kodi_vfs_CFile
1287 /// @brief Create a Curl representation
1288 ///
1289 /// @param[in] url the URL of the Type.
1290 /// @return True on success or false on failure
1291 ///
1292 bool CURLCreate(const std::string& url)
1293 {
1294 m_file = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->curl_create(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, url.c_str());
1295 return m_file != nullptr;
1296 }
1297 //--------------------------------------------------------------------------
1298
1299 //==========================================================================
1300 ///
1301 /// @ingroup cpp_kodi_vfs_CFile
1302 /// @brief Add options to the curl file created with CURLCreate
1303 ///
1304 /// @param[in] type option type to set, see \ref CURLOptiontype
1305 /// @param[in] name name of the option
1306 /// @param[in] value value of the option
1307 /// @return True on success or false on failure
1308 ///
1309 bool CURLAddOption(CURLOptiontype type, const std::string& name, const std::string& value)
1310 {
1311 if (!m_file)
1312 {
1313 kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before!");
1314 return false;
1315 }
1316 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->curl_add_option(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str(), value.c_str());
1317 }
1318 //--------------------------------------------------------------------------
1319
1320 //==========================================================================
1321 ///
1322 /// @ingroup cpp_kodi_vfs_CFile
1323 /// @brief Open the curl file created with CURLCreate
1324 ///
1325 /// @param[in] flags [opt] The flags to pass, see \ref OpenFileFlags
1326 /// @return True on success or false on failure
1327 ///
1328 bool CURLOpen(unsigned int flags = 0)
1329 {
1330 if (!m_file)
1331 {
1332 kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before!");
1333 return false;
1334 }
1335 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->curl_open(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, flags);
1336 }
1337 //--------------------------------------------------------------------------
1338
1339 //==========================================================================
1340 ///
1341 /// @ingroup cpp_kodi_vfs_CFile
1342 /// @brief Read from an open file.
1343 ///
1344 /// @param[in] ptr The buffer to store the data in.
1345 /// @param[in] size The size of the buffer.
1346 /// @return number of successfully read bytes if any bytes
1347 /// were read and stored in buffer, zero if no bytes
1348 /// are available to read (end of file was reached)
1349 /// or undetectable error occur, -1 in case of any
1350 /// explicit error
1351 ///
1352 ssize_t Read(void* ptr, size_t size)
1353 {
1354 if (!m_file)
1355 return -1;
1356 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->read_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, ptr, size);
1357 }
1358 //--------------------------------------------------------------------------
1359
1360 //==========================================================================
1361 ///
1362 /// @ingroup cpp_kodi_vfs_CFile
1363 /// @brief Read a string from an open file.
1364 ///
1365 /// @param[out] line The buffer to store the data in.
1366 /// @return True when a line was read, false otherwise.
1367 ///
1368 bool ReadLine(std::string &line)
1369 {
1370 line.clear();
1371 if (!m_file)
1372 return false;
1373 // TODO: Read 1024 chars into buffer. If file position advanced that many
1374 // chars, we didn't hit a newline. Otherwise, if file position is 1 or 2
1375 // past the number of bytes read, we read (and skipped) a newline sequence.
1376 char buffer[1025];
1377 if (::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->read_file_string(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, buffer, sizeof(buffer)))
1378 {
1379 line = buffer;
1380 return !line.empty();
1381 }
1382 return false;
1383 }
1384 //--------------------------------------------------------------------------
1385
1386 //==========================================================================
1387 ///
1388 /// @ingroup cpp_kodi_vfs_CFile
1389 /// @brief Write to a file opened in write mode.
1390 ///
1391 /// @param[in] ptr Pointer to the data to write, converted to a
1392 /// const void*.
1393 /// @param[in] size Size of the data to write.
1394 /// @return number of successfully written bytes if any
1395 /// bytes were written, zero if no bytes were
1396 /// written and no detectable error occur,-1 in case
1397 /// of any explicit error
1398 ///
1399 ssize_t Write(const void* ptr, size_t size)
1400 {
1401 if (!m_file)
1402 return -1;
1403 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->write_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, ptr, size);
1404 }
1405 //--------------------------------------------------------------------------
1406
1407 //==========================================================================
1408 ///
1409 /// @ingroup cpp_kodi_vfs_CFile
1410 /// @brief Flush buffered data.
1411 ///
1412 /// If the given stream was open for writing (or if it was open for updating
1413 /// and the last i/o operation was an output operation) any unwritten data
1414 /// in its output buffer is written to the file.
1415 ///
1416 /// The stream remains open after this call.
1417 ///
1418 /// When a file is closed, either because of a call to close or because the
1419 /// class is destructed, all the buffers associated with it are
1420 /// automatically flushed.
1421 ///
1422 void Flush()
1423 {
1424 if (!m_file)
1425 return;
1426 ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->flush_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file);
1427 }
1428 //--------------------------------------------------------------------------
1429
1430 //==========================================================================
1431 ///
1432 /// @ingroup cpp_kodi_vfs_CFile
1433 /// @brief Set the file's current position.
1434 ///
1435 /// The whence argument is optional and defaults to SEEK_SET (0)
1436 ///
1437 /// @param[in] position the position that you want to seek to
1438 /// @param[in] whence [optional] offset relative to
1439 /// You can set the value of whence to one.
1440 /// of three things:
1441 /// | Value | int | Description |
1442 /// |:--------:|:---:|:----------------------------------------------------|
1443 /// | SEEK_SET | 0 | position is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence.
1444 /// | SEEK_CUR | 1 | position is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes."
1445 /// | SEEK_END | 2 | position is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion.
1446 ///
1447 /// @return Returns the resulting offset location as
1448 /// measured in bytes from the beginning of
1449 /// the file. On error, the value -1 is
1450 /// returned.
1451 ///
1452 int64_t Seek(int64_t position, int whence = SEEK_SET)
1453 {
1454 if (!m_file)
1455 return -1;
1456 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->seek_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, position, whence);
1457 }
1458 //--------------------------------------------------------------------------
1459
1460 //==========================================================================
1461 ///
1462 /// @ingroup cpp_kodi_vfs_CFile
1463 /// @brief Truncate a file to the requested size.
1464 ///
1465 /// @param[in] size The new max size.
1466 /// @return New size? On error, the value -1 is
1467 /// returned.
1468 ///
1469 int Truncate(int64_t size)
1470 {
1471 if (!m_file)
1472 return -1;
1473 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->truncate_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, size);
1474 }
1475 //--------------------------------------------------------------------------
1476
1477 //==========================================================================
1478 ///
1479 /// @ingroup cpp_kodi_vfs_CFile
1480 /// @brief The current offset in an open file.
1481 ///
1482 /// @return The requested offset. On error, the value -1 is
1483 /// returned.
1484 ///
1485 int64_t GetPosition()
1486 { 2242 {
1487 if (!m_file) 2243 kodi::Log(ADDON_LOG_ERROR,
1488 return -1; 2244 "kodi::vfs::CURLCreate(...) needed to call before GetPropertyValue!");
1489 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_position(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file); 2245 return "";
1490 } 2246 }
1491 //-------------------------------------------------------------------------- 2247 std::vector<std::string> values = GetPropertyValues(type, name);
1492 2248 if (values.empty())
1493 //==========================================================================
1494 ///
1495 /// @ingroup cpp_kodi_vfs_CFile
1496 /// @brief Get the file size of an open file.
1497 ///
1498 /// @return The requested size. On error, the value -1 is
1499 /// returned.
1500 ///
1501 int64_t GetLength()
1502 { 2249 {
1503 if (!m_file) 2250 return "";
1504 return -1;
1505 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_length(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file);
1506 } 2251 }
1507 //-------------------------------------------------------------------------- 2252 return values[0];
1508 2253 }
1509 //========================================================================== 2254 //--------------------------------------------------------------------------
1510 /// 2255
1511 /// @ingroup cpp_kodi_vfs_CFile 2256 //==========================================================================
1512 /// @brief Checks the file access is on end position. 2257 /// @ingroup cpp_kodi_vfs_CFile
1513 /// 2258 /// @brief Retrieve file property values.
1514 /// @return If you've reached the end of the file, AtEnd() returns true. 2259 ///
1515 /// 2260 /// @param[in] type The type of the file property values to retrieve the value for
1516 bool AtEnd() 2261 /// @param[in] name The name of the named property (e.g. Header)
1517 { 2262 /// @return values of requested property, empty vector on failure / non-existance
1518 if (!m_file) 2263 ///
1519 return true; 2264 const std::vector<std::string> GetPropertyValues(FilePropertyTypes type,
1520 int64_t length = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_length(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file); 2265 const std::string& name) const
1521 int64_t position = ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_position(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file); 2266 {
1522 return position >= length; 2267 using namespace kodi::addon;
1523 } 2268
1524 //-------------------------------------------------------------------------- 2269 if (!m_file)
1525
1526 //==========================================================================
1527 ///
1528 /// @ingroup cpp_kodi_vfs_CFile
1529 /// @brief Close an open file.
1530 ///
1531 void Close()
1532 {
1533 if (!m_file)
1534 return;
1535 ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->close_file(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file);
1536 m_file = nullptr;
1537 }
1538 //--------------------------------------------------------------------------
1539
1540 //==========================================================================
1541 ///
1542 /// @ingroup cpp_kodi_vfs_CFile
1543 /// @brief Get the chunk size for an open file.
1544 ///
1545 /// @return The requested size. On error, the value -1 is
1546 /// returned.
1547 ///
1548 int GetChunkSize()
1549 {
1550 if (!m_file)
1551 return -1;
1552 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_chunk_size(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file);
1553 }
1554 //--------------------------------------------------------------------------
1555
1556 //==========================================================================
1557 ///
1558 /// @ingroup cpp_kodi_vfs_CFile
1559 /// @brief retrieve a file property
1560 ///
1561 /// @param[in] type The type of the file property to retrieve the value for
1562 /// @param[in] name The name of a named property value (e.g. Header)
1563 /// @return value of requested property, empty on failure / non-existance
1564 ///
1565 const std::string GetPropertyValue(FilePropertyTypes type, const std::string &name) const
1566 { 2270 {
1567 if (!m_file) 2271 kodi::Log(ADDON_LOG_ERROR,
1568 { 2272 "kodi::vfs::CURLCreate(...) needed to call before GetPropertyValues!");
1569 kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before GetPropertyValue!"); 2273 return std::vector<std::string>();
1570 return "";
1571 }
1572 std::vector<std::string> values = GetPropertyValues(type, name);
1573 if (values.empty()) {
1574 return "";
1575 }
1576 return values[0];
1577 } 2274 }
1578 //-------------------------------------------------------------------------- 2275 int numValues = 0;
1579 2276 char** res(CAddonBase::m_interface->toKodi->kodi_filesystem->get_property_values(
1580 //========================================================================== 2277 CAddonBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str(), &numValues));
1581 /// 2278 if (res)
1582 /// @ingroup cpp_kodi_vfs_CFile
1583 /// @brief retrieve file property values
1584 ///
1585 /// @param[in] type The type of the file property values to retrieve the value for
1586 /// @param[in] name The name of the named property (e.g. Header)
1587 /// @return values of requested property, empty vector on failure / non-existance
1588 ///
1589 const std::vector<std::string> GetPropertyValues(FilePropertyTypes type, const std::string &name) const
1590 { 2279 {
1591 if (!m_file) 2280 std::vector<std::string> vecReturn;
1592 { 2281 for (int i = 0; i < numValues; ++i)
1593 kodi::Log(ADDON_LOG_ERROR, "kodi::vfs::CURLCreate(...) needed to call before GetPropertyValues!");
1594 return std::vector<std::string>();
1595 }
1596 int numValues;
1597 char **res(::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_property_values(
1598 ::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file, type, name.c_str(), &numValues));
1599 if (res)
1600 { 2282 {
1601 std::vector<std::string> vecReturn; 2283 vecReturn.emplace_back(res[i]);
1602 for (int i = 0; i < numValues; ++i)
1603 {
1604 vecReturn.emplace_back(res[i]);
1605 }
1606 ::kodi::addon::CAddonBase::m_interface->toKodi->free_string_array(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, res, numValues);
1607 return vecReturn;
1608 } 2284 }
1609 return std::vector<std::string>(); 2285 CAddonBase::m_interface->toKodi->free_string_array(CAddonBase::m_interface->toKodi->kodiBase,
1610 } 2286 res, numValues);
1611 //-------------------------------------------------------------------------- 2287 return vecReturn;
1612
1613 //==========================================================================
1614 ///
1615 /// @ingroup cpp_kodi_vfs_CFile
1616 /// @brief Get the current download speed of file if loaded from web.
1617 ///
1618 /// @return The current download speed.
1619 ///
1620 double GetFileDownloadSpeed()
1621 {
1622 if (!m_file)
1623 return 0.0;
1624 return ::kodi::addon::CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_download_speed(::kodi::addon::CAddonBase::m_interface->toKodi->kodiBase, m_file);
1625 } 2288 }
1626 //-------------------------------------------------------------------------- 2289 return std::vector<std::string>();
2290 }
2291 //--------------------------------------------------------------------------
1627 2292
1628 private: 2293 //==========================================================================
1629 void* m_file = nullptr; 2294 /// @ingroup cpp_kodi_vfs_CFile
1630 }; 2295 /// @brief Get the current download speed of file if loaded from web.
1631 //@} 2296 ///
1632 //---------------------------------------------------------------------------- 2297 /// @return The current download speed.
2298 ///
2299 double GetFileDownloadSpeed() const
2300 {
2301 using namespace kodi::addon;
2302
2303 if (!m_file)
2304 return 0.0;
2305 return CAddonBase::m_interface->toKodi->kodi_filesystem->get_file_download_speed(
2306 CAddonBase::m_interface->toKodi->kodiBase, m_file);
2307 }
2308 //--------------------------------------------------------------------------
2309
2310private:
2311 void* m_file = nullptr;
2312};
2313//@}
2314//------------------------------------------------------------------------------
2315
2316//}}}
1633 2317
1634} /* namespace vfs */ 2318} /* namespace vfs */
1635} /* namespace kodi */ 2319} /* namespace kodi */
2320
2321#endif /* __cplusplus */