yadro-task/include/tapelib/filetape.h
erius ad976a5a9e Added using directives to avoid excessive namespaecs
Added explicit include directories to each file, even if an already included header defined them
Removed using directives from header files
2024-10-28 12:32:14 +02:00

210 lines
7 KiB
C++

#ifndef FILE_TAPE_H
#define FILE_TAPE_H
#include "tape.h"
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <string>
#include <vector>
namespace tape {
/**
* Strcuture for storing all possible settings for a file tape,
* such as read dealy, write delay etc.
*/
struct FileTapeSettings {
std::chrono::milliseconds read_delay;
std::chrono::milliseconds write_delay;
std::chrono::milliseconds seek_forward_delay;
std::chrono::milliseconds seek_backwards_delay;
};
const static struct FileTapeSettings FT_DEFAULT_SETTINGS =
FileTapeSettings{.read_delay = std::chrono::milliseconds(0),
.write_delay = std::chrono::milliseconds(0),
.seek_forward_delay = std::chrono::milliseconds(0),
.seek_backwards_delay = std::chrono::milliseconds(0)};
const static char FT_DELIMETER = '\n';
// uint32_t digits max count is 10
const static int FT_CELL_SIZE = 10;
const static int FT_SEEK_OFFSET = FT_CELL_SIZE + 1;
/**
* Mock tape implementation that uses text files as data source.
*
* Simulates tape operations by artificially pausing the execution of some
* methods using time intervals, specified in command line arguments or a
* configuration file. Each cell is represented as a plain text 32-bit unsigned
* int, padded to FT_CELL_SIZE with leading zeroes, separated by FT_DELIMETER.
* Each cell MUST be FT_CELL_SIZE long to correctly implement write operation
* without re-writing the entire file.
*
* Example of a valid file for a FileTape
* - example.txt
* 000000001
* 000000034
* 000001234
* 123456789
* 000000000
*/
class FileTape : public Tape {
private:
std::string file_name;
std::fstream file;
FileTapeSettings settings;
bool tmp = false;
public:
/**
* Creating copies of FileTape creates 2+ fstreams to one file, which
* could introduce IO errors or data races if implemented incorrectly -
* mark the copy constructor as deleted. Moving is fine.
*/
FileTape(const FileTape &) = delete;
FileTape(FileTape &&) noexcept = default;
FileTape &operator=(const FileTape &) = delete;
FileTape &operator=(FileTape &&tape) = default;
/**
* Initializes a new instance of FileTape that will open an existing file
* with the specified name, already filled with data. File must be read and
* write accessible.
*
* @param file_name Name of a file to be opened.
* @param settings FileTape settings
*/
FileTape(std::string file_name,
FileTapeSettings settings = FT_DEFAULT_SETTINGS);
/**
* Initializes a new instance of FileTape that will create and open a file
* with the specified name and fill it with *cells* amount of zeroed cells.
* File must not exist and directory must be write accessible.
*
* Writing operations when filling file with zeroes will not introduce any
* delay.
*
* @param size Size of a newly created FileTpae
* @param file_name Name of a file to be created and opened
* @param settings FileTape settings
*/
FileTape(size_t cells, std::string file_name,
FileTapeSettings settings = FT_DEFAULT_SETTINGS);
/**
* Initializes a new instance of FileTape that will create and open a file
* with the specified name and fill it with zeroed cells - the amount of
* cells will be the same as the specified FileTape.
* File must not exist and directory must be write accessible.
*
* This is necessary in the situations when the FileTapse size is a bigger
* than size_t max value. Seeking will not introduce delay during this
* operation.
*
* @param same_size_as FileTape, the size of which will be carried over to
* the new FileTape
* @param file_name Name of a file to be created and opened
* @param settings FileTape settings
*/
FileTape(FileTape &same_size_as, std::string file_name,
FileTapeSettings = FT_DEFAULT_SETTINGS);
/**
* Initializes a new instance of FileTape that will create and open a
* temporary file and fill it with *cells* amount of zeroed cells.
*
* Writing operations when filling file with zeroes will not introduce any
* delay.
*
* @param size Size of a newly created FileTape
* @param settings FileTape settings
*/
FileTape(size_t cells, FileTapeSettings settings = FT_DEFAULT_SETTINGS);
/**
* Initializes a new instance of FileTape that will create and open a
* temporary file and fill it with zeroed cells -
* the amount of cells will be the same as the specified FileTape. File must
* not exist and directory must be write accessible.
*
* This is necessary in the situations when the FileTapse size is a bigger
* than size_t max value. Seeking will not introduce delay during this
* operation.
*
* @param same_size_as FileTape, the size of which will be carried over to
* the new FileTape
* @param file_name Name of a file to be created and opened
* @param settings FileTape settings
*/
FileTape(FileTape &same_size_as, FileTapeSettings = FT_DEFAULT_SETTINGS);
/**
* Initializes a new instance of FileTape that will create and open a
* temporary file, and fill it with the data from the provided vector.
*
* Writing operations when copying vector to a FileTape will not have any
* delay.
* Use this constructor ONLY FOR TESTING. Do NOT use it to copy one
* FileTape's data to another.
*
* @param data Vector of uint32 contents of which will be copied to FileTape
* @param settings FileTape settings
*/
FileTape(const std::vector<uint32_t> &data,
FileTapeSettings settings = FT_DEFAULT_SETTINGS);
/**
* Advances the underlying fstream to a new line.
*
* @return false if empty line is reached, otherwise true.
*/
bool seek_forward() override;
/**
* Rewinds the underlying fstream to a previous line.
*
* @return false if called from the first line of a file, otherwise true.
*/
bool seek_backwards() override;
/**
* Reads and parses data from the current line.
*
* @return number from the line, or 0 if data can not be parsed.
*/
uint32_t read() override;
/**
* Writes data to the current line.
*
* @param data Number, that should be written to the current line.
*/
void write(uint32_t data) override;
/**
* Close the undetlying fstream, and, in case the FileTape is marked as
* temporary (tmp is set to true), remove the temporary file
*/
~FileTape() override;
// Define getters in header file since they are implicitly inlined
bool is_tmp() const { return this->tmp; }
bool is_open() const { return this->file.is_open(); }
const FileTapeSettings &get_settings() const { return this->settings; }
const std::string &get_file_name() const { return this->file_name; }
const std::fstream &get_file() const { return this->file; }
};
} // namespace tape
#endif // !FILE_TAPE_H