Some neat stylistic changes, Feel free to reject :)

This commit is contained in:
2025-06-04 18:32:41 -05:00
parent a49108c4d2
commit 8edd019ca8
6 changed files with 127 additions and 12 deletions

View File

@@ -1,5 +1,18 @@
cmake_minimum_required(VERSION 3.18..3.28)
project(ReArchive)
set(ArchiveProjectVersion 1.1) # The current revision of the project.
set(ArchiveFormatVersion 1.0) # The current version of Redacted Software Archive specification.
set(ArchiveAppVersion 1.1) # The current version of rsarchive.exe
project(ReArchive
VERSION ${ArchiveProjectVersion}
LANGUAGES CXX)
if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(FATAL_ERROR "In-source builds are not allowed")
endif()
set(CMAKE_CXX_STANDARD 20)
@@ -14,11 +27,25 @@ if(WIN32)
add_library(ReArchive STATIC ${SOURCES})
endif()
include(cmake/CPM.cmake)
CPMAddPackage(NAME mcolor
URL https://git.redacted.cc/maxine/mcolor/archive/Release-1.zip)
target_compile_definitions(ReArchive PUBLIC ARCHIVE_PROJECT_VERSION=${ArchiveProjectVersion})
target_compile_definitions(ReArchive PUBLIC ARCHIVE_FORMAT_VERSION=${ArchiveFormatVersion})
set_target_properties(ReArchive PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(ReArchive PUBLIC ${PROJECT_SOURCE_DIR}/include)
add_executable(rsarchive main.cpp)
target_link_libraries(rsarchive PUBLIC ReArchive)
target_compile_definitions(rsarchive PRIVATE ARCHIVE_APP_VERSION=${ArchiveAppVersion})
target_include_directories(rsarchive PUBLIC ${mcolor_SOURCE_DIR}/include)
target_link_libraries(rsarchive PUBLIC ReArchive mcolor)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the build type" FORCE)

35
README.md Normal file
View File

@@ -0,0 +1,35 @@
# Redacted Software Archive
Yet Another Archival Format :D
The ReArchive project is a lightweight C++ library designed for creating, managing, and extracting archive files. It provides a foundation for bundling multiple files and directories into a single archive, ideal for game assets (mod distribution), application deployments, and many more tasks. Included with the library is `rsarchive`, a command-line application demonstrating ReArchive's capabilities and providing a general-purpose archive management tool.
## Features
* General
* Custom bespoke archive format.
* Included CLI archive program.
* C++20 API for integrating archives into your project.
* Public Domain Source Code, Format, & Application.
* **ZERO** dependencies. Just C++ and CMake.
* Library API Features
* Bundle files together for easier distribution.
* Integrate easily into your C++ project.
* Cross-platform: Designed with Redacted Software signature portability, simplicity, and
* Archive Format
* Custom, stream-friendly archive format.
* Designed for efficiency and extensibility.
* Efficient file retrieval even from large archives.
* Lightning fast. (See Benchmarks.)
* rsarchive Application:
* Robust command-line utility.
* Create, Extract, Inspect, Modify, and Validate archive files.
* Append and remove files individually.
* Supported on Windows & Linux.
* Designed to be extended and modified.
## Acknowledgements

24
cmake/CPM.cmake Normal file
View File

@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
set(CPM_DOWNLOAD_VERSION 0.38.7)
set(CPM_HASH_SUM "83e5eb71b2bbb8b1f2ad38f1950287a057624e385c238f6087f94cdfc44af9c5")
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)
include(${CPM_DOWNLOAD_LOCATION})

View File

@@ -51,4 +51,9 @@ namespace ReArchive {
/// @param file_table If you're keeping track of the file table in your program, Providing it here will update it to reflect our changes and speed things up.
/// @note An empty vector is returned in the event that no such file exists or there was an error reading it back.
std::vector<unsigned char> ReadFile(const std::filesystem::path& archive, const std::filesystem::path& file_path, FileTable* file_table = nullptr);
}
/// Returns the rsa format version this library is compiled to support.
/// @note Future versions of this library may support backward-compatibility.
double ArchiveFormatProtocolVersion();
}

View File

