mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Attributes are now returned as part of the dirent.
This commit is contained in:
@@ -18,7 +18,7 @@ public:
|
||||
filename = filename.substr(0, filename.find(' '));
|
||||
|
||||
this->inode = inode;
|
||||
path = { filename };
|
||||
path = {filename};
|
||||
start_sector = ((bytes1[6] & 0x03) << 8) | bytes1[7];
|
||||
load_address =
|
||||
((bytes1[6] & 0x0c) << 14) | (bytes1[1] << 8) | bytes1[0];
|
||||
@@ -29,6 +29,18 @@ public:
|
||||
sector_count = (length + 255) / 256;
|
||||
file_type = TYPE_FILE;
|
||||
mode = locked ? "L" : "";
|
||||
|
||||
attributes[Filesystem::FILENAME] = filename;
|
||||
attributes[Filesystem::LENGTH] = fmt::format("{}", length);
|
||||
attributes[Filesystem::FILE_TYPE] = "file";
|
||||
attributes[Filesystem::MODE] = mode;
|
||||
attributes["acorndfs.inode"] = fmt::format("{}", inode);
|
||||
attributes["acorndfs.start_sector"] = fmt::format("{}", start_sector);
|
||||
attributes["acorndfs.load_address"] =
|
||||
fmt::format("0x{:x}", load_address);
|
||||
attributes["acorndfs.exec_address"] =
|
||||
fmt::format("0x{:x}", exec_address);
|
||||
attributes["acorndfs.locked"] = fmt::format("{}", locked);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -150,26 +162,10 @@ public:
|
||||
return data;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path)
|
||||
{
|
||||
std::map<std::string, std::string> attributes;
|
||||
|
||||
AcornDfsDirectory dir(this);
|
||||
auto dirent = dir.findFile(path);
|
||||
attributes[FILENAME] = dirent->filename;
|
||||
attributes[LENGTH] = fmt::format("{}", dirent->length);
|
||||
attributes[FILE_TYPE] = "file";
|
||||
attributes[MODE] = dirent->mode;
|
||||
attributes["acorndfs.inode"] = fmt::format("{}", dirent->inode);
|
||||
attributes["acorndfs.start_sector"] =
|
||||
fmt::format("{}", dirent->start_sector);
|
||||
attributes["acorndfs.load_address"] =
|
||||
fmt::format("0x{:x}", dirent->load_address);
|
||||
attributes["acorndfs.exec_address"] =
|
||||
fmt::format("0x{:x}", dirent->exec_address);
|
||||
attributes["acorndfs.locked"] = fmt::format("{}", dirent->locked);
|
||||
|
||||
return attributes;
|
||||
return dir.findFile(path);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -113,21 +113,13 @@ public:
|
||||
auto* entry = (struct Entry*)cell->content;
|
||||
cell = cell->next;
|
||||
|
||||
auto dirent = std::make_shared<Dirent>();
|
||||
dirent->path = path;
|
||||
dirent->path.push_back(entry->name);
|
||||
dirent->filename = entry->name;
|
||||
dirent->length = entry->size;
|
||||
dirent->file_type =
|
||||
(entry->type == ST_FILE) ? TYPE_FILE : TYPE_DIRECTORY;
|
||||
dirent->mode = modeToString(entry->access);
|
||||
results.push_back(dirent);
|
||||
results.push_back(toDirent(entry, path));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getMetadata(const Path& path)
|
||||
{
|
||||
AdfMount m(this);
|
||||
if (path.size() == 0)
|
||||
@@ -140,24 +132,7 @@ public:
|
||||
if (!entry)
|
||||
throw BadPathException();
|
||||
|
||||
std::map<std::string, std::string> attributes;
|
||||
attributes[FILENAME] = entry->name;
|
||||
attributes[LENGTH] = fmt::format("{}", entry->size);
|
||||
attributes[FILE_TYPE] = (entry->type == ST_FILE) ? "file" : "dir";
|
||||
attributes[MODE] = modeToString(entry->access);
|
||||
attributes["amigaffs.comment"] = entry->comment;
|
||||
attributes["amigaffs.sector"] = entry->sector;
|
||||
|
||||
std::tm tm = {.tm_sec = entry->secs,
|
||||
.tm_min = entry->mins,
|
||||
.tm_hour = entry->hour,
|
||||
.tm_mday = entry->days,
|
||||
.tm_mon = entry->month,
|
||||
.tm_year = entry->year - 1900};
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, "%FT%T%z");
|
||||
attributes["amigaffs.mtime"] = ss.str();
|
||||
return attributes;
|
||||
return toDirent(entry, path.parent());
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
@@ -212,6 +187,39 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Dirent> toDirent(struct Entry* entry, const Path& container)
|
||||
{
|
||||
auto dirent = std::make_shared<Dirent>();
|
||||
|
||||
dirent->path = container;
|
||||
dirent->path.push_back(entry->name);
|
||||
dirent->filename = entry->name;
|
||||
dirent->length = entry->size;
|
||||
dirent->file_type =
|
||||
(entry->type == ST_FILE) ? TYPE_FILE : TYPE_DIRECTORY;
|
||||
dirent->mode = modeToString(entry->access);
|
||||
|
||||
dirent->attributes[FILENAME] = entry->name;
|
||||
dirent->attributes[LENGTH] = fmt::format("{}", entry->size);
|
||||
dirent->attributes[FILE_TYPE] =
|
||||
(entry->type == ST_FILE) ? "file" : "dir";
|
||||
dirent->attributes[MODE] = modeToString(entry->access);
|
||||
dirent->attributes["amigaffs.comment"] = entry->comment;
|
||||
dirent->attributes["amigaffs.sector"] = entry->sector;
|
||||
|
||||
std::tm tm = {.tm_sec = entry->secs,
|
||||
.tm_min = entry->mins,
|
||||
.tm_hour = entry->hour,
|
||||
.tm_mday = entry->days,
|
||||
.tm_mon = entry->month,
|
||||
.tm_year = entry->year - 1900};
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(&tm, "%FT%T%z");
|
||||
dirent->attributes["amigaffs.mtime"] = ss.str();
|
||||
|
||||
return dirent;
|
||||
}
|
||||
|
||||
class AdfEntry
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
ByteReader br(bytes);
|
||||
filename = br.read(8);
|
||||
filename = filename.substr(0, filename.find(' '));
|
||||
path = { filename };
|
||||
path = {filename};
|
||||
|
||||
this->inode = inode;
|
||||
brother_type = br.read_8();
|
||||
@@ -41,6 +41,14 @@ public:
|
||||
length = sector_length * SECTOR_SIZE;
|
||||
file_type = TYPE_FILE;
|
||||
mode = "";
|
||||
|
||||
attributes[Filesystem::FILENAME] = filename;
|
||||
attributes[Filesystem::LENGTH] = fmt::format("{}", length);
|
||||
attributes[Filesystem::FILE_TYPE] = "file";
|
||||
attributes[Filesystem::MODE] = mode;
|
||||
attributes["brother120.inode"] = fmt::format("{}", inode);
|
||||
attributes["brother120.start_sector"] = fmt::format("{}", start_sector);
|
||||
attributes["brother120.type"] = fmt::format("{}", brother_type);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -69,7 +77,7 @@ public:
|
||||
|
||||
auto de = std::make_unique<Brother120Dirent>(inode, buffer);
|
||||
usedSectors += de->sector_length;
|
||||
// dirents.push_back(std::move(de));
|
||||
dirents.push_back(std::move(de));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +121,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata()
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
BrotherDirectory dir(this);
|
||||
|
||||
@@ -125,12 +133,12 @@ public:
|
||||
return attributes;
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path)
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
if (!path.empty())
|
||||
throw FileNotFoundException();
|
||||
@@ -144,7 +152,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
BrotherDirectory dir(this);
|
||||
auto dirent = dir.findFile(path);
|
||||
@@ -161,22 +169,10 @@ public:
|
||||
return data;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
std::map<std::string, std::string> attributes;
|
||||
|
||||
BrotherDirectory dir(this);
|
||||
auto dirent = dir.findFile(path);
|
||||
attributes[FILENAME] = dirent->filename;
|
||||
attributes[LENGTH] = fmt::format("{}", dirent->length);
|
||||
attributes[FILE_TYPE] = "file";
|
||||
attributes[MODE] = dirent->mode;
|
||||
attributes["brother120.inode"] = fmt::format("{}", dirent->inode);
|
||||
attributes["brother120.start_sector"] =
|
||||
fmt::format("{}", dirent->start_sector);
|
||||
attributes["brother120.type"] = fmt::format("{}", dirent->brother_type);
|
||||
|
||||
return attributes;
|
||||
return dir.findFile(path);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -74,7 +74,7 @@ class CbmfsFilesystem : public Filesystem
|
||||
|
||||
auto filenameBytes = br.read(16).split(0xa0)[0];
|
||||
filename = fromPetscii(filenameBytes);
|
||||
path = { filename };
|
||||
path = {filename};
|
||||
side_track = br.read_8();
|
||||
side_sector = br.read_8();
|
||||
recordlen = br.read_8();
|
||||
@@ -84,6 +84,18 @@ class CbmfsFilesystem : public Filesystem
|
||||
file_type = TYPE_FILE;
|
||||
length = sectors * 254;
|
||||
mode = "";
|
||||
|
||||
attributes[Filesystem::FILENAME] = filename;
|
||||
attributes[Filesystem::LENGTH] = fmt::format("{}", length);
|
||||
attributes[Filesystem::FILE_TYPE] = "file";
|
||||
attributes[Filesystem::MODE] = mode;
|
||||
attributes["cbmfs.type"] = toFileType(cbm_type);
|
||||
attributes["cbmfs.start_track"] = fmt::format("{}", start_track);
|
||||
attributes["cbmfs.start_sector"] = fmt::format("{}", start_sector);
|
||||
attributes["cbmfs.side_track"] = fmt::format("{}", side_track);
|
||||
attributes["cbmfs.side_sector"] = fmt::format("{}", side_sector);
|
||||
attributes["cbmfs.recordlen"] = fmt::format("{}", recordlen);
|
||||
attributes["cbmfs.sectors"] = fmt::format("{}", sectors);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -183,7 +195,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata()
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
Directory dir(this);
|
||||
|
||||
@@ -197,12 +209,12 @@ public:
|
||||
return attributes;
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path)
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
if (path.size() != 0)
|
||||
throw BadPathException();
|
||||
@@ -215,29 +227,16 @@ public:
|
||||
return results;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
Directory dir(this);
|
||||
auto de = dir.findFile(unhex(path[0]));
|
||||
|
||||
std::map<std::string, std::string> attributes;
|
||||
attributes[FILENAME] = de->filename;
|
||||
attributes[LENGTH] = fmt::format("{}", de->length);
|
||||
attributes[FILE_TYPE] = "file";
|
||||
attributes[MODE] = de->mode;
|
||||
attributes["cbmfs.type"] = toFileType(de->cbm_type);
|
||||
attributes["cbmfs.start_track"] = fmt::format("{}", de->start_track);
|
||||
attributes["cbmfs.start_sector"] = fmt::format("{}", de->start_sector);
|
||||
attributes["cbmfs.side_track"] = fmt::format("{}", de->side_track);
|
||||
attributes["cbmfs.side_sector"] = fmt::format("{}", de->side_sector);
|
||||
attributes["cbmfs.recordlen"] = fmt::format("{}", de->recordlen);
|
||||
attributes["cbmfs.sectors"] = fmt::format("{}", de->sectors);
|
||||
return attributes;
|
||||
Directory dir(this);
|
||||
return dir.findFile(unhex(path[0]));
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata()
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
mount();
|
||||
|
||||
@@ -108,12 +108,12 @@ public:
|
||||
return attributes;
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path)
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (!path.empty())
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
if (!dirent)
|
||||
{
|
||||
dirent = std::make_unique<Dirent>();
|
||||
dirent->path = { entry->filename };
|
||||
dirent->path = {entry->filename};
|
||||
dirent->filename = entry->filename;
|
||||
dirent->mode = entry->mode;
|
||||
dirent->length = 0;
|
||||
@@ -143,50 +143,33 @@ public:
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> result;
|
||||
for (auto& e : map)
|
||||
result.push_back(std::move(e.second));
|
||||
{
|
||||
auto& de = e.second;
|
||||
de->attributes[FILENAME] = de->filename;
|
||||
de->attributes[LENGTH] = fmt::format("{}", de->length);
|
||||
de->attributes[FILE_TYPE] = "file";
|
||||
de->attributes[MODE] = de->mode;
|
||||
result.push_back(std::move(de));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
|
||||
std::shared_ptr<Dirent> dirent;
|
||||
for (int d = 0; d < _config.dir_entries(); d++)
|
||||
for (const auto& dirent : list(Path()))
|
||||
{
|
||||
auto entry = getEntry(d);
|
||||
if (!entry)
|
||||
continue;
|
||||
if (path[0] != entry->filename)
|
||||
continue;
|
||||
|
||||
if (!dirent)
|
||||
{
|
||||
dirent = std::make_shared<Dirent>();
|
||||
dirent->filename = entry->filename;
|
||||
dirent->mode = entry->mode;
|
||||
dirent->length = 0;
|
||||
dirent->file_type = TYPE_FILE;
|
||||
}
|
||||
|
||||
dirent->length = std::max(
|
||||
dirent->length, entry->extent * 16384 + entry->records * 128);
|
||||
if (dirent->filename == path.front())
|
||||
return dirent;
|
||||
}
|
||||
|
||||
if (!dirent)
|
||||
throw FileNotFoundException();
|
||||
|
||||
std::map<std::string, std::string> attributes;
|
||||
attributes[FILENAME] = dirent->filename;
|
||||
attributes[LENGTH] = fmt::format("{}", dirent->length);
|
||||
attributes[FILE_TYPE] = "file";
|
||||
attributes[MODE] = dirent->mode;
|
||||
return attributes;
|
||||
throw FileNotFoundException();
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (path.size() != 1)
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata()
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
mount();
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void create(bool quick, const std::string& volumeName)
|
||||
void create(bool quick, const std::string& volumeName) override
|
||||
{
|
||||
if (!quick)
|
||||
eraseEverythingOnDisk();
|
||||
@@ -78,12 +78,12 @@ public:
|
||||
f_setlabel(volumeName.c_str());
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path)
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
|
||||
@@ -101,22 +101,14 @@ public:
|
||||
if (filinfo.fname[0] == 0)
|
||||
break;
|
||||
|
||||
auto dirent = std::make_shared<Dirent>();
|
||||
dirent->path = path;
|
||||
dirent->path.push_back(filinfo.fname);
|
||||
dirent->filename = filinfo.fname;
|
||||
dirent->length = filinfo.fsize;
|
||||
dirent->file_type =
|
||||
(filinfo.fattrib & AM_DIR) ? TYPE_DIRECTORY : TYPE_FILE;
|
||||
dirent->mode = modeToString(filinfo.fattrib);
|
||||
results.push_back(dirent);
|
||||
results.push_back(toDirent(filinfo, path));
|
||||
}
|
||||
|
||||
f_closedir(&dir);
|
||||
return results;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
std::map<std::string, std::string> attributes;
|
||||
|
||||
@@ -126,15 +118,10 @@ public:
|
||||
FRESULT res = f_stat(pathstr.c_str(), &filinfo);
|
||||
throwError(res);
|
||||
|
||||
attributes[FILENAME] = filinfo.fname;
|
||||
attributes[LENGTH] = fmt::format("{}", filinfo.fsize);
|
||||
attributes[FILE_TYPE] = (filinfo.fattrib & AM_DIR) ? "dir" : "file";
|
||||
attributes[MODE] = modeToString(filinfo.fattrib);
|
||||
|
||||
return attributes;
|
||||
return toDirent(filinfo, path.parent());
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
auto pathstr = path.to_str();
|
||||
@@ -160,7 +147,7 @@ public:
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void putFile(const Path& path, const Bytes& bytes)
|
||||
void putFile(const Path& path, const Bytes& bytes) override
|
||||
{
|
||||
mount();
|
||||
auto pathstr = path.to_str();
|
||||
@@ -184,6 +171,27 @@ public:
|
||||
f_close(&fil);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Dirent> toDirent(FILINFO& filinfo, const Path& parent)
|
||||
{
|
||||
auto dirent = std::make_shared<Dirent>();
|
||||
dirent->path = parent;
|
||||
dirent->path.push_back(filinfo.fname);
|
||||
dirent->filename = filinfo.fname;
|
||||
dirent->length = filinfo.fsize;
|
||||
dirent->file_type =
|
||||
(filinfo.fattrib & AM_DIR) ? TYPE_DIRECTORY : TYPE_FILE;
|
||||
dirent->mode = modeToString(filinfo.fattrib);
|
||||
|
||||
dirent->attributes[Filesystem::FILENAME] = filinfo.fname;
|
||||
dirent->attributes[Filesystem::LENGTH] =
|
||||
fmt::format("{}", filinfo.fsize);
|
||||
dirent->attributes[Filesystem::FILE_TYPE] =
|
||||
(filinfo.fattrib & AM_DIR) ? "dir" : "file";
|
||||
dirent->attributes[Filesystem::MODE] = modeToString(filinfo.fattrib);
|
||||
return dirent;
|
||||
}
|
||||
|
||||
public:
|
||||
DRESULT diskRead(BYTE* buffer, LBA_t sector, UINT count)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata()
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
HfsMount m(this);
|
||||
|
||||
@@ -42,12 +42,12 @@ public:
|
||||
return attributes;
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
void create(bool quick, const std::string& volumeName)
|
||||
void create(bool quick, const std::string& volumeName) override
|
||||
{
|
||||
if (!quick)
|
||||
eraseEverythingOnDisk();
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
(const char*)this, 0, HFS_MODE_ANY, volumeName.c_str(), 0, nullptr);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path)
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
HfsMount m(this);
|
||||
|
||||
@@ -73,28 +73,12 @@ public:
|
||||
if (r != 0)
|
||||
break;
|
||||
|
||||
auto dirent = std::make_shared<Dirent>();
|
||||
dirent->filename = de.name;
|
||||
dirent->path = path;
|
||||
dirent->path.push_back(de.name);
|
||||
if (de.flags & HFS_ISDIR)
|
||||
{
|
||||
|
||||
dirent->file_type = TYPE_DIRECTORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
dirent->file_type = TYPE_FILE;
|
||||
dirent->length =
|
||||
de.u.file.dsize + de.u.file.rsize + AppleSingle::OVERHEAD;
|
||||
}
|
||||
dirent->mode = (de.flags & HFS_ISLOCKED) ? "L" : "";
|
||||
results.push_back(dirent);
|
||||
results.push_back(toDirent(de, path));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
HfsMount m(this);
|
||||
if (path.size() == 0)
|
||||
@@ -106,44 +90,10 @@ public:
|
||||
if (hfs_stat(_vol, pathstr.c_str(), &de))
|
||||
throw FileNotFoundException();
|
||||
|
||||
std::map<std::string, std::string> attributes;
|
||||
attributes[FILENAME] = de.name;
|
||||
attributes[LENGTH] = "0";
|
||||
attributes[FILE_TYPE] = (de.flags & HFS_ISDIR) ? "dir" : "file";
|
||||
attributes[MODE] = (de.flags & HFS_ISLOCKED) ? "L" : "";
|
||||
attributes["machfs.ctime"] = toIso8601(de.crdate);
|
||||
attributes["machfs.mtime"] = toIso8601(de.mddate);
|
||||
attributes["machfs.last_backup"] = toIso8601(de.bkdate);
|
||||
attributes["machfs.finder.x"] = fmt::format("{}", de.fdlocation.h);
|
||||
attributes["machfs.finder.y"] = fmt::format("{}", de.fdlocation.v);
|
||||
attributes["machfs.finder.flags"] = fmt::format("0x{:x}", de.fdflags);
|
||||
if (de.flags & HFS_ISDIR)
|
||||
{
|
||||
attributes["machfs.dir.valence"] =
|
||||
fmt::format("{}", de.u.dir.valence);
|
||||
attributes["machfs.dir.x1"] = fmt::format("{}", de.u.dir.rect.left);
|
||||
attributes["machfs.dir.y1"] = fmt::format("{}", de.u.dir.rect.top);
|
||||
attributes["machfs.dir.x2"] =
|
||||
fmt::format("{}", de.u.dir.rect.right);
|
||||
attributes["machfs.dir.y2"] =
|
||||
fmt::format("{}", de.u.dir.rect.bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes["length"] = fmt::format("{}",
|
||||
de.u.file.dsize + de.u.file.rsize + AppleSingle::OVERHEAD);
|
||||
attributes["machfs.file.dsize"] =
|
||||
fmt::format("{}", de.u.file.dsize);
|
||||
attributes["machfs.file.rsize"] =
|
||||
fmt::format("{}", de.u.file.rsize);
|
||||
attributes["machfs.file.type"] = de.u.file.type;
|
||||
attributes["machfs.file.creator"] = de.u.file.creator;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
return toDirent(de, path.parent());
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
HfsMount m(this);
|
||||
if (path.size() == 0)
|
||||
@@ -170,7 +120,7 @@ public:
|
||||
return a.render();
|
||||
}
|
||||
|
||||
void putFile(const Path& path, const Bytes& bytes)
|
||||
void putFile(const Path& path, const Bytes& bytes) override
|
||||
{
|
||||
HfsMount m(this);
|
||||
if (path.size() == 0)
|
||||
@@ -202,6 +152,64 @@ public:
|
||||
writeBytes(file, a.rsrc);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Dirent> toDirent(hfsdirent& de, const Path& parent)
|
||||
{
|
||||
auto dirent = std::make_shared<Dirent>();
|
||||
dirent->filename = de.name;
|
||||
dirent->path = parent;
|
||||
dirent->path.push_back(de.name);
|
||||
if (de.flags & HFS_ISDIR)
|
||||
dirent->file_type = TYPE_DIRECTORY;
|
||||
else
|
||||
{
|
||||
dirent->file_type = TYPE_FILE;
|
||||
dirent->length =
|
||||
de.u.file.dsize + de.u.file.rsize + AppleSingle::OVERHEAD;
|
||||
}
|
||||
dirent->mode = (de.flags & HFS_ISLOCKED) ? "L" : "";
|
||||
|
||||
dirent->attributes[FILENAME] = de.name;
|
||||
dirent->attributes[LENGTH] = "0";
|
||||
dirent->attributes[FILE_TYPE] = (de.flags & HFS_ISDIR) ? "dir" : "file";
|
||||
dirent->attributes[MODE] = (de.flags & HFS_ISLOCKED) ? "L" : "";
|
||||
dirent->attributes["machfs.ctime"] = toIso8601(de.crdate);
|
||||
dirent->attributes["machfs.mtime"] = toIso8601(de.mddate);
|
||||
dirent->attributes["machfs.last_backup"] = toIso8601(de.bkdate);
|
||||
dirent->attributes["machfs.finder.x"] =
|
||||
fmt::format("{}", de.fdlocation.h);
|
||||
dirent->attributes["machfs.finder.y"] =
|
||||
fmt::format("{}", de.fdlocation.v);
|
||||
dirent->attributes["machfs.finder.flags"] =
|
||||
fmt::format("0x{:x}", de.fdflags);
|
||||
if (de.flags & HFS_ISDIR)
|
||||
{
|
||||
dirent->attributes["machfs.dir.valence"] =
|
||||
fmt::format("{}", de.u.dir.valence);
|
||||
dirent->attributes["machfs.dir.x1"] =
|
||||
fmt::format("{}", de.u.dir.rect.left);
|
||||
dirent->attributes["machfs.dir.y1"] =
|
||||
fmt::format("{}", de.u.dir.rect.top);
|
||||
dirent->attributes["machfs.dir.x2"] =
|
||||
fmt::format("{}", de.u.dir.rect.right);
|
||||
dirent->attributes["machfs.dir.y2"] =
|
||||
fmt::format("{}", de.u.dir.rect.bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
dirent->attributes["length"] = fmt::format("{}",
|
||||
de.u.file.dsize + de.u.file.rsize + AppleSingle::OVERHEAD);
|
||||
dirent->attributes["machfs.file.dsize"] =
|
||||
fmt::format("{}", de.u.file.dsize);
|
||||
dirent->attributes["machfs.file.rsize"] =
|
||||
fmt::format("{}", de.u.file.rsize);
|
||||
dirent->attributes["machfs.file.type"] = de.u.file.type;
|
||||
dirent->attributes["machfs.file.creator"] = de.u.file.creator;
|
||||
}
|
||||
|
||||
return dirent;
|
||||
}
|
||||
|
||||
private:
|
||||
Bytes readBytes(hfsfile* file)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,17 @@ Path::Path(const std::string& path)
|
||||
}
|
||||
}
|
||||
|
||||
Path Path::parent() const
|
||||
{
|
||||
Path p;
|
||||
if (!empty())
|
||||
{
|
||||
for (int i = 0; i < (size() - 1); i++)
|
||||
p.push_back((*this)[i]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
std::string Path::to_str(const std::string sep) const
|
||||
{
|
||||
return join(*this, sep);
|
||||
@@ -78,7 +89,7 @@ void Filesystem::putFile(const Path& path, const Bytes& data)
|
||||
throw UnimplementedFilesystemException();
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> Filesystem::getMetadata(const Path& path)
|
||||
std::shared_ptr<Dirent> Filesystem::getDirent(const Path& path)
|
||||
{
|
||||
throw UnimplementedFilesystemException();
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ class Path : public std::vector<std::string>
|
||||
{
|
||||
public:
|
||||
Path() {}
|
||||
Path(const std::vector<std::string> other);
|
||||
Path(const std::vector<std::string> other);
|
||||
Path(const std::string& text);
|
||||
|
||||
public:
|
||||
Path parent() const;
|
||||
std::string to_str(const std::string sep = "/") const;
|
||||
};
|
||||
|
||||
@@ -29,11 +30,12 @@ enum FileType
|
||||
|
||||
struct Dirent
|
||||
{
|
||||
Path path;
|
||||
Path path;
|
||||
std::string filename;
|
||||
FileType file_type;
|
||||
uint32_t length;
|
||||
std::string mode;
|
||||
std::map<std::string, std::string> attributes;
|
||||
};
|
||||
|
||||
enum FilesystemStatus
|
||||
@@ -137,8 +139,8 @@ public:
|
||||
/* Write a file. */
|
||||
virtual void putFile(const Path& path, const Bytes& data);
|
||||
|
||||
/* Get file metadata. */
|
||||
virtual std::map<std::string, std::string> getMetadata(const Path& path);
|
||||
/* Get a single file dirent. */
|
||||
virtual std::shared_ptr<Dirent> getDirent(const Path& path);
|
||||
|
||||
/* Update file metadata. */
|
||||
virtual void putMetadata(
|
||||
@@ -190,7 +192,7 @@ public:
|
||||
|
||||
static std::unique_ptr<Filesystem> createFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
static std::unique_ptr<Filesystem> createFilesystemFromConfig();
|
||||
static std::unique_ptr<Filesystem> createFilesystemFromConfig();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,9 +30,9 @@ int mainGetFileInfo(int argc, const char* argv[])
|
||||
try
|
||||
{
|
||||
auto filesystem = Filesystem::createFilesystemFromConfig();
|
||||
auto attributes = filesystem->getMetadata(Path(directory));
|
||||
auto dirent = filesystem->getDirent(Path(directory));
|
||||
|
||||
for (const auto& e : attributes)
|
||||
for (const auto& e : dirent->attributes)
|
||||
fmt::print("{}={}\n", e.first, quote(e.second));
|
||||
}
|
||||
catch (const FilesystemException& e)
|
||||
|
||||
28
tests/vfs.cc
28
tests/vfs.cc
@@ -6,17 +6,27 @@ using namespace snowhouse;
|
||||
|
||||
static void testPathParsing()
|
||||
{
|
||||
AssertThat(Path(""), Equals(std::vector<std::string>{}));
|
||||
AssertThat(Path("/"), Equals(std::vector<std::string>{}));
|
||||
AssertThat(Path("one"), Equals(std::vector<std::string>{ "one" }));
|
||||
AssertThat(Path("one/two"), Equals(std::vector<std::string>{ "one", "two" }));
|
||||
AssertThat(Path("/one/two"), Equals(std::vector<std::string>{ "one", "two" }));
|
||||
AssertThat(Path(""), Equals(std::vector<std::string>{}));
|
||||
AssertThat(Path("/"), Equals(std::vector<std::string>{}));
|
||||
AssertThat(Path("one"), Equals(std::vector<std::string>{"one"}));
|
||||
AssertThat(Path("one/two"), Equals(std::vector<std::string>{"one", "two"}));
|
||||
AssertThat(
|
||||
Path("/one/two"), Equals(std::vector<std::string>{"one", "two"}));
|
||||
}
|
||||
|
||||
static void testPathParenthood()
|
||||
{
|
||||
AssertThat(Path("").parent(), Equals(std::vector<std::string>{}));
|
||||
AssertThat(Path("one").parent(), Equals(std::vector<std::string>{}));
|
||||
AssertThat(
|
||||
Path("one/two").parent(), Equals(std::vector<std::string>{"one"}));
|
||||
AssertThat(Path("one/two/three").parent(),
|
||||
Equals(std::vector<std::string>{"one", "two"}));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
testPathParsing();
|
||||
return 0;
|
||||
testPathParsing();
|
||||
testPathParenthood();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user