[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / filesystem / NptXbmcFile.cpp
blob04f3bae7092f6c4b781c648564f1a935f19611f0
1 /*
2 * Neptune - Files :: XBMC Implementation
4 * Copyright (c) 2002-2008, Axiomatic Systems, LLC.
5 * All rights reserved.
7 * SPDX-License-Identifier: BSD-3-Clause
8 * See LICENSES/README.md for more information.
9 */
11 /*----------------------------------------------------------------------
12 | includes
13 +---------------------------------------------------------------------*/
14 #include "File.h"
15 #include "FileFactory.h"
16 #include "URL.h"
18 #include <limits>
20 #include <Neptune/Source/Core/NptDebug.h>
21 #include <Neptune/Source/Core/NptFile.h>
22 #include <Neptune/Source/Core/NptStrings.h>
23 #include <Neptune/Source/Core/NptUtils.h>
25 #ifdef TARGET_WINDOWS
26 #define S_IWUSR _S_IWRITE
27 #define S_ISDIR(m) ((m & _S_IFDIR) != 0)
28 #define S_ISREG(m) ((m & _S_IFREG) != 0)
29 #endif
31 using namespace XFILE;
33 typedef NPT_Reference<IFile> NPT_XbmcFileReference;
35 /*----------------------------------------------------------------------
36 | NPT_XbmcFileStream
37 +---------------------------------------------------------------------*/
38 class NPT_XbmcFileStream
40 public:
41 // constructors and destructor
42 explicit NPT_XbmcFileStream(const NPT_XbmcFileReference& file) : m_FileReference(file) {}
44 // NPT_FileInterface methods
45 NPT_Result Seek(NPT_Position offset);
46 NPT_Result Tell(NPT_Position& offset);
47 NPT_Result Flush();
49 protected:
50 // constructors and destructors
51 virtual ~NPT_XbmcFileStream() = default;
53 // members
54 NPT_XbmcFileReference m_FileReference;
57 /*----------------------------------------------------------------------
58 | NPT_XbmcFileStream::Seek
59 +---------------------------------------------------------------------*/
60 NPT_Result
61 NPT_XbmcFileStream::Seek(NPT_Position offset)
63 int64_t result;
65 result = m_FileReference->Seek(offset, SEEK_SET) ;
66 if (result >= 0) {
67 return NPT_SUCCESS;
68 } else {
69 return NPT_FAILURE;
73 /*----------------------------------------------------------------------
74 | NPT_XbmcFileStream::Tell
75 +---------------------------------------------------------------------*/
76 NPT_Result
77 NPT_XbmcFileStream::Tell(NPT_Position& offset)
79 int64_t result = m_FileReference->GetPosition();
80 if (result >= 0) {
81 offset = (NPT_Position)result;
82 return NPT_SUCCESS;
83 } else {
84 return NPT_FAILURE;
88 /*----------------------------------------------------------------------
89 | NPT_XbmcFileStream::Flush
90 +---------------------------------------------------------------------*/
91 NPT_Result
92 NPT_XbmcFileStream::Flush()
94 m_FileReference->Flush();
95 return NPT_SUCCESS;
98 /*----------------------------------------------------------------------
99 | NPT_XbmcFileInputStream
100 +---------------------------------------------------------------------*/
101 class NPT_XbmcFileInputStream : public NPT_InputStream,
102 private NPT_XbmcFileStream
105 public:
106 // constructors and destructor
107 explicit NPT_XbmcFileInputStream(NPT_XbmcFileReference& file) :
108 NPT_XbmcFileStream(file) {}
110 // NPT_InputStream methods
111 NPT_Result Read(void* buffer,
112 NPT_Size bytes_to_read,
113 NPT_Size* bytes_read) override;
114 NPT_Result Seek(NPT_Position offset) override {
115 return NPT_XbmcFileStream::Seek(offset);
117 NPT_Result Tell(NPT_Position& offset) override {
118 return NPT_XbmcFileStream::Tell(offset);
120 NPT_Result GetSize(NPT_LargeSize& size) override;
121 NPT_Result GetAvailable(NPT_LargeSize& available) override;
124 /*----------------------------------------------------------------------
125 | NPT_XbmcFileInputStream::Read
126 +---------------------------------------------------------------------*/
127 NPT_Result
128 NPT_XbmcFileInputStream::Read(void* buffer,
129 NPT_Size bytes_to_read,
130 NPT_Size* bytes_read)
132 unsigned int nb_read;
134 // check the parameters
135 if (buffer == NULL) {
136 return NPT_ERROR_INVALID_PARAMETERS;
139 // read from the file
140 nb_read = m_FileReference->Read(buffer, bytes_to_read);
141 if (nb_read > 0) {
142 if (bytes_read) *bytes_read = (NPT_Size)nb_read;
143 return NPT_SUCCESS;
144 } else {
145 if (bytes_read) *bytes_read = 0;
146 return NPT_ERROR_EOS;
147 //} else { // currently no way to indicate failure
148 // if (bytes_read) *bytes_read = 0;
149 // return NPT_ERROR_READ_FAILED;
153 /*----------------------------------------------------------------------
154 | NPT_XbmcFileInputStream::GetSize
155 +---------------------------------------------------------------------*/
156 NPT_Result
157 NPT_XbmcFileInputStream::GetSize(NPT_LargeSize& size)
159 size = m_FileReference->GetLength();
160 return NPT_SUCCESS;
163 /*----------------------------------------------------------------------
164 | NPT_XbmcFileInputStream::GetAvailable
165 +---------------------------------------------------------------------*/
166 NPT_Result
167 NPT_XbmcFileInputStream::GetAvailable(NPT_LargeSize& available)
169 int64_t offset = m_FileReference->GetPosition();
170 NPT_LargeSize size = 0;
172 if (NPT_SUCCEEDED(GetSize(size)) && offset >= 0 && (NPT_LargeSize)offset <= size) {
173 available = size - offset;
174 return NPT_SUCCESS;
175 } else {
176 available = 0;
177 return NPT_FAILURE;
181 /*----------------------------------------------------------------------
182 | NPT_XbmcFileOutputStream
183 +---------------------------------------------------------------------*/
184 class NPT_XbmcFileOutputStream : public NPT_OutputStream,
185 private NPT_XbmcFileStream
187 public:
188 // constructors and destructor
189 explicit NPT_XbmcFileOutputStream(NPT_XbmcFileReference& file) :
190 NPT_XbmcFileStream(file) {}
192 // NPT_OutputStream methods
193 NPT_Result Write(const void* buffer,
194 NPT_Size bytes_to_write,
195 NPT_Size* bytes_written) override;
196 NPT_Result Seek(NPT_Position offset) override {
197 return NPT_XbmcFileStream::Seek(offset);
199 NPT_Result Tell(NPT_Position& offset) override {
200 return NPT_XbmcFileStream::Tell(offset);
202 NPT_Result Flush() override {
203 return NPT_XbmcFileStream::Flush();
207 /*----------------------------------------------------------------------
208 | NPT_XbmcFileOutputStream::Write
209 +---------------------------------------------------------------------*/
210 NPT_Result
211 NPT_XbmcFileOutputStream::Write(const void* buffer,
212 NPT_Size bytes_to_write,
213 NPT_Size* bytes_written)
215 int nb_written;
216 nb_written = m_FileReference->Write(buffer, bytes_to_write);
218 if (nb_written > 0) {
219 if (bytes_written) *bytes_written = (NPT_Size)nb_written;
220 return NPT_SUCCESS;
221 } else {
222 if (bytes_written) *bytes_written = 0;
223 return NPT_ERROR_WRITE_FAILED;
227 /*----------------------------------------------------------------------
228 | NPT_XbmcFile
229 +---------------------------------------------------------------------*/
230 class NPT_XbmcFile: public NPT_FileInterface
232 public:
233 // constructors and destructor
234 explicit NPT_XbmcFile(NPT_File& delegator);
235 ~NPT_XbmcFile() override;
237 // NPT_FileInterface methods
238 NPT_Result Open(OpenMode mode) override;
239 NPT_Result Close() override;
240 NPT_Result GetInputStream(NPT_InputStreamReference& stream) override;
241 NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) override;
243 private:
244 // members
245 NPT_File& m_Delegator;
246 OpenMode m_Mode;
247 NPT_XbmcFileReference m_FileReference;
250 /*----------------------------------------------------------------------
251 | NPT_XbmcFile::NPT_XbmcFile
252 +---------------------------------------------------------------------*/
253 NPT_XbmcFile::NPT_XbmcFile(NPT_File& delegator) :
254 m_Delegator(delegator),
255 m_Mode(0)
259 /*----------------------------------------------------------------------
260 | NPT_XbmcFile::~NPT_XbmcFile
261 +---------------------------------------------------------------------*/
262 NPT_XbmcFile::~NPT_XbmcFile()
264 Close();
267 /*----------------------------------------------------------------------
268 | NPT_XbmcFile::Open
269 +---------------------------------------------------------------------*/
270 NPT_Result
271 NPT_XbmcFile::Open(NPT_File::OpenMode mode)
273 NPT_XbmcFileReference file;
275 // check if we're already open
276 if (!m_FileReference.IsNull()) {
277 return NPT_ERROR_FILE_ALREADY_OPEN;
280 // store the mode
281 m_Mode = mode;
283 // check for special names
284 const char* name = (const char*)m_Delegator.GetPath();
285 if (NPT_StringsEqual(name, NPT_FILE_STANDARD_INPUT)) {
286 return NPT_ERROR_FILE_NOT_READABLE;
287 } else if (NPT_StringsEqual(name, NPT_FILE_STANDARD_OUTPUT)) {
288 return NPT_ERROR_FILE_NOT_WRITABLE;
289 } else if (NPT_StringsEqual(name, NPT_FILE_STANDARD_ERROR)) {
290 return NPT_ERROR_FILE_NOT_WRITABLE;
291 } else {
293 file = CFileFactory::CreateLoader(name);
294 if (file.IsNull()) {
295 return NPT_ERROR_NO_SUCH_FILE;
298 bool result;
299 CURL* url = new CURL(name);
301 // compute mode
302 if (mode & NPT_FILE_OPEN_MODE_WRITE) {
303 result = file->OpenForWrite(*url, (mode & NPT_FILE_OPEN_MODE_TRUNCATE)?true:false);
304 } else {
305 result = file->Open(*url);
308 delete url;
309 if (!result) return NPT_ERROR_NO_SUCH_FILE;
312 // store reference
313 m_FileReference = file;
315 return NPT_SUCCESS;
318 /*----------------------------------------------------------------------
319 | NPT_XbmcFile::Close
320 +---------------------------------------------------------------------*/
321 NPT_Result
322 NPT_XbmcFile::Close()
324 // release the file reference
325 m_FileReference = NULL;
327 // reset the mode
328 m_Mode = 0;
330 return NPT_SUCCESS;
333 /*----------------------------------------------------------------------
334 | NPT_XbmcFile::GetInputStream
335 +---------------------------------------------------------------------*/
336 NPT_Result
337 NPT_XbmcFile::GetInputStream(NPT_InputStreamReference& stream)
339 // default value
340 stream = NULL;
342 // check that the file is open
343 if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN;
345 // check that the mode is compatible
346 if (!(m_Mode & NPT_FILE_OPEN_MODE_READ)) {
347 return NPT_ERROR_FILE_NOT_READABLE;
350 // create a stream
351 stream = new NPT_XbmcFileInputStream(m_FileReference);
353 return NPT_SUCCESS;
356 /*----------------------------------------------------------------------
357 | NPT_XbmcFile::GetOutputStream
358 +---------------------------------------------------------------------*/
359 NPT_Result
360 NPT_XbmcFile::GetOutputStream(NPT_OutputStreamReference& stream)
362 // default value
363 stream = NULL;
365 // check that the file is open
366 if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN;
368 // check that the mode is compatible
369 if (!(m_Mode & NPT_FILE_OPEN_MODE_WRITE)) {
370 return NPT_ERROR_FILE_NOT_WRITABLE;
373 // create a stream
374 stream = new NPT_XbmcFileOutputStream(m_FileReference);
376 return NPT_SUCCESS;
379 static NPT_Result
380 MapErrno(int err) {
381 switch (err) {
382 case EACCES: return NPT_ERROR_PERMISSION_DENIED;
383 case EPERM: return NPT_ERROR_PERMISSION_DENIED;
384 case ENOENT: return NPT_ERROR_NO_SUCH_FILE;
385 case ENAMETOOLONG: return NPT_ERROR_INVALID_PARAMETERS;
386 case EBUSY: return NPT_ERROR_FILE_BUSY;
387 case EROFS: return NPT_ERROR_FILE_NOT_WRITABLE;
388 case ENOTDIR: return NPT_ERROR_FILE_NOT_DIRECTORY;
389 case EEXIST: return NPT_ERROR_FILE_ALREADY_EXISTS;
390 case ENOSPC: return NPT_ERROR_FILE_NOT_ENOUGH_SPACE;
391 case ENOTEMPTY: return NPT_ERROR_DIRECTORY_NOT_EMPTY;
392 default: return NPT_ERROR_ERRNO(err);
395 /*----------------------------------------------------------------------
396 | NPT_FilePath::Separator
397 +---------------------------------------------------------------------*/
398 const char* const NPT_FilePath::Separator = "/";
400 /*----------------------------------------------------------------------
401 | NPT_File::NPT_File
402 +---------------------------------------------------------------------*/
403 NPT_File::NPT_File(const char* path) : m_Path(path)
405 m_Delegate = new NPT_XbmcFile(*this);
408 /*----------------------------------------------------------------------
409 | NPT_File::operator=
410 +---------------------------------------------------------------------*/
411 NPT_File&
412 NPT_File::operator=(const NPT_File& file)
414 if (this != &file) {
415 delete m_Delegate;
416 m_Path = file.m_Path;
417 m_Delegate = new NPT_XbmcFile(*this);
419 return *this;
422 /*----------------------------------------------------------------------
423 | NPT_File::GetRoots
424 +---------------------------------------------------------------------*/
425 NPT_Result
426 NPT_File::GetRoots(NPT_List<NPT_String>& roots)
428 return NPT_FAILURE;
431 /*----------------------------------------------------------------------
432 | NPT_File::CreateDir
433 +---------------------------------------------------------------------*/
434 NPT_Result
435 NPT_File::CreateDir(const char* path)
437 return NPT_ERROR_PERMISSION_DENIED;
440 /*----------------------------------------------------------------------
441 | NPT_File::RemoveFile
442 +---------------------------------------------------------------------*/
443 NPT_Result
444 NPT_File::RemoveFile(const char* path)
446 return NPT_ERROR_PERMISSION_DENIED;
449 /*----------------------------------------------------------------------
450 | NPT_File::RemoveDir
451 +---------------------------------------------------------------------*/
452 NPT_Result
453 NPT_File::RemoveDir(const char* path)
455 return NPT_ERROR_PERMISSION_DENIED;
458 /*----------------------------------------------------------------------
459 | NPT_File::Rename
460 +---------------------------------------------------------------------*/
461 NPT_Result
462 NPT_File::Rename(const char* from_path, const char* to_path)
464 return NPT_ERROR_PERMISSION_DENIED;
467 /*----------------------------------------------------------------------
468 | NPT_File::ListDir
469 +---------------------------------------------------------------------*/
470 NPT_Result
471 NPT_File::ListDir(const char* path,
472 NPT_List<NPT_String>& entries,
473 NPT_Ordinal start /* = 0 */,
474 NPT_Cardinal max /* = 0 */)
476 return NPT_FAILURE;
479 /*----------------------------------------------------------------------
480 | NPT_File::GetWorkingDir
481 +---------------------------------------------------------------------*/
482 NPT_Result
483 NPT_File::GetWorkingDir(NPT_String& path)
485 return NPT_FAILURE;
488 /*----------------------------------------------------------------------
489 | NPT_File::GetInfo
490 +---------------------------------------------------------------------*/
491 NPT_Result
492 NPT_File::GetInfo(const char* path, NPT_FileInfo* info)
494 struct __stat64 stat_buffer = {};
495 int result;
497 if (!info)
498 return NPT_FAILURE;
500 *info = NPT_FileInfo();
502 result = CFile::Stat(path, &stat_buffer);
503 if (result != 0)
504 return MapErrno(errno);
505 if (info)
507 info->m_Size = stat_buffer.st_size;
508 if (S_ISREG(stat_buffer.st_mode))
510 info->m_Type = NPT_FileInfo::FILE_TYPE_REGULAR;
512 else if (S_ISDIR(stat_buffer.st_mode))
514 info->m_Type = NPT_FileInfo::FILE_TYPE_DIRECTORY;
516 else
518 info->m_Type = NPT_FileInfo::FILE_TYPE_OTHER;
520 info->m_AttributesMask &= NPT_FILE_ATTRIBUTE_READ_ONLY;
521 if ((stat_buffer.st_mode & S_IWUSR) == 0)
523 info->m_Attributes &= NPT_FILE_ATTRIBUTE_READ_ONLY;
525 info->m_CreationTime.SetSeconds(0);
526 info->m_ModificationTime.SetSeconds(stat_buffer.st_mtime);
529 return NPT_SUCCESS;