aboutsummaryrefslogtreecommitdiff
path: root/xbmc/addons/VFSEntry.h
blob: c11fca05dac1f816432ef5ad772a616177f758a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
 *  Copyright (C) 2013 Arne Morten Kvarving
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "FileItem.h"
#include "addons/binary-addons/AddonDll.h"
#include "addons/binary-addons/AddonInstanceHandler.h"
#include "addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h"
#include "filesystem/IDirectory.h"
#include "filesystem/IFile.h"
#include "filesystem/IFileDirectory.h"

#include <utility>

namespace ADDON
{
struct AddonEvent;

class CVFSEntry;
typedef std::shared_ptr<CVFSEntry> VFSEntryPtr;

class CVFSAddonCache : public CAddonDllInformer
{
public:
  virtual ~CVFSAddonCache();
  void Init();
  void Deinit();
  const std::vector<VFSEntryPtr> GetAddonInstances();
  VFSEntryPtr GetAddonInstance(const std::string& strId);

protected:
  void Update(const std::string& id);
  void OnEvent(const AddonEvent& event);
  bool IsInUse(const std::string& id) override;

  CCriticalSection m_critSection;
  std::vector<VFSEntryPtr> m_addonsInstances;
};

  //! \brief A virtual filesystem entry add-on.
  class CVFSEntry : public IAddonInstanceHandler
  {
  public:
    //! \brief A structure encapsulating properties of supplied protocol.
    struct ProtocolInfo
    {
      bool supportPath;      //!< Protocol has path in addition to server name
      bool supportUsername;  //!< Protocol uses logins
      bool supportPassword;  //!< Protocol supports passwords
      bool supportPort;      //!< Protocol supports port customization
      bool supportBrowsing;  //!< Protocol supports server browsing
      bool supportWrite;     //!< Protocol supports write operations
      int defaultPort;       //!< Default port to use for protocol
      std::string type;      //!< URL type for protocol
      int label;             //!< String ID to use as label in dialog

      //! \brief The constructor reads the info from an add-on info structure.
      ProtocolInfo(const AddonInfoPtr& addonInfo);
    };

    //! \brief Construct from add-on properties.
    //! \param addonInfo General addon properties
    explicit CVFSEntry(const AddonInfoPtr& addonInfo);
    ~CVFSEntry() override;

    // Things that MUST be supplied by the child classes
    void* Open(const CURL& url);
    void* OpenForWrite(const CURL& url, bool bOverWrite);
    bool Exists(const CURL& url);
    int Stat(const CURL& url, struct __stat64* buffer);
    ssize_t Read(void* ctx, void* lpBuf, size_t uiBufSize);
    ssize_t Write(void* ctx, const void* lpBuf, size_t uiBufSize);
    int64_t Seek(void* ctx, int64_t iFilePosition, int iWhence = SEEK_SET);
    int Truncate(void* ctx, int64_t size);
    void Close(void* ctx);
    int64_t GetPosition(void* ctx);
    int64_t GetLength(void* ctx);
    int GetChunkSize(void* ctx);
    int IoControl(void* ctx, XFILE::EIoControl request, void* param);
    bool Delete(const CURL& url);
    bool Rename(const CURL& url, const CURL& url2);

    bool GetDirectory(const CURL& url, CFileItemList& items, void* ctx);
    bool DirectoryExists(const CURL& url);
    bool RemoveDirectory(const CURL& url);
    bool CreateDirectory(const CURL& url);
    void ClearOutIdle();
    void DisconnectAll();

    bool ContainsFiles(const CURL& url, CFileItemList& items);

