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

This commit is contained in:
ksherlock 2009-12-12 15:26:51 +00:00
parent 147a16085a
commit e3ef4d7c10
3 changed files with 264 additions and 1 deletions

View File

@ -4,6 +4,8 @@
#include "../BlockDevice.h"
#include "../BlockCache.h"
#include "IOBuffer.h"
#include <algorithm>
#include <cstring>
#include <memory>
@ -11,9 +13,54 @@
using namespace LittleEndian;
using namespace Pascal;
static bool isalpha(char c)
{
return (c >= 'A' && c <= 'Z')
|| (c >= 'a' && c <= 'z') ;
}
static bool isalnumdot(char c)
{
return (c >= 'A' && c <= 'Z')
|| (c >= 'a' && c <= 'z')
|| (c >= '0' && c <='9')
|| (c == '.') ;
}
static bool islower(char c)
{
return c >= 'a' && c <= 'z';
}
inline char tolower(char c) { return c | 0x20; }
inline char toupper(char c) { return c & ~0x20; }
#pragma mark -
#pragma mark DirEntry
unsigned Entry::ValidName(const char *cp, unsigned maxLength)
{
unsigned length;
if (!cp || !*cp) return 0;
if (!isalpaha(*cp)) return 0;
for (length = 1; cp[length]; ++length)
{
if (length >= maxLength) return 0;
if (!isalnumdot(cp[length])) return 0;
}
return length;
}
Entry::Entry()
{
_firstBlock = 0;
@ -42,10 +89,22 @@ void Entry::init(void *vp)
_inode = 0;
}
void Entry::writeDirectoryEntry(IOBuffer *b)
{
b->write16(_firstBlock);
b->write16(_lastBlock);
b->write8(_fileKind);
}
#pragma mark -
#pragma mark VolumeEntry
unsigned VolumeEntry::ValidName(const char *cp)
{
return Entry::ValidName(cp, 7);
}
VolumeEntry::VolumeEntry()
{
_fileNameLength = 0;
@ -61,6 +120,54 @@ VolumeEntry::VolumeEntry()
_device = NULL;
}
VolumeEntry::VolumeEntry(const char *name, ProFUSE::BlockDevice *device)
{
#undef __METHOD__
#define __METHOD__ "VolumeEntry::VolumeEntry"
unsigned length;
length = ValidName(name);
if (!length)
throw Exception(__METHOD__ ": Invalid volume name.");
_firstBlock = 2;
_lastBlock = 6;
_fileKind = kUntypedFile;
_inode = 1;
_inodeGenerator = 1;
_fileNameLength = length;
std::memset(_fileName, 0, sizeof(_fileName));
for (unsigned i = 0; i < _fileNameLength; ++i)
{
_fileName[i] = toupper(name[i]);
}
_lastVolumeBlock = device->blocks();
_fileCount = 0;
_accessTime = 0;
_lastBoot = Date.Today();
_cache = device->blockCache();
_device = device;
for (unsigned i = 2; i < 6; ++i)
{
device->zeroBlock(i);
}
void *vp = _blockCache->lock(2);
IOBuffer b(vp, 0x1a);
write(&b);
_blockCache->unlock(2, true);
}
VolumeEntry::VolumeEntry(ProFUSE::BlockDevice *device)
{
auto_array<uint8_t> buffer(new uint8_t[512]);
@ -185,9 +292,30 @@ void VolumeEntry::writeBlock(unsigned block, void *buffer)
}
void VolumeEntry::writeDirectoryEntry(IOBuffer *b)
{
Entry::writeDirectoryEntry(b);
b->write8(0); // reserved
b->write8(_fileNameLength);
b->writeBytes(_fileName, 7);
b->write16(_fileCount);
b->write16(_accessTime);
b->write16((unsigned)_lastBoot);
// rest is reserved.
b->writeZero(4);
}
#pragma mark -
#pragma mark FileEntry
unsigned FileEntry::ValidName(const char *cp)
{
return Entry::ValidName(cp, 15);
}
FileEntry::FileEntry(void *vp) :
Entry(vp)
{
@ -202,6 +330,31 @@ FileEntry::FileEntry(void *vp) :
_pageSize = NULL;
}
FileEntry::FileEntry(const char *name, unsigned fileKind)
{
#undef __METHOD__
#define __METHOD__ "FileEntry::FileEntry"
unsigned length = ValidName(name);
if (!length)
throw Exception(__METHOD__ ": Invalid file name.");
_fileKind = kind;
_status = 0;
_fileNameLength = length;
std::memset(_fileName, 0, sizeof(_fileName));
for (unsigned i = 0; i < length; ++i)
_fileName[i] = toupper(name[i]);
_modification = Date::Today();
_lastByte = 0;
_fileSize = 0;
_pageSize = NULL;
}
FileEntry::~FileEntry()
{
delete _pageSize;
@ -221,6 +374,16 @@ unsigned FileEntry::fileSize()
}
}
void FileEntry::writeDirectoryEntry(IOBuffer *b)
{
Entry::writeDirectoryEntry(b);
b->write8(_status ? 0x01 : 0x00);
b->write8(_fileNameLength);
b->writeBytes(_fileName, 15);
b->write16(_lastByte);
b->write16(_modification);
}
int FileEntry::read(uint8_t *buffer, unsigned size, unsigned offset)
{

View File

@ -10,6 +10,10 @@ namespace ProFUSE {
class AbstractBlockCache;
}
namespace LittleEndian {
class IOBuffer;
}
namespace Pascal {
@ -48,6 +52,10 @@ public:
protected:
unsigned static ValidName(const char *name, unsigned maxSize);
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
Entry();
Entry(void *);
@ -70,6 +78,10 @@ class VolumeEntry : public Entry {
public:
// create new
VolumeEntry(const char *name, ProFUSE::BlockDevice *);
// open existing
VolumeEntry(ProFUSE::BlockDevice *);
virtual ~VolumeEntry();
@ -80,6 +92,9 @@ public:
Pascal::Date lastBoot() const { return _lastBoot; }
FileEntry *fileAtIndex(unsigned i) const;
void addChild(FileEntry *child, unsigned blocks);
void *loadBlock(unsigned block);
@ -88,6 +103,12 @@ public:
void readBlock(unsigned block, void *);
void writeBlock(unsigned block, void *);
static ValidName(const char *);
protected:
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
private:
VolumeEntry();
@ -111,6 +132,7 @@ private:
class FileEntry : public Entry {
public:
FileEntry(const char *name, unsigned fileKind);
FileEntry(void *vp);
virtual ~FileEntry();
@ -118,13 +140,21 @@ class FileEntry : public Entry {
unsigned lastByte() const { return _lastByte; }
int read(uint8_t *buffer, unsigned size, unsigned offset);
int read(uint8_t *buffer, unsigned size, unsigned offset);
int write(uint8_t *buffer, unsigned size, unsigned offset);
const char *name() const { return _fileName; }
Date modification() const { return _modification; }
static ValidName(const char *);
protected:
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
private:
unsigned _status;
unsigned _fileNameLength;

70
pascal/IOBuffer.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef __IOBUFFER_H__
#define __IOBUFFER_H__
#include "../Endian.h"
namespace LittleEndian {
class IOBuffer {
public:
IOBuffer(void *vp, unsigned size)
{
_buffer = vp;
_size = size;
_offset = 0;
}
void write8(uint8_t value)
{
Write8(_buffer, _offset, value);
_offset += 1;
}
void write16(uint16_t value)
{
Write16(_buffer, _offset, value);
_offset += 2;
}
void write24(uint32_t value)
{
Write24(_buffer, _offset, value);
_offset += 3;
}
void write32(uint32_t value)
{
Write32(_buffer, _offset, value);
_offset += 4;
}
void writeBytes(const void *value, unsigned count);
{
std::memcpy(_offset + (uint8_t *)_buffer, value, count);
_size += count;
}
void writeZero(unsigned count)
{
uint8_t *cp = _offset + (uint8_t *)_buffer;
for (unsigned i = 0; i < count; ++i)
{
cp[i] = 0;
}
_offset += count;
}
unsigned offset() const { return _offset; }
void setOffset(unsigned offset) { _offset = offset; }
unsinged size() const { return _size; }
private:
void *_buffer;
unsigned _size;
unsigned _offset;
};
}
#endif