git-svn-id: https://profuse.googlecode.com/svn/branches/v2@104 aa027e90-d47c-11dd-86d7-074df07e0730

This commit is contained in:
ksherlock 2009-11-25 02:26:00 +00:00
parent cdd55ee726
commit 1ba3d83ec7
4 changed files with 85 additions and 58 deletions

View File

@ -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);
} }

View File

@ -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)

View 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,26 +148,35 @@ 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)
{ {
unsigned track = (block & ~0x07) << 9; case ProDOSOrder:
unsigned sector = (block & 0x07) << 1;
for (unsigned i = 0; i < 2; ++i)
{ {
size_t address = track | (DOSMap[sector+i] << 8); size_t address = block * 512;
std::memcpy(bp, (uint8_t *)_map + _offset + address, 512);
std::memcpy(bp, (uint8_t *)_map + _offset + address, 256);
bp = (uint8_t *)bp + 256;
} }
break;
case DOSOrder:
{
unsigned track = (block & ~0x07) << 9;
unsigned sector = (block & 0x07) << 1;
for (unsigned i = 0; i < 2; ++i)
{
size_t address = track | (DOSMap[sector+i] << 8);
std::memcpy(bp, (uint8_t *)_map + _offset + address, 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,27 +186,37 @@ 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)
{ {
unsigned track = (block & ~0x07) << 9; case ProDOSOrder:
unsigned sector = (block & 0x07) << 1;
for (unsigned i = 0; i < 2; ++i)
{ {
size_t address = track | (DOSMap[sector+i] << 8); size_t address = block * 512;
std::memcpy((uint8_t *)_map + _offset + address , bp, 512);
std::memcpy((uint8_t *)_map + _offset + address, bp, 256);
bp = (uint8_t *)bp + 256;
} }
break;
case DOSOrder:
{
unsigned track = (block & ~0x07) << 9;
unsigned sector = (block & 0x07) << 1;
for (unsigned i = 0; i < 2; ++i)
{
size_t address = track | (DOSMap[sector+i] << 8);
std::memcpy((uint8_t *)_map + _offset + address, bp, 256);
bp = (uint8_t *)bp + 256;
}
}
break;
default:
throw Exception(__METHOD__ ": Unsupported Encoding.");
} }
else
{
size_t address = block * 512;
std::memcpy((uint8_t *)_map + _offset + address , bp, 512);
}
} }
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;
} }

View File

@ -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;