    const std::string& GetProtocols() const { return m_protocols; }
    const std::string& GetExtensions() const { return m_extensions; }
    bool HasFiles() const { return m_files; }
    bool HasDirectories() const { return m_directories; }
    bool HasFileDirectories() const { return m_filedirectories; }
    const std::string& GetZeroconfType() const { return m_zeroconf; }
    const ProtocolInfo& GetProtocolInfo() const { return m_protocolInfo; }
  protected:
    std::string m_protocols;  //!< Protocols for VFS entry.
    std::string m_extensions; //!< Extensions for VFS entry.
    std::string m_zeroconf;   //!< Zero conf announce string for VFS protocol.
    bool m_files;             //!< Vfs entry can read files.
    bool m_directories;       //!< VFS entry can list directories.
    bool m_filedirectories;   //!< VFS entry contains file directories.
    ProtocolInfo m_protocolInfo; //!< Info about protocol for network dialog.
  };

  //! \brief Wrapper equipping a CVFSEntry with an IFile interface.
  //! \details Needed as CVFSEntry implements several VFS interfaces
  //!          with overlapping methods.
  class CVFSEntryIFileWrapper : public XFILE::IFile
  {
  public:
    //! \brief The constructor initializes the reference to the wrapped CVFSEntry.
    //! \param ptr The CVFSEntry to wrap.
    explicit CVFSEntryIFileWrapper(VFSEntryPtr ptr);

    //! \brief Empty destructor.
    ~CVFSEntryIFileWrapper() override;

    //! \brief Open a file.
    //! \param[in] url URL to open.
    //! \returns True if file was opened, false otherwise.
    bool Open(const CURL& url) override;

    //! \brief Open a file for writing.
    //! \param[in] url URL to open.
    //! \param[in] bOverWrite If true, overwrite an existing file.
    //! \returns True if file was opened, false otherwise.
    bool OpenForWrite(const CURL& url, bool bOverWrite) override;

    //! \brief Check for file existence.
    //! \param[in] url URL of file.
    bool Exists(const CURL& url) override;

    //! \brief Stat a file.
    //! \param[in] url URL of file.
    //! \param[out] buffer The stat info.
    //! \details Returns 0 on success, non-zero otherwise (see fstat() return values).
    int  Stat(const CURL& url, struct __stat64* buffer) override;

    //! \brief Read data from file:
    //! \param lpBuf Buffer to read data into.
    //! \param[in] uiBufSize Number of bytes to read.
    //! \returns Number of bytes read.
    ssize_t Read(void* lpBuf, size_t uiBufSize) override;

    //! \brief Write data to file.
    //! \param[in] lpBuf Data to write.
    //! \param[in] uiBufSize Number of bytes to write.
    //! \returns Number of bytes written.
    ssize_t Write(const void* lpBuf, size_t uiBufSize) override;

    //! \brief Seek in file.
    //! \param[in] iFilePosition Position to seek to.
    //! \param[in] whence Origin for position.
    //! \returns New file position.
    int64_t Seek(int64_t iFilePosition, int whence = SEEK_SET) override;

    //! \brief Truncate a file.
    //! \param[in] size Size of new file.
    int Truncate(int64_t size) override;

    //! \brief Close file.
    void Close() override;

    //! \brief Obtain current file position.
    int64_t GetPosition() override;

    //! \brief Obtain file size.
    int64_t GetLength() override;

    //! \brief Obtain chunksize of file.
    int GetChunkSize() override;

    //! \brief Perform I/O controls for file.
    int IoControl(XFILE::EIoControl request, void* param) override;

    //! \brief Delete a file.
    //! \param[in] url URL of file to delete.
    bool Delete(const CURL& url) override;

    //! \brief Rename a file.
    //! \param[in] url URL of file to rename.
    //! \param[in] url2 New URL of file.
    bool Rename(const CURL& url, const CURL& url2) override;
  protected:
    void* m_context = nullptr; //!< Opaque add-on specific context for opened file.
    VFSEntryPtr m_addon; //!< Pointer to wrapped CVFSEntry.
  };

