/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "filesystem/io_memory.h" using namespace GS::IO; //------------------------------------------------------------------------------ uint Memory::GetCaps() const { return CanRead | CanWrite | CanSeek| IsCaseSensitive; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ Handle *Memory::Open(const char *uri, Mode mode) { switch (mode) { case ModeRead: ListForeachPtr(MemoryFile *, f, fat) if (f->uri == uri) return new MemoryHandle(this, f, mode); break; case ModeWrite: { MemoryFile *f_entry = NULL; ListForeachPtr(MemoryFile *, f, fat) if (f->uri == uri) { f_entry = f; break; } if (!f_entry) fat.Add(f_entry = new MemoryFile(uri)); return f_entry ? new MemoryHandle(this, f_entry, mode) : NULL; } break; default: break; } return NULL; } void Memory::Close(Handle *h) { /* Nothing to be done. */ } bool Memory::Delete(const char *uri) { ListForeachPtr(MemoryFile *, f, fat) if (f->uri == uri) return fat.Remove(f); return false; } size_t Memory::Tell(Handle *h) { if (MemoryHandle *_h = (MemoryHandle *)h) if (_h->file) return _h->cursor; return (size_t)-1; } size_t Memory::Seek(Handle *h, ptrdiff_t offset, SeekRef seek_ref) { if (MemoryHandle *_h = (MemoryHandle *)h) if (_h->file) { switch (seek_ref) { case SeekStart: _h->cursor = Types::Clamp (offset, 0, _h->file->size); break; case SeekCurrent: _h->cursor = Types::Clamp (_h->cursor + offset, 0, _h->file->size); break; case SeekEnd: _h->cursor = Types::Clamp (_h->file->size - offset, 0, _h->file->size); break; } return 0; } return (size_t)-1; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ size_t Memory::Read(Handle *h, void *ptr, size_t size) { size_t read_size = 0; if (MemoryHandle *_h = (MemoryHandle *)h) if (_h->file && (_h->mode == ModeRead)) { read_size = Types::Min (size, _h->file->size - _h->cursor); GS::Memory::Copy(ptr, &_h->file->data[(int)_h->cursor], read_size); _h->cursor += read_size; } return read_size; } size_t Memory::Write(Handle *h, const void *ptr, size_t size) { size_t write_size = 0; if (MemoryHandle *_h = (MemoryHandle *)h) if (_h->file && (_h->mode == ModeWrite)) { size_t req_size = _h->cursor + size; if (req_size > _h->file->data.GetSize()) if (!_h->file->data.Reallocate(req_size + 16384)) // required size + 16 kilobytes return 0; GS::Memory::Copy(&_h->file->data[(int)_h->cursor], ptr, size); write_size = size; _h->cursor += size; _h->file->size = Types::Max(_h->file->size, req_size); } return write_size; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ MemoryHandle::MemoryHandle(Base *io, MemoryFile *_file, Mode _mode) : Handle(io), file(_file), cursor(0), mode(_mode) {} MemoryHandle::~MemoryHandle() { GetIOSystem()->Close(this); } //------------------------------------------------------------------------------