General Purpose library for Freestanding C++ and POSIX systems
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

384 linhas
8.7 KiB

  1. #pragma once
  2. #include <stddef.h>
  3. #include "gp_config.hpp"
  4. #include "gp/variant.hpp"
  5. #include "gp/optional.hpp"
  6. #include "gp/buffer.hpp"
  7. #include "gp/allocator/aggregator.hpp"
  8. namespace gp {
  9. class vfs {
  10. public:
  11. struct bad_file final {
  12. static constexpr auto _what = "bad_file";
  13. constexpr auto what() {
  14. return _what;
  15. }
  16. };
  17. struct faulty_buffer final {
  18. static constexpr auto _what = "faulty_buffer";
  19. constexpr auto what() {
  20. return _what;
  21. }
  22. };
  23. struct interrupted final {
  24. static constexpr auto _what = "interrupted";
  25. constexpr auto what() {
  26. return _what;
  27. }
  28. };
  29. struct io_error final {
  30. static constexpr auto _what = "io_error";
  31. constexpr auto what() {
  32. return _what;
  33. }
  34. };
  35. struct is_directory final {
  36. static constexpr auto _what = "is_directory";
  37. constexpr auto what() {
  38. return _what;
  39. }
  40. };
  41. struct try_again final {
  42. static constexpr auto _what = "try_again";
  43. constexpr auto what() {
  44. return _what;
  45. }
  46. };
  47. struct not_connected final {
  48. static constexpr auto _what = "not_connected";
  49. constexpr auto what() {
  50. return _what;
  51. }
  52. };
  53. struct impossible_io final {
  54. static constexpr auto _what = "impossible_io";
  55. constexpr auto what() {
  56. return _what;
  57. }
  58. };
  59. struct negative_offset final {
  60. static constexpr auto _what = "negative_offset";
  61. constexpr auto what() {
  62. return _what;
  63. }
  64. };
  65. struct is_pipe final {
  66. static constexpr auto _what = "is_pipe";
  67. constexpr auto what() {
  68. return _what;
  69. }
  70. };
  71. struct buffer_too_big final {
  72. static constexpr auto _what = "buffer_too_big";
  73. constexpr auto what() {
  74. return _what;
  75. }
  76. };
  77. struct path_not_directory final {
  78. static constexpr auto _what = "path_not_directory";
  79. constexpr auto what() {
  80. return _what;
  81. }
  82. };
  83. struct name_too_long final {
  84. static constexpr auto _what = "name_too_long";
  85. constexpr auto what() {
  86. return _what;
  87. }
  88. };
  89. struct does_not_exist final {
  90. static constexpr auto _what = "does_not_exist";
  91. constexpr auto what() {
  92. return _what;
  93. }
  94. };
  95. struct may_loop final {
  96. static constexpr auto _what = "may_loop";
  97. constexpr auto what() {
  98. return _what;
  99. }
  100. };
  101. struct invalid_flags final {
  102. static constexpr auto _what = "invalid_flags";
  103. constexpr auto what() {
  104. return _what;
  105. }
  106. };
  107. struct is_read_only final {
  108. static constexpr auto _what = "is_read_only";
  109. constexpr auto what() {
  110. return _what;
  111. }
  112. };
  113. struct fd_limit_reached final {
  114. static constexpr auto _what = "fd_limit_reached";
  115. constexpr auto what() {
  116. return _what;
  117. }
  118. };
  119. struct file_limit_reached final {
  120. static constexpr auto _what = "file_limit_reached";
  121. constexpr auto what() {
  122. return _what;
  123. }
  124. };
  125. struct no_locking final {
  126. static constexpr auto _what = "no_locking";
  127. constexpr auto what() {
  128. return _what;
  129. }
  130. };
  131. struct would_block final {
  132. static constexpr auto _what = "would_block";
  133. constexpr auto what() {
  134. return _what;
  135. }
  136. };
  137. struct no_inodes final {
  138. static constexpr auto _what = "no_inodes";
  139. constexpr auto what() {
  140. return _what;
  141. }
  142. };
  143. struct no_space final {
  144. static constexpr auto _what = "no_space";
  145. constexpr auto what() {
  146. return _what;
  147. }
  148. };
  149. struct quota_reached final {
  150. static constexpr auto _what = "quota_reached";
  151. constexpr auto what() {
  152. return _what;
  153. }
  154. };
  155. struct cannot_write_shared_text final {
  156. static constexpr auto _what = "cannot_write_shared_text";
  157. constexpr auto what() {
  158. return _what;
  159. }
  160. };
  161. struct faulty_filename final {
  162. static constexpr auto _what = "faulty_filename";
  163. constexpr auto what() {
  164. return _what;
  165. }
  166. };
  167. struct exists_already final {
  168. static constexpr auto _what = "exists_already";
  169. constexpr auto what() {
  170. return _what;
  171. }
  172. };
  173. struct is_append_only final {
  174. static constexpr auto _what = "is_append_only";
  175. constexpr auto what() {
  176. return _what;
  177. }
  178. };
  179. struct unimplemented_operation final {
  180. static constexpr auto _what = "unimplemented_operation";
  181. constexpr auto what() {
  182. return _what;
  183. }
  184. };
  185. struct is_busy final {
  186. static constexpr auto _what = "is_busy";
  187. constexpr auto what() {
  188. return _what;
  189. }
  190. };
  191. struct bad_relative_path final {
  192. static constexpr auto _what = "bad_relative_path";
  193. constexpr auto what() {
  194. return _what;
  195. }
  196. };
  197. struct no_permissions final {
  198. static constexpr auto _what = "no_permissions";
  199. constexpr auto what() {
  200. return _what;
  201. }
  202. };
  203. struct success final {
  204. static constexpr auto _what = "success";
  205. constexpr auto what() {
  206. return _what;
  207. }
  208. };
  209. struct too_big final {
  210. static constexpr auto _what = "too_big";
  211. constexpr auto what() {
  212. return _what;
  213. }
  214. };
  215. struct network_down final {
  216. static constexpr auto _what = "network_down";
  217. constexpr auto what() {
  218. return _what;
  219. }
  220. };
  221. struct destination_not_available final {
  222. static constexpr auto _what = "destination_not_available";
  223. constexpr auto what() {
  224. return _what;
  225. }
  226. };
  227. struct insufficient_buffer_space final {
  228. static constexpr auto _what = "insufficient_buffer_space";
  229. constexpr auto what() {
  230. return _what;
  231. }
  232. };
  233. using read_return = gp::fixed_variant<
  234. typename buffer<char>::associated_iterator, // iterator to last element read
  235. bad_file,
  236. faulty_buffer,
  237. interrupted,
  238. io_error,
  239. is_directory,
  240. try_again,
  241. not_connected,
  242. impossible_io,
  243. negative_offset,
  244. is_pipe,
  245. buffer_too_big
  246. >;
  247. using open_return = gp::fixed_variant<
  248. gp_config::file_descriptor_t,
  249. path_not_directory,
  250. name_too_long,
  251. does_not_exist,
  252. may_loop,
  253. is_directory,
  254. invalid_flags,
  255. is_read_only,
  256. fd_limit_reached,
  257. file_limit_reached,
  258. impossible_io,
  259. interrupted,
  260. no_locking,
  261. would_block,
  262. no_space,
  263. no_inodes,
  264. quota_reached,
  265. io_error,
  266. cannot_write_shared_text,
  267. faulty_filename,
  268. exists_already,
  269. is_append_only,
  270. unimplemented_operation,
  271. is_busy,
  272. bad_relative_path,
  273. no_permissions
  274. >;
  275. using close_return = gp::fixed_variant<
  276. success,
  277. bad_file,
  278. interrupted,
  279. io_error
  280. >;
  281. using write_return = gp::fixed_variant<
  282. typename buffer<char>::associated_iterator,
  283. bad_file,
  284. no_space,
  285. quota_reached,
  286. too_big,
  287. interrupted,
  288. io_error,
  289. faulty_buffer,
  290. is_pipe,
  291. try_again,
  292. network_down,
  293. destination_not_available,
  294. impossible_io,
  295. buffer_too_big,
  296. negative_offset,
  297. insufficient_buffer_space
  298. >;
  299. class file_flags{};
  300. class file_permissions{};
  301. private:
  302. struct virtual_fs
  303. {
  304. virtual ~virtual_fs() = default;
  305. virtual open_return open(buffer<char>, file_flags, file_permissions) = 0;
  306. virtual read_return read(gp_config::file_descriptor_t, buffer<char>) = 0;
  307. virtual write_return write(gp_config::file_descriptor_t, buffer<char>, size_t) = 0;
  308. virtual close_return close(gp_config::file_descriptor_t) = 0;
  309. };
  310. template<typename concrete>
  311. class abstract_fs final : public virtual_fs{
  312. concrete internal_representation;
  313. public:
  314. abstract_fs(abstract_fs& v) = delete;
  315. abstract_fs(abstract_fs&& v)
  316. : internal_representation{v.internal_representation}
  317. {}
  318. abstract_fs(concrete& v) = delete;
  319. abstract_fs(concrete&& v)
  320. : internal_representation{v}
  321. {}
  322. virtual ~abstract_fs() override = default;
  323. virtual open_return open(buffer<char> path, file_flags flags, file_permissions perms) override {
  324. return internal_representation.open(path, flags, perms);
  325. }
  326. virtual read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) override {
  327. return internal_representation.read(fd, buff);
  328. }
  329. virtual write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) override {
  330. return internal_representation.write(fd, buff, offset);
  331. }
  332. virtual close_return close(gp_config::file_descriptor_t fd) override {
  333. return internal_representation.close(fd);
  334. }
  335. };
  336. reference_wrapper<aggregator> allocator;
  337. virtual_fs* file_system;
  338. public:
  339. template<typename T>
  340. vfs(T&& v, reference_wrapper<aggregator> _ref)
  341. : allocator{_ref}
  342. , file_system{new(allocator.get().allocate(sizeof(T))) T(gp::move(v))}
  343. {}
  344. open_return open(buffer<char> path, file_flags flags, file_permissions perms) {
  345. return file_system->open(path, flags, perms);
  346. }
  347. read_return read(gp_config::file_descriptor_t fd, buffer<char> buff) {
  348. return file_system->read(fd, buff);
  349. }
  350. write_return write(gp_config::file_descriptor_t fd, buffer<char> buff, size_t offset) {
  351. return file_system->write(fd, buff, offset);
  352. }
  353. close_return close(gp_config::file_descriptor_t fd) {
  354. return file_system->close(fd);
  355. }
  356. ~vfs() {
  357. file_system->~virtual_fs();
  358. allocator.get().deallocate(file_system);
  359. }
  360. };
  361. }