mirror of
https://github.com/ksherlock/profuse.git
synced 2025-01-10 07:30:09 +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 "../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)
|
||||
{
|
||||
|
@ -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
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…
x
Reference in New Issue
Block a user