Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/wasmfs/memory_backend.h
6174 views
1
// Copyright 2021 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
6
// This file defines the memory file class. This should be the only backend file
7
// type defined in a header since it is the default type.
8
9
#pragma once
10
11
#include "backend.h"
12
#include "file.h"
13
#include <emscripten/threading.h>
14
15
namespace wasmfs {
16
17
// This class describes a file that lives in Wasm Memory.
18
class MemoryDataFile : public DataFile {
19
std::vector<uint8_t> buffer;
20
21
int open(oflags_t) override { return 0; }
22
int close() override { return 0; }
23
ssize_t write(const uint8_t* buf, size_t len, off_t offset) override;
24
ssize_t read(uint8_t* buf, size_t len, off_t offset) override;
25
int flush() override { return 0; }
26
off_t getSize() override { return buffer.size(); }
27
int setSize(off_t size) override {
28
if (size > buffer.max_size()) {
29
return -EOVERFLOW;
30
}
31
buffer.resize(size);
32
return 0;
33
}
34
35
public:
36
MemoryDataFile(mode_t mode, backend_t backend) : DataFile(mode, backend) {}
37
38
class Handle : public DataFile::Handle {
39
40
std::shared_ptr<MemoryDataFile> getFile() {
41
return file->cast<MemoryDataFile>();
42
}
43
44
public:
45
Handle(std::shared_ptr<File> dataFile) : DataFile::Handle(dataFile) {}
46
};
47
48
Handle locked() { return Handle(shared_from_this()); }
49
};
50
51
class MemoryDirectory : public Directory {
52
// Use a vector instead of a map to save code size.
53
struct ChildEntry {
54
std::string name;
55
std::shared_ptr<File> child;
56
};
57
58
std::vector<ChildEntry> entries;
59
60
std::vector<ChildEntry>::iterator findEntry(const std::string& name);
61
62
protected:
63
void insertChild(const std::string& name, std::shared_ptr<File> child) {
64
assert(findEntry(name) == entries.end());
65
entries.push_back({name, child});
66
}
67
68
std::shared_ptr<File> getChild(const std::string& name) override;
69
70
int removeChild(const std::string& name) override;
71
72
std::shared_ptr<DataFile> insertDataFile(const std::string& name,
73
mode_t mode) override {
74
auto child = getBackend()->createFile(mode);
75
insertChild(name, child);
76
return child;
77
}
78
79
std::shared_ptr<Directory> insertDirectory(const std::string& name,
80
mode_t mode) override {
81
auto child = getBackend()->createDirectory(mode);
82
insertChild(name, child);
83
return child;
84
}
85
86
std::shared_ptr<Symlink> insertSymlink(const std::string& name,
87
const std::string& target) override {
88
auto child = getBackend()->createSymlink(target);
89
insertChild(name, child);
90
return child;
91
}
92
93
int insertMove(const std::string& name, std::shared_ptr<File> file) override;
94
95
ssize_t getNumEntries() override { return entries.size(); }
96
Directory::MaybeEntries getEntries() override;
97
98
std::string getName(std::shared_ptr<File> file) override;
99
100
// Since we internally track files with `File` objects, we don't need the
101
// dcache as well.
102
bool maintainsFileIdentity() override { return true; }
103
104
public:
105
MemoryDirectory(mode_t mode, backend_t backend) : Directory(mode, backend) {}
106
};
107
108
class MemorySymlink : public Symlink {
109
std::string target;
110
111
std::string getTarget() const override { return target; }
112
113
public:
114
MemorySymlink(const std::string& target, backend_t backend)
115
: Symlink(backend), target(target) {}
116
};
117
118
backend_t createMemoryBackend();
119
120
} // namespace wasmfs
121
122