Filesystem metadata works on Brother 120.

This commit is contained in:
David Given
2022-08-31 21:33:51 +02:00
parent 34f034c6c4
commit a392b84d9b
2 changed files with 81 additions and 60 deletions

View File

@@ -39,10 +39,10 @@ public:
bool locked;
};
class Directory
class AcornDfsDirectory
{
public:
Directory(Filesystem* fs)
AcornDfsDirectory(Filesystem* fs)
{
auto sector0 = fs->getLogicalSector(0);
auto sector1 = fs->getLogicalSector(1);
@@ -89,7 +89,7 @@ public:
std::map<std::string, std::string> getMetadata()
{
Directory dir(this);
AcornDfsDirectory dir(this);
std::map<std::string, std::string> attributes;
attributes[VOLUME_NAME] = dir.volumeName;
@@ -108,7 +108,7 @@ public:
{
if (!path.empty())
throw FileNotFoundException();
Directory dir(this);
AcornDfsDirectory dir(this);
std::vector<std::unique_ptr<Dirent>> result;
for (auto& dirent : dir.dirents)
@@ -161,7 +161,7 @@ private:
if (path.size() != 1)
throw BadPathException();
Directory dir(this);
AcornDfsDirectory dir(this);
for (auto& dirent : dir.dirents)
{
if (dirent->filename == path[0])

View File

@@ -36,7 +36,8 @@ public:
this->inode = inode;
brother_type = br.read_8();
start_sector = br.read_be16();
length = br.read_8() * SECTOR_SIZE;
sector_length = br.read_8();
length = sector_length * SECTOR_SIZE;
file_type = TYPE_FILE;
mode = "";
}
@@ -45,6 +46,60 @@ public:
int inode;
int brother_type;
uint32_t start_sector;
uint32_t sector_length;
};
class BrotherDirectory
{
public:
BrotherDirectory(Filesystem* fs)
{
/* Read directory. */
int inode = 0;
for (int block = 0; block < DIRECTORY_SECTORS; block++)
{
auto bytes = fs->getLogicalSector(block);
for (int d = 0; d < SECTOR_SIZE / 16; d++, inode++)
{
Bytes buffer = bytes.slice(d * 16, 16);
if (buffer[0] == 0xf0)
continue;
auto de = std::make_unique<Brother120Dirent>(inode, buffer);
usedSectors += de->sector_length;
//dirents.push_back(std::move(de));
}
}
/* Read FAT. */
Bytes bytes = fs->getLogicalSector(FAT_START_SECTOR, FAT_SECTORS);
ByteReader br(bytes);
fat.push_back(0xffff);
for (int sector = 1; sector != SECTOR_COUNT; sector++)
fat.push_back(br.read_be16());
}
std::unique_ptr<Brother120Dirent> findFile(const Path& path)
{
if (path.size() != 1)
throw BadPathException();
for (auto& dirent : dirents)
{
if (dirent->filename == path[0])
return std::move(dirent);
}
throw FileNotFoundException();
}
public:
std::vector<uint16_t> fat;
std::vector<std::unique_ptr<Brother120Dirent>> dirents;
uint32_t usedSectors = 0;
};
class Brother120Filesystem : public Filesystem
@@ -57,6 +112,18 @@ public:
{
}
std::map<std::string, std::string> getMetadata()
{
BrotherDirectory dir(this);
std::map<std::string, std::string> attributes;
attributes[VOLUME_NAME] = "";
attributes[TOTAL_BLOCKS] = fmt::format("{}", getLogicalSectorCount());
attributes[USED_BLOCKS] = fmt::format("{}", dir.usedSectors);
attributes[BLOCK_SIZE] = fmt::format("{}", SECTOR_SIZE);
return attributes;
}
FilesystemStatus check()
{
return FS_OK;
@@ -67,8 +134,10 @@ public:
if (!path.empty())
throw FileNotFoundException();
BrotherDirectory dir(this);
std::vector<std::unique_ptr<Dirent>> result;
for (auto& dirent : findAllFiles())
for (auto& dirent : dir.dirents)
result.push_back(std::move(dirent));
return result;
@@ -76,8 +145,8 @@ public:
Bytes getFile(const Path& path)
{
auto fat = readFat();
auto dirent = findFile(path);
BrotherDirectory dir(this);
auto dirent = dir.findFile(path);
int sector = dirent->start_sector;
Bytes data;
@@ -85,7 +154,7 @@ public:
while ((sector != 0) && (sector != 0xffff))
{
bw += getLogicalSector(sector - 1);
sector = fat.at(sector);
sector = dir.fat.at(sector);
}
return data;
@@ -95,7 +164,8 @@ public:
{
std::map<std::string, std::string> attributes;
auto dirent = findFile(path);
BrotherDirectory dir(this);
auto dirent = dir.findFile(path);
attributes[FILENAME] = dirent->filename;
attributes[LENGTH] = fmt::format("{}", dirent->length);
attributes[FILE_TYPE] = "file";
@@ -108,55 +178,6 @@ public:
return attributes;
}
private:
std::vector<uint32_t> readFat()
{
Bytes bytes = getLogicalSector(FAT_START_SECTOR, FAT_SECTORS);
ByteReader br(bytes);
std::vector<uint32_t> table;
table.push_back(0xffff);
for (int sector = 1; sector != SECTOR_COUNT; sector++)
table.push_back(br.read_be16());
return table;
}
std::vector<std::unique_ptr<Brother120Dirent>> findAllFiles()
{
std::vector<std::unique_ptr<Brother120Dirent>> result;
int inode = 0;
for (int block = 0; block < DIRECTORY_SECTORS; block++)
{
auto bytes = getLogicalSector(block);
for (int d = 0; d < SECTOR_SIZE / 16; d++, inode++)
{
Bytes buffer = bytes.slice(d * 16, 16);
if (buffer[0] == 0xf0)
continue;
result.push_back(
std::make_unique<Brother120Dirent>(inode, buffer));
}
}
return result;
}
std::unique_ptr<Brother120Dirent> findFile(const Path& path)
{
if (path.size() != 1)
throw BadPathException();
for (auto& dirent : findAllFiles())
{
if (dirent->filename == path[0])
return std::move(dirent);
}
throw FileNotFoundException();
}
private:
const Brother120FsProto& _config;
};