/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #if __PLATFORM_POSIX__ #include #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); } //------------------------------------------------------------------------------