  //! \brief Wrapper equpping a CVFSEntry with an IDirectory interface.
  //! \details Needed as CVFSEntry implements several VFS interfaces
  //!          with overlapping methods.
  class CVFSEntryIDirectoryWrapper : public XFILE::IDirectory
  {
  public:
    //! \brief The constructor initializes the reference to the wrapped CVFSEntry.
    //! \param ptr The CVFSEntry to wrap.
    explicit CVFSEntryIDirectoryWrapper(VFSEntryPtr ptr);

    //! \brief Empty destructor.
    ~CVFSEntryIDirectoryWrapper() override = default;

    //! \brief Return directory listing.
    //! \param[in] url URL to file to list.
    //! \param items List of items in file.
    //! \return True if listing succeeded, false otherwise.
    bool GetDirectory(const CURL& url, CFileItemList& items) override;

    //! \brief Check if directory exists.
    //! \param[in] url URL to check.
    bool Exists(const CURL& url) override;

    //! \brief Delete directory.
    //! \param[in] url URL to delete.
    bool Remove(const CURL& url) override;

    //! \brief Create directory.
    //! \param[in] url URL to delete.
    bool Create(const CURL& url) override;

    //! \brief Static helper for doing a keyboard callback.
    static bool DoGetKeyboardInput(void* context, const char* heading,
                                   char** input, bool hidden_input);

    //! \brief Get keyboard input.
    bool GetKeyboardInput2(const char* heading, char** input, bool hidden_input);

    //! \brief Static helper for displaying an error dialog.
    static void DoSetErrorDialog(void* ctx, const char* heading,
                                 const char* line1, const char* line2,
                                 const char* line3);

    //! \brief Show an error dialog.
    void SetErrorDialog2(const char* heading, const char* line1,
                         const char* line2, const char* line3);

    //! \brief Static helper for requiring authentication.
    static void DoRequireAuthentication(void* ctx, const char* url);

    //! \brief Require authentication.
    void RequireAuthentication2(const CURL& url);
  protected:
    VFSEntryPtr m_addon; //!< Pointer to wrapper CVFSEntry.
  };

  //! \brief Wrapper equpping a CVFSEntry with an IFileDirectory interface.
  //! \details Needed as CVFSEntry implements several VFS interfaces
  //!          with overlapping methods.
  class CVFSEntryIFileDirectoryWrapper : public XFILE::IFileDirectory,
                                         public CVFSEntryIDirectoryWrapper
  {
  public:
    //! \brief The constructor initializes the reference to the wrapped CVFSEntry.
    //! \param ptr The CVFSEntry to wrap.
    explicit CVFSEntryIFileDirectoryWrapper(VFSEntryPtr ptr)
      : CVFSEntryIDirectoryWrapper(std::move(ptr))
    {
    }

    //! \brief Empty destructor.
    ~CVFSEntryIFileDirectoryWrapper() override = default;

    //! \brief Check if the given file should be treated as a directory.
    //! \param[in] url URL for file to probe.
    bool ContainsFiles(const CURL& url) override
    {
      return m_addon->ContainsFiles(url, m_items);
    }

    //! \brief Return directory listing.
    //! \param[in] url URL to file to list.
    //! \param items List of items in file.
    //! \return True if listing succeeded, false otherwise.
    bool GetDirectory(const CURL& url, CFileItemList& items) override
    {
      return CVFSEntryIDirectoryWrapper::GetDirectory(url, items);
    }

    //! \brief Check if directory exists.
    //! \param[in] url URL to check.
    bool Exists(const CURL& url) override
    {
      return CVFSEntryIDirectoryWrapper::Exists(url);
    }

    //! \brief Delete directory.
    //! \param[in] url URL to delete.
    bool Remove(const CURL& url) override
    {
      return CVFSEntryIDirectoryWrapper::Remove(url);
    }

    //! \brief Create directory.
    //! \param[in] url URL to delete.
    bool Create(const CURL& url) override
    {
      return CVFSEntryIDirectoryWrapper::Create(url);
    }

    CFileItemList m_items; //!< Internal list of items, used for cache purposes.
  };

} /*namespace ADDON*/