Files
Webcam/include/platform/filesystem/filesystem.cpp

219 lines
5.9 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "filesystem/filesystem.h"
#include "filesystem/io_handle.h"
#include "log/log.h"
#if __PLATFORM_POSIX__
#include <unistd.h>
#include <sys/stat.h>
#elif __PLATFORM_WINDOWS__
#include <direct.h>
#endif
#include "filesystem/io_cfile.h"
#include "memory/nauto_ptr.h"
using GS::String;
using namespace GS::IO;
//------------------------------------------------------------------------------
bool Filesystem::Exists(const char *uri) const
{
AutoPtr <Handle> h(Open(uri));
return h.IsValid();
}
size_t Filesystem::FileSize(const char *uri) const
{
AutoPtr <Handle> h(Open(uri));
return h.IsNull() ? 0 : h->GetSize();
}
bool Filesystem::FileLoad(const char *uri, GS::Array <char> &buffer, bool verbose) const
{
AutoPtr <Handle> h(Open(uri));
if (h.IsNull())
{
if (verbose)
__LOG_W__ << "Failed to open '" << uri << "'.\n";
return false;
}
// Warning: Do not load through IO::Base::FileLoad. That would create another handle!
size_t size = h->GetSize();
if (!buffer.Allocate(size))
__ERR__(__LOG_W__ << "Failed to allocate memory to load '" << uri << "'.\n", false)
return asbool(h->Read(buffer.c_ptr(), size) == size);
}
bool Filesystem::FileSave(const char *uri, const GS::Array <char> &buffer) const
{
AutoPtr <Handle> h(Open(uri, ModeWrite));
if (h.IsNull())
__ERR__(__LOG_W__ << "Failed to open '" << uri << "'.\n", false)
return asbool(h->Write(buffer.c_ptr(), buffer.GetSize()) == buffer.GetSize());
}
bool Filesystem::FileCopy(const char *src, const char *dst) const
{
Array <char> buffer;
return FileLoad(src, buffer) && FileSave(dst, buffer);
}
bool Filesystem::FileMove(const char *src, const char *dst) const
{
Array <char> buffer;
return FileLoad(src, buffer) && FileSave(dst, buffer) && Delete(src);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
String Filesystem::MapToAbsolute(const char *uri) const
{
String _uri(uri);
ListForeachPtr(MountPoint *, m, mount_list)
if (_uri.StartsWith(m->mount_point))
return m->io_sys->MapToAbsolute(_uri.Mid(m->mount_point.Len())).CleanFilePath();
ListForeachPtr(Base *, i, root_mount)
{
AutoPtr <Handle> h(i->Open(_uri));
if (h.IsValid())
return i->MapToAbsolute(_uri).CleanFilePath();
}
return _uri;
}
String Filesystem::StripRootPath(const char *path) const
{
String _path(path);
_path.FileCleanName();
ListForeachPtr(Base *, i, root_mount)
{
String rpath = i->MapToRelative(_path);
if (!rpath.IsEmpty())
if (rpath != _path)
return rpath[0] == '/' ? rpath.Mid(1) : rpath; // Ensure no leading '/' remains.
}
return _path;
}
bool Filesystem::Mount(Base *io_sys, const char *mount_point)
{
if (mount_point)
{
ListForeachPtr(MountPoint *, m, mount_list)
if (m->mount_point == mount_point)
{
delete io_sys;
return false;
}
return asbool(mount_list.Prepend(new MountPoint(mount_point, io_sys)));
}
else
{
ListForeachPtr(Base *, i, root_mount)
if (i == io_sys)
__ERR__(__LOG_E__ << "Cannot mount IO system twice as root.\n", false)
return asbool(root_mount.Prepend(io_sys));
}
}
void Filesystem::Unmount(const char *mount_point)
{ Unmount(GetIOSystem(mount_point)); }
void Filesystem::Unmount(Base *io_sys)
{
ListForeachPtr(MountPoint *, m, mount_list)
if (m->io_sys.c_ptr() == io_sys)
mount_list.Remove(m);
ListForeachPtr(Base *, i, root_mount)
if (i == io_sys)
root_mount.Remove(i);
}
void Filesystem::UnmountAll()
{
ListForeachPtr(MountPoint *, m, mount_list)
mount_list.Remove(m);
while (List <Base *> ::Item *m = root_mount.GetRoot())
root_mount.Remove(m);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Base *Filesystem::GetIOSystem(const char *mount_point) const
{
ListForeachPtr(MountPoint *, m, mount_list)
if (m->mount_point == mount_point)
return m->io_sys;
return NULL;
}
const char *Filesystem::GetMountPoint(const Base *io_sys) const
{
ListForeachPtr(MountPoint *, m, mount_list)
if (m->io_sys == io_sys)
return m->mount_point;
return NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Handle *Filesystem::Open(const char *uri, Mode mode) const
{
String _uri(uri);
if (_uri.IsEmpty())
return NULL;
ListForeachPtr(MountPoint *, m, mount_list)
if (_uri.StartsWith(m->mount_point))
return m->io_sys->Open(_uri.Mid(m->mount_point.Len()), mode);
ListForeachPtr(Base *, i, root_mount)
if (Handle *h = i->Open(uri, mode))
return h;
return NULL;
}
void Filesystem::Close(Handle *h) const
{
ListForeachPtr(MountPoint *, m, mount_list)
if (m->io_sys.c_ptr() == h->GetIOSystem())
m->io_sys->Close(h);
ListForeachPtr(Base *, i, root_mount)
if (i == h->GetIOSystem())
i->Close(h);
}
bool Filesystem::Delete(const char *uri) const
{
AutoPtr <Handle> h(Open(uri));
if (h.IsValid())
{
Base *io_sys = h->GetIOSystem();
h = NULL;
return io_sys->Delete(uri);
}
else
return asbool(unlink(uri) == 0);
return false;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool Filesystem::MkDir(const char *path) const
{
String _path(path);
if (_path.IsEmpty())
return false;
ListForeachPtr(MountPoint *, m, mount_list)
if (_path.StartsWith(m->mount_point))
return m->io_sys->MkDir(_path.Mid(m->mount_point.Len()));
// [EJ] No creation on a root filesystem here!
return false;
}
//------------------------------------------------------------------------------