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

This commit is contained in:
ksherlock 2009-11-23 22:36:05 +00:00
parent f8ddc09a70
commit 9f0b5f1004
6 changed files with 100 additions and 16 deletions

View File

@ -60,6 +60,7 @@ Entry::Entry(unsigned type, const char *name)
{ {
_storageType = type; _storageType = type;
_address = 0; _address = 0;
_index = 0;
_volume = NULL; _volume = NULL;
// everything else initialized in setName. // everything else initialized in setName.
@ -74,6 +75,7 @@ Entry::Entry(const void *bp)
uint8_t x; uint8_t x;
uint16_t xcase = 0; uint16_t xcase = 0;
_address = 0; _address = 0;
_index = 0;
_volume = NULL; _volume = NULL;
_caseFlag = 0; _caseFlag = 0;
std::memset(_name, 0, 16); std::memset(_name, 0, 16);
@ -318,12 +320,24 @@ void VolumeDirectory::write(Buffer *out)
#pragma mark SubDirectory #pragma mark SubDirectory
SubDirectory::SubDirectory(unsigned type, const char *name) : SubDirectory::SubDirectory(FileEntry *e) :
Directory(type, name) Directory(DirectoryHeader, e->iname())
{
_creation = e->creation();
setAccess(e->access());
_parentEntryPointer = e->block();
_parentEntryNumber = e->index();
_parentEntryLength = 0x27;
}
SubDirectory::SubDirectory(const char *name) :
Directory(DirectoryHeader, name)
{ {
_parentPointer = 0; _parentPointer = 0;
_parentEntryNumber = 0; _parentEntryNumber = 0;
_parentEntryLength = 0x27; _parentEntryLength = 0x27;
} }
SubDirectory::SubDirectory(const void *bp) : SubDirectory::SubDirectory(const void *bp) :

View File

@ -61,6 +61,14 @@ public:
// returns strlen() on success, 0 on failure. // returns strlen() on success, 0 on failure.
static unsigned ValidName(const char *); static unsigned ValidName(const char *);
unsigned block() const { return _address / 512; }
unsigned offset() const { return _address % 512; }
unsigned address() const { return _address; }
unsigned index() const { return _index; }
protected: protected:
Entry(int storageType, const char *name); Entry(int storageType, const char *name);
Entry(const void *bp); Entry(const void *bp);
@ -71,16 +79,26 @@ protected:
_storageType = type; _storageType = type;
} }
setAddress(unsigned address) setAddress(unsigned address)
{ {
_address = address; _address = address;
} }
setIndex(unsigned index)
{
_index = index;
}
Volume *volume() { return _volume; } Volume *volume() { return _volume; }
private: private:
unsigned _address; // absolute address on disk. unsigned _address;
unsigned _index;
Volume *_volume; Volume *_volume;
unsigned _storageType; unsigned _storageType;
@ -123,7 +141,7 @@ private:
unsigned _version unsigned _version
unsigned _minVersion unsigned _minVersion
unsigned _access; unsigned _access;
usnigned _entryLength; // always 0x27 unsigned _entryLength; // always 0x27
unsigned _entriesPerBlock; //always 0x0d unsigned _entriesPerBlock; //always 0x0d
unsigned _fileCount; unsigned _fileCount;
@ -156,7 +174,7 @@ private:
class SubDirectory : public Directory { class SubDirectory : public Directory {
public: public:
SubDirectory(FileEntry *);
private: private:
unsigned _parentPointer; unsigned _parentPointer;
unsigned _parentEntryNumber; unsigned _parentEntryNumber;
@ -172,6 +190,9 @@ public:
unsigned blocksUsed() const { return _blocksUsed; } unsigned blocksUsed() const { return _blocksUsed; }
unsigned eof() const { return _eof; } unsigned eof() const { return _eof; }
unsigned access() const { return _access; }
DateTime creation() const { return _creation; } DateTime creation() const { return _creation; }
DateTime modification() const { return _modification; } DateTime modification() const { return _modification; }

View File

@ -21,8 +21,21 @@ MappedFile::MappedFile(const char *name, bool readOnly) :
#undef __METHOD__ #undef __METHOD__
#define __METHOD__ "MappedFile::MappedFile" #define __METHOD__ "MappedFile::MappedFile"
auto_fd fd(::open(name, readOnly ? O_RDONLY : O_RDWR));
// if unable to open as read/write, open as read-only.
auto_fd fd;
if (!readOnly)
{
fd.reset(::open(name, O_RDWR));
}
if (fd < 0)
{
fd.reset(::open(name, O_RDONLY));
readOnly = true;
}
if (fd < 0) if (fd < 0)
{ {
throw Exception(__METHOD__ ": Unable to open file.", errno); throw Exception(__METHOD__ ": Unable to open file.", errno);
@ -38,7 +51,6 @@ MappedFile::MappedFile(int fd, bool readOnly) :
init(fd, readOnly); init(fd, readOnly);
} }
// todo -- verify throw calls destructor.
MappedFile::MappedFile(const char *name, size_t size) : MappedFile::MappedFile(const char *name, size_t size) :
_fd(-1), _fd(-1),
_map(MAP_FAILED) _map(MAP_FAILED)
@ -48,6 +60,7 @@ MappedFile::MappedFile(const char *name, size_t size) :
_size = size; _size = size;
_readOnly = false; _readOnly = false;
auto_fd fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644)); auto_fd fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644));
if (fd < 0) if (fd < 0)

