Skip to content

Commit

Permalink
Add support for renaming files.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgiven committed May 13, 2024
1 parent 78d5584 commit 7643457
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
46 changes: 45 additions & 1 deletion lib/vfs/cpmfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class CpmFsFilesystem : public Filesystem, public HasBitmap, public HasMount
uint32_t capabilities() const override
{
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_PUTFILE | OP_DELETE |
OP_GETDIRENT | OP_CREATE;
OP_GETDIRENT | OP_CREATE | OP_MOVE;
}

std::map<std::string, std::string> getMetadata() override
Expand Down Expand Up @@ -439,6 +439,50 @@ class CpmFsFilesystem : public Filesystem, public HasBitmap, public HasMount
unmount();
}

void moveFile(const Path& oldPath, const Path& newPath) override
{
mount();
if ((oldPath.size() != 1) || (newPath.size() != 1))
throw BadPathException();

/* Check to make sure that the file exists, and that the new filename
* does not. */

bool found = false;
for (int d = 0; d < _config.dir_entries(); d++)
{
auto entry = getEntry(d);
if (entry->deleted)
continue;

auto filename = entry->combinedFilename();
if (filename == oldPath[0])
found = true;
if (filename == newPath[0])
throw CannotWriteException();
}
if (!found)
throw FileNotFoundException();

/* Now do the rename. */

for (int d = 0; d < _config.dir_entries(); d++)
{
auto entry = getEntry(d);
if (entry->deleted)
continue;

auto filename = entry->combinedFilename();
if (filename == oldPath[0])
{
entry->changeFilename(newPath[0]);
putEntry(entry);
}
}

unmount();
}

void deleteFile(const Path& path) override
{
mount();
Expand Down
26 changes: 25 additions & 1 deletion tests/cpmfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static void testPutBigFile()
createDirent("BIGFILE", 2, 0x20, {17, 18})));
}

static auto testDelete()
static void testDelete()
{
auto sectors = std::make_shared<TestSectorInterface>();
auto fs = Filesystem::createCpmFsFilesystem(
Expand All @@ -223,6 +223,29 @@ static auto testDelete()
Equals((Bytes{0xe5} * 32) + createDirent("FILE2", 0, 1, {2})));
}

static void testMove()
{
auto sectors = std::make_shared<TestSectorInterface>();
auto fs = Filesystem::createCpmFsFilesystem(
globalConfig()->filesystem(), sectors);
fs->create(true, "volume");

fs->putFile(Path("0:FILE1"), Bytes{0x55} * 0x9000);
fs->putFile(Path("0:FILE2"), Bytes{5, 6, 7, 8});

fs->moveFile(Path("0:FILE1"), Path("1:FILE3"));

auto directory = getBlock(sectors, 0, 256).slice(0, 32 * 3);
AssertThat(directory,
Equals(createDirent("FILE3",
0,
0x80,
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
1) +
createDirent("FILE3", 2, 0x20, {17, 18}, 1) +
createDirent("FILE2", 0, 1, {19})));
}

int main(void)
{
try
Expand Down Expand Up @@ -262,6 +285,7 @@ int main(void)
testPutGet();
testPutBigFile();
testDelete();
testMove();
}
catch (const ErrorException& e)
{
Expand Down

0 comments on commit 7643457

Please sign in to comment.