summaryrefslogtreecommitdiff
path: root/lib/binarytools
diff options
context:
space:
mode:
authorKiritoDv <kiritodev01@gmail.com>2023-08-17 00:35:58 -0600
committerKiritoDv <kiritodev01@gmail.com>2023-08-17 00:35:58 -0600
commit6fd8e5ee43dd0f87eb4e57b86e84770fcd95db25 (patch)
tree6a22e06c6105b63a0ae560f571f6d4e2522ba364 /lib/binarytools
Added StormLib, nlohmann, BinaryTools and CLI11
Diffstat (limited to 'lib/binarytools')
-rw-r--r--lib/binarytools/BinaryReader.cpp193
-rw-r--r--lib/binarytools/BinaryReader.h48
-rw-r--r--lib/binarytools/BinaryWriter.cpp150
-rw-r--r--lib/binarytools/BinaryWriter.h45
-rw-r--r--lib/binarytools/CMakeLists.txt10
-rw-r--r--lib/binarytools/FileHelper.h99
-rw-r--r--lib/binarytools/MemoryStream.cpp83
-rw-r--r--lib/binarytools/MemoryStream.h34
-rw-r--r--lib/binarytools/PathHelper.h49
-rw-r--r--lib/binarytools/Stream.cpp5
-rw-r--r--lib/binarytools/Stream.h33
-rw-r--r--lib/binarytools/endianness.h88
12 files changed, 837 insertions, 0 deletions
diff --git a/lib/binarytools/BinaryReader.cpp b/lib/binarytools/BinaryReader.cpp
new file mode 100644
index 0000000..3aff001
--- /dev/null
+++ b/lib/binarytools/BinaryReader.cpp
@@ -0,0 +1,193 @@
+#include "BinaryReader.h"
+#include "MemoryStream.h"
+#include <cmath>
+#include <stdexcept>
+
+LUS::BinaryReader::BinaryReader(char* nBuffer, size_t nBufferSize) {
+ mStream = std::make_shared<MemoryStream>(nBuffer, nBufferSize);
+}
+
+LUS::BinaryReader::BinaryReader(Stream* nStream) {
+ mStream.reset(nStream);
+}
+
+LUS::BinaryReader::BinaryReader(std::shared_ptr<Stream> nStream) {
+ mStream = nStream;
+}
+
+void LUS::BinaryReader::Close() {
+ mStream->Close();
+}
+
+void LUS::BinaryReader::SetEndianness(Endianness endianness) {
+ this->mEndianness = endianness;
+}
+
+LUS::Endianness LUS::BinaryReader::GetEndianness() const {
+ return mEndianness;
+}
+
+void LUS::BinaryReader::Seek(int32_t offset, SeekOffsetType seekType) {
+ mStream->Seek(offset, seekType);
+}
+
+uint32_t LUS::BinaryReader::GetBaseAddress() {
+ return mStream->GetBaseAddress();
+}
+
+void LUS::BinaryReader::Read(int32_t length) {
+ mStream->Read(length);
+}
+
+void LUS::BinaryReader::Read(char* buffer, int32_t length) {
+ mStream->Read(buffer, length);
+}
+
+char LUS::BinaryReader::ReadChar() {
+ return (char)mStream->ReadByte();
+}
+
+int8_t LUS::BinaryReader::ReadInt8() {
+ return mStream->ReadByte();
+}
+
+int16_t LUS::BinaryReader::ReadInt16() {
+ int16_t result = 0;
+ mStream->Read((char*)&result, sizeof(int16_t));
+ if (mEndianness != Endianness::Native) {
+ result = BSWAP16(result);
+ }
+
+ return result;
+}
+
+int32_t LUS::BinaryReader::ReadInt32() {
+ int32_t result = 0;
+
+ mStream->Read((char*)&result, sizeof(int32_t));
+
+ if (mEndianness != Endianness::Native) {
+ result = BSWAP32(result);
+ }
+
+ return result;
+}
+
+uint8_t LUS::BinaryReader::ReadUByte() {
+ return (uint8_t)mStream->ReadByte();
+}
+
+uint16_t LUS::BinaryReader::ReadUInt16() {
+ uint16_t result = 0;
+
+ mStream->Read((char*)&result, sizeof(uint16_t));
+
+ if (mEndianness != Endianness::Native) {
+ result = BSWAP16(result);
+ }
+
+ return result;
+}
+
+uint32_t LUS::BinaryReader::ReadUInt32() {
+ uint32_t result = 0;
+
+ mStream->Read((char*)&result, sizeof(uint32_t));
+
+ if (mEndianness != Endianness::Native) {
+ result = BSWAP32(result);
+ }
+
+ return result;
+}
+
+uint64_t LUS::BinaryReader::ReadUInt64() {
+ uint64_t result = 0;
+
+ mStream->Read((char*)&result, sizeof(uint64_t));
+
+ if (mEndianness != Endianness::Native) {
+ result = BSWAP64(result);
+ }
+
+ return result;
+}
+
+float LUS::BinaryReader::ReadFloat() {
+ float result = NAN;
+
+ mStream->Read((char*)&result, sizeof(float));
+
+ if (mEndianness != Endianness::Native) {
+ float tmp;
+ char* dst = (char*)&tmp;
+ char* src = (char*)&result;
+ dst[3] = src[0];
+ dst[2] = src[1];
+ dst[1] = src[2];
+ dst[0] = src[3];
+ result = tmp;
+ }
+
+ if (std::isnan(result)) {
+ throw std::runtime_error("BinaryReader::ReadFloat(): Error reading stream");
+ }
+
+ return result;
+}
+
+double LUS::BinaryReader::ReadDouble() {
+ double result = NAN;
+
+ mStream->Read((char*)&result, sizeof(double));
+
+ if (mEndianness != Endianness::Native) {
+ double tmp;
+ char* dst = (char*)&tmp;
+ char* src = (char*)&result;
+ dst[7] = src[0];
+ dst[6] = src[1];
+ dst[5] = src[2];
+ dst[4] = src[3];
+ dst[3] = src[4];
+ dst[2] = src[5];
+ dst[1] = src[6];
+ dst[0] = src[7];
+ result = tmp;
+ }
+
+ if (std::isnan(result)) {
+ throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream");
+ }
+
+ return result;
+}
+
+std::string LUS::BinaryReader::ReadString() {
+ std::string res;
+ int numChars = ReadInt32();
+ for (int i = 0; i < numChars; i++) {
+ res += ReadChar();
+ }
+ return res;
+}
+
+std::string LUS::BinaryReader::ReadCString() {
+ std::string res;
+
+ unsigned char c = 0;
+ do {
+ if (mStream->GetBaseAddress() >= mStream->GetLength()) {
+ break;
+ }
+
+ c = ReadChar();
+ res += c;
+ } while (c != '\0');
+
+ return res;
+}
+
+std::vector<char> LUS::BinaryReader::ToVector() {
+ return mStream->ToVector();
+}
diff --git a/lib/binarytools/BinaryReader.h b/lib/binarytools/BinaryReader.h
new file mode 100644
index 0000000..59eeb52
--- /dev/null
+++ b/lib/binarytools/BinaryReader.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <string>
+#include <memory>
+#include <vector>
+#include "endianness.h"
+#include "Stream.h"
+
+class BinaryReader;
+
+namespace LUS {
+
+class BinaryReader {
+ public:
+ BinaryReader(char* nBuffer, size_t nBufferSize);
+ BinaryReader(Stream* nStream);
+ BinaryReader(std::shared_ptr<Stream> nStream);
+
+ void Close();
+
+ void SetEndianness(Endianness endianness);
+ Endianness GetEndianness() const;
+
+ void Seek(int32_t offset, SeekOffsetType seekType);
+ uint32_t GetBaseAddress();
+
+ void Read(int32_t length);
+ void Read(char* buffer, int32_t length);
+ char ReadChar();
+ int8_t ReadInt8();
+ int16_t ReadInt16();
+ int32_t ReadInt32();
+ uint8_t ReadUByte();
+ uint16_t ReadUInt16();
+ uint32_t ReadUInt32();
+ uint64_t ReadUInt64();
+ float ReadFloat();
+ double ReadDouble();
+ std::string ReadString();
+ std::string ReadCString();
+
+ std::vector<char> ToVector();
+
+ protected:
+ std::shared_ptr<Stream> mStream;
+ Endianness mEndianness = Endianness::Native;
+};
+} // namespace LUS
diff --git a/lib/binarytools/BinaryWriter.cpp b/lib/binarytools/BinaryWriter.cpp
new file mode 100644
index 0000000..362824f
--- /dev/null
+++ b/lib/binarytools/BinaryWriter.cpp
@@ -0,0 +1,150 @@
+#include "BinaryWriter.h"
+#include "MemoryStream.h"
+
+LUS::BinaryWriter::BinaryWriter() {
+ mStream = std::make_shared<MemoryStream>();
+}
+
+LUS::BinaryWriter::BinaryWriter(Stream* nStream) {
+ mStream.reset(nStream);
+}
+
+LUS::BinaryWriter::BinaryWriter(std::shared_ptr<Stream> nStream) {
+ mStream = nStream;
+}
+
+void LUS::BinaryWriter::SetEndianness(Endianness endianness) {
+ this->mEndianness = endianness;
+}
+
+void LUS::BinaryWriter::Close() {
+ mStream->Close();
+}
+
+std::shared_ptr<LUS::Stream> LUS::BinaryWriter::GetStream() {
+ return mStream;
+}
+
+uint64_t LUS::BinaryWriter::GetBaseAddress() {
+ return mStream->GetBaseAddress();
+}
+
+uint64_t LUS::BinaryWriter::GetLength() {
+ return mStream->GetLength();
+}
+
+void LUS::BinaryWriter::Seek(int32_t offset, SeekOffsetType seekType) {
+ mStream->Seek(offset, seekType);
+}
+
+void LUS::BinaryWriter::Write(int8_t value) {
+ mStream->Write((char*)&value, sizeof(int8_t));
+}
+
+void LUS::BinaryWriter::Write(uint8_t value) {
+ mStream->Write((char*)&value, sizeof(uint8_t));
+}
+
+void LUS::BinaryWriter::Write(int16_t value) {
+ if (mEndianness != Endianness::Native) {
+ value = BSWAP16(value);
+ }
+
+ mStream->Write((char*)&value, sizeof(int16_t));
+}
+
+void LUS::BinaryWriter::Write(uint16_t value) {
+ if (mEndianness != Endianness::Native) {
+ value = BSWAP16(value);
+ }
+
+ mStream->Write((char*)&value, sizeof(uint16_t));
+}
+
+void LUS::BinaryWriter::Write(int32_t value) {
+ if (mEndianness != Endianness::Native) {
+ value = BSWAP32(value);
+ }
+
+ mStream->Write((char*)&value, sizeof(int32_t));
+}
+
+void LUS::BinaryWriter::Write(int32_t valueA, int32_t valueB) {
+ Write(valueA);
+ Write(valueB);
+}
+
+void LUS::BinaryWriter::Write(uint32_t value) {
+ if (mEndianness != Endianness::Native) {
+ value = BSWAP32(value);
+ }
+
+ mStream->Write((char*)&value, sizeof(uint32_t));
+}
+
+void LUS::BinaryWriter::Write(int64_t value) {
+ if (mEndianness != Endianness::Native) {
+ value = BSWAP64(value);
+ }
+
+ mStream->Write((char*)&value, sizeof(int64_t));
+}
+
+void LUS::BinaryWriter::Write(uint64_t value) {
+ if (mEndianness != Endianness::Native) {
+ value = BSWAP64(value);
+ }
+
+ mStream->Write((char*)&value, sizeof(uint64_t));
+}
+
+void LUS::BinaryWriter::Write(float value) {
+ if (mEndianness != Endianness::Native) {
+ float tmp;
+ char* dst = (char*)&tmp;
+ char* src = (char*)&value;
+ dst[3] = src[0];
+ dst[2] = src[1];
+ dst[1] = src[2];
+ dst[0] = src[3];
+ value = tmp;
+ }
+
+ mStream->Write((char*)&value, sizeof(float));
+}
+
+void LUS::BinaryWriter::Write(double value) {
+ if (mEndianness != Endianness::Native) {
+ double tmp;
+ char* dst = (char*)&tmp;
+ char* src = (char*)&value;
+ dst[7] = src[0];
+ dst[6] = src[1];
+ dst[5] = src[2];
+ dst[4] = src[3];
+ dst[3] = src[4];
+ dst[2] = src[5];
+ dst[1] = src[6];
+ dst[0] = src[7];
+ value = tmp;
+ }
+
+ mStream->Write((char*)&value, sizeof(double));
+}
+
+void LUS::BinaryWriter::Write(const std::string& str) {
+ int strLen = str.size();
+ Write(strLen);
+
+ for (char c : str) {
+ mStream->WriteByte(c);
+ }
+}
+
+void LUS::BinaryWriter::Write(char* srcBuffer, size_t length) {
+ mStream->Write(srcBuffer, length);
+}
+
+std::vector<char> LUS::BinaryWriter::ToVector() {
+ return mStream->ToVector();
+}
diff --git a/lib/binarytools/BinaryWriter.h b/lib/binarytools/BinaryWriter.h
new file mode 100644
index 0000000..fbd4f65
--- /dev/null
+++ b/lib/binarytools/BinaryWriter.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <array>
+#include <memory>
+#include <string>
+#include <vector>
+#include "endianness.h"
+#include "Stream.h"
+
+namespace LUS {
+class BinaryWriter {
+ public:
+ BinaryWriter();
+ BinaryWriter(Stream* nStream);
+ BinaryWriter(std::shared_ptr<Stream> nStream);
+
+ void SetEndianness(Endianness endianness);
+
+ std::shared_ptr<Stream> GetStream();
+ uint64_t GetBaseAddress();
+ uint64_t GetLength();
+ void Seek(int32_t offset, SeekOffsetType seekType);
+ void Close();
+
+ void Write(int8_t value);
+ void Write(uint8_t value);
+ void Write(int16_t value);
+ void Write(uint16_t value);
+ void Write(int32_t value);
+ void Write(int32_t valueA, int32_t valueB);
+ void Write(uint32_t value);
+ void Write(int64_t value);
+ void Write(uint64_t value);
+ void Write(float value);
+ void Write(double value);
+ void Write(const std::string& str);
+ void Write(char* srcBuffer, size_t length);
+
+ std::vector<char> ToVector();
+
+ protected:
+ std::shared_ptr<Stream> mStream;
+ Endianness mEndianness = Endianness::Native;
+};
+} // namespace LUS
diff --git a/lib/binarytools/CMakeLists.txt b/lib/binarytools/CMakeLists.txt
new file mode 100644
index 0000000..cc982d5
--- /dev/null
+++ b/lib/binarytools/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.12)
+project(BinaryTools)
+
+set(CMAKE_CXX_STANDARD 20)
+
+file(GLOB CXX_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
+set(SRC_DIR ${CXX_FILES})
+
+add_library(${PROJECT_NAME} STATIC ${SRC_DIR})
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file
diff --git a/lib/binarytools/FileHelper.h b/lib/binarytools/FileHelper.h
new file mode 100644
index 0000000..bb65886
--- /dev/null
+++ b/lib/binarytools/FileHelper.h
@@ -0,0 +1,99 @@
+#pragma once
+
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+#include "PathHelper.h"
+#include "Utils/StringHelper.h"
+#include "Utils/Directory.h"
+
+namespace LUS {
+class FileHelper {
+ public:
+ static bool Exists(const fs::path& filePath) {
+ std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate);
+ return file.good();
+ }
+
+ static std::vector<uint8_t> ReadAllBytes(const fs::path& filePath) {
+ std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate);
+
+ if (!file) {
+ return std::vector<uint8_t>();
+ }
+
+ int32_t fileSize = (int32_t)file.tellg();
+ file.seekg(0);
+ char* data = nullptr;
+ std::vector<uint8_t> result;
+
+ try {
+ data = new char[fileSize];
+ file.read(data, fileSize);
+ result = std::vector<uint8_t>(data, data + fileSize);
+ } catch (const std::exception& e) {
+ delete[] data;
+ throw e;
+ }
+
+ delete[] data;
+
+ return result;
+ };
+
+ static std::string ReadAllText(const fs::path& filePath) {
+ std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate);
+ int32_t fileSize = (int32_t)file.tellg();
+ file.seekg(0);
+ char* data = nullptr;
+ std::string str;
+
+ try {
+ data = new char[fileSize + 1];
+ memset(data, 0, fileSize + 1);
+ file.read(data, fileSize);
+ str = std::string((const char*)data);
+ } catch (const std::exception& e) {
+ delete[] data;
+ throw e;
+ }
+
+ delete[] data;
+
+ return str;
+ };
+
+ static std::vector<std::string> ReadAllLines(const fs::path& filePath) {
+ std::string text = ReadAllText(filePath);
+ std::vector<std::string> lines = StringHelper::Split(text, "\n");
+
+ return lines;
+ };
+
+ static void WriteAllBytes(const fs::path& filePath, const std::vector<uint8_t>& data) {
+ std::ofstream file(filePath, std::ios::binary);
+ file.write((char*)data.data(), data.size());
+ };
+
+ static void WriteAllBytes(const std::string& filePath, const std::vector<char>& data) {
+ if (!Directory::Exists(PathHelper::GetDirectoryName(filePath))) {
+ Directory::MakeDirectory(PathHelper::GetDirectoryName(filePath).string());
+ }
+
+ std::ofstream file(filePath, std::ios::binary);
+ file.write((char*)data.data(), data.size());
+ };
+
+ static void WriteAllBytes(const std::string& filePath, const char* data, int dataSize) {
+ std::ofstream file(filePath, std::ios::binary);
+ file.write((char*)data, dataSize);
+ };
+
+ static void WriteAllText(const fs::path& filePath, const std::string& text) {
+ std::ofstream file(filePath, std::ios::out);
+ file.write(text.c_str(), text.size());
+ }
+};
+} // namespace LUS \ No newline at end of file
diff --git a/lib/binarytools/MemoryStream.cpp b/lib/binarytools/MemoryStream.cpp
new file mode 100644
index 0000000..d94b7d3
--- /dev/null
+++ b/lib/binarytools/MemoryStream.cpp
@@ -0,0 +1,83 @@
+#include "MemoryStream.h"
+#include <cstring>
+
+#ifndef _MSC_VER
+#define memcpy_s(dest, destSize, source, sourceSize) memcpy(dest, source, destSize)
+#endif
+
+LUS::MemoryStream::MemoryStream() {
+ mBuffer = std::vector<char>();
+ // mBuffer.reserve(1024 * 16);
+ mBufferSize = 0;
+ mBaseAddress = 0;
+}
+
+LUS::MemoryStream::MemoryStream(char* nBuffer, size_t nBufferSize) : MemoryStream() {
+ mBuffer = std::vector<char>(nBuffer, nBuffer + nBufferSize);
+ mBufferSize = nBufferSize;
+ mBaseAddress = 0;
+}
+
+LUS::MemoryStream::~MemoryStream() {
+}
+
+uint64_t LUS::MemoryStream::GetLength() {
+ return mBuffer.size();
+}
+
+void LUS::MemoryStream::Seek(int32_t offset, SeekOffsetType seekType) {
+ if (seekType == SeekOffsetType::Start) {
+ mBaseAddress = offset;
+ } else if (seekType == SeekOffsetType::Current) {
+ mBaseAddress += offset;
+ } else if (seekType == SeekOffsetType::End) {
+ mBaseAddress = mBufferSize - 1 - offset;
+ }
+}
+
+std::unique_ptr<char[]> LUS::MemoryStream::Read(size_t length) {
+ std::unique_ptr<char[]> result = std::make_unique<char[]>(length);
+
+ memcpy_s(result.get(), length, &mBuffer[mBaseAddress], length);
+ mBaseAddress += length;
+
+ return result;
+}
+
+void LUS::MemoryStream::Read(const char* dest, size_t length) {
+ memcpy_s((void*)dest, length, &mBuffer[mBaseAddress], length);
+ mBaseAddress += length;
+}
+
+int8_t LUS::MemoryStream::ReadByte() {
+ return mBuffer[mBaseAddress++];
+}
+
+void LUS::MemoryStream::Write(char* srcBuffer, size_t length) {
+ if (mBaseAddress + length >= mBuffer.size()) {
+ mBuffer.resize(mBaseAddress + length);
+ mBufferSize += length;
+ }
+
+ memcpy_s(&mBuffer[mBaseAddress], length, srcBuffer, length);
+ mBaseAddress += length;
+}
+
+void LUS::MemoryStream::WriteByte(int8_t value) {
+ if (mBaseAddress >= mBuffer.size()) {
+ mBuffer.resize(mBaseAddress + 1);
+ mBufferSize = mBaseAddress;
+ }
+
+ mBuffer[mBaseAddress++] = value;
+}
+
+std::vector<char> LUS::MemoryStream::ToVector() {
+ return mBuffer;
+}
+
+void LUS::MemoryStream::Flush() {
+}
+
+void LUS::MemoryStream::Close() {
+}
diff --git a/lib/binarytools/MemoryStream.h b/lib/binarytools/MemoryStream.h
new file mode 100644
index 0000000..9f38169
--- /dev/null
+++ b/lib/binarytools/MemoryStream.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+#include "Stream.h"
+
+namespace LUS {
+class MemoryStream : public Stream {
+ public:
+ MemoryStream();
+ MemoryStream(char* nBuffer, size_t nBufferSize);
+ ~MemoryStream();
+
+ uint64_t GetLength() override;
+
+ void Seek(int32_t offset, SeekOffsetType seekType) override;
+
+ std::unique_ptr<char[]> Read(size_t length) override;
+ void Read(const char* dest, size_t length) override;
+ int8_t ReadByte() override;
+
+ void Write(char* srcBuffer, size_t length) override;
+ void WriteByte(int8_t value) override;
+
+ std::vector<char> ToVector() override;
+
+ void Flush() override;
+ void Close() override;
+
+ protected:
+ std::vector<char> mBuffer;
+ std::size_t mBufferSize;
+};
+} // namespace LUS
diff --git a/lib/binarytools/PathHelper.h b/lib/binarytools/PathHelper.h
new file mode 100644
index 0000000..3ac9906
--- /dev/null
+++ b/lib/binarytools/PathHelper.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+#include "Utils/StringHelper.h"
+
+#if __has_include(<filesystem>)
+#include <filesystem>
+namespace fs = std::filesystem;
+#else
+#include <experimental/filesystem>
+namespace fs = std::experimental::filesystem;
+#endif
+
+namespace LUS {
+class PathHelper {
+ public:
+ static std::string GetFileName(const fs::path& input) {
+ // https://en.cppreference.com/w/cpp/filesystem/path/filename
+ return input.filename().string();
+ };
+
+ static std::string GetFileNameWithoutExtension(const fs::path& input) {
+ // https://en.cppreference.com/w/cpp/filesystem/path/stem
+ return input.stem().string();
+ };
+
+ static std::string GetFileNameExtension(const std::string& input) {
+ return input.substr(input.find_last_of("."), input.length());
+ };
+
+ static fs::path GetPath(const std::string& input) {
+ std::vector<std::string> split = StringHelper::Split(input, "/");
+ fs::path output;
+
+ for (std::string str : split) {
+ if (str.find_last_of(".") == std::string::npos) {
+ output /= str;
+ }
+ }
+
+ return output;
+ };
+
+ static fs::path GetDirectoryName(const fs::path& path) {
+ return path.parent_path();
+ };
+};
+} // namespace LUS
diff --git a/lib/binarytools/Stream.cpp b/lib/binarytools/Stream.cpp
new file mode 100644
index 0000000..17810fa
--- /dev/null
+++ b/lib/binarytools/Stream.cpp
@@ -0,0 +1,5 @@
+#include "Stream.h"
+
+uint64_t LUS::Stream::GetBaseAddress() {
+ return mBaseAddress;
+}
diff --git a/lib/binarytools/Stream.h b/lib/binarytools/Stream.h
new file mode 100644
index 0000000..f22c212
--- /dev/null
+++ b/lib/binarytools/Stream.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+namespace LUS {
+enum class SeekOffsetType { Start, Current, End };
+
+class Stream {
+ public:
+ virtual ~Stream() = default;
+ virtual uint64_t GetLength() = 0;
+ uint64_t GetBaseAddress();
+
+ virtual void Seek(int32_t offset, SeekOffsetType seekType) = 0;
+
+ virtual std::unique_ptr<char[]> Read(size_t length) = 0;
+ virtual void Read(const char* dest, size_t length) = 0;
+ virtual int8_t ReadByte() = 0;
+
+ virtual void Write(char* destBuffer, size_t length) = 0;
+ virtual void WriteByte(int8_t value) = 0;
+
+ virtual std::vector<char> ToVector() = 0;
+
+ virtual void Flush() = 0;
+ virtual void Close() = 0;
+
+ protected:
+ uint64_t mBaseAddress;
+};
+} // namespace LUS
diff --git a/lib/binarytools/endianness.h b/lib/binarytools/endianness.h
new file mode 100644
index 0000000..d7a9baa
--- /dev/null
+++ b/lib/binarytools/endianness.h
@@ -0,0 +1,88 @@
+#ifndef ENDIANESS_H
+#define ENDIANESS_H
+
+#ifdef __cplusplus
+namespace LUS {
+enum class Endianness {
+ Little = 0,
+ Big = 1,
+
+#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
+ Native = Big,
+#else
+ Native = Little,
+#endif
+};
+} // namespace LUS
+#endif
+
+#ifdef _MSC_VER
+#include <stdlib.h>
+
+#define BSWAP16 _byteswap_ushort
+#define BSWAP32 _byteswap_ulong
+#define BSWAP64 _byteswap_uint64
+
+#define BOMSWAP16 _byteswap_ushort
+#define BOMSWAP32 _byteswap_ulong
+#define BOMSWAP64 _byteswap_uint64
+
+#define BOMSWAP16_CONST(x) ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
+#define BOMSWAP32_CONST(x) \
+ ((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | (((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
+#define BOMSWAP64_CONST(x) \
+ ((((x) >> 56) & 0x00000000000000FF) | (((x) >> 40) & 0x000000000000FF00) | (((x) >> 24) & 0x0000000000FF0000) | \
+ (((x) >> 8) & 0x00000000FF000000) | (((x) << 8) & 0x000000FF00000000) | (((x) << 24) & 0x0000FF0000000000) | \
+ (((x) << 40) & 0x00FF000000000000) | (((x) << 56) & 0xFF00000000000000))
+#else
+
+#define BSWAP16 __builtin_bswap16
+#define BSWAP32 __builtin_bswap32
+#define BSWAP64 __builtin_bswap64
+
+#define BOMSWAP16 __builtin_bswap16
+#define BOMSWAP32 __builtin_bswap32
+#define BOMSWAP64 __builtin_bswap64
+
+#define BOMSWAP16_CONST __builtin_bswap16
+#define BOMSWAP32_CONST __builtin_bswap32
+#define BOMSWAP64_CONST __builtin_bswap64
+#endif
+
+#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
+#ifndef IS_BIGENDIAN
+#define IS_BIGENDIAN
+#endif
+#endif
+
+#ifdef IS_BIGENDIAN
+#define BE16SWAP(x) (x)
+#define BE32SWAP(x) (x)
+#define BE64SWAP(x) (x)
+#define LE16SWAP(x) BOMSWAP16(x)
+#define LE32SWAP(x) BOMSWAP32(x)
+#define LE64SWAP(x) BOMSWAP64(x)
+
+#define BE16SWAP_CONST(x) (x)
+#define BE32SWAP_CONST(x) (x)
+#define BE64SWAP_CONST(x) (x)
+#define LE16SWAP_CONST(x) BOMSWAP16_CONST(x)
+#define LE32SWAP_CONST(x) BOMSWAP32_CONST(x)
+#define LE64SWAP_CONST(x) BOMSWAP64_CONST(x)
+#else
+#define BE16SWAP(x) BOMSWAP16(x)
+#define BE32SWAP(x) BOMSWAP32(x)
+#define BE64SWAP(x) BOMSWAP64(x)
+#define LE16SWAP(x) (x)
+#define LE32SWAP(x) (x)
+#define LE64SWAP(x) (x)
+
+#define BE16SWAP_CONST(x) BOMSWAP16_CONST(x)
+#define BE32SWAP_CONST(x) BOMSWAP32_CONST(x)
+#define BE64SWAP_CONST(x) BOMSWAP64_CONST(x)
+#define LE16SWAP_CONST(x) (x)
+#define LE32SWAP_CONST(x) (x)
+#define LE64SWAP_CONST(x) (x)
+#endif
+
+#endif