summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-09 20:46:41 -0400
committerGravatar Zach Hilman2018-08-11 22:50:08 -0400
commit42114e1df49ff65f09865b53395e01858ca4929e (patch)
tree3d67f3a63681a531d629f25e85ddf22d2f8581fc /src/core
parentcrypto: Remove hex utilities from key_manager (diff)
downloadyuzu-42114e1df49ff65f09865b53395e01858ca4929e.tar.gz
yuzu-42114e1df49ff65f09865b53395e01858ca4929e.tar.xz
yuzu-42114e1df49ff65f09865b53395e01858ca4929e.zip
vfs: Add ConcatenatedVfsFile
Diffstat (limited to 'src/core')
-rw-r--r--src/core/file_sys/vfs_concat.cpp93
-rw-r--r--src/core/file_sys/vfs_concat.h41
2 files changed, 134 insertions, 0 deletions
diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp
new file mode 100644
index 000000000..1d439e0a4
--- /dev/null
+++ b/src/core/file_sys/vfs_concat.cpp
@@ -0,0 +1,93 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <utility>
7
8#include "core/file_sys/vfs_concat.h"
9
10namespace FileSys {
11
12VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string_view name) {
13 if (files.empty())
14 return nullptr;
15 if (files.size() == 1)
16 return files[0];
17
18 return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), name));
19}
20
21ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string_view name)
22 : name(name) {
23 size_t next_offset = 0;
24 for (const auto& file : files_) {
25 files[next_offset] = file;
26 next_offset += file->GetSize();
27 }
28}
29
30std::string ConcatenatedVfsFile::GetName() const {
31 if (files.empty())
32 return "";
33 if (!name.empty())
34 return name;
35 return files.begin()->second->GetName();
36}
37
38size_t ConcatenatedVfsFile::GetSize() const {
39 if (files.empty())
40 return 0;
41 return files.rbegin()->first + files.rbegin()->second->GetSize();
42}
43
44bool ConcatenatedVfsFile::Resize(size_t new_size) {
45 return false;
46}
47
48std::shared_ptr<VfsDirectory> ConcatenatedVfsFile::GetContainingDirectory() const {
49 if (files.empty())
50 return nullptr;
51 return files.begin()->second->GetContainingDirectory();
52}
53
54bool ConcatenatedVfsFile::IsWritable() const {
55 return false;
56}
57
58bool ConcatenatedVfsFile::IsReadable() const {
59 return true;
60}
61
62size_t ConcatenatedVfsFile::Read(u8* data, size_t length, size_t offset) const {
63 auto entry = files.end();
64 for (auto iter = files.begin(); iter != files.end(); ++iter) {
65 if (iter->first > offset) {
66 entry = --iter;
67 break;
68 }
69 }
70
71 if (entry == files.end() && offset < files.rbegin()->first + files.rbegin()->second->GetSize())
72 --entry;
73
74 if (entry == files.end())
75 return 0;
76
77 const auto remaining = entry->second->GetSize() + offset - entry->first;
78 if (length > remaining) {
79 return entry->second->Read(data, remaining, offset - entry->first) +
80 Read(data + remaining, length - remaining, offset + remaining);
81 }
82
83 return entry->second->Read(data, length, offset - entry->first);
84}
85
86size_t ConcatenatedVfsFile::Write(const u8* data, size_t length, size_t offset) {
87 return 0;
88}
89
90bool ConcatenatedVfsFile::Rename(std::string_view name) {
91 return false;
92}
93} // namespace FileSys
diff --git a/src/core/file_sys/vfs_concat.h b/src/core/file_sys/vfs_concat.h
new file mode 100644
index 000000000..d319c5786
--- /dev/null
+++ b/src/core/file_sys/vfs_concat.h
@@ -0,0 +1,41 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <string_view>
9#include <boost/container/flat_map.hpp>
10#include "core/file_sys/vfs.h"
11
12namespace FileSys {
13
14// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases.
15VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string_view name = "");
16
17// Class that wraps multiple vfs files and concatenates them, making reads seamless. Currently
18// read-only.
19class ConcatenatedVfsFile : public VfsFile {
20 friend VirtualFile ConcatenateFiles(std::vector<VirtualFile> files, std::string_view name);
21
22 ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string_view name);
23
24public:
25 std::string GetName() const override;
26 size_t GetSize() const override;
27 bool Resize(size_t new_size) override;
28 std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
29 bool IsWritable() const override;
30 bool IsReadable() const override;
31 size_t Read(u8* data, size_t length, size_t offset) const override;
32 size_t Write(const u8* data, size_t length, size_t offset) override;
33 bool Rename(std::string_view name) override;
34
35private:
36 // Maps starting offset to file -- more efficient.
37 boost::container::flat_map<u64, VirtualFile> files;
38 std::string name;
39};
40
41} // namespace FileSys