diff options
| author | Dylan <boss@tehbox.org> | 2026-05-04 18:36:15 +1200 |
|---|---|---|
| committer | Dylan <boss@tehbox.org> | 2026-05-04 18:36:15 +1200 |
| commit | a75bdd0e167140eeb4afb091c9dedd84474c8531 (patch) | |
| tree | 9c94262edc1c1eea4bd4977f76c7cd8ec6a43da1 /src/files.cpp | |
| parent | 500151be4794923cee6034c26881effeb1bb056d (diff) | |
| download | tehimage-a75bdd0e167140eeb4afb091c9dedd84474c8531.tar.gz tehimage-a75bdd0e167140eeb4afb091c9dedd84474c8531.zip | |
feat: Added a writer class
Also moved both the reader and writer class to the same files, named
files.{cpp,h}
Diffstat (limited to 'src/files.cpp')
| -rw-r--r-- | src/files.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/files.cpp b/src/files.cpp new file mode 100644 index 0000000..b757811 --- /dev/null +++ b/src/files.cpp @@ -0,0 +1,160 @@ +#include "files.h" + +#include <bit> +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstring> +#include <iostream> + + +using std::cout, std::endl; + +namespace TehImage +{ + // HELPERS + void convertEndian(uint8_t* in, uint8_t* out, std::size_t bytes, FileEndianness target) + { + constexpr bool LE = std::endian::native == std::endian::little; + constexpr bool BE = !LE; + if(target == NO_CONVERT || (target == BIG && BE) || (target == LITTLE && LE)) + { + for(int i = 0; i < bytes; i++) + { + out[i] = in[i]; + } + return; + } + // std::cout << "Converting" << std::endl; + for(int i = 0; i < bytes; i++) + { + out[bytes - 1 - i] = in[i]; + } + } + + + // READER + Reader::Reader(std::string filename, FileEndianness fileEndianness) + :fileEndianness(fileEndianness) + { + file = fopen(filename.c_str(), "rb"); + refreshBuffer(); + ready = true; + } + Reader::~Reader() + { + if(ready) + fclose(file); + } + + char Reader::readByte() + { + if(pos == READER_BUFFER_SIZE) + refreshBuffer(); + return buffer[pos++]; + } + + void Reader::refreshBuffer() + { + fread(buffer, sizeof(buffer), 1, file); + pos = 0; + } + + template<> uint8_t Reader::readData<uint8_t>() + { + return readByte(); + } + + DEFINE_INT_READER(uint16_t); + DEFINE_INT_READER(uint32_t); + DEFINE_INT_READER(uint64_t); + + + void Reader::readBytes(char* out, size_t len) + { + while(len > 0) + { + size_t bytesToRead = std::min(len, READER_BUFFER_SIZE - pos); + if(bytesToRead == 0) + { + refreshBuffer(); + continue; + } + memcpy(out, buffer + pos, bytesToRead); + out += bytesToRead; + len -= bytesToRead; + pos += bytesToRead; + } + } + + void Reader::skipBytes(size_t len) + { + while(len > 0) + { + size_t bytesToRead = std::min(len, READER_BUFFER_SIZE - pos); + if(bytesToRead == 0) + { + refreshBuffer(); + continue; + } + len -= bytesToRead; + pos += bytesToRead; + } + } + + void Reader::close() + { + fclose(file); + ready = false; + } + + + // WRITER + Writer::Writer(std::string filename, FileEndianness fileEndianness) + :fileEndianness(fileEndianness) + { + file = fopen(filename.c_str(), "w"); + ready = true; + } + + Writer::~Writer() + { + close(); + } + + void Writer::writeByte(char toWrite) + { + fwrite(&toWrite, sizeof(char), 1, file); + } + + void Writer::writeBytes(char toWrite[], std::size_t len) + { + // for(int i = 0; i < len; i++) + // cout << toWrite[i] << endl; + fwrite(toWrite, sizeof(char), len, file); + } + + void Writer::zeroBytes(std::size_t len) + { + char *zeroes = new char[len]; + memset(zeroes, 0, len); + writeBytes(zeroes, len); + delete[] zeroes; + } + + void Writer::close() + { + if(ready) + fclose(file); + ready = false; + } + + template <> void Writer::writeData(uint8_t toWrite) + { + writeByte(toWrite); + } + + DEFINE_INT_WRITER(uint16_t); + DEFINE_INT_WRITER(uint32_t); + DEFINE_INT_WRITER(uint64_t); +} |
