1 /* 2 * Copyright (C) 2013 Arne Morten Kvarving 3 * 4 * SPDX-License-Identifier: GPL-2.0-or-later 5 * See LICENSES/README.md for more information. 6 */ 7 8 #pragma once 9 10 #include "addons/binary-addons/AddonInstanceHandler.h" 11 #include "addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h" 12 #include "filesystem/IDirectory.h" 13 #include "filesystem/IFile.h" 14 #include "filesystem/IFileDirectory.h" 15 16 #include <utility> 17 18 namespace ADDON 19 { 20 21 class CVFSEntry; 22 typedef std::shared_ptr<CVFSEntry> VFSEntryPtr; 23 24 class CVFSAddonCache : public CAddonDllInformer 25 { 26 public: 27 virtual ~CVFSAddonCache(); 28 void Init(); 29 void Deinit(); 30 const std::vector<VFSEntryPtr> GetAddonInstances(); 31 VFSEntryPtr GetAddonInstance(const std::string& strId); 32 33 protected: 34 void Update(const std::string& id); 35 void OnEvent(const AddonEvent& event); 36 bool IsInUse(const std::string& id) override; 37 38 CCriticalSection m_critSection; 39 std::vector<VFSEntryPtr> m_addonsInstances; 40 }; 41 42 //! \brief A virtual filesystem entry add-on. 43 class CVFSEntry : public IAddonInstanceHandler 44 { 45 public: 46 //! \brief A structure encapsulating properties of supplied protocol. 47 struct ProtocolInfo 48 { 49 bool supportPath; //!< Protocol has path in addition to server name 50 bool supportUsername; //!< Protocol uses logins 51 bool supportPassword; //!< Protocol supports passwords 52 bool supportPort; //!< Protocol supports port customization 53 bool supportBrowsing; //!< Protocol supports server browsing 54 bool supportWrite; //!< Protocol supports write operations 55 int defaultPort; //!< Default port to use for protocol 56 std::string type; //!< URL type for protocol 57 int label; //!< String ID to use as label in dialog 58 59 //! \brief The constructor reads the info from an add-on info structure. 60 ProtocolInfo(const AddonInfoPtr& addonInfo); 61 }; 62 63 //! \brief Construct from add-on properties. 64 //! \param addonInfo General addon properties 65 explicit CVFSEntry(const AddonInfoPtr& addonInfo); 66 ~CVFSEntry() override; 67 68 // Things that MUST be supplied by the child classes 69 void* Open(const CURL& url); 70 void* OpenForWrite(const CURL& url, bool bOverWrite); 71 bool Exists(const CURL& url); 72 int Stat(const CURL& url, struct __stat64* buffer); 73 ssize_t Read(void* ctx, void* lpBuf, size_t uiBufSize); 74 ssize_t Write(void* ctx, const void* lpBuf, size_t uiBufSize); 75 int64_t Seek(void* ctx, int64_t iFilePosition, int iWhence = SEEK_SET); 76 int Truncate(void* ctx, int64_t size); 77 void Close(void* ctx); 78 int64_t GetPosition(void* ctx); 79 int64_t GetLength(void* ctx); 80 int GetChunkSize(void* ctx); 81 int IoControl(void* ctx, XFILE::EIoControl request, void* param); 82 bool Delete(const CURL& url); 83 bool Rename(const CURL& url, const CURL& url2); 84 85 bool GetDirectory(const CURL& url, CFileItemList& items, void* ctx); 86 bool DirectoryExists(const CURL& url); 87 bool RemoveDirectory(const CURL& url); 88 bool CreateDirectory(const CURL& url); 89 void ClearOutIdle(); 90 void DisconnectAll(); 91 92 bool ContainsFiles(const CURL& url, CFileItemList& items); 93 GetProtocols()94 const std::string& GetProtocols() const { return m_protocols; } GetExtensions()95 const std::string& GetExtensions() const { return m_extensions; } HasFiles()96 bool HasFiles() const { return m_files; } HasDirectories()97 bool HasDirectories() const { return m_directories; } HasFileDirectories()98 bool HasFileDirectories() const { return m_filedirectories; } GetZeroconfType()99 const std::string& GetZeroconfType() const { return m_zeroconf; } GetProtocolInfo()100 const ProtocolInfo& GetProtocolInfo() const { return m_protocolInfo; } 101 protected: 102 std::string m_protocols; //!< Protocols for VFS entry. 103 std::string m_extensions; //!< Extensions for VFS entry. 104 std::string m_zeroconf; //!< Zero conf announce string for VFS protocol. 105 bool m_files; //!< Vfs entry can read files. 106 bool m_directories; //!< VFS entry can list directories. 107 bool m_filedirectories; //!< VFS entry contains file directories. 108 ProtocolInfo m_protocolInfo; //!< Info about protocol for network dialog. 109 AddonInstance_VFSEntry m_struct; //!< VFS callback table 110 }; 111 112 //! \brief Wrapper equipping a CVFSEntry with an IFile interface. 113 //! \details Needed as CVFSEntry implements several VFS interfaces 114 //! with overlapping methods. 115 class CVFSEntryIFileWrapper : public XFILE::IFile 116 { 117 public: 118 //! \brief The constructor initializes the reference to the wrapped CVFSEntry. 119 //! \param ptr The CVFSEntry to wrap. 120 explicit CVFSEntryIFileWrapper(VFSEntryPtr ptr); 121 122 //! \brief Empty destructor. 123 ~CVFSEntryIFileWrapper() override; 124 125 //! \brief Open a file. 126 //! \param[in] url URL to open. 127 //! \returns True if file was opened, false otherwise. 128 bool Open(const CURL& url) override; 129 130 //! \brief Open a file for writing. 131 //! \param[in] url URL to open. 132 //! \param[in] bOverWrite If true, overwrite an existing file. 133 //! \returns True if file was opened, false otherwise. 134 bool OpenForWrite(const CURL& url, bool bOverWrite) override; 135 136 //! \brief Check for file existence. 137 //! \param[in] url URL of file. 138 bool Exists(const CURL& url) override; 139 140 //! \brief Stat a file. 141 //! \param[in] url URL of file. 142 //! \param[out] buffer The stat info. 143 //! \details Returns 0 on success, non-zero otherwise (see fstat() return values). 144 int Stat(const CURL& url, struct __stat64* buffer) override; 145 146 //! \brief Read data from file: 147 //! \param lpBuf Buffer to read data into. 148 //! \param[in] uiBufSize Number of bytes to read. 149 //! \returns Number of bytes read. 150 ssize_t Read(void* lpBuf, size_t uiBufSize) override; 151 152 //! \brief Write data to file. 153 //! \param[in] lpBuf Data to write. 154 //! \param[in] uiBufSize Number of bytes to write. 155 //! \returns Number of bytes written. 156 ssize_t Write(const void* lpBuf, size_t uiBufSize) override; 157 158 //! \brief Seek in file. 159 //! \param[in] iFilePosition Position to seek to. 160 //! \param[in] whence Origin for position. 161 //! \returns New file position. 162 int64_t Seek(int64_t iFilePosition, int whence = SEEK_SET) override; 163 164 //! \brief Truncate a file. 165 //! \param[in] size Size of new file. 166 int Truncate(int64_t size) override; 167 168 //! \brief Close file. 169 void Close() override; 170 171 //! \brief Obtain current file position. 172 int64_t GetPosition() override; 173 174 //! \brief Obtain file size. 175 int64_t GetLength() override; 176 177 //! \brief Obtain chunksize of file. 178 int GetChunkSize() override; 179 180 //! \brief Perform I/O controls for file. 181 int IoControl(XFILE::EIoControl request, void* param) override; 182 183 //! \brief Delete a file. 184 //! \param[in] url URL of file to delete. 185 bool Delete(const CURL& url) override; 186 187 //! \brief Rename a file. 188 //! \param[in] url URL of file to rename. 189 //! \param[in] url2 New URL of file. 190 bool Rename(const CURL& url, const CURL& url2) override; 191 protected: 192 void* m_context; //!< Opaque add-on specific context for opened file. 193 VFSEntryPtr m_addon; //!< Pointer to wrapped CVFSEntry. 194 }; 195 196 //! \brief Wrapper equpping a CVFSEntry with an IDirectory interface. 197 //! \details Needed as CVFSEntry implements several VFS interfaces 198 //! with overlapping methods. 199 class CVFSEntryIDirectoryWrapper : public XFILE::IDirectory 200 { 201 public: 202 //! \brief The constructor initializes the reference to the wrapped CVFSEntry. 203 //! \param ptr The CVFSEntry to wrap. 204 explicit CVFSEntryIDirectoryWrapper(VFSEntryPtr ptr); 205 206 //! \brief Empty destructor. 207 ~CVFSEntryIDirectoryWrapper() override = default; 208 209 //! \brief Return directory listing. 210 //! \param[in] url URL to file to list. 211 //! \param items List of items in file. 212 //! \return True if listing succeeded, false otherwise. 213 bool GetDirectory(const CURL& url, CFileItemList& items) override; 214 215 //! \brief Check if directory exists. 216 //! \param[in] url URL to check. 217 bool Exists(const CURL& url) override; 218 219 //! \brief Delete directory. 220 //! \param[in] url URL to delete. 221 bool Remove(const CURL& url) override; 222 223 //! \brief Create directory. 224 //! \param[in] url URL to delete. 225 bool Create(const CURL& url) override; 226 227 //! \brief Static helper for doing a keyboard callback. 228 static bool DoGetKeyboardInput(void* context, const char* heading, 229 char** input, bool hidden_input); 230 231 //! \brief Get keyboard input. 232 bool GetKeyboardInput2(const char* heading, char** input, bool hidden_input); 233 234 //! \brief Static helper for displaying an error dialog. 235 static void DoSetErrorDialog(void* ctx, const char* heading, 236 const char* line1, const char* line2, 237 const char* line3); 238 239 //! \brief Show an error dialog. 240 void SetErrorDialog2(const char* heading, const char* line1, 241 const char* line2, const char* line3); 242 243 //! \brief Static helper for requiring authentication. 244 static void DoRequireAuthentication(void* ctx, const char* url); 245 246 //! \brief Require authentication. 247 void RequireAuthentication2(const CURL& url); 248 protected: 249 VFSEntryPtr m_addon; //!< Pointer to wrapper CVFSEntry. 250 }; 251 252 //! \brief Wrapper equpping a CVFSEntry with an IFileDirectory interface. 253 //! \details Needed as CVFSEntry implements several VFS interfaces 254 //! with overlapping methods. 255 class CVFSEntryIFileDirectoryWrapper : public XFILE::IFileDirectory, 256 public CVFSEntryIDirectoryWrapper 257 { 258 public: 259 //! \brief The constructor initializes the reference to the wrapped CVFSEntry. 260 //! \param ptr The CVFSEntry to wrap. CVFSEntryIFileDirectoryWrapper(VFSEntryPtr ptr)261 explicit CVFSEntryIFileDirectoryWrapper(VFSEntryPtr ptr) 262 : CVFSEntryIDirectoryWrapper(std::move(ptr)) 263 { 264 } 265 266 //! \brief Empty destructor. 267 ~CVFSEntryIFileDirectoryWrapper() override = default; 268 269 //! \brief Check if the given file should be treated as a directory. 270 //! \param[in] url URL for file to probe. ContainsFiles(const CURL & url)271 bool ContainsFiles(const CURL& url) override 272 { 273 return m_addon->ContainsFiles(url, m_items); 274 } 275 276 //! \brief Return directory listing. 277 //! \param[in] url URL to file to list. 278 //! \param items List of items in file. 279 //! \return True if listing succeeded, false otherwise. GetDirectory(const CURL & url,CFileItemList & items)280 bool GetDirectory(const CURL& url, CFileItemList& items) override 281 { 282 return CVFSEntryIDirectoryWrapper::GetDirectory(url, items); 283 } 284 285 //! \brief Check if directory exists. 286 //! \param[in] url URL to check. Exists(const CURL & url)287 bool Exists(const CURL& url) override 288 { 289 return CVFSEntryIDirectoryWrapper::Exists(url); 290 } 291 292 //! \brief Delete directory. 293 //! \param[in] url URL to delete. Remove(const CURL & url)294 bool Remove(const CURL& url) override 295 { 296 return CVFSEntryIDirectoryWrapper::Remove(url); 297 } 298 299 //! \brief Create directory. 300 //! \param[in] url URL to delete. Create(const CURL & url)301 bool Create(const CURL& url) override 302 { 303 return CVFSEntryIDirectoryWrapper::Create(url); 304 } 305 306 CFileItemList m_items; //!< Internal list of items, used for cache purposes. 307 }; 308 309 } /*namespace ADDON*/ 310