Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ target_compile_features(trx PUBLIC cxx_std_17)

target_link_libraries(trx
PUBLIC
${TRX_LIBZIP_TARGET}
${TRX_EIGEN3_TARGET}
PRIVATE
${TRX_LIBZIP_TARGET}
)
target_include_directories(trx
PUBLIC
Expand All @@ -202,8 +203,8 @@ get_target_property(_trx_libzip_includes ${TRX_LIBZIP_TARGET} INTERFACE_INCLUDE_
if(NOT _trx_libzip_includes)
find_path(TRX_LIBZIP_INCLUDE_DIR zip.h)
if(TRX_LIBZIP_INCLUDE_DIR)
target_include_directories(trx PUBLIC
$<BUILD_INTERFACE:${TRX_LIBZIP_INCLUDE_DIR}>
target_include_directories(trx PRIVATE
${TRX_LIBZIP_INCLUDE_DIR}
)
else()
message(FATAL_ERROR "libzip headers not found. Set TRX_LIBZIP_INCLUDE_DIR or fix libzip CMake targets.")
Expand Down Expand Up @@ -300,20 +301,19 @@ if(TRX_BUILD_DOCS)
endif()

# ── Installation and package config ─────────────────────────────────────────
# Installation requires that link dependencies are IMPORTED targets (so they
# don't need to be in the export set). This is the case when libzip and Eigen
# were found via find_package (libzip::zip, Eigen3::Eigen). When they were
# built via FetchContent (bare "zip" target), installation is not supported —
# the FetchContent path is a developer/CI convenience, not an installable
# configuration.
# CMake's install(EXPORT) requires that all link dependencies (even PRIVATE)
# are either IMPORTED targets or in the same export set. When libzip was built
# via FetchContent the bare "zip" target is neither, so install must be skipped.
if(TRX_ENABLE_INSTALL AND TARGET zip)
get_target_property(_zip_imported zip IMPORTED)
if(NOT _zip_imported)
get_target_property(_zip_aliased zip ALIASED_TARGET)
if(NOT _zip_imported AND NOT _zip_aliased)
message(STATUS "trx-cpp: skipping install — libzip was built via FetchContent. "
"Install libzip separately and reconfigure to enable installation.")
set(TRX_ENABLE_INSTALL OFF)
endif()
unset(_zip_imported)
unset(_zip_aliased)
endif()

if(TRX_ENABLE_INSTALL)
Expand Down
4 changes: 2 additions & 2 deletions cmake/trx-cppConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(libzip)
find_dependency(Eigen3)
# mio is header-only and vendored; no package required
# mio and json11 are header-only and vendored; no package required
# libzip is a PRIVATE dependency — consumers do not need it

include("${CMAKE_CURRENT_LIST_DIR}/trx-cppTargets.cmake")

Expand Down
93 changes: 34 additions & 59 deletions include/trx/trx.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
#include <utility>
#include <vector>
#include <thread>
#include <zip.h>


#include <mio/mmap.hpp>
#include <mio/shared_mmap.hpp>

#include <trx/detail/exceptions.h>
#include <trx/detail/zip_raii.h>


namespace trx {
namespace fs = std::filesystem;
Expand All @@ -47,6 +47,8 @@ using json = json11::Json;
namespace trx {
enum class TrxSaveMode { Auto, Archive, Directory };

enum class TrxCompression { None, Deflate };

enum class TrxScalarType { Float16, Float32, Float64 };

enum class ConnectivityMeasure {
Expand All @@ -61,7 +63,7 @@ struct ConnectivityMatrixResult {
};

struct TrxSaveOptions {
zip_uint32_t compression_standard = ZIP_CM_STORE;
TrxCompression compression = TrxCompression::None;
TrxSaveMode mode = TrxSaveMode::Auto;
size_t memory_limit_bytes = 0; // Reserved for future save-path tuning.
bool overwrite_existing = true;
Expand Down Expand Up @@ -121,30 +123,7 @@ inline std::string to_utf8_string(const trx::fs::path &path) {
#endif
}

inline zip_t *open_zip_for_read(const std::string &path, int &errorp) {
zip_t *zf = zip_open(path.c_str(), 0, &errorp);
if (zf != nullptr) {
return zf;
}

const trx::fs::path fs_path(path);
const std::string generic = fs_path.generic_string();
if (generic != path) {
zf = zip_open(generic.c_str(), 0, &errorp);
if (zf != nullptr) {
return zf;
}
}

#if defined(_WIN32) || defined(_WIN64)
const std::string u8 = to_utf8_string(fs_path);
if (!u8.empty() && u8 != path && u8 != generic) {
zf = zip_open(u8.c_str(), 0, &errorp);
}
#endif

return zf;
}

template <typename T> struct DTypeName {
static constexpr bool supported = false;
Expand Down Expand Up @@ -330,9 +309,9 @@ template <typename DT> class TrxFile {
* @brief Save a TrxFile
*
* @param filename The path to save the TrxFile to
* @param compression_standard The compression standard to use, as defined by libzip (default: no compression)
* @param compression Compression method (default: no compression).
*/
void save(const std::string &filename, zip_uint32_t compression_standard = ZIP_CM_STORE);
void save(const std::string &filename, TrxCompression compression = TrxCompression::None);
void save(const std::string &filename, const TrxSaveOptions &options);
/**
* @brief Normalize in-memory arrays for deterministic save semantics.
Expand Down Expand Up @@ -723,7 +702,7 @@ class AnyTrxFile {
size_t num_vertices() const;
size_t num_streamlines() const;
void close();
void save(const std::string &filename, zip_uint32_t compression_standard = ZIP_CM_STORE);
void save(const std::string &filename, TrxCompression compression = TrxCompression::None);
void save(const std::string &filename, const TrxSaveOptions &options);

const TypedArray *get_dps(const std::string &name) const;
Expand Down Expand Up @@ -852,10 +831,10 @@ class TrxStream {
/**
* @brief Finalize and write a TRX file.
*/
template <typename DT> void finalize(const std::string &filename, zip_uint32_t compression_standard = ZIP_CM_STORE);
template <typename DT> void finalize(const std::string &filename, TrxCompression compression = TrxCompression::None);
void finalize(const std::string &filename,
TrxScalarType output_dtype,
zip_uint32_t compression_standard = ZIP_CM_STORE);
TrxCompression compression = TrxCompression::None);
void finalize(const std::string &filename, const TrxSaveOptions &options);

/**
Expand Down Expand Up @@ -955,15 +934,6 @@ class TrxStream {
*/
json assignHeader(const json &root);

/**
* This function loads the header json file
* stored within a Zip archive
*
* @param[in] zfolder a pointer to an opened zip archive
* @param[out] header the JSONCpp root of the header. nullptr on error.
*
* */
json load_header(zip_t *zfolder);

/**
* Load the TRX file stored within a Zip archive.
Expand Down Expand Up @@ -1052,7 +1022,7 @@ PositionsOutputInfo prepare_positions_output(const AnyTrxFile &input,
struct MergeTrxShardsOptions {
std::vector<std::string> shard_directories;
std::string output_path;
zip_uint32_t compression_standard = ZIP_CM_STORE;
TrxCompression compression = TrxCompression::None;
bool output_directory = false;
bool overwrite_existing = true;
};
Expand Down Expand Up @@ -1325,22 +1295,28 @@ void ediff1d(Eigen::Matrix<DT, Eigen::Dynamic, 1> &lengths,
* @tparam DT
* @param trx The TrxFile to save
* @param filename The path to save the TrxFile to
* @param compression_standard The compression standard to use, as defined by libzip (default: no
* compression)
* @param compression Compression method (default: no compression).
*/

/**
* @brief Extract a TRX zip archive to a temporary directory.
*
* Returns the path to the temporary directory containing the extracted files.
*/
std::string extract_trx_archive(const std::string &zip_path);

/**
* @brief Utils function to zip on-disk memmaps
* @brief Create a TRX zip archive from an on-disk directory.
*
* @param directory The path to the on-disk memmap
* @param filename The path where the zip file should be created
* @param compression_standard The compression standard to use, as defined by the ZipFile library
* Creates the archive at @p filename, compresses the contents of @p source_dir
* into it, optionally adding a converted-positions entry.
*/
void zip_from_folder(zip_t *zf,
const std::string &root,
const std::string &directory,
zip_uint32_t compression_standard = ZIP_CM_STORE,
const std::unordered_set<std::string> *skip = nullptr);
void write_trx_archive(const std::string &filename,
const std::string &source_dir,
TrxCompression compression,
const std::string &converted_positions_path = "",
const std::string &converted_positions_entry = "",
const std::unordered_set<std::string> *skip = nullptr);

std::string get_base(const std::string &delimiter, const std::string &str);
std::string get_ext(const std::string &str);
Expand All @@ -1350,7 +1326,6 @@ void copy_dir(const std::string &src, const std::string &dst);
void copy_file(const std::string &src, const std::string &dst);
int rm_dir(const std::string &d);
std::string make_temp_dir(const std::string &prefix);
std::string extract_zip_to_directory(zip_t *zfolder);

std::string rm_root(const std::string &root, const std::string &path);

Expand All @@ -1363,13 +1338,13 @@ std::string rm_root(const std::string &root, const std::string &path);
*
* @param path Path to an existing TRX zip file (.trx).
* @param groups Map from group name to sorted vector of uint32 streamline indices.
* @param compression Compression method for new entries (default: ZIP_CM_STORE).
* @param compression Compression method for new entries (default: TrxCompression::None).
* @param overwrite If false, existing entries with the same name are skipped (default: true).
* @throws TrxIOError on any zip failure.
*/
void append_groups_to_zip(const std::string &path,
const std::map<std::string, std::vector<uint32_t>> &groups,
zip_uint32_t compression = ZIP_CM_STORE, bool overwrite = true);
TrxCompression compression = TrxCompression::None, bool overwrite = true);

/**
* @brief Append named groups to an existing TRX directory.
Expand All @@ -1396,12 +1371,12 @@ void append_groups_to_directory(const std::string &directory,
*
* @param path Path to an existing TRX zip file (.trx).
* @param dps Map from array name to TypedArray (e.g. AnyTrxFile::data_per_streamline).
* @param compression Compression method for new entries (default: ZIP_CM_STORE).
* @param compression Compression method for new entries (default: TrxCompression::None).
* @param overwrite If false, existing entries with the same name are skipped (default: true).
* @throws TrxIOError on any zip failure.
*/
void append_dps_to_zip(const std::string &path, const std::map<std::string, TypedArray> &dps,
zip_uint32_t compression = ZIP_CM_STORE, bool overwrite = true);
TrxCompression compression = TrxCompression::None, bool overwrite = true);

/**
* @brief Append per-streamline data arrays to an existing TRX directory.
Expand All @@ -1427,12 +1402,12 @@ void append_dps_to_directory(const std::string &directory,
*
* @param path Path to an existing TRX zip file (.trx).
* @param dpv Map from array name to TypedArray (e.g. AnyTrxFile::data_per_vertex).
* @param compression Compression method for new entries (default: ZIP_CM_STORE).
* @param compression Compression method for new entries (default: TrxCompression::None).
* @param overwrite If false, existing entries with the same name are skipped (default: true).
* @throws TrxIOError on any zip failure.
*/
void append_dpv_to_zip(const std::string &path, const std::map<std::string, TypedArray> &dpv,
zip_uint32_t compression = ZIP_CM_STORE, bool overwrite = true);
TrxCompression compression = TrxCompression::None, bool overwrite = true);

/**
* @brief Append per-vertex data arrays to an existing TRX directory.
Expand Down
Loading
Loading