View File

@ -1,18 +1,25 @@
#include "UniversalDiskImage.h" #include "UniversalDiskImage.h"
#include "MappedFile.h" #include "MappedFile.h"
#include "Buffer.h" #include "Buffer.h"
#inluce "Endian.h"
using namespace ProFUSE; using namespace ProFUSE;
using namespace LittleEndian;
UniversalDiskImage::UniversalDiskImage(const char *name, bool readOnly) : UniversalDiskImage::UniversalDiskImage(const char *name, bool readOnly) :
DiskImage(name, readOnly) DiskImage(name, readOnly)
{ {
Validate(file()); Validate(file());
const void *data = file()->fileData();
// flags. bit 31 = locked.
_flags = Read32(data, 0x10;
} }
UniversalDiskImage::UniversalDiskImage(MappedFile *file) : UniversalDiskImage::UniversalDiskImage(MappedFile *file) :
DiskImage(file) DiskImage(file)
{ {
_flags = 0;
} }
UniversalDiskImage *UniversalDiskImage::Create(const char *name, size_t blocks) UniversalDiskImage *UniversalDiskImage::Create(const char *name, size_t blocks)
@ -75,7 +82,7 @@ void UniversalDiskImage::Validate(MappedFile *file)
#undef __METHOD__ #undef __METHOD__
#define __METHOD__ "DavexDiskImage::Validate" #define __METHOD__ "DavexDiskImage::Validate"
uint8_t *data = (uint8_t *)file->fileData(); const void *data = file->fileData();
size_t size = file->fileSize(); size_t size = file->fileSize();
bool ok = false; bool ok = false;
unsigned blocks = 0; unsigned blocks = 0;
@ -88,13 +95,13 @@ void UniversalDiskImage::Validate(MappedFile *file)
if (std::memcmp(data, "2IMG", 4)) break; if (std::memcmp(data, "2IMG", 4)) break;
// only prodos supported, for now... // only prodos supported, for now...
if (file->read32(0x0c, LittleEndian) != 1) break; if (Read32(data, 0x0c) != 1) break;
offset = file->read32(0x20, LittleEndian); offset = Read32(data, 0x20);
blocks = file->read32(0x14, LittleEndian); blocks = Read32(data, 0x14);
// file size == blocks * 512 // file size == blocks * 512
if (file->read32(0x1c, LittleEndian) != blocks * 512) break; if (Read32(data, 0x1c) != blocks * 512) break;
if (offset + blocks * 512 > size) break; if (offset + blocks * 512 > size) break;
@ -107,4 +114,10 @@ void UniversalDiskImage::Validate(MappedFile *file)
file->reset(); file->reset();
file->setOffset(offset); file->setOffset(offset);
file->setBlocks(blocks); file->setBlocks(blocks);
}
bool UniversalDiskImage::readOnly()
{
return (_flags & 0x8000000) || DiskImage::readOnly();
} }

View File

@ -13,9 +13,13 @@ public:
static UniversalDiskImage *Create(const char *name, size_t blocks); static UniversalDiskImage *Create(const char *name, size_t blocks);
static UniversalDiskImage *Open(MappedFile *); static UniversalDiskImage *Open(MappedFile *);
virtual bool readOnly();
private: private:
UniversalDiskImage(MappedFile *); UniversalDiskImage(MappedFile *);
static void Validate(MappedFile *); static void Validate(MappedFile *);
uint32_t flags;
}; };
} }

25
auto.h
View File

@ -26,18 +26,37 @@ private:
class auto_fd class auto_fd
{ {
public: public:
auto_fd(int fd) : _fd(fd) { } auto_fd(int fd = -1) : _fd(fd) { }
~auto_fd() ~auto_fd() { close(); }
{ if (_fd != -1) ::close(_fd); }
int release() int release()
{ int tmp = _fd; _fd = -1; return tmp; } { int tmp = _fd; _fd = -1; return tmp; }
int get() const { return _fd; } int get() const { return _fd; }
operator int() const { return _fd; } operator int() const { return _fd; }
void reset(int fd)
{
if (fd != _fd)
{
close();
_fd = fd;
}
}
private: private:
auto_fd& operator=(const auto_fd&);
void close()
{
if (_fd >= 0)
{
::close(_fd);
fd = -1;
}
}
int _fd; int _fd;
}; };
#endif #endif