mirror of
https://github.com/ksherlock/profuse.git
synced 2024-12-22 20:29:59 +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 <algorithm>
|
||||
#include <cerrno>
|
||||
|
||||
#include <Pascal/Pascal.h>
|
||||
|
||||
@ -24,6 +25,10 @@ using ProFUSE::Exception;
|
||||
using ProFUSE::ProDOSException;
|
||||
using ProFUSE::POSIXException;
|
||||
|
||||
enum {
|
||||
kMaxFiles = 77
|
||||
};
|
||||
|
||||
unsigned VolumeEntry::ValidName(const char *cp)
|
||||
{
|
||||
// 7 chars max. Legal values: ascii, printable,
|
||||
@ -145,7 +150,6 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device)
|
||||
try
|
||||
{
|
||||
|
||||
std::vector<FileEntry *>::reverse_iterator riter;
|
||||
std::vector<FileEntry *>::iterator iter;
|
||||
|
||||
unsigned block;
|
||||
@ -192,15 +196,7 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
calcMaxFileSize();
|
||||
|
||||
}
|
||||
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()
|
||||
{
|
||||
@ -468,6 +552,9 @@ unsigned VolumeEntry::krunch()
|
||||
|
||||
_cache->sync();
|
||||
|
||||
|
||||
calcMaxFileSize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -476,14 +563,6 @@ unsigned VolumeEntry::krunch()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void *VolumeEntry::loadBlock(unsigned block)
|
||||
{
|
||||
return _cache->acquire(block);
|
||||
@ -584,6 +663,19 @@ void VolumeEntry::writeEntry(FileEntry *e)
|
||||
|
||||
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 <Device/BlockDevice.h>
|
||||
|
||||
namespace Pascal {
|
||||
|
||||
@ -44,10 +45,16 @@ namespace Pascal {
|
||||
void writeBlock(unsigned block, void *);
|
||||
|
||||
void sync();
|
||||
|
||||
bool readOnly() { return _device->readOnly(); }
|
||||
|
||||
unsigned unlink(const char *name);
|
||||
unsigned rename(const char *oldName, const char *newName);
|
||||
|
||||
|
||||
FileEntry *create(const char *name, unsigned blocks);
|
||||
|
||||
|
||||
unsigned krunch();
|
||||
|
||||
|
||||
@ -71,6 +78,8 @@ namespace Pascal {
|
||||
|
||||
void writeEntry(FileEntry *e);
|
||||
|
||||
void calcMaxFileSize();
|
||||
|
||||
|
||||
unsigned _fileNameLength;
|
||||
char _fileName[8];
|
||||
|
Loading…
Reference in New Issue
Block a user