add no-throwing validation code.

git-svn-id: https://profuse.googlecode.com/svn/branches/profuse_interim@376 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
ksherlock 2011-03-07 23:39:52 +00:00
parent c6165e16d2
commit 5ab8fd3d87
8 changed files with 156 additions and 112 deletions

View File

@ -47,42 +47,48 @@ DavexDiskImage::~DavexDiskImage()
// scan and update usedBlocks?
}
void DavexDiskImage::Validate(MappedFile *f)
bool DavexDiskImage::Validate(MappedFile *f, const std::nothrow_t &)
{
#undef __METHOD__
#define __METHOD__ "DavexDiskImage::Validate"
size_t size = f->length();
const void * data = f->address();
unsigned blocks = (size / 512) - 1;
if (size < 512) return false;
if (size % 512) return false;
// identity.
if (std::memcmp(data, IdentityCheck, 16))
return false;
// file format.
if (Read8(data, 0x10) != 0)
return false;
// total blocks
if (Read32(data, 33) != blocks)
return false;
// file number -- must be 1
if (Read8(data, 64) != 1)
return false;
return true;
}
bool DavexDiskImage::Validate(MappedFile *f)
{
#undef __METHOD__
#define __METHOD__ "DavexDiskImage::Validate"
size_t size = f->length();
const void * data = f->address();
bool ok = false;
unsigned blocks = (size / 512) - 1;
do {
if (size < 512) break;
if (size % 512) break;
// identity.
if (std::memcmp(data, IdentityCheck, 16))
break;
// file format.
if (Read8(data, 0x10) != 0)
break;
// total blocks
if (Read32(data, 33) != blocks)
break;
// file number -- must be 1
if (Read8(data, 64) != 1)
break;
ok = true;
} while (false);
if (!ok)
if (!Validate(f, std::nothrow))
throw Exception(__METHOD__ ": Invalid file format.");
return true;
}
BlockDevicePointer DavexDiskImage::Open(MappedFile *file)

View File

@ -2,6 +2,7 @@
#define __DAVEXDISKIMAGE_H__
#include <string>
#include <new>
#include <Device/BlockDevice.h>
#include <Device/DiskImage.h>
@ -22,12 +23,15 @@ public:
virtual BlockCachePointer createBlockCache();
static bool Validate(MappedFile *, const std::nothrow_t &);
static bool Validate(MappedFile *);
private:
DavexDiskImage();
DavexDiskImage(MappedFile *);
static void Validate(MappedFile *);
bool _changed;
std::string _volumeName;

View File

@ -126,18 +126,33 @@ BlockDevicePointer ProDOSOrderDiskImage::Open(MappedFile *file)
return MAKE_SHARED(ProDOSOrderDiskImage, file);
}
void ProDOSOrderDiskImage::Validate(MappedFile *f)
bool ProDOSOrderDiskImage::Validate(MappedFile *f, const std::nothrow_t &)
{
#undef __METHOD__
#define __METHOD__ "ProDOSOrderDiskImage::Validate"
size_t size = f->length();
if (size % 512)
return false;
return true;
}
bool ProDOSOrderDiskImage::Validate(MappedFile *f)
{
#undef __METHOD__
#define __METHOD__ "ProDOSOrderDiskImage::Validate"
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
size_t size = f->length();
if (size % 512)
if (!Validate(f))
throw Exception(__METHOD__ ": Invalid file format.");
return true;
}
BlockCachePointer ProDOSOrderDiskImage::createBlockCache()
@ -157,6 +172,8 @@ DOSOrderDiskImage::DOSOrderDiskImage(const char *name, bool readOnly) :
}
*/
DOSOrderDiskImage::DOSOrderDiskImage(MappedFile *file) :
DiskImage(file)
{
@ -182,16 +199,30 @@ BlockDevicePointer DOSOrderDiskImage::Open(MappedFile *file)
}
void DOSOrderDiskImage::Validate(MappedFile *f)
bool DOSOrderDiskImage::Validate(MappedFile *f, const std::nothrow_t &)
{
#undef __METHOD__
#define __METHOD__ "DOSOrderDiskImage::Validate"
size_t size = f->length();
if (size % 512)
return false;
return true;
}
bool DOSOrderDiskImage::Validate(MappedFile *f)
{
#undef __METHOD__
#define __METHOD__ "DOSOrderDiskImage::Validate"
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
size_t size = f->length();
if (size % 512)
if (!Validate(f))
throw Exception(__METHOD__ ": Invalid file format.");
return true;
}

View File

