summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys/vfs_vector.h
blob: bfedb6e42aa7213be4e9988fd81d69ccf41b48a6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <array>
#include <cstring>
#include <memory>
#include <string>
#include <vector>
#include "core/file_sys/vfs.h"

namespace FileSys {

// An implementation of VfsFile that is backed by a statically-sized array
template <std::size_t size>
class ArrayVfsFile : public VfsFile {
public:
    explicit ArrayVfsFile(const std::array<u8, size>& data_, std::string name_ = "",
                          VirtualDir parent_ = nullptr)
        : data(data_), name(std::move(name_)), parent(std::move(parent_)) {}

    std::string GetName() const override {
        return name;
    }

    std::size_t GetSize() const override {
        return size;
    }

    bool Resize(std::size_t new_size) override {
        return false;
    }

    VirtualDir GetContainingDirectory() const override {
        return parent;
    }

    bool IsWritable() const override {
        return false;
    }

    bool IsReadable() const override {
        return true;
    }

    std::size_t Read(u8* data_, std::size_t length, std::size_t offset) const override {
        const auto read = std::min(length, size - offset);
        std::memcpy(data_, data.data() + offset, read);
        return read;
    }

    std::size_t Write(const u8* data_, std::size_t length, std::size_t offset) override {
        return 0;
    }

    bool Rename(std::string_view new_name) override {
        name = new_name;
        return true;
    }

private:
    std::array<u8, size> data;
    std::string name;
    VirtualDir parent;
};

template <std::size_t Size, typename... Args>
std::shared_ptr<ArrayVfsFile<Size>> MakeArrayFile(const std::array<u8, Size>& data,
                                                  Args&&... args) {
    return std::make_shared<ArrayVfsFile<Size>>(data, std::forward<Args>(args)...);
}

// An implementation of VfsFile that is backed by a vector optionally supplied upon construction
class VectorVfsFile : public VfsFile {
public:
    explicit VectorVfsFile(std::vector<u8> initial_data = {}, std::string name_ = "",
                           VirtualDir parent_ = nullptr);
    ~VectorVfsFile() override;

    std::string GetName() const override;
    std::size_t GetSize() const override;
    bool Resize(std::size_t new_size) override;
    VirtualDir GetContainingDirectory() const override;
    bool IsWritable() const override;
    bool IsReadable() const override;
    std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
    std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
    bool Rename(std::string_view name) override;

    virtual void Assign(std::vector<u8> new_data);

private:
    std::vector<u8> data;
    VirtualDir parent;
    std::string name;
};

// An implementation of VfsDirectory that maintains two vectors for subdirectories and files.
// Vector data is supplied upon construction.
class VectorVfsDirectory : public VfsDirectory {
public:
    explicit VectorVfsDirectory(std::vector<VirtualFile> files = {},
                                std::vector<VirtualDir> dirs = {}, std::string name = "",
                                VirtualDir parent = nullptr);
    ~VectorVfsDirectory() override;

    std::vector<VirtualFile> GetFiles() const override;
    std::vector<VirtualDir> GetSubdirectories() const override;
    bool IsWritable() const override;
    bool IsReadable() const override;
    std::string GetName() const override;
    VirtualDir GetParentDirectory() const override;
    bool DeleteSubdirectory(std::string_view subdir_name) override;
    bool DeleteFile(std::string_view file_name) override;
    bool Rename(std::string_view name) override;
    VirtualDir CreateSubdirectory(std::string_view subdir_name) override;
    VirtualFile CreateFile(std::string_view file_name) override;

    virtual void AddFile(VirtualFile file);
    virtual void AddDirectory(VirtualDir dir);

private:
    std::vector<VirtualFile> files;
    std::vector<VirtualDir> dirs;

    VirtualDir parent;
    std::string name;
};

} // namespace FileSys