81 lines
2.4 KiB
C++
81 lines
2.4 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include "io_archive/io_archive.h"
|
|
#include "log/log.h"
|
|
|
|
using namespace GS::IO;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
uint Archive::GetCaps() const
|
|
{ return CanSeek | CanRead | IsCaseSensitive; }
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Handle *Archive::Open(const char *uri, Mode mode)
|
|
{
|
|
if (mode == ModeRead)
|
|
if (ArchiveEntry *e = archive.Exists(uri))
|
|
{
|
|
AutoPtr <ArchiveHandle> h(new ArchiveHandle(this));
|
|
if (!h->data.Allocate(e->length) || !archive.FileRead(uri, (void *)h->data.c_ptr()))
|
|
return NULL;
|
|
return h.Detach();
|
|
}
|
|
return NULL;
|
|
}
|
|
void Archive::Close(Handle *) {}
|
|
bool Archive::Delete(const char *) { return false; }
|
|
|
|
size_t Archive::Tell(Handle *h)
|
|
{
|
|
if (ArchiveHandle *_h = (ArchiveHandle *)h)
|
|
return _h->cursor;
|
|
return (size_t)-1;
|
|
}
|
|
size_t Archive::Seek(Handle *h, ptrdiff_t offset, SeekRef seek_ref)
|
|
{
|
|
if (ArchiveHandle *_h = (ArchiveHandle *)h)
|
|
{
|
|
switch (seek_ref)
|
|
{
|
|
case SeekStart:
|
|
_h->cursor = Types::Clamp <ptrdiff_t> (offset, 0, _h->data.GetSize());
|
|
break;
|
|
case SeekCurrent:
|
|
_h->cursor = Types::Clamp <ptrdiff_t> (_h->cursor + offset, 0, _h->data.GetSize());
|
|
break;
|
|
case SeekEnd:
|
|
_h->cursor = Types::Clamp <ptrdiff_t> (_h->data.GetSize() - offset, 0, _h->data.GetSize());
|
|
break;
|
|
}
|
|
return _h->cursor;
|
|
}
|
|
return (size_t)-1;
|
|
}
|
|
|
|
size_t Archive::Read(Handle *h, void *ptr, size_t size)
|
|
{
|
|
size_t read_size = 0;
|
|
if (ArchiveHandle *_h = (ArchiveHandle *)h)
|
|
{
|
|
read_size = Types::Min <ptrdiff_t> (size, _h->data.GetSize() - _h->cursor);
|
|
GS::Memory::Copy(ptr, &_h->data[(int)_h->cursor], read_size);
|
|
_h->cursor += read_size;
|
|
}
|
|
return read_size;
|
|
}
|
|
size_t Archive::Write(Handle *, const void *, size_t size)
|
|
{ return 0; }
|
|
//------------------------------------------------------------------------------
|
|
|
|
Archive::Archive(const char *uri, const char *index_uri)
|
|
{
|
|
if ((connected = archive.OpenRead(uri, index_uri)) == false)
|
|
__LOG_E__ << "Failed to connect filesystem to archive '" << uri << "'.\n";
|
|
}
|