From d0151153fbaaf531ad6f42e73854db660ebd0241 Mon Sep 17 00:00:00 2001 From: Bechir Braham Date: Fri, 22 Mar 2024 15:02:15 +0100 Subject: [PATCH] add contextManager to hanldle files --- .vscode/launch.json | 4 +-- core/include/aare/Frame.hpp | 9 ++++++ examples/CMakeLists.txt | 1 - examples/json_file_read.cpp | 29 ++++++++++--------- examples/numpy_file_read.cpp | 28 ++++++++++--------- file_io/include/aare/ContextManager.hpp | 34 +++++++++++++++++++++++ file_io/include/aare/File.hpp | 14 ++++------ file_io/include/aare/FileFactory.hpp | 6 ++++ file_io/include/aare/FileHandler.hpp | 28 ------------------- file_io/include/aare/JsonFile.hpp | 2 +- file_io/include/aare/JsonFileFactory.hpp | 3 +- file_io/include/aare/NumpyFile.hpp | 8 +++++- file_io/include/aare/NumpyFileFactory.hpp | 2 +- file_io/src/JsonFile.cpp | 4 +-- file_io/src/JsonFileFactory.cpp | 4 +-- file_io/src/NumpyFile.cpp | 6 ++-- file_io/src/NumpyFileFactory.cpp | 4 +-- 17 files changed, 105 insertions(+), 81 deletions(-) create mode 100644 file_io/include/aare/ContextManager.hpp delete mode 100644 file_io/include/aare/FileHandler.hpp diff --git a/.vscode/launch.json b/.vscode/launch.json index ba0f5fe..97d83f9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,11 +4,11 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/aare", + "program": "${workspaceFolder}/build/examples/json_example", "args": [], "stopAtEntry": true, "cwd": "${fileDirname}", - "environment": [], + "environment": [{"name": "PROJECT_ROOT_DIR", "value": "/home/l_bechir/github/aare"}], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ diff --git a/core/include/aare/Frame.hpp b/core/include/aare/Frame.hpp index b6e8446..20048f7 100644 --- a/core/include/aare/Frame.hpp +++ b/core/include/aare/Frame.hpp @@ -38,6 +38,15 @@ class Frame { std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8); return *this; } + // add move constructor + Frame(Frame &&other) { + m_rows = other.rows(); + m_cols = other.cols(); + m_bitdepth = other.bitdepth(); + m_data = other.m_data; + other.m_data = nullptr; + other.m_rows = other.m_cols = other.m_bitdepth = 0; + } template NDView view() { diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 003a556..90e7c86 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -10,4 +10,3 @@ target_link_libraries(numpy_example PUBLIC aare) - diff --git a/examples/json_file_read.cpp b/examples/json_file_read.cpp index d8ac8bd..026e8fa 100644 --- a/examples/json_file_read.cpp +++ b/examples/json_file_read.cpp @@ -1,30 +1,29 @@ // Your First C++ Program -#include "aare/FileHandler.hpp" +#include "aare/ContextManager.hpp" #include #define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" -void test(FileHandler *f, int frame_number) { +void test(File *f, int frame_number) { std::cout << "frame number: " << frame_number << std::endl; - Frame *frame = f->get_frame(frame_number); - std::cout << *((uint16_t *)frame->get(0, 0)) << std::endl; - std::cout << *((uint16_t *)frame->get(0, 1)) << std::endl; - std::cout << *((uint16_t *)frame->get(1, 0)) << std::endl; - std::cout << *((uint16_t *)frame->get(511, 1023)) << std::endl; - - delete frame; + Frame frame = f->get_frame(frame_number); + std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; + std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; + std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl; + std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl; } int main() { + ContextManager ctx_manager; auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau_single_master_0.json"); // std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "test_numpy_file.npy"); std::cout << fpath << std::endl; - auto fileHandler = new FileHandler(fpath); - test(fileHandler, 0); - test(fileHandler, 2); - test(fileHandler, 9); - delete fileHandler; -} + File *file = ctx_manager.get_file(fpath); + test(file, 0); + test(file, 2); + test(file, 9); + +} \ No newline at end of file diff --git a/examples/numpy_file_read.cpp b/examples/numpy_file_read.cpp index dd827c3..3ab6c76 100644 --- a/examples/numpy_file_read.cpp +++ b/examples/numpy_file_read.cpp @@ -1,30 +1,32 @@ // Your First C++ Program -#include "aare/FileHandler.hpp" +#include "aare/ContextManager.hpp" #include #define AARE_ROOT_DIR_VAR "PROJECT_ROOT_DIR" -void test(FileHandler *f, int frame_number) { +void test(File* f, int frame_number) { std::cout << "frame number: " << frame_number << std::endl; - Frame *frame = f->get_frame(frame_number); - std::cout << *((uint16_t *)frame->get(0, 0)) << std::endl; - std::cout << *((uint16_t *)frame->get(0, 1)) << std::endl; - std::cout << *((uint16_t *)frame->get(1, 0)) << std::endl; - std::cout << *((uint16_t *)frame->get(49, 49)) << std::endl; + Frame frame = f->get_frame(frame_number); + std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl; + std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl; + std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl; + std::cout << *((uint16_t *)frame.get(49, 49)) << std::endl; - delete frame; } int main() { + ContextManager ctx_manager; + auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR)); // std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau_single_master_0.json"); std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "test_numpy_file.npy"); std::cout << fpath << std::endl; - auto fileHandler = new FileHandler(fpath); - test(fileHandler, 0); - test(fileHandler, 2); - test(fileHandler, 24); + File* file = ctx_manager.get_file(fpath); + test(file, 0); + test(file, 2); + test(file, 24); + + - delete fileHandler; } diff --git a/file_io/include/aare/ContextManager.hpp b/file_io/include/aare/ContextManager.hpp new file mode 100644 index 0000000..231f60f --- /dev/null +++ b/file_io/include/aare/ContextManager.hpp @@ -0,0 +1,34 @@ +#include "aare/File.hpp" +#include "aare/FileFactory.hpp" +#include +#include + + +/** + * @brief A class to manage the context of the files and network connections + * closes the files and network connections when the context is destroyed +*/ +class ContextManager { + public: + ContextManager() = default; + + File *get_file(std::filesystem::path fname) { + auto tmp_file = FileFactory::load_file(fname); + this->files.push_back(tmp_file); + return tmp_file; + } + + // prevent default copying, it can delete the file twice + ContextManager(const ContextManager &) = delete; + ContextManager &operator=(const ContextManager &) = delete; + + ~ContextManager() { + for (auto f : files) { + delete f; + } + } + + private: + std::vector files; + // std::vector connections; +}; \ No newline at end of file diff --git a/file_io/include/aare/File.hpp b/file_io/include/aare/File.hpp index eff33ca..52c622a 100644 --- a/file_io/include/aare/File.hpp +++ b/file_io/include/aare/File.hpp @@ -1,24 +1,22 @@ #pragma once -#include "aare/defs.hpp" -#include "aare/Frame.hpp" #include "SubFile.hpp" +#include "aare/Frame.hpp" +#include "aare/defs.hpp" #include #include #include - class File { public: - virtual Frame* get_frame(size_t frame_number) = 0; + virtual Frame get_frame(size_t frame_number) =0; private: - //comment - + // comment public: - virtual ~File() = default; + virtual ~File() = default; std::filesystem::path fname; std::filesystem::path base_path; std::string base_name, ext; @@ -35,11 +33,9 @@ class File { ssize_t cols{}; ssize_t bitdepth{}; // File(); - inline size_t bytes_per_frame() const { return rows * cols * bitdepth / 8; } inline size_t pixels() const { return rows * cols; } - // size_t total_frames(); }; \ No newline at end of file diff --git a/file_io/include/aare/FileFactory.hpp b/file_io/include/aare/FileFactory.hpp index 0841b35..634b7ae 100644 --- a/file_io/include/aare/FileFactory.hpp +++ b/file_io/include/aare/FileFactory.hpp @@ -9,6 +9,12 @@ class FileFactory{ public: static FileFactory* get_factory(std::filesystem::path); // virtual int deleteFile() = 0; + static File* load_file(std::filesystem::path p){ + auto factory = get_factory(p); + File* tmp= factory->load_file(); + delete factory; + return tmp; + }; virtual File* load_file()=0;//TODO: add option to load all file to memory or keep it on disk virtual void parse_metadata(File*)=0; virtual void parse_fname(File*)=0; diff --git a/file_io/include/aare/FileHandler.hpp b/file_io/include/aare/FileHandler.hpp deleted file mode 100644 index 18900d5..0000000 --- a/file_io/include/aare/FileHandler.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include "aare/FileFactory.hpp" -#include "aare/File.hpp" - -class FileHandler{ - private: - std::filesystem::path fpath; - FileFactory* fileFactory; - File* f; - - public: - FileHandler(std::filesystem::path fname){ - this->fpath = fname; - this->fileFactory= FileFactory::get_factory(fname); - this->f= fileFactory->load_file(); - delete fileFactory; - } - - Frame* get_frame(int index){ - return f->get_frame(index); - } - - - - ~FileHandler(){ - delete f; - } -}; \ No newline at end of file diff --git a/file_io/include/aare/JsonFile.hpp b/file_io/include/aare/JsonFile.hpp index e632121..1f8b93a 100644 --- a/file_io/include/aare/JsonFile.hpp +++ b/file_io/include/aare/JsonFile.hpp @@ -9,7 +9,7 @@ class JsonFile : public File { using config = RawFileConfig; public: - Frame *get_frame(size_t frame_number); + Frame get_frame(size_t frame_number); int n_subfiles; std::vector subfiles; int subfile_rows, subfile_cols; diff --git a/file_io/include/aare/JsonFileFactory.hpp b/file_io/include/aare/JsonFileFactory.hpp index 1aa5d86..9aa2cce 100644 --- a/file_io/include/aare/JsonFileFactory.hpp +++ b/file_io/include/aare/JsonFileFactory.hpp @@ -1,11 +1,12 @@ #include "aare/FileFactory.hpp" +#include "aare/JsonFile.hpp" class JsonFileFactory: public FileFactory { private: /* data */ public: JsonFileFactory(std::filesystem::path fpath); - File* load_file() override; + virtual JsonFile* load_file() override; void parse_metadata(File*) override; void parse_fname(File*) override; void open_subfiles(File*); diff --git a/file_io/include/aare/NumpyFile.hpp b/file_io/include/aare/NumpyFile.hpp index bd62d2d..5235764 100644 --- a/file_io/include/aare/NumpyFile.hpp +++ b/file_io/include/aare/NumpyFile.hpp @@ -11,7 +11,7 @@ class NumpyFile : public File { public: NumpyFile(std::filesystem::path fname); - Frame *get_frame(size_t frame_number) override; + Frame get_frame(size_t frame_number) override; header_t header{}; static constexpr std::array magic_str{'\x93', 'N', 'U', 'M', 'P', 'Y'}; uint8_t major_ver_{}; @@ -24,4 +24,10 @@ class NumpyFile : public File { return std::accumulate(header.shape.begin() + 1, header.shape.end(), 1, std::multiplies()); }; inline ssize_t bytes_per_frame() { return header.dtype.itemsize * pixels_per_frame(); }; + ~NumpyFile(){ + if (fp != nullptr) { + fclose(fp); + } + + } }; \ No newline at end of file diff --git a/file_io/include/aare/NumpyFileFactory.hpp b/file_io/include/aare/NumpyFileFactory.hpp index 6dbac55..71c962d 100644 --- a/file_io/include/aare/NumpyFileFactory.hpp +++ b/file_io/include/aare/NumpyFileFactory.hpp @@ -14,7 +14,7 @@ class NumpyFileFactory : public FileFactory { public: NumpyFileFactory(std::filesystem::path fpath); void parse_metadata(File *_file) override; - File *load_file() override; + NumpyFile* load_file() override; void parse_fname(File*){}; }; \ No newline at end of file diff --git a/file_io/src/JsonFile.cpp b/file_io/src/JsonFile.cpp index 0ba0f25..2b2abdc 100644 --- a/file_io/src/JsonFile.cpp +++ b/file_io/src/JsonFile.cpp @@ -1,6 +1,6 @@ #include "aare/JsonFile.hpp" -Frame *JsonFile::get_frame(size_t frame_number) { +Frame JsonFile::get_frame(size_t frame_number) { if (frame_number > this->total_frames) { throw std::runtime_error("Frame number out of range"); } @@ -9,7 +9,7 @@ Frame *JsonFile::get_frame(size_t frame_number) { size_t frame_size = this->subfiles[subfile_id]->bytes_per_frame(); buffer = new std::byte[frame_size]; this->subfiles[subfile_id]->get_frame(buffer, frame_number % this->max_frames_per_file); - auto f = new Frame(buffer, this->rows, this->cols, this->bitdepth ); + auto f = Frame(buffer, this->rows, this->cols, this->bitdepth ); delete[] buffer; diff --git a/file_io/src/JsonFileFactory.cpp b/file_io/src/JsonFileFactory.cpp index 60885ce..518dcbc 100644 --- a/file_io/src/JsonFileFactory.cpp +++ b/file_io/src/JsonFileFactory.cpp @@ -49,8 +49,8 @@ void JsonFileFactory::open_subfiles(File*_file) { } } -File* JsonFileFactory::load_file() { - JsonFile *file = new JsonFile(); +JsonFile* JsonFileFactory::load_file() { + JsonFile* file = new JsonFile(); file->fname = this->m_fpath; this->parse_fname(file); this->parse_metadata(file); diff --git a/file_io/src/NumpyFile.cpp b/file_io/src/NumpyFile.cpp index 90c1d8d..fc62424 100644 --- a/file_io/src/NumpyFile.cpp +++ b/file_io/src/NumpyFile.cpp @@ -6,16 +6,16 @@ NumpyFile::NumpyFile(std::filesystem::path fname_){ fp = fopen(this->fname.c_str(), "rb"); } -Frame* NumpyFile::get_frame(size_t frame_number) { +Frame NumpyFile::get_frame(size_t frame_number) { if (fp == nullptr) { throw std::runtime_error("File not open"); } if (frame_number > header.shape[0]) { throw std::runtime_error("Frame number out of range"); } - Frame *frame = new Frame(header.shape[1], header.shape[2], header.dtype.itemsize*8); + Frame frame = Frame(header.shape[1], header.shape[2], header.dtype.itemsize*8); fseek(fp, header_size + frame_number * bytes_per_frame(), SEEK_SET); - fread(frame->_get_data(), bytes_per_frame(), 1, fp); + fread(frame._get_data(), bytes_per_frame(), 1, fp); return frame; } diff --git a/file_io/src/NumpyFileFactory.cpp b/file_io/src/NumpyFileFactory.cpp index 893c90e..cf6d99f 100644 --- a/file_io/src/NumpyFileFactory.cpp +++ b/file_io/src/NumpyFileFactory.cpp @@ -72,8 +72,8 @@ void NumpyFileFactory::parse_metadata(File *_file) { file->header = {dtype, fortran_order, shape}; } - File* NumpyFileFactory::load_file() { - NumpyFile *file = new NumpyFile(this->m_fpath); + NumpyFile* NumpyFileFactory::load_file() { + NumpyFile* file = new NumpyFile(this->m_fpath); parse_metadata(file); std::cout << "parsed header: " << file->header.to_string() << std::endl; return file;