mirror of
https://github.com/ksherlock/profuse.git
synced 2024-12-24 17:29:22 +00:00
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@104 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
cdd55ee726
commit
1ba3d83ec7
@ -153,7 +153,7 @@ DOSOrderDiskImage::DOSOrderDiskImage(MappedFile *file) :
|
|||||||
DOSOrderDiskImage *DOSOrderDiskImage::Create(const char *name, size_t blocks)
|
DOSOrderDiskImage *DOSOrderDiskImage::Create(const char *name, size_t blocks)
|
||||||
{
|
{
|
||||||
MappedFile *file = new MappedFile(name, blocks * 512);
|
MappedFile *file = new MappedFile(name, blocks * 512);
|
||||||
file->setDosOrder(true);
|
file->setEncoding(MappedFile::DOSOrder);
|
||||||
return new DOSOrderDiskImage(file);
|
return new DOSOrderDiskImage(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +176,6 @@ void DOSOrderDiskImage::Validate(MappedFile *f)
|
|||||||
throw Exception(__METHOD__ ": Invalid file format.");
|
throw Exception(__METHOD__ ": Invalid file format.");
|
||||||
|
|
||||||
f->reset();
|
f->reset();
|
||||||
f->setDosOrder(true);
|
f->setEncoding(MappedFile::DOSOrder);
|
||||||
f->setBlocks(size / 512);
|
f->setBlocks(size / 512);
|
||||||
}
|
}
|
||||||
|
@ -74,9 +74,9 @@ void DavexDiskImage::Validate(MappedFile *f)
|
|||||||
if (!ok)
|
if (!ok)
|
||||||
throw Exception(__METHOD__ ": Invalid file format.");
|
throw Exception(__METHOD__ ": Invalid file format.");
|
||||||
|
|
||||||
|
f->reset();
|
||||||
f->setBlocks(blocks);
|
f->setBlocks(blocks);
|
||||||
f->setOffset(512);
|
f->setOffset(512);
|
||||||
f->setDosOrder(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DavexDiskImage *DavexDiskImage::Open(MappedFile *file)
|
DavexDiskImage *DavexDiskImage::Open(MappedFile *file)
|
||||||
|
@ -14,9 +14,7 @@ using namespace ProFUSE;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
MappedFile::MappedFile(const char *name, bool readOnly) :
|
MappedFile::MappedFile(const char *name, bool readOnly)
|
||||||
_fd(-1),
|
|
||||||
_map(MAP_FAILED)
|
|
||||||
{
|
{
|
||||||
#undef __METHOD__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "MappedFile::MappedFile"
|
#define __METHOD__ "MappedFile::MappedFile"
|
||||||
@ -40,26 +38,27 @@ MappedFile::MappedFile(const char *name, bool readOnly) :
|
|||||||
{
|
{
|
||||||
throw Exception(__METHOD__ ": Unable to open file.", errno);
|
throw Exception(__METHOD__ ": Unable to open file.", errno);
|
||||||
}
|
}
|
||||||
//
|
// init may throw; auto_fd guarantees the file will be closed if that happens.
|
||||||
init(fd.release(), readOnly);
|
init(fd, readOnly);
|
||||||
|
fd.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
MappedFile::MappedFile(int fd, bool readOnly) :
|
// does NOT close fd on failure.
|
||||||
_fd(-1),
|
MappedFile::MappedFile(int fd, bool readOnly)
|
||||||
_map(MAP_FAILED)
|
|
||||||
{
|
{
|
||||||
init(fd, readOnly);
|
init(fd, readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
MappedFile::MappedFile(const char *name, size_t size) :
|
MappedFile::MappedFile(const char *name, size_t size)
|
||||||
_fd(-1),
|
|
||||||
_map(MAP_FAILED)
|
|
||||||
{
|
{
|
||||||
#undef __METHOD__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "MappedFile::MappedFile"
|
#define __METHOD__ "MappedFile::MappedFile"
|
||||||
|
|
||||||
|
_fd = -1;
|
||||||
|
_map = MAP_FAILED;
|
||||||
_size = size;
|
_size = size;
|
||||||
_readOnly = false;
|
_readOnly = false;
|
||||||
|
_encoding = ProDOSOrder;
|
||||||
|
|
||||||
auto_fd fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644));
|
auto_fd fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644));
|
||||||
|
|
||||||
@ -93,20 +92,22 @@ MappedFile::~MappedFile()
|
|||||||
if (_fd >= 0) ::close(_fd);
|
if (_fd >= 0) ::close(_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// does NOT close f on exception.
|
||||||
void MappedFile::init(int f, bool readOnly)
|
void MappedFile::init(int f, bool readOnly)
|
||||||
{
|
{
|
||||||
#undef __METHOD__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "MappedFile::init"
|
#define __METHOD__ "MappedFile::init"
|
||||||
|
|
||||||
auto_fd fd(f);
|
//auto_fd fd(f);
|
||||||
|
|
||||||
|
_fd = -1;
|
||||||
|
_map = MAP_FAILED;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_blocks = 0;
|
_blocks = 0;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_readOnly = readOnly;
|
_readOnly = readOnly;
|
||||||
_dosOrder = false;
|
_encoding = ProDOSOrder;
|
||||||
|
_size = ::lseek(f, 0, SEEK_END);
|
||||||
_size = ::lseek(_fd, 0, SEEK_END);
|
|
||||||
|
|
||||||
if (_size < 0)
|
if (_size < 0)
|
||||||
throw Exception(__METHOD__ ": Unable to determine file size.", errno);
|
throw Exception(__METHOD__ ": Unable to determine file size.", errno);
|
||||||
@ -116,7 +117,7 @@ void MappedFile::init(int f, bool readOnly)
|
|||||||
MAP_FILE | MAP_SHARED, fd, 0);
|
MAP_FILE | MAP_SHARED, fd, 0);
|
||||||
*/
|
*/
|
||||||
auto_map map(
|
auto_map map(
|
||||||
fd,
|
f,
|
||||||
_size,
|
_size,
|
||||||
readOnly ? PROT_READ : PROT_READ | PROT_WRITE,
|
readOnly ? PROT_READ : PROT_READ | PROT_WRITE,
|
||||||
readOnly ? MAP_FILE : MAP_FILE | MAP_SHARED
|
readOnly ? MAP_FILE : MAP_FILE | MAP_SHARED
|
||||||
@ -124,7 +125,7 @@ void MappedFile::init(int f, bool readOnly)
|
|||||||
|
|
||||||
if (map == MAP_FAILED) throw Exception(__METHOD__ ": Unable to map file.", errno);
|
if (map == MAP_FAILED) throw Exception(__METHOD__ ": Unable to map file.", errno);
|
||||||
|
|
||||||
_fd = fd.release();
|
_fd = f;
|
||||||
_map = map.release();
|
_map = map.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +148,16 @@ void MappedFile::readBlock(unsigned block, void *bp)
|
|||||||
if (bp == 0) throw Exception(__METHOD__ ": Invalid address.");
|
if (bp == 0) throw Exception(__METHOD__ ": Invalid address.");
|
||||||
|
|
||||||
|
|
||||||
if (_dosOrder)
|
switch(_encoding)
|
||||||
|
{
|
||||||
|
case ProDOSOrder:
|
||||||
|
{
|
||||||
|
size_t address = block * 512;
|
||||||
|
std::memcpy(bp, (uint8_t *)_map + _offset + address, 512);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOSOrder:
|
||||||
{
|
{
|
||||||
unsigned track = (block & ~0x07) << 9;
|
unsigned track = (block & ~0x07) << 9;
|
||||||
unsigned sector = (block & 0x07) << 1;
|
unsigned sector = (block & 0x07) << 1;
|
||||||
@ -160,13 +170,13 @@ void MappedFile::readBlock(unsigned block, void *bp)
|
|||||||
|
|
||||||
bp = (uint8_t *)bp + 256;
|
bp = (uint8_t *)bp + 256;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception(__METHOD__ ": Unsupported Encoding.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t address = block * 512;
|
|
||||||
std::memcpy(bp, (uint8_t *)_map + _offset + address, 512);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappedFile::writeBlock(unsigned block, const void *bp)
|
void MappedFile::writeBlock(unsigned block, const void *bp)
|
||||||
@ -176,10 +186,19 @@ void MappedFile::writeBlock(unsigned block, const void *bp)
|
|||||||
|
|
||||||
if (block > _blocks) throw Exception(__METHOD__ ": Invalid block number.");
|
if (block > _blocks) throw Exception(__METHOD__ ": Invalid block number.");
|
||||||
|
|
||||||
if ( (_readOnly) || (_map == MAP_FAILED))
|
if (_readOnly) throw Exception(__METHOD__ ": File is readonly.");
|
||||||
throw Exception(__METHOD__ ": File is readonly.");
|
|
||||||
|
|
||||||
if (_dosOrder)
|
|
||||||
|
switch(_encoding)
|
||||||
|
{
|
||||||
|
case ProDOSOrder:
|
||||||
|
{
|
||||||
|
size_t address = block * 512;
|
||||||
|
std::memcpy((uint8_t *)_map + _offset + address , bp, 512);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DOSOrder:
|
||||||
{
|
{
|
||||||
unsigned track = (block & ~0x07) << 9;
|
unsigned track = (block & ~0x07) << 9;
|
||||||
unsigned sector = (block & 0x07) << 1;
|
unsigned sector = (block & 0x07) << 1;
|
||||||
@ -192,11 +211,12 @@ void MappedFile::writeBlock(unsigned block, const void *bp)
|
|||||||
bp = (uint8_t *)bp + 256;
|
bp = (uint8_t *)bp + 256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
size_t address = block * 512;
|
default:
|
||||||
std::memcpy((uint8_t *)_map + _offset + address , bp, 512);
|
throw Exception(__METHOD__ ": Unsupported Encoding.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappedFile::sync()
|
void MappedFile::sync()
|
||||||
@ -204,8 +224,7 @@ void MappedFile::sync()
|
|||||||
#undef __METHOD__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "MappedFile::sync"
|
#define __METHOD__ "MappedFile::sync"
|
||||||
|
|
||||||
if ( (_readOnly) || (_map == MAP_FAILED))
|
if (_readOnly) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (::msync(_map, _size, MS_SYNC) < 0)
|
if (::msync(_map, _size, MS_SYNC) < 0)
|
||||||
throw Exception(__METHOD__ ": msync error.", errno);
|
throw Exception(__METHOD__ ": msync error.", errno);
|
||||||
@ -215,7 +234,7 @@ void MappedFile::reset()
|
|||||||
{
|
{
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
_blocks = 0;
|
_blocks = 0;
|
||||||
_dosOrder = false;
|
_encoding = ProDOSOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
14
MappedFile.h
14
MappedFile.h
@ -11,6 +11,14 @@ namespace ProFUSE {
|
|||||||
|
|
||||||
class MappedFile {
|
class MappedFile {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum Encoding {
|
||||||
|
ProDOSOrder = 0,
|
||||||
|
DOSOrder,
|
||||||
|
Nibblized62,
|
||||||
|
Nibblized53
|
||||||
|
};
|
||||||
|
|
||||||
MappedFile(const char *name, bool ReadOnly);
|
MappedFile(const char *name, bool ReadOnly);
|
||||||
MappedFile(int fd, bool readOnly);
|
MappedFile(int fd, bool readOnly);
|
||||||
MappedFile(const char *name, size_t size);
|
MappedFile(const char *name, size_t size);
|
||||||
@ -24,8 +32,8 @@ public:
|
|||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
bool dosOrder() const { return _dosOrder; }
|
Encoding encoding() const { return _encoding; }
|
||||||
void setDosOrder(bool tf) { _dosOrder = tf; }
|
void setEncoding(Encoding e) { _encoding = e; }
|
||||||
|
|
||||||
unsigned offset() const { return _offset; }
|
unsigned offset() const { return _offset; }
|
||||||
void setOffset(unsigned o) { _offset = o; }
|
void setOffset(unsigned o) { _offset = o; }
|
||||||
@ -52,7 +60,7 @@ private:
|
|||||||
size_t _size;
|
size_t _size;
|
||||||
bool _readOnly;
|
bool _readOnly;
|
||||||
|
|
||||||
bool _dosOrder;
|
Encoding _encoding;
|
||||||
unsigned _offset;
|
unsigned _offset;
|
||||||
unsigned _blocks;
|
unsigned _blocks;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user