libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
ramfs.hpp
1#pragma once
2
3#include <functional>
4
5#include "libxr_assert.hpp"
6#include "libxr_def.hpp"
7#include "libxr_rw.hpp"
8#include "libxr_type.hpp"
9#include "rbt.hpp"
10
11namespace LibXR
12{
19class RamFS
20{
21 public:
28 RamFS(const char *name = "ramfs")
29 : root_(CreateDir(name)), bin_(CreateDir("bin")), dev_(CreateDir("dev"))
30 {
31 root_.Add(bin_);
32 root_.Add(dev_);
33 }
34
42 static int CompareStr(const char *const &a, const char *const &b)
43 {
44 return strcmp(a, b);
45 }
46
52 enum class FsNodeType : uint8_t
53 {
54 FILE,
55 DIR,
56 DEVICE,
57 STORAGE,
58 UNKNOW,
59 };
60
66 enum class FileType : uint8_t
67 {
68 READ_ONLY,
70 EXEC,
71 };
72
73 class Dir;
74
80 class FsNode
81 {
82 public:
83 const char *name;
84 FsNodeType type;
85 Dir *parent;
86 };
87
93 typedef class FileNode : public FsNode
94 {
95 public:
96 union
97 {
98 void *addr;
99 const void *addr_const;
100 int (*exec)(void *raw, int argc,
101 char **argv);
102 };
103
104 union
105 {
106 size_t size;
107 void *arg;
108 };
109
111
119 int Run(int argc, char **argv)
120 {
121 ASSERT(type == FileType::EXEC);
122 return exec(arg, argc, argv);
123 }
124
132 template <typename DataType, SizeLimitMode LimitMode = SizeLimitMode::MORE>
134 {
135 LibXR::Assert::SizeLimitCheck<LimitMode>(sizeof(DataType), size);
137 {
138 return *reinterpret_cast<DataType *>(addr);
139 }
140 else if (type == FileType::READ_ONLY)
141 {
142 return *reinterpret_cast<const DataType *>(addr_const);
143 }
144 else
145 {
146 ASSERT(false);
147 const void *addr = nullptr;
148 return *reinterpret_cast<const DataType *>(addr);
149 }
150 }
151 } FileNode;
152
153 typedef RBTree<const char *>::Node<FileNode> File;
154
165
171 class Device : public RBTree<const char *>::Node<DeviceNode>
172 {
173 public:
181 Device(const char *name, const ReadPort &read_port = ReadPort(),
182 const WritePort &write_port = WritePort())
183 {
184 char *name_buff = new char[strlen(name) + 1];
185 strcpy(name_buff, name);
186 data_.name = name_buff;
188
189 UNUSED(read_port);
190 UNUSED(write_port);
191 }
192
201 template <typename ReadOperation>
202 ErrorCode Read(ReadOperation &&op, RawData data)
203 {
204 return data_.read_port(data, std::forward<ReadOperation>(op));
205 }
206
215 template <typename WriteOperation>
216 ErrorCode Write(WriteOperation &&op, ConstRawData data)
217 {
218 return data_.write_port(data, std::forward<WriteOperation>(op));
219 }
220
222 };
223
224 typedef struct
225 {
226 // TODO:
227 uint32_t res;
228 } StorageBlock;
229
235 class DirNode : public FsNode
236 {
237 public:
239
241 };
242
249 class Dir : public RBTree<const char *>::Node<DirNode>
250 {
251 public:
257 void Add(File &file)
258 {
259 (*this)->rbt.Insert(file, file->name);
260 file->parent = this;
261 }
267 void Add(Dir &dir)
268 {
269 (*this)->rbt.Insert(dir, dir->name);
270 dir->parent = this;
271 }
278 {
279 (*this)->rbt.Insert(dev, dev->name);
280 dev->parent = this;
281 }
282
290 File *FindFile(const char *name)
291 {
292 auto ans = (*this)->rbt.Search<FsNode>(name);
293 if (ans && ans->data_.type == FsNodeType::FILE)
294 {
295 return reinterpret_cast<File *>(ans);
296 }
297 else
298 {
299 return nullptr;
300 }
301 }
302
310 File *FindFileRev(const char *name)
311 {
312 auto ans = FindFile(name);
313
314 std::function<ErrorCode(RBTree<const char *>::Node<FsNode> &)> fun;
315
316 fun = [&](RBTree<const char *>::Node<FsNode> &item) -> ErrorCode
317 {
318 FsNode &node = item;
319 if (node.type == FsNodeType::DIR)
320 {
321 Dir *dir = reinterpret_cast<Dir *>(&item);
322
323 ans = dir->FindFile(name);
324 if (ans)
325 {
326 return ErrorCode::FAILED;
327 }
328
329 dir->data_.rbt.Foreach<FsNode>([&](RBTree<const char *>::Node<FsNode> &child)
330 { return fun(child); });
331
332 return ans ? ErrorCode::FAILED : ErrorCode::OK;
333 }
334 return ErrorCode::OK;
335 };
336
337 if (ans == nullptr)
338 {
340 { return fun(item); });
341 }
342
343 return ans;
344 }
345
353 Dir *FindDir(const char *name)
354 {
355 if (name[0] == '.' && name[1] == '\0')
356 {
357 return this;
358 }
359
360 if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
361 {
362 return reinterpret_cast<Dir *>(data_.parent);
363 }
364
365 auto ans = (*this)->rbt.Search<RamFS::FsNode>(name);
366
367 if (ans && (*ans)->type == FsNodeType::DIR)
368 {
369 return reinterpret_cast<Dir *>(ans);
370 }
371 else
372 {
373 return nullptr;
374 }
375 }
376
384 Dir *FindDirRev(const char *name)
385 {
386 auto ans = FindDir(name);
387
388 std::function<ErrorCode(RBTree<const char *>::Node<FsNode> &)> fun;
389
390 fun = [&](RBTree<const char *>::Node<FsNode> &item) -> ErrorCode
391 {
392 FsNode &node = item;
393 if (node.type == FsNodeType::DIR)
394 {
395 Dir *dir = reinterpret_cast<Dir *>(&item);
396 if (strcmp(dir->data_.name, name) == 0)
397 {
398 ans = dir;
399 return ErrorCode::OK;
400 }
401 else
402 {
403 dir->data_.rbt.Foreach<FsNode>([&](RBTree<const char *>::Node<FsNode> &child)
404 { return fun(child); });
405
406 return ans ? ErrorCode::FAILED : ErrorCode::OK;
407 }
408 }
409 return ErrorCode::OK;
410 };
411
412 if (ans == nullptr)
413 {
415 { return fun(item); });
416 }
417
418 return ans;
419 }
420
428 Device *FindDeviceRev(const char *name)
429 {
430 auto ans = FindDevice(name);
431
432 std::function<ErrorCode(RBTree<const char *>::Node<FsNode> &)> fun;
433
434 fun = [&](RBTree<const char *>::Node<FsNode> &item) -> ErrorCode
435 {
436 FsNode &node = item;
437 if (node.type == FsNodeType::DIR)
438 {
439 Dir *dir = reinterpret_cast<Dir *>(&item);
440
441 ans = dir->FindDevice(name);
442 if (ans)
443 {
444 return ErrorCode::FAILED;
445 }
446
447 dir->data_.rbt.Foreach<FsNode>([&](RBTree<const char *>::Node<FsNode> &child)
448 { return fun(child); });
449
450 return ans ? ErrorCode::FAILED : ErrorCode::OK;
451 }
452 return ErrorCode::OK;
453 };
454
455 if (ans == nullptr)
456 {
458 { return fun(item); });
459 }
460 return ans;
461 }
462
470 Device *FindDevice(const char *name)
471 {
472 auto ans = (*this)->rbt.Search<FsNode>(name);
473 if (ans && ans->data_.type == FsNodeType::DEVICE)
474 {
475 return reinterpret_cast<Device *>(ans);
476 }
477 else
478 {
479 return nullptr;
480 }
481 }
482 };
483
492 template <typename DataType>
493 static File CreateFile(const char *name, DataType &raw)
494 {
495 File file;
496 char *name_buff = new char[strlen(name) + 1];
497 strcpy(name_buff, name);
498 file->name = name_buff;
499
500 if (std::is_const<DataType>())
501 {
502 file->type = FileType::READ_ONLY;
503 file->addr_const = &raw;
504 }
505 else
506 {
507 file->type = FileType::READ_WRITE;
508 file->addr = &raw;
509 }
510
511 file->size = sizeof(DataType);
512
513 return file;
514 }
515
525 template <typename ArgType>
526 static File CreateFile(const char *name,
527 int (*exec)(ArgType arg, int argc, char **argv), ArgType &&arg)
528 {
529 typedef struct
530 {
531 ArgType arg;
532 typeof(exec) exec_fun;
533 } FileBlock;
534
535 File file;
536
537 char *name_buff = new char[strlen(name) + 1];
538 strcpy(name_buff, name);
539 file->name = name_buff;
540 file->type = FileType::EXEC;
541
542 auto block = new FileBlock;
543 block->arg = std::forward<ArgType>(arg);
544 block->exec_fun = exec;
545 file->arg = block;
546
547 auto fun = [](void *arg, int argc, char **argv)
548 {
549 auto block = reinterpret_cast<FileBlock *>(arg);
550 return block->exec_fun(block->arg, argc, argv);
551 };
552
553 file->exec = fun;
554
555 return file;
556 }
557
564 static Dir CreateDir(const char *name)
565 {
566 Dir dir;
567
568 char *name_buff = new char[strlen(name) + 1];
569 strcpy(name_buff, name);
570 dir->name = name_buff;
571 dir->type = FsNodeType::DIR;
572
573 return dir;
574 }
575
581 void Add(File &file) { root_.Add(file); }
587 void Add(Dir &dir) { root_.Add(dir); }
593 void Add(Device &dev) { root_.Add(dev); }
594
602 File *FindFile(const char *name) { return root_.FindFileRev(name); }
610 Dir *FindDir(const char *name) { return root_.FindDirRev(name); }
618 Device *FindDevice(const char *name) { return root_.FindDeviceRev(name); }
619
625
631
637};
638} // namespace LibXR
常量原始数据封装类。 A class for encapsulating constant raw data.
红黑树的泛型数据节点,继承自 BaseNode (Generic data node for Red-Black Tree, inheriting from BaseNode).
Definition rbt.hpp:64
DeviceNode data_
存储的数据 (Stored data).
Definition rbt.hpp:99
红黑树实现,支持泛型键和值,并提供线程安全操作 (Red-Black Tree implementation supporting generic keys and values with thread...
Definition rbt.hpp:24
设备类,继承自红黑树节点 DeviceNode Device class inheriting from Red-Black tree node DeviceNode
Definition ramfs.hpp:172
uint32_t device_type
设备类型 Device type
Definition ramfs.hpp:221
ErrorCode Write(WriteOperation &&op, ConstRawData data)
向设备写入数据 Writes data to the device
Definition ramfs.hpp:216
ErrorCode Read(ReadOperation &&op, RawData data)
读取设备数据 Reads data from the device
Definition ramfs.hpp:202
Device(const char *name, const ReadPort &read_port=ReadPort(), const WritePort &write_port=WritePort())
设备构造函数 Device constructor
Definition ramfs.hpp:181
目录类,继承自 RBTree 节点,用于管理文件、子目录和设备 Directory class, inheriting from RBTree node, used for managing files...
Definition ramfs.hpp:250
Dir * FindDirRev(const char *name)
递归查找子目录 Recursively searches for a subdirectory
Definition ramfs.hpp:384
void Add(Dir &dir)
添加子目录到当前目录 Adds a subdirectory to the current directory
Definition ramfs.hpp:267
Dir * FindDir(const char *name)
查找当前目录中的子目录 Finds a subdirectory in the current directory
Definition ramfs.hpp:353
void Add(Device &dev)
添加设备到当前目录 Adds a device to the current directory
Definition ramfs.hpp:277
Device * FindDeviceRev(const char *name)
递归查找设备 Recursively searches for a device
Definition ramfs.hpp:428
void Add(File &file)
添加文件到当前目录 Adds a file to the current directory
Definition ramfs.hpp:257
Device * FindDevice(const char *name)
在当前目录中查找设备 Finds a device in the current directory
Definition ramfs.hpp:470
File * FindFileRev(const char *name)
递归查找文件 Recursively searches for a file
Definition ramfs.hpp:310
File * FindFile(const char *name)
查找当前目录中的文件 Finds a file in the current directory
Definition ramfs.hpp:290
目录节点,继承自 FsNode Directory node, inheriting from FsNode
Definition ramfs.hpp:236
RBTree< const char * > rbt
目录中的文件树 File tree in the directory
Definition ramfs.hpp:240
文件节点类,继承自 FsNode,表示文件 File node class, inheriting from FsNode, representing a file
Definition ramfs.hpp:94
int(* exec)(void *raw, int argc, char **argv)
可执行文件指针 Executable function pointer
Definition ramfs.hpp:100
void * addr
读写地址 Read/Write address
Definition ramfs.hpp:98
FileType type
文件类型 File type
Definition ramfs.hpp:110
void * arg
可执行文件参数 Executable file argument
Definition ramfs.hpp:107
const DataType & GetData()
获取文件数据 Retrieves file data
Definition ramfs.hpp:133
const void * addr_const
只读地址 Read-only address
Definition ramfs.hpp:99
size_t size
文件大小 File size
Definition ramfs.hpp:106
int Run(int argc, char **argv)
运行可执行文件 Runs an executable file
Definition ramfs.hpp:119
文件系统节点基类,所有文件和目录均继承自该类 Base class for file system nodes; all files and directories inherit from this
Definition ramfs.hpp:81
轻量级的内存文件系统,实现基本的文件、目录和设备管理 A lightweight in-memory file system implementing basic file,...
Definition ramfs.hpp:20
Dir * FindDir(const char *name)
在整个文件系统中查找目录 Finds a directory in the entire file system
Definition ramfs.hpp:610
Device * FindDevice(const char *name)
在整个文件系统中查找设备 Finds a device in the entire file system
Definition ramfs.hpp:618
static File CreateFile(const char *name, DataType &raw)
创建一个新的文件 Creates a new file
Definition ramfs.hpp:493
void Add(Dir &dir)
向文件系统的根目录添加子目录 Adds a subdirectory to the root directory of the file system
Definition ramfs.hpp:587
FsNodeType
文件系统节点类型 Types of file system nodes
Definition ramfs.hpp:53
@ UNKNOW
未知 Unknown
@ STORAGE
存储 Storage
@ DIR
目录 Directory
static Dir CreateDir(const char *name)
创建一个新的目录 Creates a new directory
Definition ramfs.hpp:564
static int CompareStr(const char *const &a, const char *const &b)
比较两个字符串 Compares two strings
Definition ramfs.hpp:42
void Add(Device &dev)
向文件系统的根目录添加设备 Adds a device to the root directory of the file system
Definition ramfs.hpp:593
Dir dev_
dev 目录,用于存放设备文件 dev directory for storing device files
Definition ramfs.hpp:636
FileType
文件类型 Types of files
Definition ramfs.hpp:67
@ READ_ONLY
只读 Read-only
@ READ_WRITE
读写 Read/Write
@ EXEC
可执行 Executable
Dir bin_
bin 目录,用于存放可执行文件 bin directory for storing executable files
Definition ramfs.hpp:630
static File CreateFile(const char *name, int(*exec)(ArgType arg, int argc, char **argv), ArgType &&arg)
创建一个可执行文件 Creates an executable file
Definition ramfs.hpp:526
void Add(File &file)
向文件系统的根目录添加文件 Adds a file to the root directory of the file system
Definition ramfs.hpp:581
Dir root_
文件系统的根目录 Root directory of the file system
Definition ramfs.hpp:624
File * FindFile(const char *name)
在整个文件系统中查找文件 Finds a file in the entire file system
Definition ramfs.hpp:602
RamFS(const char *name="ramfs")
构造函数,初始化内存文件系统的根目录 Constructor that initializes the root directory of the in-memory file system
Definition ramfs.hpp:28
原始数据封装类。 A class for encapsulating raw data.
ReadPort class for handling read operations.
Definition libxr_rw.hpp:309
WritePort class for handling write operations.
Definition libxr_rw.hpp:503
LibXR Color Control Library / LibXR终端颜色控制库
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
设备节点,继承自 FsNode Device node, inheriting from FsNode
Definition ramfs.hpp:161
ReadPort read_port
读端口 Read port
Definition ramfs.hpp:162
WritePort write_port
写端口 Write port
Definition ramfs.hpp:163