mirror of
https://github.com/ksherlock/profuse.git
synced 2024-05-28 22:41:39 +00:00
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@152 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
147a16085a
commit
e3ef4d7c10
163
pascal/File.cpp
163
pascal/File.cpp
|
@ -4,6 +4,8 @@
|
||||||
#include "../BlockDevice.h"
|
#include "../BlockDevice.h"
|
||||||
#include "../BlockCache.h"
|
#include "../BlockCache.h"
|
||||||
|
|
||||||
|
#include "IOBuffer.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -11,9 +13,54 @@
|
||||||
using namespace LittleEndian;
|
using namespace LittleEndian;
|
||||||
using namespace Pascal;
|
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 -
|
||||||
#pragma mark DirEntry
|
#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()
|
Entry::Entry()
|
||||||
{
|
{
|
||||||
_firstBlock = 0;
|
_firstBlock = 0;
|
||||||
|
@ -42,10 +89,22 @@ void Entry::init(void *vp)
|
||||||
_inode = 0;
|
_inode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entry::writeDirectoryEntry(IOBuffer *b)
|
||||||
|
{
|
||||||
|
b->write16(_firstBlock);
|
||||||
|
b->write16(_lastBlock);
|
||||||
|
b->write8(_fileKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark VolumeEntry
|
#pragma mark VolumeEntry
|
||||||
|
|
||||||
|
unsigned VolumeEntry::ValidName(const char *cp)
|
||||||
|
{
|
||||||
|
return Entry::ValidName(cp, 7);
|
||||||
|
}
|
||||||
|
|
||||||
VolumeEntry::VolumeEntry()
|
VolumeEntry::VolumeEntry()
|
||||||
{
|
{
|
||||||
_fileNameLength = 0;
|
_fileNameLength = 0;
|
||||||
|
@ -61,6 +120,54 @@ VolumeEntry::VolumeEntry()
|
||||||
_device = NULL;
|
_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)
|
VolumeEntry::VolumeEntry(ProFUSE::BlockDevice *device)
|
||||||
{
|
{
|
||||||
auto_array<uint8_t> buffer(new uint8_t[512]);
|
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 -
|
||||||
#pragma mark FileEntry
|
#pragma mark FileEntry
|
||||||
|
|
||||||
|
unsigned FileEntry::ValidName(const char *cp)
|
||||||
|
{
|
||||||
|
return Entry::ValidName(cp, 15);
|
||||||
|
}
|
||||||
|
|
||||||
FileEntry::FileEntry(void *vp) :
|
FileEntry::FileEntry(void *vp) :
|
||||||
Entry(vp)
|
Entry(vp)
|
||||||
{
|
{
|
||||||
|
@ -202,6 +330,31 @@ FileEntry::FileEntry(void *vp) :
|
||||||
_pageSize = NULL;
|
_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()
|
FileEntry::~FileEntry()
|
||||||
{
|
{
|
||||||
delete _pageSize;
|
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)
|
int FileEntry::read(uint8_t *buffer, unsigned size, unsigned offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,10 @@ namespace ProFUSE {
|
||||||
class AbstractBlockCache;
|
class AbstractBlockCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace LittleEndian {
|
||||||
|
class IOBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Pascal {
|
namespace Pascal {
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +52,10 @@ public:
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
unsigned static ValidName(const char *name, unsigned maxSize);
|
||||||
|
|
||||||
|
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
|
||||||
|
|
||||||
Entry();
|
Entry();
|
||||||
Entry(void *);
|
Entry(void *);
|
||||||
|
@ -70,6 +78,10 @@ class VolumeEntry : public Entry {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// create new
|
||||||
|
VolumeEntry(const char *name, ProFUSE::BlockDevice *);
|
||||||
|
|
||||||
|
// open existing
|
||||||
VolumeEntry(ProFUSE::BlockDevice *);
|
VolumeEntry(ProFUSE::BlockDevice *);
|
||||||
virtual ~VolumeEntry();
|
virtual ~VolumeEntry();
|
||||||
|
|
||||||
|
@ -80,6 +92,9 @@ public:
|
||||||
Pascal::Date lastBoot() const { return _lastBoot; }
|
Pascal::Date lastBoot() const { return _lastBoot; }
|
||||||
|
|
||||||
FileEntry *fileAtIndex(unsigned i) const;
|
FileEntry *fileAtIndex(unsigned i) const;
|
||||||
|
|
||||||
|
void addChild(FileEntry *child, unsigned blocks);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void *loadBlock(unsigned block);
|
void *loadBlock(unsigned block);
|
||||||
|
@ -88,6 +103,12 @@ public:
|
||||||
void readBlock(unsigned block, void *);
|
void readBlock(unsigned block, void *);
|
||||||
void writeBlock(unsigned block, void *);
|
void writeBlock(unsigned block, void *);
|
||||||
|
|
||||||
|
|
||||||
|
static ValidName(const char *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VolumeEntry();
|
VolumeEntry();
|
||||||
|
|
||||||
|
@ -111,6 +132,7 @@ private:
|
||||||
class FileEntry : public Entry {
|
class FileEntry : public Entry {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
FileEntry(const char *name, unsigned fileKind);
|
||||||
FileEntry(void *vp);
|
FileEntry(void *vp);
|
||||||
virtual ~FileEntry();
|
virtual ~FileEntry();
|
||||||
|
|
||||||
|
@ -118,13 +140,21 @@ class FileEntry : public Entry {
|
||||||
|
|
||||||
unsigned lastByte() const { return _lastByte; }
|
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; }
|
const char *name() const { return _fileName; }
|
||||||
Date modification() const { return _modification; }
|
Date modification() const { return _modification; }
|
||||||
|
|
||||||
|
static ValidName(const char *);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
unsigned _status;
|
unsigned _status;
|
||||||
|
|
||||||
unsigned _fileNameLength;
|
unsigned _fileNameLength;
|
||||||
|
|
70
pascal/IOBuffer.h
Normal file
70
pascal/IOBuffer.h
Normal 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
|
Loading…
Reference in New Issue
Block a user