@@ -1,6 +1,9 @@
#include <ReArchive/ReArchive.h>
#include <iostream>
#include <fstream>
#include <mcolor.h>
bool GetConfirmation(const std::string& message) {
std::string user_input;
@@ -32,6 +35,11 @@ std::vector<unsigned char> ReadFileFromDisk(const std::filesystem::path& file_to
return buffer;
}
std::string PrettyVersionString()
{
return std::format("{}Redacted Software Archive Project v{} (rsarchive v{}) (RSA Format v{}){}", Colors::Browns::GoldenRod.ToEscapeCode(), ARCHIVE_PROJECT_VERSION, ARCHIVE_APP_VERSION, ARCHIVE_FORMAT_VERSION, mcolor::AnsiEscapeCodes::ResetAll);
}
bool WriteFileToDisk(const std::vector<unsigned char>& file_data, const std::filesystem::path& destination) {
std::ofstream file(destination, std::ios::binary);
if (!file)
@@ -42,6 +50,7 @@ bool WriteFileToDisk(const std::vector<unsigned char>& file_data, const std::fil
}
void DisplayLicense() {
std::cout << Colors::Oranges::Gold.ToEscapeCode();
std::cout << "This is free and unencumbered software released into the public domain." << std::endl;
std::cout << std::endl;
std::cout << "Anyone is free to copy, modify, publish, use, compile, sell, or" << std::endl;
@@ -63,16 +72,23 @@ void DisplayLicense() {
std::cout << "IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR" << std::endl;
std::cout << "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE," << std::endl;
std::cout << "ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR" << std::endl;
std::cout << "OTHER DEALINGS IN THE SOFTWARE." << std::endl;
std::cout << "OTHER DEALINGS IN THE SOFTWARE." << mcolor::AnsiEscapeCodes::ResetAll << std::endl;
}
void DisplayHelp() {
std::cout << "Redacted Software Archive version 1.0" << std::endl;
std::cout << "-v version: show the version string -h help: shows this listing" << std::endl;
std::cout << "-L license: show software license -l list: show all files in-to an archive" << std::endl;
std::cout << "-x extract: retrieve files from an archive -a add: put a file in-to an archive" << std::endl;
std::cout << "-c create: make a new, empty archive -r create an archive from a directory" << std::endl;
std::cout << "-ar add recursive: put all files in a directory in-to an archive" << std::endl;
std::string sep = Colors::DarkGray.ToEscapeCode() + mcolor::AnsiEscapeCodes::Bold + ">>> " + mcolor::AnsiEscapeCodes::ResetAll;
std::cout << PrettyVersionString() << std::endl;
int col = 45;
std::cout.width(col);
std::cout << std::left << "-v version: show the version string " << sep << std::left << "-h help: shows this listing" << std::endl;
std::cout.width(col);
std::cout << std::left << "-L license: show software license " << sep << std::right << "-l list: show all files in-to an archive" << std::endl;
std::cout.width(col);
std::cout << std::left <<"-x extract: retrieve files from an archive " << sep << std::right << "-a add: put a file in-to an archive" << std::endl;
std::cout.width(col);
std::cout << std::left << "-c create: make a new, empty archive " << sep << std::right << "-r create an archive from a directory" << std::endl;
std::cout.width(col);
std::cout << std::left << "-ar add recursive: put all files in a directory in-to an archive" << std::endl;
}
void DisplayArchiveContents(const std::filesystem::path& archive) {
@@ -92,7 +108,8 @@ void DisplayArchiveContents(const std::filesystem::path& archive) {
}
void DisplayInvalidParameters() {
std::cerr << "Invalid parameters received. Use -h or 'man rsarchive' for a complete guide." << std::endl;
//std::cerr << "Invalid parameters received. Use -h or 'man rsarchive' for a complete guide." << std::endl;
std::cout << Colors::Reds::LightCoral.ToEscapeCode() << "Invalid parameters received." << Colors::White.ToEscapeCode() << " Use -h or 'man rsarchive' for a complete guide." << mcolor::AnsiEscapeCodes::ResetAll << std::endl;
}
void AddFileToArchive(const std::filesystem::path& file_to_add, const std::filesystem::path& archive, ReArchive::FileTable* file_table = nullptr) {
@@ -183,13 +200,18 @@ void ExtractArchive(const std::filesystem::path& archive) {
}
}
int main(int argc, char* argv[]) {
mcolor::windowsSaneify();
if (argc == 1)
DisplayInvalidParameters();
if (argc == 2) {
if (std::string(argv[1]) == "-v")
std::cout << "Redacted Software Archive version 1.0" << std::endl;
std::cout << PrettyVersionString() << std::endl;
else if (std::string(argv[1]) == "-h")
DisplayHelp();

View File

@@ -306,6 +306,8 @@ std::vector<unsigned char> ReArchive::ReadFile(const std::filesystem::path& arch
return result;
}
double ReArchive::ArchiveFormatProtocolVersion() { return ARCHIVE_FORMAT_VERSION; }
// I tried to do this several different ways but this seems to be the best approach - Redacted.
bool ReArchive::EraseFile(const std::filesystem::path& archive, const std::filesystem::path& file_path, FileTable* running_tally) {