2012-06-01 15:23:19 +00:00
|
|
|
// VFSFile.cpp - basic file interface + classes
|
|
|
|
// For conditions of distribution and use, see copyright notice in VFS.h
|
|
|
|
|
|
|
|
#include "VFSInternal.h"
|
2014-04-07 02:16:15 +00:00
|
|
|
#include <stdio.h> // for SEEK_* constants
|
|
|
|
|
2012-06-01 15:23:19 +00:00
|
|
|
#include "VFSFile.h"
|
|
|
|
#include "VFSTools.h"
|
|
|
|
#include "VFSFileFuncs.h"
|
|
|
|
|
|
|
|
|
|
|
|
VFS_NAMESPACE_START
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
File::File(const char *name)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
_setName(name);
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
File::~File()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
DiskFile::DiskFile(const char *name /* = NULL */)
|
|
|
|
: File(name), _fh(NULL), _buf(NULL)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
DiskFile::~DiskFile()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
close();
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
bool DiskFile::open(const char *mode /* = NULL */)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
if(isopen())
|
|
|
|
close();
|
|
|
|
|
|
|
|
_fh = real_fopen(fullname(), mode ? mode : "rb");
|
|
|
|
|
2012-06-14 15:54:40 +00:00
|
|
|
return !!_fh;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
bool DiskFile::isopen() const
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
return !!_fh;
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
bool DiskFile::iseof() const
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
return !_fh || real_feof((FILE*)_fh);
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
void DiskFile::close()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
if(_fh)
|
|
|
|
{
|
|
|
|
real_fclose((FILE*)_fh);
|
|
|
|
_fh = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
bool DiskFile::seek(vfspos pos, int whence)
|
|
|
|
{
|
|
|
|
return _fh && real_fseek((FILE*)_fh, pos, whence) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DiskFile::flush()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
return _fh && real_fflush((FILE*)_fh) == 0;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
vfspos DiskFile::getpos() const
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
return _fh ? real_ftell((FILE*)_fh) : npos;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 02:16:15 +00:00
|
|
|
size_t DiskFile::read(void *dst, size_t bytes)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
return _fh ? real_fread(dst, 1, bytes, (FILE*)_fh) : 0;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 02:16:15 +00:00
|
|
|
size_t DiskFile::write(const void *src, size_t bytes)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
return _fh ? real_fwrite(src, 1, bytes, (FILE*)_fh) : 0;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
vfspos DiskFile::size()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
vfspos sz = 0;
|
|
|
|
bool ok = GetFileSize(fullname(), sz);
|
|
|
|
return ok ? sz : npos;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
// ------------- MemFile -----------------------
|
|
|
|
|
|
|
|
MemFile::MemFile(const char *name, void *buf, unsigned int size, delete_func delfunc /* = NULL */, DeleteMode delmode /* = ON_CLOSE */)
|
|
|
|
: File(name), _pos(0), _size(size), _buf(buf), _delfunc(delfunc), _delmode(delmode)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
MemFile::~MemFile()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
if(_delmode == ON_DESTROY)
|
|
|
|
_clearMem();
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
void MemFile::_clearMem()
|
|
|
|
{
|
|
|
|
if(_delfunc)
|
|
|
|
_delfunc(_buf);
|
|
|
|
_delfunc = NULL;
|
|
|
|
_buf = NULL;
|
|
|
|
_size = 0;
|
|
|
|
_pos = 0;
|
|
|
|
}
|
2012-06-01 15:23:19 +00:00
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
void MemFile::close()
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
if(_delmode == ON_CLOSE)
|
|
|
|
_clearMem();
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-06 17:19:33 +00:00
|
|
|
bool MemFile::seek(vfspos pos, int whence)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
2014-04-06 17:19:33 +00:00
|
|
|
switch(whence)
|
|
|
|
{
|
|
|
|
case SEEK_SET:
|
|
|
|
if(pos < _size)
|
|
|
|
{
|
|
|
|
_pos = pos;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEEK_CUR:
|
|
|
|
if(_pos + pos < _size)
|
|
|
|
{
|
|
|
|
_pos += pos;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEEK_END:
|
|
|
|
if(pos < _size)
|
|
|
|
{
|
|
|
|
_pos = _size - pos;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2012-06-01 15:23:19 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 02:16:15 +00:00
|
|
|
size_t MemFile::read(void *dst, size_t bytes)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
if(iseof())
|
|
|
|
return 0;
|
2014-04-07 02:16:15 +00:00
|
|
|
size_t rem = std::min((size_t)(_size - _pos), bytes);
|
2012-06-01 15:23:19 +00:00
|
|
|
|
|
|
|
memcpy(dst, (char*)_buf + _pos, rem);
|
|
|
|
return rem;
|
|
|
|
}
|
|
|
|
|
2014-04-07 02:16:15 +00:00
|
|
|
size_t MemFile::write(const void *src, size_t bytes)
|
2012-06-01 15:23:19 +00:00
|
|
|
{
|
|
|
|
if(iseof())
|
|
|
|
return 0;
|
2014-04-07 02:16:15 +00:00
|
|
|
size_t rem = std::min((size_t)(_size - _pos), bytes);
|
2012-06-01 15:23:19 +00:00
|
|
|
|
|
|
|
memcpy((char*)_buf + _pos, src, rem);
|
|
|
|
return rem;
|
|
|
|
}
|
|
|
|
|
|
|
|
VFS_NAMESPACE_END
|