142 lines
4.0 KiB
C++
142 lines
4.0 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#if __PLATFORM_POSIX__
|
|
#include <unistd.h>
|
|
#endif
|
|
#include "filesystem/io_dispatcher.h"
|
|
#include "memory/nauto_ptr.h"
|
|
|
|
using namespace GS;
|
|
using namespace GS::IO;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Dispatcher::AddDispatch(Base *fs, const char *prefix)
|
|
{
|
|
if (prefix)
|
|
{
|
|
DispatchFS *d = new DispatchFS;
|
|
if (!d)
|
|
return false;
|
|
|
|
d->fs = fs;
|
|
d->prefix = prefix;
|
|
mounts.Add(d);
|
|
}
|
|
else
|
|
roots.Add(fs);
|
|
|
|
return true;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
uint Dispatcher::GetCaps() const
|
|
{
|
|
uint flags = CanRead | CanWrite | CanSeek;
|
|
#ifndef __PLATFORM_WINDOWS__
|
|
flags |= IsCaseSensitive;
|
|
#endif
|
|
return flags;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Base *Dispatcher::Dispatch(String &uri, Mode mode)
|
|
{
|
|
ListForeachPtr(DispatchFS *, d, mounts)
|
|
if (uri.StartsWith(d->prefix))
|
|
{
|
|
uri = uri.Mid(d->prefix.Len());
|
|
return d->fs;
|
|
}
|
|
|
|
// Root FS make no sense for write operations.
|
|
if (mode == ModeRead)
|
|
ListForeachPtr(Base *, d, roots)
|
|
if (d->Exists(uri))
|
|
return d;
|
|
|
|
return NULL;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Handle *Dispatcher::Open(const char *uri, Mode mode)
|
|
{
|
|
String _uri(uri);
|
|
|
|
Base *base = Dispatch(_uri, mode);
|
|
if (!base)
|
|
return NULL;
|
|
|
|
Handle *h = base->Open(_uri, mode);
|
|
return h ? new DispatcherHandle(this, h) : NULL;
|
|
}
|
|
void Dispatcher::Close(Handle *h)
|
|
{
|
|
if (DispatcherHandle *dh = (DispatcherHandle *)h)
|
|
dh->handle->GetIOSystem()->Close(dh->handle);
|
|
}
|
|
bool Dispatcher::Delete(const char *uri)
|
|
{ return false; }
|
|
size_t Dispatcher::Seek(Handle *h, ptrdiff_t offset, SeekRef ref)
|
|
{
|
|
if (DispatcherHandle *dh = (DispatcherHandle *)h)
|
|
return dh->handle->GetIOSystem()->Seek(dh->handle, offset, ref);
|
|
return (size_t)-1;
|
|
}
|
|
size_t Dispatcher::Tell(Handle *h)
|
|
{
|
|
if (DispatcherHandle *dh = (DispatcherHandle *)h)
|
|
return dh->handle->GetIOSystem()->Tell(dh->handle);
|
|
return (size_t)-1;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
size_t Dispatcher::Read(Handle *h, void *b, size_t size)
|
|
{
|
|
if (DispatcherHandle *dh = (DispatcherHandle *)h)
|
|
return dh->handle->GetIOSystem()->Read(dh->handle, b, size);
|
|
return 0;
|
|
}
|
|
size_t Dispatcher::Write(Handle *h, const void *b, size_t size)
|
|
{
|
|
if (DispatcherHandle *dh = (DispatcherHandle *)h)
|
|
return dh->handle->GetIOSystem()->Write(dh->handle, b, size);
|
|
return 0;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Dispatcher::MkDir(const char *path)
|
|
{
|
|
String _path(path);
|
|
if (Base *base = Dispatch(_path, ModeWrite))
|
|
return base->MkDir(_path);
|
|
return false;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
String Dispatcher::Hash(const char *uri)
|
|
{
|
|
String _uri(uri);
|
|
if (Base *base = Dispatch(_uri, ModeRead))
|
|
return base->Hash(_uri);
|
|
return String();
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
DispatcherHandle::DispatcherHandle(Base *io, Handle *h) : Handle(io), handle(h)
|
|
{}
|
|
DispatcherHandle::~DispatcherHandle()
|
|
{ GetIOSystem()->Close(this); }
|
|
//------------------------------------------------------------------------------
|