mirror of
https://github.com/Team-Resurgent/XBMC4Xbox.git
synced 2026-08-15 11:18:13 -07:00
If ever adding the XBMC4Xbox source to GitHub use "git add -f -A" or it wont add all the files.
417 lines
12 KiB
C++
417 lines
12 KiB
C++
/*****************************************************************
|
|
|
|
|
| Neptune - Files :: XBMC Implementation
|
|
|
|
|
| (c) 2001-2006 Gilles Boccon-Gibod
|
|
| Author: Gilles Boccon-Gibod (bok@bok.net)
|
|
|
|
|
****************************************************************/
|
|
|
|
/*----------------------------------------------------------------------
|
|
| includes
|
|
+---------------------------------------------------------------------*/
|
|
#include "system.h"
|
|
#include "IFile.h"
|
|
#include "FileFactory.h"
|
|
#include "utils/log.h"
|
|
#include "Util.h"
|
|
#include "URL.h"
|
|
|
|
#ifdef max
|
|
#undef max
|
|
#endif
|
|
|
|
#ifdef min
|
|
#undef min
|
|
#endif
|
|
|
|
#include <limits>
|
|
|
|
|
|
#include "NptUtils.h"
|
|
#include "NptFile.h"
|
|
#include "NptThreads.h"
|
|
#include "NptInterfaces.h"
|
|
#include "NptStrings.h"
|
|
#include "NptDebug.h"
|
|
|
|
using namespace XFILE;
|
|
|
|
typedef NPT_Reference<IFile> NPT_XbmcFileReference;
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileStream
|
|
+---------------------------------------------------------------------*/
|
|
class NPT_XbmcFileStream
|
|
{
|
|
public:
|
|
// constructors and destructor
|
|
NPT_XbmcFileStream(NPT_XbmcFileReference file) :
|
|
m_FileReference(file) {}
|
|
|
|
// NPT_FileInterface methods
|
|
NPT_Result Seek(NPT_Position offset);
|
|
NPT_Result Tell(NPT_Position& offset);
|
|
NPT_Result Flush();
|
|
|
|
protected:
|
|
// constructors and destructors
|
|
virtual ~NPT_XbmcFileStream() {}
|
|
|
|
// members
|
|
NPT_XbmcFileReference m_FileReference;
|
|
};
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileStream::Seek
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileStream::Seek(NPT_Position offset)
|
|
{
|
|
int64_t result;
|
|
|
|
result = m_FileReference->Seek(offset, SEEK_SET) ;
|
|
if (result >= 0) {
|
|
return NPT_SUCCESS;
|
|
} else {
|
|
return NPT_FAILURE;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileStream::Tell
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileStream::Tell(NPT_Position& offset)
|
|
{
|
|
int64_t result = m_FileReference->GetPosition();
|
|
if (result >= 0) {
|
|
offset = (NPT_Position)result;
|
|
return NPT_SUCCESS;
|
|
} else {
|
|
return NPT_FAILURE;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileStream::Flush
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileStream::Flush()
|
|
{
|
|
m_FileReference->Flush();
|
|
return NPT_SUCCESS;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileInputStream
|
|
+---------------------------------------------------------------------*/
|
|
class NPT_XbmcFileInputStream : public NPT_InputStream,
|
|
private NPT_XbmcFileStream
|
|
|
|
{
|
|
public:
|
|
// constructors and destructor
|
|
NPT_XbmcFileInputStream(NPT_XbmcFileReference& file) :
|
|
NPT_XbmcFileStream(file) {}
|
|
|
|
// NPT_InputStream methods
|
|
NPT_Result Read(void* buffer,
|
|
NPT_Size bytes_to_read,
|
|
NPT_Size* bytes_read);
|
|
NPT_Result Seek(NPT_Position offset) {
|
|
return NPT_XbmcFileStream::Seek(offset);
|
|
}
|
|
NPT_Result Tell(NPT_Position& offset) {
|
|
return NPT_XbmcFileStream::Tell(offset);
|
|
}
|
|
NPT_Result GetSize(NPT_LargeSize& size);
|
|
NPT_Result GetAvailable(NPT_LargeSize& available);
|
|
};
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileInputStream::Read
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileInputStream::Read(void* buffer,
|
|
NPT_Size bytes_to_read,
|
|
NPT_Size* bytes_read)
|
|
{
|
|
unsigned int nb_read;
|
|
|
|
// check the parameters
|
|
if (buffer == NULL) {
|
|
return NPT_ERROR_INVALID_PARAMETERS;
|
|
}
|
|
|
|
// read from the file
|
|
nb_read = m_FileReference->Read(buffer, bytes_to_read);
|
|
if (nb_read > 0) {
|
|
if (bytes_read) *bytes_read = (NPT_Size)nb_read;
|
|
return NPT_SUCCESS;
|
|
} else {
|
|
if (bytes_read) *bytes_read = 0;
|
|
return NPT_ERROR_EOS;
|
|
//} else { // currently no way to indicate failure
|
|
// if (bytes_read) *bytes_read = 0;
|
|
// return NPT_ERROR_READ_FAILED;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileInputStream::GetSize
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileInputStream::GetSize(NPT_LargeSize& size)
|
|
{
|
|
size = m_FileReference->GetLength();
|
|
return NPT_SUCCESS;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileInputStream::GetAvailable
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileInputStream::GetAvailable(NPT_LargeSize& available)
|
|
{
|
|
int64_t offset = m_FileReference->GetPosition();
|
|
NPT_LargeSize size = 0;
|
|
|
|
if (NPT_SUCCEEDED(GetSize(size)) && offset >= 0 && (NPT_LargeSize)offset <= size) {
|
|
available = size - offset;
|
|
return NPT_SUCCESS;
|
|
} else {
|
|
available = 0;
|
|
return NPT_FAILURE;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileOutputStream
|
|
+---------------------------------------------------------------------*/
|
|
class NPT_XbmcFileOutputStream : public NPT_OutputStream,
|
|
private NPT_XbmcFileStream
|
|
{
|
|
public:
|
|
// constructors and destructor
|
|
NPT_XbmcFileOutputStream(NPT_XbmcFileReference& file) :
|
|
NPT_XbmcFileStream(file) {}
|
|
|
|
// NPT_OutputStream methods
|
|
NPT_Result Write(const void* buffer,
|
|
NPT_Size bytes_to_write,
|
|
NPT_Size* bytes_written);
|
|
NPT_Result Seek(NPT_Position offset) {
|
|
return NPT_XbmcFileStream::Seek(offset);
|
|
}
|
|
NPT_Result Tell(NPT_Position& offset) {
|
|
return NPT_XbmcFileStream::Tell(offset);
|
|
}
|
|
NPT_Result Flush() {
|
|
return NPT_XbmcFileStream::Flush();
|
|
}
|
|
};
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFileOutputStream::Write
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFileOutputStream::Write(const void* buffer,
|
|
NPT_Size bytes_to_write,
|
|
NPT_Size* bytes_written)
|
|
{
|
|
int nb_written;
|
|
nb_written = m_FileReference->Write(buffer, bytes_to_write);
|
|
|
|
if (nb_written > 0) {
|
|
if (bytes_written) *bytes_written = (NPT_Size)nb_written;
|
|
return NPT_SUCCESS;
|
|
} else {
|
|
if (bytes_written) *bytes_written = 0;
|
|
return NPT_ERROR_WRITE_FAILED;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile
|
|
+---------------------------------------------------------------------*/
|
|
class NPT_XbmcFile: public NPT_FileInterface
|
|
{
|
|
public:
|
|
// constructors and destructor
|
|
NPT_XbmcFile(NPT_File& delegator);
|
|
~NPT_XbmcFile();
|
|
|
|
// NPT_FileInterface methods
|
|
NPT_Result Open(OpenMode mode);
|
|
NPT_Result Close();
|
|
NPT_Result GetInputStream(NPT_InputStreamReference& stream);
|
|
NPT_Result GetOutputStream(NPT_OutputStreamReference& stream);
|
|
|
|
private:
|
|
// members
|
|
NPT_File& m_Delegator;
|
|
OpenMode m_Mode;
|
|
NPT_XbmcFileReference m_FileReference;
|
|
};
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile::NPT_XbmcFile
|
|
+---------------------------------------------------------------------*/
|
|
NPT_XbmcFile::NPT_XbmcFile(NPT_File& delegator) :
|
|
m_Delegator(delegator),
|
|
m_Mode(0)
|
|
{
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile::~NPT_XbmcFile
|
|
+---------------------------------------------------------------------*/
|
|
NPT_XbmcFile::~NPT_XbmcFile()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile::Open
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFile::Open(NPT_File::OpenMode mode)
|
|
{
|
|
NPT_XbmcFileReference file;
|
|
|
|
// check if we're already open
|
|
if (!m_FileReference.IsNull()) {
|
|
return NPT_ERROR_FILE_ALREADY_OPEN;
|
|
}
|
|
|
|
// store the mode
|
|
m_Mode = mode;
|
|
|
|
// check for special names
|
|
const char* name = (const char*)m_Delegator.GetPath();
|
|
if (NPT_StringsEqual(name, NPT_FILE_STANDARD_INPUT)) {
|
|
return NPT_ERROR_FILE_NOT_READABLE;
|
|
} else if (NPT_StringsEqual(name, NPT_FILE_STANDARD_OUTPUT)) {
|
|
return NPT_ERROR_FILE_NOT_WRITABLE;
|
|
} else if (NPT_StringsEqual(name, NPT_FILE_STANDARD_ERROR)) {
|
|
return NPT_ERROR_FILE_NOT_WRITABLE;
|
|
} else {
|
|
|
|
file = CFileFactory::CreateLoader(name);
|
|
if (file.IsNull()) {
|
|
return NPT_ERROR_NO_SUCH_FILE;
|
|
}
|
|
|
|
bool result;
|
|
CURL* url = new CURL(name);
|
|
/* path is not fully qualified so assume it's relative to home dir */
|
|
if (url->GetFileName().IsEmpty()) {
|
|
delete url;
|
|
CStdString homepath;
|
|
CUtil::GetHomePath(homepath);
|
|
url = new CURL(homepath + "/" + name);
|
|
}
|
|
|
|
// compute mode
|
|
if (mode & NPT_FILE_OPEN_MODE_WRITE) {
|
|
result = file->OpenForWrite(*url, (mode & NPT_FILE_OPEN_MODE_TRUNCATE)?true:false);
|
|
} else {
|
|
result = file->Open(*url);
|
|
}
|
|
|
|
delete url;
|
|
if (!result) return NPT_ERROR_NO_SUCH_FILE;
|
|
}
|
|
|
|
// store reference
|
|
m_FileReference = file;
|
|
|
|
return NPT_SUCCESS;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile::Close
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFile::Close()
|
|
{
|
|
// release the file reference
|
|
m_FileReference = NULL;
|
|
|
|
// reset the mode
|
|
m_Mode = 0;
|
|
|
|
return NPT_SUCCESS;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile::GetInputStream
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFile::GetInputStream(NPT_InputStreamReference& stream)
|
|
{
|
|
// default value
|
|
stream = NULL;
|
|
|
|
// check that the file is open
|
|
if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN;
|
|
|
|
// check that the mode is compatible
|
|
if (!(m_Mode & NPT_FILE_OPEN_MODE_READ)) {
|
|
return NPT_ERROR_FILE_NOT_READABLE;
|
|
}
|
|
|
|
// create a stream
|
|
stream = new NPT_XbmcFileInputStream(m_FileReference);
|
|
|
|
return NPT_SUCCESS;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_XbmcFile::GetOutputStream
|
|
+---------------------------------------------------------------------*/
|
|
NPT_Result
|
|
NPT_XbmcFile::GetOutputStream(NPT_OutputStreamReference& stream)
|
|
{
|
|
// default value
|
|
stream = NULL;
|
|
|
|
// check that the file is open
|
|
if (m_FileReference.IsNull()) return NPT_ERROR_FILE_NOT_OPEN;
|
|
|
|
// check that the mode is compatible
|
|
if (!(m_Mode & NPT_FILE_OPEN_MODE_WRITE)) {
|
|
return NPT_ERROR_FILE_NOT_WRITABLE;
|
|
}
|
|
|
|
// create a stream
|
|
stream = new NPT_XbmcFileOutputStream(m_FileReference);
|
|
|
|
return NPT_SUCCESS;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_File::NPT_File
|
|
+---------------------------------------------------------------------*/
|
|
NPT_File::NPT_File(const char* path) : m_Path(path)
|
|
{
|
|
m_Delegate = new NPT_XbmcFile(*this);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
| NPT_File::operator=
|
|
+---------------------------------------------------------------------*/
|
|
NPT_File&
|
|
NPT_File::operator=(const NPT_File& file)
|
|
{
|
|
if (this != &file) {
|
|
delete m_Delegate;
|
|
m_Path = file.m_Path;
|
|
m_Delegate = new NPT_XbmcFile(*this);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
|