@ -62,13 +62,14 @@ public:
virtual BlockCachePointer createBlockCache();
static bool Validate(MappedFile *, const std::nothrow_t &);
static bool Validate(MappedFile *);
private:
ProDOSOrderDiskImage();
ProDOSOrderDiskImage(MappedFile *);
static void Validate(MappedFile *);
};
class DOSOrderDiskImage : public DiskImage {
@ -78,11 +79,13 @@ public:
static BlockDevicePointer Create(const char *name, size_t blocks);
static BlockDevicePointer Open(MappedFile *);
static bool Validate(MappedFile *, const std::nothrow_t &);
static bool Validate(MappedFile *);
private:
DOSOrderDiskImage();
DOSOrderDiskImage(MappedFile *);
static void Validate(MappedFile *);
};

View File

@ -62,48 +62,6 @@ struct record_thread
NuThreadIdx thread_index;
};
/*
* callback function to scan contents.
* (not used).
*
*/
static NuResult ContentFunction(NuArchive *archive, void *vp)
{
const NuRecord *record = (const NuRecord *)vp;
/*
* The application must not attempt to retain a copy of "pRecord"
* after the callback returns, as the structure may be freed.
* Anything of interest should be copied out.
*/
for (unsigned i = 0; i < NuRecordGetNumThreads(record); ++i)
{
const NuThread *thread = NuGetThread(record, i);
printf("%ld, %ld\n", (long)record->recordIdx, (long)thread->threadIdx);
if (NuGetThreadID(thread) == kNuThreadIDDiskImage)
{
record_thread *rt;
NuGetExtraData(archive, (void **)&rt);
if (rt)
{
rt->record_index = record->recordIdx;
rt->thread_index = thread->threadIdx;
}
return kNuAbort;
}
}
return kNuOK;
}
static record_thread FindDiskImageThread(NuArchive *archive)
{
@ -245,3 +203,34 @@ BlockDevicePointer SDKImage::Open(const char *name)
return ProDOSOrderDiskImage::Open(&file);
}
bool SDKImage::Validate(MappedFile * f, const std::nothrow_t &)
{
// NuFile, alternating ASCII.
static const char IdentityCheck[6] = { 0x4E, 0xF5, 0x46, 0xE9, 0x6C, 0xE5 };
if (f->length() < sizeof(IdentityCheck))
return false;
if (std::memcmp(f->address(), IdentityCheck, sizeof(IdentityCheck)))
return false;
return true;
}
bool SDKImage::Validate(MappedFile * f)
{
#undef __METHOD__
#define __METHOD__ "SDKImage::Validate"
if (!Validate(f))
throw Exception(__METHOD__ ": Invalid file format.");
return true;
}

View File

@ -18,6 +18,9 @@ namespace Device {
static BlockDevicePointer Open(const char *name);
static bool Validate(MappedFile *, const std::nothrow_t &);
static bool Validate(MappedFile *);
private:
SDKImage();
SDKImage(const SDKImage &);

View File

@ -100,42 +100,47 @@ BlockDevicePointer UniversalDiskImage::Open(MappedFile *file)
* TODO -- honor read-only flag.
*
*/
void UniversalDiskImage::Validate(MappedFile *file)
bool UniversalDiskImage::Validate(MappedFile *file, const std::nothrow_t &)
{
#undef __METHOD__
#define __METHOD__ "UniversalDiskImage::Validate"
const void *data = file->address();
size_t size = file->length();
bool ok = false;
unsigned blocks = 0;
unsigned offset = 0;
do {
if (size < 64) break;
if (std::memcmp(data, "2IMG", 4)) break;
// only prodos supported, for now...
// TODO -- Dos Order, Nibble support.
if (Read32(data, 0x0c) != 1) break;
blocks = Read32(data, 0x14);
offset = Read32(data, 0x18);
// file size == blocks * 512
if (Read32(data, 0x1c) != blocks * 512) break;
if (offset + blocks * 512 > size) break;
ok = true;
} while (false);
if (size < 64) return false;
if (!ok)
if (std::memcmp(data, "2IMG", 4)) return false;
// only prodos supported, for now...
// TODO -- Dos Order, Nibble support.
if (Read32(data, 0x0c) != 1) return false;
blocks = Read32(data, 0x14);
offset = Read32(data, 0x18);
// file size == blocks * 512
if (Read32(data, 0x1c) != blocks * 512) return false;
if (offset + blocks * 512 > size) return false;
return true;
}
bool UniversalDiskImage::Validate(MappedFile *file)
{
#undef __METHOD__
#define __METHOD__ "UniversalDiskImage::Validate"
if (!Validate(file, std::nothrow))
throw Exception(__METHOD__ ": Invalid file format.");
return true;
}

View File

@ -21,13 +21,16 @@ public:
virtual BlockCachePointer createBlockCache();
static bool Validate(MappedFile *, const std::nothrow_t &);
static bool Validate(MappedFile *);
private:
UniversalDiskImage();
UniversalDiskImage(MappedFile *);
static void Validate(MappedFile *);
uint32_t _format;
uint32_t _flags;