mirror of
https://github.com/ksherlock/profuse.git
synced 2024-12-23 11:31:43 +00:00
create()
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@289 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
e4efb135ed
commit
d4a8391650
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
#include <Pascal/Pascal.h>
|
#include <Pascal/Pascal.h>
|
||||||
|
|
||||||
@ -24,6 +25,10 @@ using ProFUSE::Exception;
|
|||||||
using ProFUSE::ProDOSException;
|
using ProFUSE::ProDOSException;
|
||||||
using ProFUSE::POSIXException;
|
using ProFUSE::POSIXException;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kMaxFiles = 77
|
||||||
|
};
|
||||||
|
|
||||||
unsigned VolumeEntry::ValidName(const char *cp)
|
unsigned VolumeEntry::ValidName(const char *cp)
|
||||||
{
|
{
|
||||||
// 7 chars max. Legal values: ascii, printable,
|
// 7 chars max. Legal values: ascii, printable,
|
||||||
@ -145,7 +150,6 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<FileEntry *>::reverse_iterator riter;
|
|
||||||
std::vector<FileEntry *>::iterator iter;
|
std::vector<FileEntry *>::iterator iter;
|
||||||
|
|
||||||
unsigned block;
|
unsigned block;
|
||||||
@ -192,15 +196,7 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
calcMaxFileSize();
|
||||||
// set up _maxFileSize;
|
|
||||||
block= _lastVolumeBlock;
|
|
||||||
for (riter = _files.rbegin(); riter != _files.rend(); ++riter)
|
|
||||||
{
|
|
||||||
FileEntry *e = *riter;
|
|
||||||
e->_maxFileSize = (block - e->_firstBlock) * 512;
|
|
||||||
block = e->_firstBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
@ -379,6 +375,94 @@ unsigned VolumeEntry::rename(const char *oldName, const char *newName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create a file. if blocks is defined, verifies the file could
|
||||||
|
* expand to fit.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FileEntry *VolumeEntry::create(const char *name, unsigned blocks)
|
||||||
|
{
|
||||||
|
// 0. check read only access.
|
||||||
|
// 1. verify < 77 file names.
|
||||||
|
// 2. verify space at end of disk.
|
||||||
|
// 3. make sure it's a legal file name.
|
||||||
|
// 4. verify it's not a duplicate file name.
|
||||||
|
// 6. create the file entry.
|
||||||
|
// 7. insert into _files, write to disk, update _maxFileSize
|
||||||
|
|
||||||
|
unsigned lastBlock;
|
||||||
|
unsigned maxBlocks;
|
||||||
|
|
||||||
|
std::auto_ptr<FileEntry>entry;
|
||||||
|
FileEntry *prev = NULL;
|
||||||
|
FileEntry *curr = NULL;
|
||||||
|
|
||||||
|
if (readOnly())
|
||||||
|
{
|
||||||
|
errno = EACCES;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_fileCount == kMaxFiles)
|
||||||
|
{
|
||||||
|
errno = ENOSPC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_fileCount)
|
||||||
|
{
|
||||||
|
prev = _files.back();
|
||||||
|
lastBlock = prev->_lastBlock;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lastBlock = _lastBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxBlocks = _lastVolumeBlock - lastBlock;
|
||||||
|
|
||||||
|
if (maxBlocks < blocks || maxBlocks == 0)
|
||||||
|
{
|
||||||
|
errno = ENOSPC;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FileEntry::ValidName(name))
|
||||||
|
{
|
||||||
|
errno = ENAMETOOLONG; // or invalid.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileByName(name))
|
||||||
|
{
|
||||||
|
errno = EEXIST;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
entry.reset(new FileEntry(name, kUntypedFile));
|
||||||
|
|
||||||
|
_files.push_back(entry.get());
|
||||||
|
|
||||||
|
curr = entry.release();
|
||||||
|
|
||||||
|
curr->_firstBlock = lastBlock;
|
||||||
|
curr->_lastBlock = lastBlock + 1;
|
||||||
|
curr->_lastByte = 0;
|
||||||
|
curr->_maxFileSize = maxBlocks * 512;
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
prev->_maxFileSize = prev->blocks() * 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeEntry(curr);
|
||||||
|
|
||||||
|
return curr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned VolumeEntry::krunch()
|
unsigned VolumeEntry::krunch()
|
||||||
{
|
{
|
||||||
@ -468,6 +552,9 @@ unsigned VolumeEntry::krunch()
|
|||||||
|
|
||||||
_cache->sync();
|
_cache->sync();
|
||||||
|
|
||||||
|
|
||||||
|
calcMaxFileSize();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,14 +563,6 @@ unsigned VolumeEntry::krunch()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void *VolumeEntry::loadBlock(unsigned block)
|
void *VolumeEntry::loadBlock(unsigned block)
|
||||||
{
|
{
|
||||||
return _cache->acquire(block);
|
return _cache->acquire(block);
|
||||||
@ -584,6 +663,19 @@ void VolumeEntry::writeEntry(FileEntry *e)
|
|||||||
|
|
||||||
writeBlocks(buffer.get(), startBlock, 2);
|
writeBlocks(buffer.get(), startBlock, 2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
// set _maxFileSize for all entries.
|
||||||
|
void VolumeEntry::calcMaxFileSize()
|
||||||
|
{
|
||||||
|
std::vector<FileEntry *>::reverse_iterator riter;
|
||||||
|
unsigned block = _lastVolumeBlock;
|
||||||
|
for (riter = _files.rbegin(); riter != _files.rend(); ++riter)
|
||||||
|
{
|
||||||
|
FileEntry *e = *riter;
|
||||||
|
e->_maxFileSize = (block - e->_firstBlock) * 512;
|
||||||
|
block = e->_firstBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <Device/BlockDevice.h>
|
||||||
|
|
||||||
namespace Pascal {
|
namespace Pascal {
|
||||||
|
|
||||||
@ -44,10 +45,16 @@ namespace Pascal {
|
|||||||
void writeBlock(unsigned block, void *);
|
void writeBlock(unsigned block, void *);
|
||||||
|
|
||||||
void sync();
|
void sync();
|
||||||
|
|
||||||
|
bool readOnly() { return _device->readOnly(); }
|
||||||
|
|
||||||
unsigned unlink(const char *name);
|
unsigned unlink(const char *name);
|
||||||
unsigned rename(const char *oldName, const char *newName);
|
unsigned rename(const char *oldName, const char *newName);
|
||||||
|
|
||||||
|
|
||||||
|
FileEntry *create(const char *name, unsigned blocks);
|
||||||
|
|
||||||
|
|
||||||
unsigned krunch();
|
unsigned krunch();
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +78,8 @@ namespace Pascal {
|
|||||||
|
|
||||||
void writeEntry(FileEntry *e);
|
void writeEntry(FileEntry *e);
|
||||||
|
|
||||||
|
void calcMaxFileSize();
|
||||||
|
|
||||||
|
|
||||||
unsigned _fileNameLength;
|
unsigned _fileNameLength;
|
||||||
char _fileName[8];
|
char _fileName[8];
|
||||||
|
Loading…
Reference in New Issue
Block a user