From 77cd5981b398075ff866aab9d4145fc28542d773 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Mon, 12 Oct 2026 11:09:51 +0800 Subject: add unix file class --- include/error.h | 6 +++ include/util/file.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 include/util/file.h (limited to 'include') diff --git a/include/error.h b/include/error.h index d058ec4..50ca23e 100644 --- a/include/error.h +++ b/include/error.h @@ -20,6 +20,12 @@ enum class error_code // eval EVAL_FAIL_TO_CREATE_PIPE, + // file + FILE_MODE_NOT_SET, + FILE_FAIL_TO_OPEN, + FILE_OFLAG_ERROR, + FILE_POINTER_FAIL_TO_OPEN, + }; class T_error : public std::runtime_error { diff --git a/include/util/file.h b/include/util/file.h new file mode 100644 index 0000000..bbc6539 --- /dev/null +++ b/include/util/file.h @@ -0,0 +1,104 @@ +#pragma once + +#include +#include +#include +#include + +#include "error.h" + +namespace ov4 +{ + +class T_unix_file_d; +class T_unix_file_p; + + +class T_unix_file_d +{ +public: + int fd = -1; + + virtual int close() + { + if (fd == -1) return -1; + int ret = ::close(fd); + fd = -1; + return ret; + } + + T_unix_file_d(const std::string &path, int oflag, int mode = -1) + { + if (oflag & O_CREAT) + { + if (mode == -1) throw T_error{error_code::FILE_MODE_NOT_SET, "Mode should be set for O_CREAT"}; + fd = open(path.c_str(), oflag, mode); + if (fd == -1) + throw T_error(error_code::FILE_FAIL_TO_OPEN, "Fail to open file"); + return; + } + fd = open(path.c_str(), oflag); + if (fd == -1) + throw T_error(error_code::FILE_FAIL_TO_OPEN, "Fail to open file"); + } + + ~T_unix_file_d() + { + this->close(); + } + + T_unix_file_d(const T_unix_file_d &) = delete; + T_unix_file_d &operator=(const T_unix_file_d &) = delete; +}; + +class T_unix_file_p : public T_unix_file_d +{ +public: + FILE* fp = nullptr; + + int close() override + { + if (fp == nullptr) return -1; + int ret = fclose(fp); + fp = nullptr; + fd = -1; + return ret; + } + + T_unix_file_p(const std::string &path, int oflag, int mode = -1) + : T_unix_file_d(path, oflag, mode) + { + const char *fp_mode; + switch (oflag & O_ACCMODE) + { + case O_RDONLY: + fp_mode = "r"; + break; + + case O_WRONLY: + fp_mode = "w"; + break; + + case O_RDWR: + fp_mode = "r+"; + break; + + default: + throw T_error{error_code::FILE_OFLAG_ERROR, "oflag error"}; + } + fp = fdopen(fd, fp_mode); + + if (fp == nullptr) + throw T_error{error_code::FILE_POINTER_FAIL_TO_OPEN, "Fail to open file pointer"}; + } + + ~T_unix_file_p() + { + this->close(); + } + + T_unix_file_p(const T_unix_file_p &) = delete; + T_unix_file_p &operator=(const T_unix_file_p &) = delete; +}; + +} \ No newline at end of file -- cgit v1.3.1-4-g156e