diff options
Diffstat (limited to 'libs/libbsarch/src')
| -rw-r--r-- | libs/libbsarch/src/bs_archive.cpp | 185 | ||||
| -rw-r--r-- | libs/libbsarch/src/bs_archive_auto.cpp | 87 | ||||
| -rw-r--r-- | libs/libbsarch/src/bs_archive_entries.cpp | 52 | ||||
| -rw-r--r-- | libs/libbsarch/src/libbsarch.cpp | 206 | ||||
| -rw-r--r-- | libs/libbsarch/src/libbsarch.def | 38 | ||||
| -rw-r--r-- | libs/libbsarch/src/utils/convertible_ostream.cpp | 58 | ||||
| -rw-r--r-- | libs/libbsarch/src/utils/convertible_string.cpp | 108 | ||||
| -rw-r--r-- | libs/libbsarch/src/utils/string_convert.cpp | 39 |
8 files changed, 773 insertions, 0 deletions
diff --git a/libs/libbsarch/src/bs_archive.cpp b/libs/libbsarch/src/bs_archive.cpp new file mode 100644 index 0000000..b50ef5b --- /dev/null +++ b/libs/libbsarch/src/bs_archive.cpp @@ -0,0 +1,185 @@ +#include "bs_archive.h" + +namespace libbsarch { + +bs_archive::bs_archive() + : archive_(bsa_create()) +{} + +bs_archive::bs_archive(const bsa_archive_type_t &type) + : archive_(bsa_create()) + , type_(type) +{} + +bs_archive::~bs_archive() +{ + bsa_close(archive_); + bsa_free(archive_); +} + +/* Properties */ +convertible_string bs_archive::get_filename() +{ + wchar_t name[max_string_buffer_size]; + bsa_filename_get(archive_, max_string_buffer_size, name); + return name; +} + +bsa_archive_type_t bs_archive::get_type() +{ + return bsa_archive_type_get(archive_); +} + +uint32_t bs_archive::get_version() +{ + return bsa_version_get(archive_); +} + +convertible_string bs_archive::get_format_name() +{ + wchar_t format_name[max_string_buffer_size]; + bsa_format_name_get(archive_, max_string_buffer_size, format_name); + return format_name; +} + +uint32_t bs_archive::get_file_count() +{ + return bsa_file_count_get(archive_); +} + +uint32_t bs_archive::get_archive_flags() +{ + return bsa_archive_flags_get(archive_); +} + +void bs_archive::set_archive_flags(uint32_t flags) +{ + bsa_archive_flags_set(archive_, flags); +} + +uint32_t bs_archive::get_file_flags() +{ + return bsa_file_flags_get(archive_); +} + +void bs_archive::set_file_flags(uint32_t flags) +{ + bsa_file_flags_set(archive_, flags); +} + +void bs_archive::set_compressed(bool value) +{ + bsa_compress_set(archive_, value); +} + +void bs_archive::set_share_data(bool value) +{ + bsa_share_data_set(archive_, value); +} + +bool bs_archive::get_compressed() +{ + return bsa_compress_get(archive_); +} + +bool bs_archive::get_share_data() +{ + return bsa_share_data_get(archive_); +} + +void bs_archive::load_from_disk(const convertible_string &archive_path) +{ + debug_log() << "Opening archive: " << archive_path; + const std::wstring str = archive_path; + const auto &result = bsa_load_from_file(archive_, str.c_str()); + libbsarch::checkResult(result); +} + +void bs_archive::create(const convertible_string &archiveName, const bs_archive_entries &entries) +{ + create(archiveName, entries, type_); +} + +void bs_archive::create(const convertible_string &archiveName, + const bs_archive_entries &entries, + const bsa_archive_type_t type) +{ + debug_log() << "Creating archive. Archive name: " << archiveName << '\n' + << "type: " << type_ << '\n' + << "entries: " << entries.getEntries(); + bsa_create_archive(archive_, archiveName, type, entries.getEntries()); +} + +void bs_archive::save() const +{ + debug_log() << "Saving archive: " << archive_; + + const auto &result = bsa_save(archive_); + + libbsarch::checkResult(result); +} + +void bs_archive::add_file_from_disk(const disk_blob &blob) +{ + debug_log() << "Adding file from disk root. Path in archive: " << blob.path_in_archive << '\n' + << "Filepath: " << blob.path_on_disk << '\n' + << "Archive: " << archive_; + + const auto &result = bsa_add_file_from_disk(archive_, blob.path_in_archive, blob.path_on_disk); + + libbsarch::checkResult(result); +} + +void bs_archive::add_file_from_memory(const convertible_string &path_in_archive, + const memory_blob &memory_data) //NOTE UNTESTED +{ + debug_log() << "Adding file from memory. Filename: " << path_in_archive << '\n' + << "Data size: " << memory_data.size; + const auto &result = bsa_add_file_from_memory(archive_, path_in_archive, memory_data.size, memory_data.data); + libbsarch::checkResult(result); +} + +bsa_file_record_t bs_archive::find_file_record(const convertible_string &filename) +{ + debug_log() << "Finding file record of: " << filename; + const auto &result = bsa_find_file_record(archive_, filename); + return result; +} + +memory_blob bs_archive::extract_to_memory(bsa_file_record_t record) +{ + const auto &result = bsa_extract_file_data_by_record(archive_, record); + libbsarch::checkResult(result); + return memory_blob(result.buffer, archive_); +} + +memory_blob bs_archive::extract_to_memory(const convertible_string &filename) +{ + const auto &result = bsa_extract_file_data_by_filename(archive_, filename); + libbsarch::checkResult(result); + return memory_blob(result.buffer, archive_); +} + +void bs_archive::extract_to_disk(const convertible_string &filename, const convertible_string &save_as) const +{ + debug_log() << "Extracting: " << filename << " saved as " << save_as; + const auto &result = bsa_extract_file(archive_, filename, save_as); + + libbsarch::checkResult(result); +} + +std::vector<convertible_string> bs_archive::list_files() const +{ + bsa_entry_list_t list = bsa_entry_list_create(); + const auto &result = bsa_get_resource_list(archive_, list, L""); + + libbsarch::checkResult(result); + + return bs_archive_entries(list).list(); +} + +bsa_archive_t bs_archive::get_archive() const +{ + return archive_; +} +} // namespace libbsarch diff --git a/libs/libbsarch/src/bs_archive_auto.cpp b/libs/libbsarch/src/bs_archive_auto.cpp new file mode 100644 index 0000000..1ad8e3e --- /dev/null +++ b/libs/libbsarch/src/bs_archive_auto.cpp @@ -0,0 +1,87 @@ +/* Copyright (C) 2019 G'k + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "bs_archive_auto.hpp" +#include <filesystem> +namespace libbsarch { +bs_archive_auto::bs_archive_auto(const bsa_archive_type_t &type) + : bs_archive(type) +{} + +void bs_archive_auto::add_file_from_disk(const disk_blob &blob) +{ + files_.emplace_back(blob); +} + +void bs_archive_auto::add_file_from_disk(const std::vector<disk_blob> &blobs) +{ + files_.reserve(blobs.size()); + files_.insert(files_.end(), blobs.cbegin(), blobs.cend()); +} + +void bs_archive_auto::add_file_from_memory(const convertible_string &path_in_archive, const memory_blob &memory_data) +{ + files_.emplace_back(bs_packed_file(path_in_archive, memory_data)); +} + +void bs_archive_auto::add_file(const bs_packed_file &file) +{ + files_.emplace_back(file); +} + +void bs_archive_auto::extract_all(const convertible_string &directory, bool overwrite_current_files) +{ + namespace fs = std::filesystem; + for (const auto &file : list_files()) + { + convertible_string path_string = std::string(directory) + "/" + std::string(file); + fs::path current_file(path_string); + fs::path current_path = fs::path(current_file).remove_filename(); + + fs::create_directories(current_path); + if (fs::exists(current_file) && overwrite_current_files) + { + fs::remove(current_file); + extract_to_disk(file, current_file.string()); + } + else if (!fs::exists(current_file)) + extract_to_disk(file, current_file.string()); + } +} + +void bs_archive_auto::load_from_disk(const convertible_string &archive_path) +{ + bs_archive::load_from_disk(archive_path); + for (const auto &file : list_files()) + entries_.add(file); +} + +void bs_archive_auto::save_to_disk(const convertible_string &archive_path) +{ + for (const auto &file : files_) + entries_.add(file.path_in_archive); + + bs_archive::create(archive_path, entries_); + + for (const auto &file : files_) + { + switch (file.data.index()) + { + case 0: { + const auto &blob = std::get<memory_blob>(file.data); + bs_archive::add_file_from_memory(file.path_in_archive, blob); + break; + } + case 1: { + const auto &file_path = std::get<convertible_string>(file.data); + const auto &blob = disk_blob(file.path_in_archive, file_path, bool()); + bs_archive::add_file_from_disk(blob); + } + } + } + bs_archive::save(); +} + +} // namespace libbsarch diff --git a/libs/libbsarch/src/bs_archive_entries.cpp b/libs/libbsarch/src/bs_archive_entries.cpp new file mode 100644 index 0000000..4dc9c6d --- /dev/null +++ b/libs/libbsarch/src/bs_archive_entries.cpp @@ -0,0 +1,52 @@ +#include "bs_archive_entries.h" + +namespace libbsarch { +bs_archive_entries::bs_archive_entries() + : _entries(bsa_entry_list_create()) +{} + +bs_archive_entries::bs_archive_entries(const std::vector<convertible_string> &entries) + : _entries(bsa_entry_list_create()) +{ + for (const auto &entry : entries) + add(entry); +} + +bs_archive_entries::bs_archive_entries(const bsa_entry_list_t &entries) + : _entries(entries) +{} + +bs_archive_entries::~bs_archive_entries() +{ + bsa_entry_list_free(_entries); +} + +void bs_archive_entries::add(const convertible_string &filepath) +{ + debug_log() << "Adding to entries: " << filepath; + const auto &result = bsa_entry_list_add(_entries, filepath); + libbsarch::checkResult(result); +} + +uint32_t bs_archive_entries::count() +{ + return bsa_entry_list_count(_entries); +} + +std::vector<convertible_string> bs_archive_entries::list() +{ + std::vector<convertible_string> list; + for (uint32_t i = 0; i < count(); ++i) + { + wchar_t buffer[max_string_buffer_size]; + bsa_entry_list_get(_entries, i, max_string_buffer_size, buffer); + list.push_back(buffer); + } + return list; +} + +bsa_entry_list_t bs_archive_entries::getEntries() const +{ + return _entries; +} +} // namespace libbsarch diff --git a/libs/libbsarch/src/libbsarch.cpp b/libs/libbsarch/src/libbsarch.cpp new file mode 100644 index 0000000..52ded9f --- /dev/null +++ b/libs/libbsarch/src/libbsarch.cpp @@ -0,0 +1,206 @@ +#ifdef BSARCH_DLL_EXPORT +#include "libbsarch.h" + +namespace libbsarch { + +BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create() +{ + return nullptr; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_free(bsa_entry_list_t entry_list) +{ + return {0}; +} + +BSARCH_DLL_API(uint32_t) bsa_entry_list_count(bsa_entry_list_t entry_list) +{ + return 0; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_add(bsa_entry_list_t entry_list, const wchar_t *entry_string) +{ + return {0}; +} + +BSARCH_DLL_API(uint32_t) +bsa_entry_list_get(bsa_entry_list_t entry_list, uint32_t index, uint32_t string_buffer_size, wchar_t *string_buffer) +{ + return 0; +} + +BSARCH_DLL_API(bsa_archive_t) bsa_create() +{ + return nullptr; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *file_path) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_create_archive(bsa_archive_t archive, + const wchar_t *file_path, + bsa_archive_type_t archive_type, + bsa_entry_list_t entry_list) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *source_path) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_add_file_from_disk_root(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *source_path) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *file_path, uint32_t size, bsa_buffer_t data) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *file_path) +{ + return nullptr; +} + +BSARCH_DLL_API(bsa_result_message_buffer_t) +bsa_extract_file_data_by_record(bsa_archive_t archive, bsa_file_record_t file_record) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_buffer_t) +bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *file_path) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, bsa_result_buffer_t file_data_result) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_extract_file(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *save_as) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context) +{ + return {0}; +} + +BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *file_path) +{ + return false; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_get_resource_list(bsa_archive_t archive, bsa_entry_list_t entry_result_list, const wchar_t *folder) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) +bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list) +{ + return {0}; +} + +BSARCH_DLL_API(bsa_result_message_t) bsa_close(bsa_archive_t archive) +{ + return {0}; +} + +BSARCH_DLL_API(uint32_t) bsa_filename_get(bsa_archive_t archive, uint32_t string_buffer_size, wchar_t *string_buffer) +{ + return 0; +} + +BSARCH_DLL_API(bsa_archive_type_t) bsa_archive_type_get(bsa_archive_t archive) +{ + return bsa_archive_type_t::baNone; +} + +BSARCH_DLL_API(uint32_t) bsa_version_get(bsa_archive_t archive) +{ + return 0; +} + +BSARCH_DLL_API(uint32_t) bsa_format_name_get(bsa_archive_t archive, uint32_t string_buffer_size, wchar_t *string_buffer) +{ + return 0; +} + +BSARCH_DLL_API(uint32_t) bsa_file_count_get(bsa_archive_t archive) +{ + return 0; +} + +BSARCH_DLL_API(uint32_t) bsa_archive_flags_get(bsa_archive_t archive) +{ + return 0; +} + +BSARCH_DLL_API(void) bsa_archive_flags_set(bsa_archive_t archive, uint32_t flags) +{ + return; +} + +BSARCH_DLL_API(uint32_t) bsa_file_flags_get(bsa_archive_t archive) +{ + return 0; +} + +BSARCH_DLL_API(void) bsa_file_flags_set(bsa_archive_t archive, uint32_t flags) +{ + return; +} + +BSARCH_DLL_API(bool) bsa_compress_get(bsa_archive_t archive) +{ + return false; +} + +BSARCH_DLL_API(void) bsa_compress_set(bsa_archive_t archive, bool flags) +{ + return; +} + +BSARCH_DLL_API(bool) bsa_share_data_get(bsa_archive_t archive) +{ + return false; +} + +BSARCH_DLL_API(void) bsa_share_data_set(bsa_archive_t archive, bool flags) +{ + return; +} + +BSARCH_DLL_API(void) +bsa_file_dds_info_callback_set(bsa_archive_t archive, bsa_file_dds_info_proc_t file_dds_info_proc, void *context) +{ + return; +} +} // namespace libbsarch +#endif diff --git a/libs/libbsarch/src/libbsarch.def b/libs/libbsarch/src/libbsarch.def new file mode 100644 index 0000000..d6386b0 --- /dev/null +++ b/libs/libbsarch/src/libbsarch.def @@ -0,0 +1,38 @@ +;DESCRIPTION "BSArch DLL" +EXPORTS + bsa_entry_list_create + bsa_entry_list_free + bsa_entry_list_count + bsa_entry_list_add + bsa_entry_list_get + bsa_create + bsa_free + bsa_load_from_file + bsa_create_archive + bsa_save + bsa_add_file_from_disk + bsa_add_file_from_disk_root + bsa_add_file_from_memory + bsa_find_file_record + bsa_extract_file_data_by_record + bsa_extract_file_data_by_filename + bsa_file_data_free + bsa_extract_file + bsa_iterate_files + bsa_file_exists + bsa_get_resource_list + bsa_close + bsa_filename_get + bsa_archive_type_get + bsa_version_get + bsa_format_name_get + bsa_file_count_get + bsa_archive_flags_get + bsa_archive_flags_set + bsa_file_flags_get + bsa_file_flags_set + bsa_compress_get + bsa_compress_set + bsa_share_data_get + bsa_share_data_set + bsa_file_dds_info_callback_set diff --git a/libs/libbsarch/src/utils/convertible_ostream.cpp b/libs/libbsarch/src/utils/convertible_ostream.cpp new file mode 100644 index 0000000..d5ac238 --- /dev/null +++ b/libs/libbsarch/src/utils/convertible_ostream.cpp @@ -0,0 +1,58 @@ +/* Copyright (C) 2019 G'k + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#include "convertible_ostream.hpp" + +namespace libbsarch { +convertible_ostream &convertible_ostream::operator<<(const std::string &rh) +{ + std::cout << rh; + return *this; +} +convertible_ostream &convertible_ostream::operator<<(const char *rh) +{ + std::cout << rh; + return *this; +} +convertible_ostream &convertible_ostream::operator<<(const char rh) +{ + std::cout << rh; + return *this; +} +convertible_ostream &convertible_ostream::operator<<(const std::wstring &rh) +{ + std::wcout << rh; + return *this; +} +convertible_ostream &convertible_ostream::operator<<(const void *rh) +{ + std::cout << rh; + return *this; +} +convertible_ostream &convertible_ostream::operator<<(const convertible_string &rh) +{ + return *this << std::string(rh); +} + +convertible_ostream::operator std::ostream &() +{ + return std::cout; +} +convertible_ostream::operator std::wostream &() +{ + return std::wcout; +} + +#ifdef LIBBSARCH_QT_SUPPORT +convertible_ostream::operator QDebug() +{ + return qDebug(); +} +convertible_ostream &convertible_ostream::operator<<(const QString &rh) +{ + qDebug() << rh; + return *this; +} +#endif +} // namespace libbsarch diff --git a/libs/libbsarch/src/utils/convertible_string.cpp b/libs/libbsarch/src/utils/convertible_string.cpp new file mode 100644 index 0000000..c965202 --- /dev/null +++ b/libs/libbsarch/src/utils/convertible_string.cpp @@ -0,0 +1,108 @@ +/* Copyright (C) 2019 G'k + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "convertible_string.hpp" +#include <cwchar> +#include <filesystem> + +namespace libbsarch { +/* conversion ctors */ +convertible_string::convertible_string(std::string value, bool to_native_path) + : str_(std::move(value)) + , auto_convert_to_native_path(to_native_path) +{ + if (auto_convert_to_native_path) + this->to_native_path(); +} + +convertible_string::convertible_string(const char *const val_array, bool to_native_path) + : str_(std::string(val_array)) + , auto_convert_to_native_path(to_native_path) + +{ + if (auto_convert_to_native_path) + this->to_native_path(); +} +convertible_string::convertible_string(const std::wstring &wvalue, bool to_native_path) + : str_(to_string(wvalue)) + , auto_convert_to_native_path(to_native_path) + +{ + if (auto_convert_to_native_path) + this->to_native_path(); +} +convertible_string::convertible_string(wchar_t const *wval_array, bool to_native_path) + : str_(to_string(std::wstring(wval_array))) + , auto_convert_to_native_path(to_native_path) +{ + if (auto_convert_to_native_path) + this->to_native_path(); +} + +/* assignment operators */ +convertible_string &convertible_string::operator=(const std::string &value) +{ + str_ = value; + if (auto_convert_to_native_path) + this->to_native_path(); + return *this; +} +convertible_string &convertible_string::operator=(const std::wstring &wvalue) +{ + str_ = to_string(wvalue); + if (auto_convert_to_native_path) + this->to_native_path(); + return *this; +} + +convertible_string &convertible_string::operator=(const wchar_t *wvalue) +{ + str_ = to_string(std::wstring(wvalue)); + if (auto_convert_to_native_path) + this->to_native_path(); + return *this; +} + +/* implicit conversion operators */ +convertible_string::operator std::string() const +{ + return str_; +} +convertible_string::operator std::wstring() const +{ + return to_wstring(str_); +} +convertible_string::operator const wchar_t *() const +{ + const std::wstring wstr = to_wstring(str_); + wchar_t *wchar_array = new wchar_t[wstr.length() + 1]; +#ifdef _WIN32 + wcscpy_s(wchar_array, wstr.length() + 1, wstr.c_str()); +#else + std::wmemcpy(wchar_array, wstr.c_str(), wstr.length() + 1); +#endif + return wchar_array; +} + +/* Util */ +bool convertible_string::remove_substring(const convertible_string &sub_str) +{ + size_t pos = str_.find(sub_str); + if (pos != std::string::npos) + { + str_.erase(pos, std::string(sub_str).length()); + return true; + } + return false; +} + +convertible_string &convertible_string::to_native_path() +{ + std::filesystem::path path(str_); + str_ = path.make_preferred().string(); + return *this; +} + +} // namespace libbsarch diff --git a/libs/libbsarch/src/utils/string_convert.cpp b/libs/libbsarch/src/utils/string_convert.cpp new file mode 100644 index 0000000..1e8ce9e --- /dev/null +++ b/libs/libbsarch/src/utils/string_convert.cpp @@ -0,0 +1,39 @@ +/* Copyright (C) 2019 G'k + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#include "string_convert.hpp" + +#include <cstdlib> +#include <cstring> + +namespace libbsarch { + +std::string to_string(const std::wstring &str) +{ + if (str.empty()) return {}; + std::mbstate_t state{}; + const wchar_t* src = str.data(); + std::size_t len = std::wcsrtombs(nullptr, &src, 0, &state); + if (len == static_cast<std::size_t>(-1)) return {}; + std::string result(len, '\0'); + src = str.data(); + state = std::mbstate_t{}; + std::wcsrtombs(result.data(), &src, len + 1, &state); + return result; +} + +std::wstring to_wstring(const std::string &str) +{ + if (str.empty()) return {}; + std::mbstate_t state{}; + const char* src = str.data(); + std::size_t len = std::mbsrtowcs(nullptr, &src, 0, &state); + if (len == static_cast<std::size_t>(-1)) return {}; + std::wstring result(len, L'\0'); + src = str.data(); + state = std::mbstate_t{}; + std::mbsrtowcs(result.data(), &src, len + 1, &state); + return result; +} +} // namespace libbsarch |
