disk_archive.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <memory>
  7. #include "common/common_types.h"
  8. #include "common/file_util.h"
  9. #include "common/logging/log.h"
  10. #include "core/file_sys/disk_archive.h"
  11. #include "core/file_sys/errors.h"
  12. ////////////////////////////////////////////////////////////////////////////////////////////////////
  13. // FileSys namespace
  14. namespace FileSys {
  15. ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
  16. if (!mode.read_flag)
  17. return ERROR_INVALID_OPEN_FLAGS;
  18. file->Seek(offset, SEEK_SET);
  19. return MakeResult<size_t>(file->ReadBytes(buffer, length));
  20. }
  21. ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush,
  22. const u8* buffer) const {
  23. if (!mode.write_flag)
  24. return ERROR_INVALID_OPEN_FLAGS;
  25. file->Seek(offset, SEEK_SET);
  26. size_t written = file->WriteBytes(buffer, length);
  27. if (flush)
  28. file->Flush();
  29. return MakeResult<size_t>(written);
  30. }
  31. u64 DiskFile::GetSize() const {
  32. return file->GetSize();
  33. }
  34. bool DiskFile::SetSize(const u64 size) const {
  35. file->Resize(size);
  36. file->Flush();
  37. return true;
  38. }
  39. bool DiskFile::Close() const {
  40. return file->Close();
  41. }
  42. ////////////////////////////////////////////////////////////////////////////////////////////////////
  43. DiskDirectory::DiskDirectory(const std::string& path) : directory() {
  44. unsigned size = FileUtil::ScanDirectoryTree(path, directory);
  45. directory.size = size;
  46. directory.isDirectory = true;
  47. children_iterator = directory.children.begin();
  48. }
  49. u32 DiskDirectory::Read(const u32 count, Entry* entries) {
  50. u32 entries_read = 0;
  51. while (entries_read < count && children_iterator != directory.children.cend()) {
  52. const FileUtil::FSTEntry& file = *children_iterator;
  53. const std::string& filename = file.virtualName;
  54. Entry& entry = entries[entries_read];
  55. LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size,
  56. file.isDirectory);
  57. // TODO(Link Mauve): use a proper conversion to UTF-16.
  58. for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
  59. entry.filename[j] = filename[j];
  60. if (!filename[j])
  61. break;
  62. }
  63. FileUtil::SplitFilename83(filename, entry.short_name, entry.extension);
  64. entry.is_directory = file.isDirectory;
  65. entry.is_hidden = (filename[0] == '.');
  66. entry.is_read_only = 0;
  67. entry.file_size = file.size;
  68. // We emulate a SD card where the archive bit has never been cleared, as it would be on
  69. // most user SD cards.
  70. // Some homebrews (blargSNES for instance) are known to mistakenly use the archive bit as a
  71. // file bit.
  72. entry.is_archive = !file.isDirectory;
  73. ++entries_read;
  74. ++children_iterator;
  75. }
  76. return entries_read;
  77. }
  78. } // namespace FileSys