diff --git a/.gitea/workflows/CI-nix.yaml b/.gitea/workflows/CI-nix.yaml new file mode 100644 index 0000000..4e17e27 --- /dev/null +++ b/.gitea/workflows/CI-nix.yaml @@ -0,0 +1,58 @@ +name: Gitea Actions Demo +run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +on: [push] + +jobs: + Explore-Gitea-Actions: + runs-on: nixos-latest + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" + - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." + - name: install node + run: nix-env -iA nixpkgs.nodejs_20 + - name: Check out repository code + #uses: actions/checkout@v4 + uses: https://gitea.com/ScMi1/checkout@v1.4 + with: + submodules: false + - run: | + git submodule update --init + - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." + - run: echo "🖥️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + printenv | sort + ls ${{ gitea.workspace }} + - name: compute dependencies cache hash + id: cache_hash + shell: bash + run: | + HASH=$(sha256sum <(git submodule | cut -d ' ' -f 2) | cut -d ' ' -f 1) + echo "hash=$HASH" >> $GITHUB_OUTPUT + echo "output: hash=$HASH" + - name: cache dependencies + id: caching + uses: actions/cache@v4 + with: + key: ${{ steps.cache_hash.outputs.hash }} + path: | + ext/Linux_* + ext/Darwin_* + ext/xWindows_* + - name: compile dependencies + run: | + nix-shell --run "make -C ext" + - name: build project + shell: nix-shell --run "{0}" + run: | + mkdir -vp build + cd build + cmake --fresh -G Ninja -DCMAKE_BUILD_TYPE=Debug .. + ninja + - name: test project + shell: nix-shell --run "{0}" + run: | + cd build + ./tests/cpp/utelykseer-cpp --report_level=detailed + - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6223bce..af3420e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -29,14 +29,6 @@ jobs: sudo apt update sudo apt-get -y install cmake ninja-build clang-19 clang-tools-19 cppcheck m4 busybox libdigest-sha3-perl libboost-all-dev libboost-contract-dev gettext pkg-config automake autoconf libtool texinfo -# - name: Set up cache on external code -# uses: actions/cache@v2 -# with: -# path: ext -# key: ${{ runner.os }}-ext-${{ hashFiles('**/CMakeLists.txt') }} -# restore-keys: | -# ${{ runner.os }}-ext- - - name: Update submodules shell: bash working-directory: ${{github.workspace}}/ @@ -44,33 +36,36 @@ jobs: mkdir -vp build git submodule update --init + - name: compute dependencies cache hash + id: cache_hash + shell: bash + run: | + HASH=$(sha256sum <(git submodule | cut -d ' ' -f 2) | cut -d ' ' -f 1) + echo "hash=$HASH" >> $GITHUB_OUTPUT + echo "output: hash=$HASH" + - name: cache dependencies + id: caching + uses: actions/cache@v4 + with: + key: ${{ steps.cache_hash.outputs.hash }} + path: | + ext/Linux_* + ext/Darwin_* + ext/xWindows_* + - name: Build dependencies shell: bash working-directory: ${{github.workspace}}/ext run: make - - name: Set up cache on build dir - uses: actions/cache@v2 - with: - path: build - key: ${{ runner.os }}-build-${{ hashFiles('**/CMakeLists.txt') }} - restore-keys: | - ${{ runner.os }}-build- - - name: Configure CMake - # Use a bash shell so we can use the same syntax for environment variable - # access regardless of the host operating system shell: bash working-directory: ${{github.workspace}}/build - # Note the current convention is to use the -S and -B options here to specify source - # and build directories, but this is only available with CMake 3.13 and higher. - # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 run: cmake --fresh -GNinja -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. - name: Build working-directory: ${{github.workspace}}/build shell: bash - # Execute the build. You can specify a specific target with "--target " run: cmake --build . --config $BUILD_TYPE - name: Test @@ -79,7 +74,7 @@ jobs: # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail #run: ctest -C $BUILD_TYPE - run: ctest + run: ./tests/cpp/utelykseer-cpp --report_level=detailed - name: Packaging working-directory: ${{github.workspace}}/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f32492..c6e4dc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,8 +24,8 @@ project(elykseer-cpp LANGUAGES CXX) # The version number. set (${PROJECT_NAME}_VERSION_MAJOR 4) -set (${PROJECT_NAME}_VERSION_MINOR 0) -set (${PROJECT_NAME}_VERSION_PATCH 1) +set (${PROJECT_NAME}_VERSION_MINOR 1) +set (${PROJECT_NAME}_VERSION_PATCH 0) set (${PROJECT_NAME}_VERSION_STRING ${elykseer-cpp_VERSION_MAJOR}.${elykseer-cpp_VERSION_MINOR}.${elykseer-cpp_VERSION_PATCH}) # set to '-DDEBUG' to turn on debugging output diff --git a/ext/Makefile b/ext/Makefile index fe6ffe5..b51c3eb 100644 --- a/ext/Makefile +++ b/ext/Makefile @@ -54,6 +54,8 @@ makedirs: $(CCACHE_DIR) $(HOST_TARGETDIR) $(WIN64_TARGETDIR) $(CCACHE_DIR) $(HOST_TARGETDIR) $(WIN64_TARGETDIR): mkdir -vp $@ + mkdir -vp $@/lib + ln -sf $@/lib $@/lib64 check_cross_compilers: check_cc check_cxx check_ar check_ranlib check_ar: @@ -116,11 +118,11 @@ $(fset_elykseer_crypto): if [ -z "$(CROSS_COMPILATION)" ]; then \ $(MAKE) -C ext; \ mkdir -vp build; cd build; \ - cmake --fresh -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} --install-prefix "${TARGETDIR}" -G Ninja .. ; \ + cmake --fresh -DUSE_OPENSSL=ON -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} --install-prefix "${TARGETDIR}" -G Ninja .. ; \ else \ $(MAKE) -C ext xWin64; \ cd build; \ - cmake --fresh -DCMAKE_TOOLCHAIN_FILE=${XCOMPILE_TOOLCHAIN} -DCMAKE_BUILD_TYPE=Release --install-prefix "${TARGETDIR}" -G "${CMAKE_GENERATOR}" . ; \ + cmake --fresh -DUSE_OPENSSL=ON -DCMAKE_TOOLCHAIN_FILE=${XCOMPILE_TOOLCHAIN} -DCMAKE_BUILD_TYPE=Release --install-prefix "${TARGETDIR}" -G "${CMAKE_GENERATOR}" . ; \ fi; \ ninja; \ ninja install; diff --git a/ext/elykseer-crypto b/ext/elykseer-crypto index 44a29f5..c6078d4 160000 --- a/ext/elykseer-crypto +++ b/ext/elykseer-crypto @@ -1 +1 @@ -Subproject commit 44a29f5bf75a8dbb0f3ef21b94bf97a45b0b60b4 +Subproject commit c6078d48abfa6bbf44c06f1a8508751ee4c73e5b diff --git a/ext/rapidcheck b/ext/rapidcheck index 1c91f40..ff6af6f 160000 --- a/ext/rapidcheck +++ b/ext/rapidcheck @@ -1 +1 @@ -Subproject commit 1c91f40e64d87869250cfb610376c629307bf77d +Subproject commit ff6af6fc683159deb51c543b065eba14dfcf329b diff --git a/shell.nix b/shell.nix index e885e4c..f3c6b5a 100644 --- a/shell.nix +++ b/shell.nix @@ -8,17 +8,21 @@ stdenv.mkDerivation rec { # Customizable development requirements nativeBuildInputs = [ cmake + ninja + ccache git gnused - pandoc - html2text + gettext + texinfo swig - #gcc - clang + gcc + llvmPackages_19.clang-tools + llvmPackages_19.openmp + lldb_19 + clang_19 opam m4 - #global cppcheck - #busybox + perl perl538Packages.DigestSHA3 pkg-config autoconf automake libtool @@ -29,7 +33,8 @@ stdenv.mkDerivation rec { buildInputs = [ openssl zlib - boost + zstd + boost186 ]; shellHook = '' @@ -39,7 +44,6 @@ stdenv.mkDerivation rec { else export SED=sed fi - export SED=sed export CC=clang export CXX=clang++ ''; diff --git a/src/cpp/cli/lxrbackup.cpp b/src/cpp/cli/lxrbackup.cpp index 1c06bb8..6cfe06b 100644 --- a/src/cpp/cli/lxrbackup.cpp +++ b/src/cpp/cli/lxrbackup.cpp @@ -95,7 +95,7 @@ void output_help() { std::cout << "--dry-run just validate arguments" << std::endl; std::cout << "-x --pX sets output path for encrypted chunks" << std::endl; std::cout << "-o --pD sets output path for meta data" << std::endl; - std::cout << "-n --nchunks sets number of chunks (16-256) per assembly" << std::endl; + std::cout << "-n --nchunks sets number of chunks (16-128) per assembly" << std::endl; // std::cout << "-c --compression sets compression (0 or 1)" << std::endl; // std::cout << "-u --deduplication sets duplication mode (0, 1 or 2)" << std::endl; std::cout << "--refdbfi adds reference dbfi for deduplication (*)" << std::endl; @@ -183,10 +183,10 @@ void set_backup_dir_rec(std::string const fp) { void set_n_chunks(std::optional &nchunks, std::string const p) { int n = atoi(p.c_str()); - if (n >= 16 && n <= 256) { + if (n >= 16 && n <= 128) { nchunks = n; } else { - std::clog << "number of chunks, out of range (16-256): " << p << std::endl; + std::clog << "number of chunks, out of range (16-128): " << p << std::endl; output_error(); } } diff --git a/src/cpp/cli/lxrrestore.cpp b/src/cpp/cli/lxrrestore.cpp index e07e376..4a9baa4 100644 --- a/src/cpp/cli/lxrrestore.cpp +++ b/src/cpp/cli/lxrrestore.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -188,10 +189,10 @@ void set_myid(std::optional &myid, std::string const p) { void set_n_chunks(std::optional &nchunks, std::string const p) { int n = atoi(p.c_str()); - if (n >= 16 && n <= 256) { + if (n >= 16 && n <= 128) { nchunks = n; } else { - std::clog << "number of chunks, out of range (16-256): " << p << std::endl; + std::clog << "number of chunks, out of range (16-128): " << p << std::endl; output_error(); } } @@ -322,7 +323,7 @@ int main (int argc, char * const argv[]) { #ifdef DEBUG std::clog << " open file " << fp.c_str() << std::endl; #endif - FILE *tgt = fopen(fp.c_str(), "wx"); + std::ofstream tgt(fp, std::ios::binary); if (tgt) { #ifdef DEBUG std::clog << " file ready." << std::endl; @@ -333,7 +334,7 @@ int main (int argc, char * const argv[]) { #ifdef DEBUG std::clog << " fseek to " << rqr._readrequest._fpos << std::endl; #endif - fseek(tgt, rqr._readrequest._fpos, SEEK_SET); + tgt.seekp(rqr._readrequest._fpos); #ifdef DEBUG std::clog << " writing " << rqr._rresult->len() << " bytes" << std::endl; #endif @@ -354,7 +355,7 @@ int main (int argc, char * const argv[]) { } } process_read_blocks(qac->iterate_read_queue()); - fclose(tgt); + tgt.close(); } } } diff --git a/src/cpp/coqassembly.cpp b/src/cpp/coqassembly.cpp index 04b7c43..3086cf9 100644 --- a/src/cpp/coqassembly.cpp +++ b/src/cpp/coqassembly.cpp @@ -20,6 +20,7 @@ module; #include #include +#include #include #include #include @@ -118,12 +119,17 @@ CoqAssemblyPlainWritable::CoqAssemblyPlainWritable(const CoqConfiguration &c) // std::clog << "CoqAssemblyPlainWritable::CoqAssemblyPlainWritable(const CoqConfiguration &c)" << std::endl; const Nchunks& nchunks = c.nchunks(); _buffer.reset(new CoqBufferPlain(assemblysize(nchunks))); - Key128 _rand128{false}; - const char *r = (const char*)_rand128.bytes(); - for (int i = 0; i < 16; i++) { - _buffer->at(idx2apos(i,nchunks), r[i]); + uint32_t _rand32; + uint32_t idx{0}; + while (idx < nchunks.u()) { + _rand32 = Random::rng().random(); + const unsigned char *r = (const unsigned char[4])_rand32; + for (int i = 0; i < 4; i++) { + _buffer->at(idx, r[i]); + } + idx += 4; } - _assemblyinformation._apos = 16; + _assemblyinformation._apos = nchunks.u(); _assemblyinformation._nchunks = nchunks; mk_assembly_id(); } @@ -357,13 +363,12 @@ CoqAssembly::BlockInformation CoqAssemblyPlainWritable::backup(const CoqBufferPl CoqAssembly::BlockInformation CoqAssemblyPlainWritable::backup(const CoqBufferPlain &b, const uint32_t offset, const uint32_t dlen) { uint32_t apos_n = _assemblyinformation._apos; - const Nchunks nchunks = _config.nchunks(); if (dlen + offset > b.len()) { return {}; } auto const chksum = b.calc_checksum(offset, dlen); if (chksum) { // TODO parallelise ! for (int i = 0; i < dlen; i++) { - uint32_t apos = idx2apos(i + apos_n, nchunks); + uint32_t apos = idx2apos(i + apos_n); _buffer->at(apos, b.at(i + offset)); } _assemblyinformation._apos += dlen; @@ -398,7 +403,7 @@ uint32_t CoqAssemblyEncrypted::extract() if (const auto cfpathopt = chunk_path(cid, aid); cfpathopt) { const std::filesystem::path cfpath = cfpathopt.value(); if (! std::filesystem::exists(cfpath)) { - if (FILE * fstr = fopen(cfpath.string().c_str(), "wb"); fstr) { + if (std::ofstream fstr(cfpath, std::ios::binary); fstr.good()) { #ifdef DEBUG std::clog << " extract chunk " << cid << " to path " << cfpath << std::endl; #endif @@ -407,7 +412,7 @@ uint32_t CoqAssemblyEncrypted::extract() } else { std::clog << "only wrote " << n << " bytes to chunk with path " << cfpath.string() << std::endl; } - fclose(fstr); + fstr.close(); } else { std::clog << "cannot write to chunk with path " << cfpath.string() << std::endl; } @@ -459,7 +464,7 @@ std::shared_ptr CoqAssemblyEncrypted::recall(const CoqConf if (const auto cfpathopt = newassembly->chunk_path(cid, aid); cfpathopt) { const std::filesystem::path cfpath = cfpathopt.value(); if (std::filesystem::exists(cfpath)) { - if (FILE * fstr = fopen(cfpath.string().c_str(), "rb"); fstr) { + if (std::ifstream fstr(cfpath, std::ios::binary); fstr.good()) { #ifdef DEBUG std::clog << " recall chunk " << cid << " from path " << cfpath << std::endl; #endif @@ -468,7 +473,7 @@ std::shared_ptr CoqAssemblyEncrypted::recall(const CoqConf } else { std::clog << "only read " << n << " bytes from chunk with path " << cfpath.string() << std::endl; } - fclose(fstr); + fstr.close(); } else { std::clog << "cannot read from chunk with path " << cfpath.string() << std::endl; } @@ -499,9 +504,8 @@ Program Definition restore (b : AssemblyPlainFull.B) (bi : blockinformation) : o std::shared_ptr CoqAssemblyPlainFull::restore(const CoqAssembly::BlockInformation & bi) const { std::shared_ptr b{new CoqBufferPlain(bi.blocksize)}; - const Nchunks& nchunks = _config.nchunks(); for (uint32_t idx = 0; idx < bi.blocksize; idx++) { - uint32_t apos = idx2apos(idx + bi.blockapos, nchunks); + uint32_t apos = idx2apos(idx + bi.blockapos); b->at(idx, _buffer->at(apos)); } return b; diff --git a/src/cpp/coqassembly.ixx b/src/cpp/coqassembly.ixx index 6b1d1d4..685e980 100644 --- a/src/cpp/coqassembly.ixx +++ b/src/cpp/coqassembly.ixx @@ -84,16 +84,17 @@ class CoqAssembly virtual int buffer_len() const = 0; virtual std::optional calc_checksum() const = 0; virtual std::optional chunk_path(const uint16_t cnum, const aid_t aid) const final; - - public: + + public: virtual int apos() const final; virtual int afree() const final; virtual std::string aid() const final; - inline const uint32_t idx2apos (const uint32_t idx, const Nchunks & nchunks) const { - uint32_t nc = nchunks.u(); - uint32_t cnum = idx % nc; - uint32_t cidx = idx / nc; - return cnum * CoqAssembly::chunksize + cidx; + const uint32_t idx2apos (const uint32_t idx) const { + uint32_t nc = _assemblyinformation._nchunks.u(); + uint32_t asize = assemblysize(_assemblyinformation._nchunks); + uint32_t eff_asize = asize - nc; + uint32_t proj = idx * nc; + return (proj % eff_asize) + floor(proj / eff_asize) + nc; } protected: diff --git a/src/cpp/coqbuffer.cpp b/src/cpp/coqbuffer.cpp index 416c6e7..688c17a 100644 --- a/src/cpp/coqbuffer.cpp +++ b/src/cpp/coqbuffer.cpp @@ -19,6 +19,7 @@ module; */ #include +#include #include #include #include @@ -55,8 +56,8 @@ struct CoqBuffer::pimpl { uint32_t len() const; std::optional calc_checksum(int offset, int dlen) const; int copy_sz_pos(int pos0, int sz, CoqBuffer &target, int pos1) const; - int fileout_sz_pos(int pos, int sz, FILE *fstr) const; - int filein_sz_pos(int pos, int sz, FILE *fstr); + int fileout_sz_pos(int pos, int sz, std::ofstream & fstr) const; + int filein_sz_pos(int pos, int sz, std::ifstream & fstr); int to_buffer(int n, char *b) const; char at(uint32_t idx0) const { return _buffer[std::min(_len, idx0)]; } void at(uint32_t idx0, char v) { _buffer[std::min(_len, idx0)] = v; } @@ -94,19 +95,20 @@ int CoqBuffer::pimpl::copy_sz_pos(int pos0, int sz, CoqBuffer &target, int pos1) return 0; } -int CoqBuffer::pimpl::fileout_sz_pos(int pos, int sz, FILE *fstr) const +int CoqBuffer::pimpl::fileout_sz_pos(int pos, int sz, std::ofstream & fstr) const { if (sz < 1 || pos < 0) { return 0; } if (sz + pos > _len) { return -1; } - fwrite(_buffer+pos, 1, sz, fstr); - return sz; + fstr.write(_buffer+pos, sz); + return fstr.good()?sz:-2; } -int CoqBuffer::pimpl::filein_sz_pos(int pos, int sz, FILE *fstr) +int CoqBuffer::pimpl::filein_sz_pos(int pos, int sz, std::ifstream & fstr) { if (sz < 1 || pos < 0) { return 0; } if (sz + pos > _len) { return -1; } - return fread(_buffer+pos, 1, sz, fstr); + fstr.read(_buffer+pos, sz); + return fstr.gcount(); } int CoqBuffer::pimpl::to_buffer(int n, char *b) const @@ -265,18 +267,18 @@ int CoqBuffer::copy_sz_pos(int pos0, int sz, CoqBuffer &target, int pos1) const } } -int CoqBuffer::fileout_sz_pos(int pos, int sz, FILE *fstr) const +int CoqBuffer::fileout_sz_pos(int pos, int sz, std::ofstream & fstr) const { - if (_pimpl && fstr) { + if (_pimpl && fstr.good()) { return _pimpl->fileout_sz_pos(pos, sz, fstr); } else { return -1; } } -int CoqBuffer::filein_sz_pos(int pos, int sz, FILE *fstr) +int CoqBuffer::filein_sz_pos(int pos, int sz, std::ifstream & fstr) { - if (_pimpl && fstr) { + if (_pimpl && fstr.good()) { return _pimpl->filein_sz_pos(pos, sz, fstr); } else { return -1; diff --git a/src/cpp/coqbuffer.ixx b/src/cpp/coqbuffer.ixx index 2de9494..b79fd1c 100644 --- a/src/cpp/coqbuffer.ixx +++ b/src/cpp/coqbuffer.ixx @@ -18,7 +18,7 @@ module; along with this program. If not, see . */ -#include +#include #include #include @@ -114,8 +114,8 @@ class CoqBuffer std::optional calc_checksum() const; std::optional calc_checksum(int offset, int dlen) const; int copy_sz_pos(int pos0, int sz, CoqBuffer & target, int pos1) const; - int fileout_sz_pos(int pos, int sz, FILE *fstr) const; - int filein_sz_pos(int pos, int sz, FILE *fstr); + int fileout_sz_pos(int pos, int sz, std::ofstream & fstr) const; + int filein_sz_pos(int pos, int sz, std::ifstream & fstr); int to_buffer(int n, char *b) const; char at(uint32_t idx) const; void at(uint32_t idx, char v); diff --git a/src/cpp/coqprocessor.cpp b/src/cpp/coqprocessor.cpp index 6f48274..8fa8c99 100644 --- a/src/cpp/coqprocessor.cpp +++ b/src/cpp/coqprocessor.cpp @@ -23,9 +23,9 @@ module; #include #include #include +#include #include #include -#include import lxr_sha3; import lxr_key256; @@ -144,7 +144,7 @@ std::optional CoqProcessor::file_backup(const s std::clog << "file_backup skipped for '" << fp << "' as it is the same as before." << std::endl; #endif } else { - FILE *fstr = fopen(fp.c_str(), "rb"); + std::ifstream fstr(fp, std::ios::binary); if (! fstr) { return {}; } { const uint64_t fsize{fi.fsize}; @@ -154,8 +154,9 @@ std::optional CoqProcessor::file_backup(const s auto dsz = fsize - fpos; int sz = block_sz; if (dsz < block_sz) { sz = dsz; } - fseek(fstr, fpos, SEEK_SET); - int nread = fread(buffer, 1, sz, fstr); + fstr.seekg(fpos); + fstr.read(buffer, sz); + int nread = fstr.gcount(); WriteQueueEntity wqe; wqe._fhash = fhash; @@ -170,7 +171,7 @@ std::optional CoqProcessor::file_backup(const s } _cache->iterate_write_queue(); } - fclose(fstr); + fstr.close(); _cache->get_finfo_store()->add(fhash.toHex(), fi); return fi; } diff --git a/src/cpp/coqstore.ixx b/src/cpp/coqstore.ixx index 8eeb518..1c95316 100644 --- a/src/cpp/coqstore.ixx +++ b/src/cpp/coqstore.ixx @@ -20,7 +20,6 @@ module; #include #include -// #include #include #include #include diff --git a/src/cpp/filectrl.cpp b/src/cpp/filectrl.cpp index 416d9bb..aa793b8 100644 --- a/src/cpp/filectrl.cpp +++ b/src/cpp/filectrl.cpp @@ -21,7 +21,6 @@ module; #include "generator.hpp" #include -typedef std::filesystem::path filepath; #include #include @@ -40,6 +39,8 @@ module lxr_filectrl; namespace lxr { +#if defined(PLATFORM_win64) +#else static uid_t fp_uid = getuid(); static gid_t fp_gid = getgid(); static std::vector fp_gids{}; @@ -55,34 +56,36 @@ void initialize_fp_gids() { fp_gids_initialised = true; } } +#endif -std::optional FileCtrl::fileLastWriteTime(filepath const & fp) noexcept +std::optional FileCtrl::fileLastWriteTime(std::filesystem::path const & fp) noexcept { try { return std::filesystem::last_write_time(fp); } catch (...) { return {}; } } -std::optional FileCtrl::fileSize(filepath const & fp) noexcept +std::optional FileCtrl::fileSize(std::filesystem::path const & fp) noexcept { try { return std::filesystem::file_size(fp); } catch (...) { return {}; } } -bool FileCtrl::fileExists(filepath const & fp) noexcept +bool FileCtrl::fileExists(std::filesystem::path const & fp) noexcept { try { return std::filesystem::exists(fp); } catch (...) { return {}; } } -bool FileCtrl::isFileReadable(filepath const & fp) noexcept +bool FileCtrl::isFileReadable(std::filesystem::path const & fp) noexcept { try { if (! std::filesystem::exists(fp)) { return false; } auto s = std::filesystem::status(fp); if (! std::filesystem::is_regular_file(s)) { return false; } +#if !defined(PLATFORM_win64) struct stat finfo; if (stat(fp.c_str(), &finfo) != 0) { return false; } auto we_are_owner = [&finfo]() -> bool { return finfo.st_uid == fp_uid; }; @@ -104,16 +107,18 @@ bool FileCtrl::isFileReadable(filepath const & fp) noexcept if (g == finfo.st_gid) { return true; } } } +#endif } catch (...) {} return false; } -bool FileCtrl::dirExists(filepath const & fp) noexcept +bool FileCtrl::dirExists(std::filesystem::path const & fp) noexcept { try { auto s = std::filesystem::status(fp); if (std::filesystem::is_symlink(s) && fp.string().find("../") != std::string::npos) { return false; } // prevent loop if (! std::filesystem::is_directory(s)) { return false; } +#if !defined(PLATFORM_win64) struct stat finfo; if (stat(fp.c_str(), &finfo) != 0) { return false; @@ -137,11 +142,12 @@ bool FileCtrl::dirExists(filepath const & fp) noexcept if (g == finfo.st_gid) { return true; } } } +#endif } catch (...) {} return false; } -std::generator FileCtrl::fileListRecursive(const filepath fp) +std::generator FileCtrl::fileListRecursive(const std::filesystem::path fp) { std::filesystem::directory_iterator dirit{fp}; while (dirit != std::filesystem::directory_iterator{}) { diff --git a/src/cpp/generator.hpp b/src/cpp/generator.hpp index e27ec1c..81b1da9 100644 --- a/src/cpp/generator.hpp +++ b/src/cpp/generator.hpp @@ -169,7 +169,7 @@ namespace std { static void* operator new(const size_t _Size) { // default: new/delete void* const _Ptr = ::operator new[](_Size + sizeof(_Dealloc_fn)); const _Dealloc_fn _Dealloc = [](void* const _Ptr, const size_t _Size) { - ::operator delete[](_Ptr, _Size + sizeof(_Dealloc_fn)); + ::operator delete[](_Ptr, (void*)(_Size + sizeof(_Dealloc_fn))); }; ::memcpy(static_cast(_Ptr) + _Size, &_Dealloc, sizeof(_Dealloc_fn)); return _Ptr; diff --git a/src/cpp/liz.cpp b/src/cpp/liz.cpp index f607208..da3b390 100644 --- a/src/cpp/liz.cpp +++ b/src/cpp/liz.cpp @@ -122,7 +122,7 @@ const std::string Liz::copyright() noexcept const std::string Liz::version() noexcept { - static std::string _enc = "VmVyc2lvbiA0LjAuMQ=="; + static std::string _enc = "VmVyc2lvbiA0LjEuMAo="; return decodeb64(_enc); } diff --git a/src/cpp/nchunks.ixx b/src/cpp/nchunks.ixx index 5040039..d4c0e79 100644 --- a/src/cpp/nchunks.ixx +++ b/src/cpp/nchunks.ixx @@ -30,7 +30,7 @@ class ChunkRange { public: static constexpr int min_n { 16 }; - static constexpr int max_n { 256 }; + static constexpr int max_n { 128 }; }; class Nchunks diff --git a/tests/cpp/utCoqAssembly.cpp b/tests/cpp/utCoqAssembly.cpp index 6564057..8dd65a2 100644 --- a/tests/cpp/utCoqAssembly.cpp +++ b/tests/cpp/utCoqAssembly.cpp @@ -21,10 +21,9 @@ #define BOOST_ALL_DYN_LINK #endif +#include #include #include -#include -#include #include "boost/test/unit_test.hpp" @@ -51,6 +50,29 @@ BOOST_AUTO_TEST_CASE( cannot_instantiate_CoqAssembly_directly ) } #endif +// Test case: calculate and verify some idx2apos values + +BOOST_AUTO_TEST_CASE( verify_idx2apos ) +{ + lxr::CoqConfiguration _config; + _config.nchunks(17); + lxr::CoqAssemblyPlainWritable _assembly(_config); + BOOST_CHECK_EQUAL(_assembly.apos(), 17); + + // map file position to assembly buffer position + uint32_t apos0 = _assembly.idx2apos(0); + uint32_t apos1 = _assembly.idx2apos(1); + BOOST_CHECK_EQUAL(apos1 - apos0, _config.nchunks().u()); + uint32_t apos2 = _assembly.idx2apos(2); + BOOST_CHECK_EQUAL(apos2 - apos1, _config.nchunks().u()); + // verify we never write to the first (nchunks) bytes in the assembly + for (int i = 0; i < _assembly.assemblysize(_config.nchunks()) - _config.nchunks().i(); i++) { + uint32_t apos = _assembly.idx2apos(i); + if (apos < _config.nchunks().u()) { printf(" i = %d\n", i); } + BOOST_CHECK_GE(apos, _config.nchunks().u()); + } +} + // Test case: create a _CoqAssemblyPlainWritable_ BOOST_AUTO_TEST_CASE( instantiate_CoqAssemblyPlainWritable ) @@ -102,13 +124,13 @@ BOOST_AUTO_TEST_CASE( backup_restore_roundtrip ) lxr::CoqAssemblyPlainWritable _assembly(_config); BOOST_CHECK_EQUAL(_assembly.buffer_len(), 17 * lxr::CoqAssembly::chunksize); - BOOST_CHECK_EQUAL(16, _assembly.apos()); + BOOST_CHECK_EQUAL(_config.nchunks().i(), _assembly.apos()); // backup const std::string msg{"good morning and hello world\n."}; lxr::CoqBufferPlain buffer(msg.length(), msg.c_str()); lxr::CoqAssembly::BlockInformation bi = _assembly.backup(buffer); - BOOST_CHECK_EQUAL(16 + msg.length(), _assembly.apos()); + BOOST_CHECK_EQUAL(_config.nchunks().i() + msg.length(), _assembly.apos()); // finish std::shared_ptr afinished = _assembly.finish(); @@ -121,21 +143,24 @@ BOOST_AUTO_TEST_CASE( backup_restore_roundtrip ) // encrypt lxr::CoqAssembly::KeyInformation ki(_config); - std::clog << "ivec: " << ki._ivec.toHex() << std::endl; - std::clog << "pkey: " << ki._pkey.toHex() << std::endl; + // std::clog << "ivec: " << ki._ivec.toHex() << std::endl; + // std::clog << "pkey: " << ki._pkey.toHex() << std::endl; std::shared_ptr aencrypted = afinished->encrypt(ki); // extract uint32_t n_ex = aencrypted->extract(); - + // recall std::shared_ptr arecalled = lxr::CoqAssemblyEncrypted::recall(_config, aencrypted->aid()); + aencrypted.reset(); // decrypt std::shared_ptr adecrypted = arecalled->decrypt(ki); + arecalled.reset(); // restore std::shared_ptr restored_block = adecrypted->restore(bi); + adecrypted.reset(); // test restored bytes BOOST_CHECK_EQUAL(bi.blocksize, msg.length());