From a8470a843313a5766e1f62cac191d71a0216094d Mon Sep 17 00:00:00 2001 From: ccutullic Date: Wed, 2 Sep 2026 14:53:40 +0200 Subject: [PATCH 1/8] feat: add new class ZipBuffer to manage zip/unzip data to/from buffer --- SolARFramework.pri | 2 + interfaces/core/ZipBuffer.h | 65 +++++++++++++ src/core/ZipBuffer.cpp | 180 ++++++++++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 interfaces/core/ZipBuffer.h create mode 100644 src/core/ZipBuffer.cpp diff --git a/SolARFramework.pri b/SolARFramework.pri index 1e499dc3..57be16d5 100644 --- a/SolARFramework.pri +++ b/SolARFramework.pri @@ -130,6 +130,7 @@ interfaces/core/Messages.h \ interfaces/core/SerializationDefinitions.h \ interfaces/core/SolARFramework.h \ interfaces/core/SolARFrameworkDefinitions.h \ +interfaces/core/ZipBuffer.h \ interfaces/datastructure/BufferInternal.hpp \ interfaces/datastructure/CameraDefinitions.h \ interfaces/datastructure/CameraParametersCollection.h \ @@ -191,6 +192,7 @@ src/datastructure/RelocalizationInformation.cpp \ src/datastructure/StorageCapabilities.cpp \ src/core/Log.cpp \ src/core/SolARFramework.cpp \ +src/core/ZipBuffer.cpp \ src/datastructure/CameraParametersCollection.cpp \ src/datastructure/CloudPoint.cpp \ src/datastructure/CoordinateSystem.cpp \ diff --git a/interfaces/core/ZipBuffer.h b/interfaces/core/ZipBuffer.h new file mode 100644 index 00000000..381a8bcb --- /dev/null +++ b/interfaces/core/ZipBuffer.h @@ -0,0 +1,65 @@ +/** + * @copyright Copyright (c) 2026 B-com http://www.b-com.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOLAR_ZIPBUFFER_H +#define SOLAR_ZIPBUFFER_H + +#include +#include + +namespace SolAR { + +/** + * @class ZipBuffer + * @brief Defines methods to zip/unzip data to/from a binary buffer + * + */ + +class ZipBuffer { + +public: + + /// @brief Class constructor + ZipBuffer(); + + /// @brief Class destructor + ~ZipBuffer(); + + /// @brief zip the content of the original path and store the binary result in the output buffer + /// @param[in] originalPath path to data to zip + /// @param[out] compressedZipBuffer output buffer containing the zip data + /// return true if processing succeeds, else false + bool zipToBuffer(const std::string & originalPath, + std::vector & compressedZipBuffer); + + /// @brief unzip the content of the input buffer and store the result in the destination path + /// @param[in] compressedZipBuffer input buffer containing the zip data + /// @param[out] destinationPath path for unzipped data + /// return true if processing succeeds, else false + bool bufferToUnzip(const std::vector & compressedZipBuffer, + std::string & destinationPath); + +private: + + /// @brief Delete the content of the working directory + void cleanWorkingDirectory(); + + std::string m_workingPath = "./working_dir"; // Working directory used to copy, zip or unzip data +}; + +} // end of namespace SolAR + +#endif // SOLAR_ZIPBUFFER_H diff --git a/src/core/ZipBuffer.cpp b/src/core/ZipBuffer.cpp new file mode 100644 index 00000000..8cbb0713 --- /dev/null +++ b/src/core/ZipBuffer.cpp @@ -0,0 +1,180 @@ +#include "core/ZipBuffer.h" +#include "core/Log.h" + +#include + +using namespace SolAR; +namespace fs = std::filesystem; + +ZipBuffer::ZipBuffer() +{ + try { + // Create a working directory for zip/unzip features + fs::path wp(m_workingPath); + if (!fs::exists(wp)) { + if (!fs::create_directories(wp)) { + LOG_ERROR("Error while creating the working directory for zip/unzip features: {}", m_workingPath); + } + LOG_DEBUG("Working directory created for zip/unzip features: {}", m_workingPath); + } + } + catch (const fs::filesystem_error & e) { + LOG_ERROR("The following exception has been caught {}", e.what()); + } +} + +ZipBuffer::~ZipBuffer() +{ + try { + // Delete the working directory + fs::remove_all(m_workingPath); + } + catch (const fs::filesystem_error & e) { + LOG_ERROR("The following exception has been caught {}", e.what()); + } +} + +bool ZipBuffer::zipToBuffer(const std::string & originalPath, + std::vector & compressedZipBuffer) +{ + try { + // Check working directory + fs::path wp(m_workingPath); + if (!fs::is_directory(wp)) { + LOG_ERROR("Can not find the working directory: {}", m_workingPath); + return false; + } + + // Check original path + fs::path op(originalPath); + if (!fs::is_directory(op)) { + LOG_ERROR("The original path is not a directory: {}", originalPath); + return false; + } + if (fs::is_empty(op)) { + LOG_ERROR("The original path is empty: {}", originalPath); + return false; + } + + // Copy data to zip in the working directory + const auto copyOptions = fs::copy_options::recursive; + fs::copy(op, wp, copyOptions); + } + catch (const fs::filesystem_error & e) { + LOG_ERROR("The following exception has been caught {}", e.what()); + cleanWorkingDirectory(); + return false; + } + + bool result = [&]() { + // Try to zip the working directory content + std::string command = "cd " + m_workingPath + ";zip -r data.zip ."; + if (std::system(command.c_str()) != 0) { + LOG_ERROR("Error occured while trying to zip the working directory content: {}", m_workingPath); + return false; + } + + // Open the resulting zip file + std::string zipFile = m_workingPath + "/data.zip"; + std::ifstream file(zipFile, std::ios::binary); + if (!file.is_open()) { + LOG_ERROR("Cannot open the zip binary file: {}", zipFile); + return false; + } + + // Get its size + file.seekg(0, std::ios::end); + std::streampos fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + if (fileSize == 0) { + LOG_ERROR("Empty zip binary file: {}", zipFile); + return false; + } + LOG_DEBUG("Zip file size ({}): {}", zipFile, fmt::streamed(fileSize)); + + // Read the data and put it in the output buffer + compressedZipBuffer.resize(fileSize); + file.read(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); + + return true; + }(); + + cleanWorkingDirectory(); + + return result; +} + +bool ZipBuffer::bufferToUnzip(const std::vector & compressedZipBuffer, + std::string & destinationPath) +{ + if (compressedZipBuffer.empty()) { + LOG_ERROR("Empty input buffer"); + return false; + } + + try { + fs::path wp(m_workingPath); + fs::path dp(destinationPath); + + // Check working directory + if (!fs::is_directory(wp)) { + LOG_ERROR("Can not find the working directory: {}", m_workingPath); + return false; + } + + // Check destination path + if (!fs::is_directory(dp)) { + LOG_ERROR("The destination path is not a directory: {}", destinationPath); + return false; + } + + bool result = [&]() { + // Create the zip file from the input buffer + std::string zipFile = m_workingPath + "/data.zip"; + std::ofstream file(zipFile, std::ios::out | std::ios::binary); + if (!file.is_open()) { + LOG_ERROR("Cannot create/open zip file: {}", zipFile); + return false; + } + + // Write the compressed data + file.write(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); + file.close(); + + // Try to unzip the file content + std::string command = "cd " + m_workingPath + "; unzip data.zip"; + if (std::system(command.c_str()) != 0) { + LOG_ERROR("Error occured while trying to unzip the compressed data file: {}", zipFile); + return false; + } + + // Delete the zip file + fs::remove(zipFile); + + // Copy unzipped data in the destination directory + const auto copyOptions = fs::copy_options::recursive; + fs::copy(wp, dp, copyOptions); + + return true; + } (); + + cleanWorkingDirectory(); + + return result; + } + catch (const fs::filesystem_error & e) { + LOG_ERROR("The following exception has been caught {}", e.what()); + cleanWorkingDirectory(); + return false; + } +} + +// private + +void ZipBuffer::cleanWorkingDirectory() +{ + fs::path wp(m_workingPath); + for (auto& path: fs::directory_iterator(wp)) { + fs::remove_all(path); + } +} \ No newline at end of file From 1fbeac7acc034ef46f3e1512b2bee8f77e1dcec7 Mon Sep 17 00:00:00 2001 From: ccutullic Date: Wed, 2 Sep 2026 15:27:48 +0200 Subject: [PATCH 2/8] feat: ZipBuffer methods return FrameworkReturnCode instead of boolean --- interfaces/core/ZipBuffer.h | 18 ++++++++++------ src/core/ZipBuffer.cpp | 42 ++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/interfaces/core/ZipBuffer.h b/interfaces/core/ZipBuffer.h index 381a8bcb..2fb291a0 100644 --- a/interfaces/core/ZipBuffer.h +++ b/interfaces/core/ZipBuffer.h @@ -17,6 +17,7 @@ #ifndef SOLAR_ZIPBUFFER_H #define SOLAR_ZIPBUFFER_H +#include "core/Messages.h" #include #include @@ -41,16 +42,21 @@ class ZipBuffer { /// @brief zip the content of the original path and store the binary result in the output buffer /// @param[in] originalPath path to data to zip /// @param[out] compressedZipBuffer output buffer containing the zip data - /// return true if processing succeeds, else false - bool zipToBuffer(const std::string & originalPath, - std::vector & compressedZipBuffer); + /// @return + /// * FrameworkReturnCode::_SUCCESS if the process succeeds + /// * FrameworkReturnCode::_NOT_FOUND if data is not found in original path + /// * else FrameworkReturnCode::_ERROR_ + FrameworkReturnCode zipToBuffer(const std::string & originalPath, + std::vector & compressedZipBuffer); /// @brief unzip the content of the input buffer and store the result in the destination path /// @param[in] compressedZipBuffer input buffer containing the zip data /// @param[out] destinationPath path for unzipped data - /// return true if processing succeeds, else false - bool bufferToUnzip(const std::vector & compressedZipBuffer, - std::string & destinationPath); + /// @return + /// * FrameworkReturnCode::_SUCCESS if the process succeeds + /// * else FrameworkReturnCode::_ERROR_ + FrameworkReturnCode bufferToUnzip(const std::vector & compressedZipBuffer, + std::string & destinationPath); private: diff --git a/src/core/ZipBuffer.cpp b/src/core/ZipBuffer.cpp index 8cbb0713..567ca851 100644 --- a/src/core/ZipBuffer.cpp +++ b/src/core/ZipBuffer.cpp @@ -34,26 +34,26 @@ ZipBuffer::~ZipBuffer() } } -bool ZipBuffer::zipToBuffer(const std::string & originalPath, - std::vector & compressedZipBuffer) +FrameworkReturnCode ZipBuffer::zipToBuffer(const std::string & originalPath, + std::vector & compressedZipBuffer) { try { // Check working directory fs::path wp(m_workingPath); if (!fs::is_directory(wp)) { LOG_ERROR("Can not find the working directory: {}", m_workingPath); - return false; + FrameworkReturnCode::_ERROR_; } // Check original path fs::path op(originalPath); if (!fs::is_directory(op)) { LOG_ERROR("The original path is not a directory: {}", originalPath); - return false; + return FrameworkReturnCode::_NOT_FOUND; } if (fs::is_empty(op)) { LOG_ERROR("The original path is empty: {}", originalPath); - return false; + return FrameworkReturnCode::_NOT_FOUND; } // Copy data to zip in the working directory @@ -63,15 +63,15 @@ bool ZipBuffer::zipToBuffer(const std::string & originalPath, catch (const fs::filesystem_error & e) { LOG_ERROR("The following exception has been caught {}", e.what()); cleanWorkingDirectory(); - return false; + return FrameworkReturnCode::_ERROR_; } - bool result = [&]() { + FrameworkReturnCode result = [&]() { // Try to zip the working directory content std::string command = "cd " + m_workingPath + ";zip -r data.zip ."; if (std::system(command.c_str()) != 0) { LOG_ERROR("Error occured while trying to zip the working directory content: {}", m_workingPath); - return false; + return FrameworkReturnCode::_ERROR_; } // Open the resulting zip file @@ -79,7 +79,7 @@ bool ZipBuffer::zipToBuffer(const std::string & originalPath, std::ifstream file(zipFile, std::ios::binary); if (!file.is_open()) { LOG_ERROR("Cannot open the zip binary file: {}", zipFile); - return false; + return FrameworkReturnCode::_ERROR_; } // Get its size @@ -88,7 +88,7 @@ bool ZipBuffer::zipToBuffer(const std::string & originalPath, file.seekg(0, std::ios::beg); if (fileSize == 0) { LOG_ERROR("Empty zip binary file: {}", zipFile); - return false; + return FrameworkReturnCode::_ERROR_; } LOG_DEBUG("Zip file size ({}): {}", zipFile, fmt::streamed(fileSize)); @@ -96,7 +96,7 @@ bool ZipBuffer::zipToBuffer(const std::string & originalPath, compressedZipBuffer.resize(fileSize); file.read(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); - return true; + return FrameworkReturnCode::_SUCCESS; }(); cleanWorkingDirectory(); @@ -104,12 +104,12 @@ bool ZipBuffer::zipToBuffer(const std::string & originalPath, return result; } -bool ZipBuffer::bufferToUnzip(const std::vector & compressedZipBuffer, - std::string & destinationPath) +FrameworkReturnCode ZipBuffer::bufferToUnzip(const std::vector & compressedZipBuffer, + std::string & destinationPath) { if (compressedZipBuffer.empty()) { LOG_ERROR("Empty input buffer"); - return false; + return FrameworkReturnCode::_ERROR_; } try { @@ -119,22 +119,22 @@ bool ZipBuffer::bufferToUnzip(const std::vector & compressedZipBu // Check working directory if (!fs::is_directory(wp)) { LOG_ERROR("Can not find the working directory: {}", m_workingPath); - return false; + return FrameworkReturnCode::_ERROR_; } // Check destination path if (!fs::is_directory(dp)) { LOG_ERROR("The destination path is not a directory: {}", destinationPath); - return false; + return FrameworkReturnCode::_ERROR_; } - bool result = [&]() { + FrameworkReturnCode result = [&]() { // Create the zip file from the input buffer std::string zipFile = m_workingPath + "/data.zip"; std::ofstream file(zipFile, std::ios::out | std::ios::binary); if (!file.is_open()) { LOG_ERROR("Cannot create/open zip file: {}", zipFile); - return false; + return FrameworkReturnCode::_ERROR_; } // Write the compressed data @@ -145,7 +145,7 @@ bool ZipBuffer::bufferToUnzip(const std::vector & compressedZipBu std::string command = "cd " + m_workingPath + "; unzip data.zip"; if (std::system(command.c_str()) != 0) { LOG_ERROR("Error occured while trying to unzip the compressed data file: {}", zipFile); - return false; + return FrameworkReturnCode::_ERROR_; } // Delete the zip file @@ -155,7 +155,7 @@ bool ZipBuffer::bufferToUnzip(const std::vector & compressedZipBu const auto copyOptions = fs::copy_options::recursive; fs::copy(wp, dp, copyOptions); - return true; + return FrameworkReturnCode::_SUCCESS; } (); cleanWorkingDirectory(); @@ -165,7 +165,7 @@ bool ZipBuffer::bufferToUnzip(const std::vector & compressedZipBu catch (const fs::filesystem_error & e) { LOG_ERROR("The following exception has been caught {}", e.what()); cleanWorkingDirectory(); - return false; + return FrameworkReturnCode::_ERROR_; } } From d8c8c4623b010d20de254a93d8d29a7b8ef563af Mon Sep 17 00:00:00 2001 From: ccutullic Date: Thu, 3 Sep 2026 13:54:22 +0200 Subject: [PATCH 3/8] refactor: changes following PR comments --- SolARFramework.pri | 4 +- .../core/{ZipBuffer.h => ZipBufferUtils.h} | 47 +++-- src/core/ZipBuffer.cpp | 180 ------------------ src/core/ZipBufferUtils.cpp | 135 +++++++++++++ 4 files changed, 163 insertions(+), 203 deletions(-) rename interfaces/core/{ZipBuffer.h => ZipBufferUtils.h} (59%) delete mode 100644 src/core/ZipBuffer.cpp create mode 100644 src/core/ZipBufferUtils.cpp diff --git a/SolARFramework.pri b/SolARFramework.pri index 57be16d5..8191519b 100644 --- a/SolARFramework.pri +++ b/SolARFramework.pri @@ -130,7 +130,7 @@ interfaces/core/Messages.h \ interfaces/core/SerializationDefinitions.h \ interfaces/core/SolARFramework.h \ interfaces/core/SolARFrameworkDefinitions.h \ -interfaces/core/ZipBuffer.h \ +interfaces/core/ZipBufferUtils.h \ interfaces/datastructure/BufferInternal.hpp \ interfaces/datastructure/CameraDefinitions.h \ interfaces/datastructure/CameraParametersCollection.h \ @@ -192,7 +192,7 @@ src/datastructure/RelocalizationInformation.cpp \ src/datastructure/StorageCapabilities.cpp \ src/core/Log.cpp \ src/core/SolARFramework.cpp \ -src/core/ZipBuffer.cpp \ +src/core/ZipBufferUtils.cpp \ src/datastructure/CameraParametersCollection.cpp \ src/datastructure/CloudPoint.cpp \ src/datastructure/CoordinateSystem.cpp \ diff --git a/interfaces/core/ZipBuffer.h b/interfaces/core/ZipBufferUtils.h similarity index 59% rename from interfaces/core/ZipBuffer.h rename to interfaces/core/ZipBufferUtils.h index 2fb291a0..ade30c5b 100644 --- a/interfaces/core/ZipBuffer.h +++ b/interfaces/core/ZipBufferUtils.h @@ -14,40 +14,51 @@ * limitations under the License. */ -#ifndef SOLAR_ZIPBUFFER_H -#define SOLAR_ZIPBUFFER_H +#ifndef SOLAR_ZIPBUFFERUTILS_H +#define SOLAR_ZIPBUFFERUTILS_H #include "core/Messages.h" #include #include +#include + +namespace fs = std::filesystem; namespace SolAR { /** - * @class ZipBuffer + * @class ZipBufferUtils * @brief Defines methods to zip/unzip data to/from a binary buffer * */ -class ZipBuffer { +class ZipBufferUtils { public: - /// @brief Class constructor - ZipBuffer(); - - /// @brief Class destructor - ~ZipBuffer(); + /** + * @class ScopedWorkingDir + * @brief Create a temporary working directory + * + */ + class ScopedWorkingDir { + public: + ScopedWorkingDir() { m_workingPath = fs::temp_directory_path(); m_workingPath += "/solar"; } + ~ScopedWorkingDir() { fs::remove_all(m_workingPath); } + fs::path getPath() { return m_workingPath; } + std::string getStringPath() { return m_workingPath.string(); } + private: + fs::path m_workingPath; // Temporary working directory used to copy, zip or unzip data + }; /// @brief zip the content of the original path and store the binary result in the output buffer /// @param[in] originalPath path to data to zip /// @param[out] compressedZipBuffer output buffer containing the zip data /// @return /// * FrameworkReturnCode::_SUCCESS if the process succeeds - /// * FrameworkReturnCode::_NOT_FOUND if data is not found in original path /// * else FrameworkReturnCode::_ERROR_ - FrameworkReturnCode zipToBuffer(const std::string & originalPath, - std::vector & compressedZipBuffer); + static FrameworkReturnCode compress(const std::string & originalPath, + std::vector & compressedZipBuffer); /// @brief unzip the content of the input buffer and store the result in the destination path /// @param[in] compressedZipBuffer input buffer containing the zip data @@ -55,17 +66,11 @@ class ZipBuffer { /// @return /// * FrameworkReturnCode::_SUCCESS if the process succeeds /// * else FrameworkReturnCode::_ERROR_ - FrameworkReturnCode bufferToUnzip(const std::vector & compressedZipBuffer, - std::string & destinationPath); - -private: - - /// @brief Delete the content of the working directory - void cleanWorkingDirectory(); + static FrameworkReturnCode extract(const std::vector & compressedZipBuffer, + std::string & destinationPath); - std::string m_workingPath = "./working_dir"; // Working directory used to copy, zip or unzip data }; } // end of namespace SolAR -#endif // SOLAR_ZIPBUFFER_H +#endif // SOLAR_ZIPBUFFERUTILS_H diff --git a/src/core/ZipBuffer.cpp b/src/core/ZipBuffer.cpp deleted file mode 100644 index 567ca851..00000000 --- a/src/core/ZipBuffer.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "core/ZipBuffer.h" -#include "core/Log.h" - -#include - -using namespace SolAR; -namespace fs = std::filesystem; - -ZipBuffer::ZipBuffer() -{ - try { - // Create a working directory for zip/unzip features - fs::path wp(m_workingPath); - if (!fs::exists(wp)) { - if (!fs::create_directories(wp)) { - LOG_ERROR("Error while creating the working directory for zip/unzip features: {}", m_workingPath); - } - LOG_DEBUG("Working directory created for zip/unzip features: {}", m_workingPath); - } - } - catch (const fs::filesystem_error & e) { - LOG_ERROR("The following exception has been caught {}", e.what()); - } -} - -ZipBuffer::~ZipBuffer() -{ - try { - // Delete the working directory - fs::remove_all(m_workingPath); - } - catch (const fs::filesystem_error & e) { - LOG_ERROR("The following exception has been caught {}", e.what()); - } -} - -FrameworkReturnCode ZipBuffer::zipToBuffer(const std::string & originalPath, - std::vector & compressedZipBuffer) -{ - try { - // Check working directory - fs::path wp(m_workingPath); - if (!fs::is_directory(wp)) { - LOG_ERROR("Can not find the working directory: {}", m_workingPath); - FrameworkReturnCode::_ERROR_; - } - - // Check original path - fs::path op(originalPath); - if (!fs::is_directory(op)) { - LOG_ERROR("The original path is not a directory: {}", originalPath); - return FrameworkReturnCode::_NOT_FOUND; - } - if (fs::is_empty(op)) { - LOG_ERROR("The original path is empty: {}", originalPath); - return FrameworkReturnCode::_NOT_FOUND; - } - - // Copy data to zip in the working directory - const auto copyOptions = fs::copy_options::recursive; - fs::copy(op, wp, copyOptions); - } - catch (const fs::filesystem_error & e) { - LOG_ERROR("The following exception has been caught {}", e.what()); - cleanWorkingDirectory(); - return FrameworkReturnCode::_ERROR_; - } - - FrameworkReturnCode result = [&]() { - // Try to zip the working directory content - std::string command = "cd " + m_workingPath + ";zip -r data.zip ."; - if (std::system(command.c_str()) != 0) { - LOG_ERROR("Error occured while trying to zip the working directory content: {}", m_workingPath); - return FrameworkReturnCode::_ERROR_; - } - - // Open the resulting zip file - std::string zipFile = m_workingPath + "/data.zip"; - std::ifstream file(zipFile, std::ios::binary); - if (!file.is_open()) { - LOG_ERROR("Cannot open the zip binary file: {}", zipFile); - return FrameworkReturnCode::_ERROR_; - } - - // Get its size - file.seekg(0, std::ios::end); - std::streampos fileSize = file.tellg(); - file.seekg(0, std::ios::beg); - if (fileSize == 0) { - LOG_ERROR("Empty zip binary file: {}", zipFile); - return FrameworkReturnCode::_ERROR_; - } - LOG_DEBUG("Zip file size ({}): {}", zipFile, fmt::streamed(fileSize)); - - // Read the data and put it in the output buffer - compressedZipBuffer.resize(fileSize); - file.read(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); - - return FrameworkReturnCode::_SUCCESS; - }(); - - cleanWorkingDirectory(); - - return result; -} - -FrameworkReturnCode ZipBuffer::bufferToUnzip(const std::vector & compressedZipBuffer, - std::string & destinationPath) -{ - if (compressedZipBuffer.empty()) { - LOG_ERROR("Empty input buffer"); - return FrameworkReturnCode::_ERROR_; - } - - try { - fs::path wp(m_workingPath); - fs::path dp(destinationPath); - - // Check working directory - if (!fs::is_directory(wp)) { - LOG_ERROR("Can not find the working directory: {}", m_workingPath); - return FrameworkReturnCode::_ERROR_; - } - - // Check destination path - if (!fs::is_directory(dp)) { - LOG_ERROR("The destination path is not a directory: {}", destinationPath); - return FrameworkReturnCode::_ERROR_; - } - - FrameworkReturnCode result = [&]() { - // Create the zip file from the input buffer - std::string zipFile = m_workingPath + "/data.zip"; - std::ofstream file(zipFile, std::ios::out | std::ios::binary); - if (!file.is_open()) { - LOG_ERROR("Cannot create/open zip file: {}", zipFile); - return FrameworkReturnCode::_ERROR_; - } - - // Write the compressed data - file.write(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); - file.close(); - - // Try to unzip the file content - std::string command = "cd " + m_workingPath + "; unzip data.zip"; - if (std::system(command.c_str()) != 0) { - LOG_ERROR("Error occured while trying to unzip the compressed data file: {}", zipFile); - return FrameworkReturnCode::_ERROR_; - } - - // Delete the zip file - fs::remove(zipFile); - - // Copy unzipped data in the destination directory - const auto copyOptions = fs::copy_options::recursive; - fs::copy(wp, dp, copyOptions); - - return FrameworkReturnCode::_SUCCESS; - } (); - - cleanWorkingDirectory(); - - return result; - } - catch (const fs::filesystem_error & e) { - LOG_ERROR("The following exception has been caught {}", e.what()); - cleanWorkingDirectory(); - return FrameworkReturnCode::_ERROR_; - } -} - -// private - -void ZipBuffer::cleanWorkingDirectory() -{ - fs::path wp(m_workingPath); - for (auto& path: fs::directory_iterator(wp)) { - fs::remove_all(path); - } -} \ No newline at end of file diff --git a/src/core/ZipBufferUtils.cpp b/src/core/ZipBufferUtils.cpp new file mode 100644 index 00000000..9955e8bb --- /dev/null +++ b/src/core/ZipBufferUtils.cpp @@ -0,0 +1,135 @@ +#include "core/ZipBufferUtils.h" +#include "core/Log.h" + +using namespace SolAR; + +FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, + std::vector & compressedZipBuffer) +{ + LOG_DEBUG("ZipBufferUtils::compress - Original path: {}", originalPath); + + compressedZipBuffer.clear(); + + // Get a temporary working directory + ScopedWorkingDir workingDir; + + LOG_DEBUG("ZipBufferUtils::compress - Working temporary path: {}", workingDir.getStringPath()); + + try { + // Check original path + fs::path op(originalPath); + if (!fs::is_directory(op)) { + LOG_ERROR("ZipBufferUtils::compress - The original path is not a directory: {}", originalPath); + return FrameworkReturnCode::_ERROR_; + } + if (fs::is_empty(op)) { + LOG_WARNING("ZipBufferUtils::compress - The original path is empty: {}", originalPath); + return FrameworkReturnCode::_SUCCESS; + } + + // Copy data to zip in the working directory + const auto copyOptions = fs::copy_options::recursive; + fs::copy(op, workingDir.getPath(), copyOptions); + } + catch (const fs::filesystem_error & e) { + LOG_ERROR("ZipBufferUtils::compress - The following exception has been caught {}", e.what()); + return FrameworkReturnCode::_ERROR_; + } + + // Try to zip the working directory content + std::string command = "cd " + workingDir.getStringPath() + ";zip -r data.zip ."; + if (std::system(command.c_str()) != 0) { + LOG_ERROR("ZipBufferUtils::compress - Error occured while trying to zip the working directory content: {}", workingDir.getStringPath()); + return FrameworkReturnCode::_ERROR_; + } + + // Open the resulting zip file + std::string zipFile = workingDir.getStringPath() + "/data.zip"; + std::ifstream file(zipFile, std::ios::binary); + if (!file.is_open()) { + LOG_ERROR("ZipBufferUtils::compress - Cannot open the zip binary file: {}", zipFile); + return FrameworkReturnCode::_ERROR_; + } + + // Get its size + file.seekg(0, std::ios::end); + std::streampos fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + if (fileSize == 0) { + LOG_ERROR("ZipBufferUtils::compress - Empty zip binary file: {}", zipFile); + return FrameworkReturnCode::_ERROR_; + } + LOG_DEBUG("ZipBufferUtils::compress - Zip file size ({}): {}", zipFile, fmt::streamed(fileSize)); + + // Read the data and put it in the output buffer + compressedZipBuffer.resize(fileSize); + file.read(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); + + return FrameworkReturnCode::_SUCCESS; +} + +FrameworkReturnCode ZipBufferUtils::extract(const std::vector & compressedZipBuffer, + std::string & destinationPath) +{ + LOG_DEBUG("ZipBufferUtils::extract - Destination path: {}", destinationPath); + + if (compressedZipBuffer.empty()) { + LOG_WARNING("ZipBufferUtils::extract - Empty input buffer"); + return FrameworkReturnCode::_SUCCESS; + } + + try { + fs::path dp(destinationPath); + + // Check destination path + if (!fs::is_directory(dp)) { + LOG_ERROR("ZipBufferUtils::extract - The destination path is not a directory: {}", destinationPath); + return FrameworkReturnCode::_ERROR_; + } + + // Get a temporary working directory + ScopedWorkingDir workingDir; + + LOG_DEBUG("ZipBufferUtils::extract - Working temporary path: {}", workingDir.getStringPath()); + + // Check/create the working directory + if (!fs::exists(workingDir.getPath())) { + if (!fs::create_directories(workingDir.getPath())) { + LOG_ERROR("Error while creating the working directory for zip/unzip features: {}", workingDir.getStringPath()); + } + LOG_DEBUG("Working directory created for zip/unzip features: {}", workingDir.getStringPath()); + } + + // Create the zip file from the input buffer + std::string zipFile = workingDir.getStringPath() + "/data.zip"; + std::ofstream file(zipFile, std::ios::out | std::ios::binary); + if (!file.is_open()) { + LOG_ERROR("ZipBufferUtils::extract - Cannot create/open zip file: {}", zipFile); + return FrameworkReturnCode::_ERROR_; + } + + // Write the compressed data + file.write(reinterpret_cast(compressedZipBuffer.data()), compressedZipBuffer.size()); + file.close(); + + // Try to unzip the file content + std::string command = "cd " + workingDir.getStringPath() + "; unzip data.zip"; + if (std::system(command.c_str()) != 0) { + LOG_ERROR("ZipBufferUtils::extract - Error occured while trying to unzip the compressed data file: {}", zipFile); + return FrameworkReturnCode::_ERROR_; + } + + // Delete the zip file + fs::remove(zipFile); + + // Copy unzipped data in the destination directory + const auto copyOptions = fs::copy_options::recursive; + fs::copy(workingDir.getPath(), dp, copyOptions); + + return FrameworkReturnCode::_SUCCESS; + } + catch (const fs::filesystem_error & e) { + LOG_ERROR("ZipBufferUtils::extract - The following exception has been caught {}", e.what()); + return FrameworkReturnCode::_ERROR_; + } +} From 8a50ced4a747d7544c05b529bb1286d85210e6b9 Mon Sep 17 00:00:00 2001 From: ccutullic Date: Thu, 3 Sep 2026 18:27:16 +0200 Subject: [PATCH 4/8] refactor: changes following PR comments --- interfaces/core/ZipBufferUtils.h | 17 ---------- src/core/ZipBufferUtils.cpp | 58 ++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/interfaces/core/ZipBufferUtils.h b/interfaces/core/ZipBufferUtils.h index ade30c5b..dfa76480 100644 --- a/interfaces/core/ZipBufferUtils.h +++ b/interfaces/core/ZipBufferUtils.h @@ -22,8 +22,6 @@ #include #include -namespace fs = std::filesystem; - namespace SolAR { /** @@ -36,21 +34,6 @@ class ZipBufferUtils { public: - /** - * @class ScopedWorkingDir - * @brief Create a temporary working directory - * - */ - class ScopedWorkingDir { - public: - ScopedWorkingDir() { m_workingPath = fs::temp_directory_path(); m_workingPath += "/solar"; } - ~ScopedWorkingDir() { fs::remove_all(m_workingPath); } - fs::path getPath() { return m_workingPath; } - std::string getStringPath() { return m_workingPath.string(); } - private: - fs::path m_workingPath; // Temporary working directory used to copy, zip or unzip data - }; - /// @brief zip the content of the original path and store the binary result in the output buffer /// @param[in] originalPath path to data to zip /// @param[out] compressedZipBuffer output buffer containing the zip data diff --git a/src/core/ZipBufferUtils.cpp b/src/core/ZipBufferUtils.cpp index 9955e8bb..d74f8475 100644 --- a/src/core/ZipBufferUtils.cpp +++ b/src/core/ZipBufferUtils.cpp @@ -1,8 +1,42 @@ #include "core/ZipBufferUtils.h" #include "core/Log.h" +namespace fs = std::filesystem; + using namespace SolAR; +/** + * @class ScopedTempDir + * @brief Create a temporary directory + * + */ +class ScopedTempDir { +public: + ScopedTempDir() + { + m_tempPath = fs::temp_directory_path(); + m_tempPath /= "solar"; + // Create the working directory + std::error_code ec; + fs::create_directories(m_tempPath, ec); + } + + ~ScopedTempDir() { std::error_code ec; fs::remove_all(m_tempPath, ec); } + + // Delete copy operations to prevent double deletion + ScopedTempDir(const ScopedTempDir&) = delete; + ScopedTempDir& operator=(const ScopedTempDir&) = delete; + ScopedTempDir(ScopedTempDir&&) = delete; + ScopedTempDir& operator=(ScopedTempDir&&) = delete; + + const fs::path getPath() const { return m_tempPath; } + const std::string getStringPath() const { return m_tempPath.string(); } + +private: + fs::path m_tempPath; // Temporary working directory used to copy, zip or unzip data +}; + + FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, std::vector & compressedZipBuffer) { @@ -11,13 +45,14 @@ FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, compressedZipBuffer.clear(); // Get a temporary working directory - ScopedWorkingDir workingDir; + ScopedTempDir workingDir; LOG_DEBUG("ZipBufferUtils::compress - Working temporary path: {}", workingDir.getStringPath()); + fs::path op(originalPath); + try { // Check original path - fs::path op(originalPath); if (!fs::is_directory(op)) { LOG_ERROR("ZipBufferUtils::compress - The original path is not a directory: {}", originalPath); return FrameworkReturnCode::_ERROR_; @@ -26,18 +61,14 @@ FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, LOG_WARNING("ZipBufferUtils::compress - The original path is empty: {}", originalPath); return FrameworkReturnCode::_SUCCESS; } - - // Copy data to zip in the working directory - const auto copyOptions = fs::copy_options::recursive; - fs::copy(op, workingDir.getPath(), copyOptions); } catch (const fs::filesystem_error & e) { LOG_ERROR("ZipBufferUtils::compress - The following exception has been caught {}", e.what()); return FrameworkReturnCode::_ERROR_; } - // Try to zip the working directory content - std::string command = "cd " + workingDir.getStringPath() + ";zip -r data.zip ."; + // Try to zip the original path content + std::string command = "cd " + originalPath +"; zip -r " + workingDir.getStringPath() + "/data.zip ."; if (std::system(command.c_str()) != 0) { LOG_ERROR("ZipBufferUtils::compress - Error occured while trying to zip the working directory content: {}", workingDir.getStringPath()); return FrameworkReturnCode::_ERROR_; @@ -88,7 +119,7 @@ FrameworkReturnCode ZipBufferUtils::extract(const std::vector & c } // Get a temporary working directory - ScopedWorkingDir workingDir; + ScopedTempDir workingDir; LOG_DEBUG("ZipBufferUtils::extract - Working temporary path: {}", workingDir.getStringPath()); @@ -113,19 +144,12 @@ FrameworkReturnCode ZipBufferUtils::extract(const std::vector & c file.close(); // Try to unzip the file content - std::string command = "cd " + workingDir.getStringPath() + "; unzip data.zip"; + std::string command = "unzip " + workingDir.getStringPath() + "/data.zip -d " + destinationPath; if (std::system(command.c_str()) != 0) { LOG_ERROR("ZipBufferUtils::extract - Error occured while trying to unzip the compressed data file: {}", zipFile); return FrameworkReturnCode::_ERROR_; } - // Delete the zip file - fs::remove(zipFile); - - // Copy unzipped data in the destination directory - const auto copyOptions = fs::copy_options::recursive; - fs::copy(workingDir.getPath(), dp, copyOptions); - return FrameworkReturnCode::_SUCCESS; } catch (const fs::filesystem_error & e) { From e4935e8936192e3d37f08cfd4ec0be5019caf61c Mon Sep 17 00:00:00 2001 From: ccutullic Date: Mon, 7 Sep 2026 17:34:20 +0200 Subject: [PATCH 5/8] feat: expose the ScopedTempDir class so that it can be used by other projects. --- interfaces/core/ZipBufferUtils.h | 29 +++++++++++++++++ src/core/ZipBufferUtils.cpp | 55 ++++++++++++-------------------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/interfaces/core/ZipBufferUtils.h b/interfaces/core/ZipBufferUtils.h index dfa76480..86ff255d 100644 --- a/interfaces/core/ZipBufferUtils.h +++ b/interfaces/core/ZipBufferUtils.h @@ -24,6 +24,35 @@ namespace SolAR { +/** + * @class ScopedTempDir + * @brief Create a temporary directory + * + */ +class ScopedTempDir { + +public: + + ScopedTempDir(); + + ~ScopedTempDir(); + + // Delete copy operations to prevent double deletion + ScopedTempDir(const ScopedTempDir&) = delete; + ScopedTempDir& operator=(const ScopedTempDir&) = delete; + ScopedTempDir(ScopedTempDir&&) = delete; + ScopedTempDir& operator=(ScopedTempDir&&) = delete; + + const std::filesystem::path getPath() const; + const std::string getStringPath() const; + +private: + + std::filesystem::path m_tempPath; // Temporary working directory used to copy, zip or unzip data + +}; + + /** * @class ZipBufferUtils * @brief Defines methods to zip/unzip data to/from a binary buffer diff --git a/src/core/ZipBufferUtils.cpp b/src/core/ZipBufferUtils.cpp index d74f8475..6cc624bb 100644 --- a/src/core/ZipBufferUtils.cpp +++ b/src/core/ZipBufferUtils.cpp @@ -5,36 +5,31 @@ namespace fs = std::filesystem; using namespace SolAR; -/** - * @class ScopedTempDir - * @brief Create a temporary directory - * - */ -class ScopedTempDir { -public: - ScopedTempDir() - { - m_tempPath = fs::temp_directory_path(); - m_tempPath /= "solar"; - // Create the working directory - std::error_code ec; - fs::create_directories(m_tempPath, ec); - } - ~ScopedTempDir() { std::error_code ec; fs::remove_all(m_tempPath, ec); } +ScopedTempDir::ScopedTempDir() +{ + m_tempPath = fs::temp_directory_path(); + m_tempPath /= "solar"; + // Create the temporary directory + std::error_code ec; + fs::create_directories(m_tempPath, ec); +} - // Delete copy operations to prevent double deletion - ScopedTempDir(const ScopedTempDir&) = delete; - ScopedTempDir& operator=(const ScopedTempDir&) = delete; - ScopedTempDir(ScopedTempDir&&) = delete; - ScopedTempDir& operator=(ScopedTempDir&&) = delete; +ScopedTempDir::~ScopedTempDir() +{ + // Delete the temporary directory (and its contents) + std::error_code ec; fs::remove_all(m_tempPath, ec); +} - const fs::path getPath() const { return m_tempPath; } - const std::string getStringPath() const { return m_tempPath.string(); } +const fs::path ScopedTempDir::getPath() const +{ + return m_tempPath; +} -private: - fs::path m_tempPath; // Temporary working directory used to copy, zip or unzip data -}; +const std::string ScopedTempDir::getStringPath() const +{ + return m_tempPath.string(); +} FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, @@ -123,14 +118,6 @@ FrameworkReturnCode ZipBufferUtils::extract(const std::vector & c LOG_DEBUG("ZipBufferUtils::extract - Working temporary path: {}", workingDir.getStringPath()); - // Check/create the working directory - if (!fs::exists(workingDir.getPath())) { - if (!fs::create_directories(workingDir.getPath())) { - LOG_ERROR("Error while creating the working directory for zip/unzip features: {}", workingDir.getStringPath()); - } - LOG_DEBUG("Working directory created for zip/unzip features: {}", workingDir.getStringPath()); - } - // Create the zip file from the input buffer std::string zipFile = workingDir.getStringPath() + "/data.zip"; std::ofstream file(zipFile, std::ios::out | std::ios::binary); From 2689a4885847638350152171c3a760344daecb90 Mon Sep 17 00:00:00 2001 From: ccutullic Date: Mon, 7 Sep 2026 18:46:46 +0200 Subject: [PATCH 6/8] feat: add a subdirectory in the ScopedTempDir constructor + other minor changes --- interfaces/core/ZipBufferUtils.h | 9 +++++---- src/core/ZipBufferUtils.cpp | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/interfaces/core/ZipBufferUtils.h b/interfaces/core/ZipBufferUtils.h index 86ff255d..13fdce43 100644 --- a/interfaces/core/ZipBufferUtils.h +++ b/interfaces/core/ZipBufferUtils.h @@ -33,7 +33,8 @@ class ScopedTempDir { public: - ScopedTempDir(); + ScopedTempDir() = delete; + ScopedTempDir(const std::string & subdirectory); ~ScopedTempDir(); @@ -73,13 +74,13 @@ class ZipBufferUtils { std::vector & compressedZipBuffer); /// @brief unzip the content of the input buffer and store the result in the destination path + /// @param[in] destinationPath path for unzipped data /// @param[in] compressedZipBuffer input buffer containing the zip data - /// @param[out] destinationPath path for unzipped data /// @return /// * FrameworkReturnCode::_SUCCESS if the process succeeds /// * else FrameworkReturnCode::_ERROR_ - static FrameworkReturnCode extract(const std::vector & compressedZipBuffer, - std::string & destinationPath); + static FrameworkReturnCode extract(const std::string & destinationPath, + const std::vector & compressedZipBuffer); }; diff --git a/src/core/ZipBufferUtils.cpp b/src/core/ZipBufferUtils.cpp index 6cc624bb..3a0f84e7 100644 --- a/src/core/ZipBufferUtils.cpp +++ b/src/core/ZipBufferUtils.cpp @@ -6,10 +6,10 @@ namespace fs = std::filesystem; using namespace SolAR; -ScopedTempDir::ScopedTempDir() +ScopedTempDir::ScopedTempDir(const std::string &subdirectory) { m_tempPath = fs::temp_directory_path(); - m_tempPath /= "solar"; + m_tempPath /= subdirectory; // Create the temporary directory std::error_code ec; fs::create_directories(m_tempPath, ec); @@ -40,7 +40,7 @@ FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, compressedZipBuffer.clear(); // Get a temporary working directory - ScopedTempDir workingDir; + ScopedTempDir workingDir("compress"); LOG_DEBUG("ZipBufferUtils::compress - Working temporary path: {}", workingDir.getStringPath()); @@ -94,8 +94,8 @@ FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, return FrameworkReturnCode::_SUCCESS; } -FrameworkReturnCode ZipBufferUtils::extract(const std::vector & compressedZipBuffer, - std::string & destinationPath) +FrameworkReturnCode ZipBufferUtils::extract(const std::string & destinationPath, + const std::vector & compressedZipBuffer) { LOG_DEBUG("ZipBufferUtils::extract - Destination path: {}", destinationPath); @@ -114,7 +114,7 @@ FrameworkReturnCode ZipBufferUtils::extract(const std::vector & c } // Get a temporary working directory - ScopedTempDir workingDir; + ScopedTempDir workingDir("extract"); LOG_DEBUG("ZipBufferUtils::extract - Working temporary path: {}", workingDir.getStringPath()); From 6cc1c26d05484f04f6b3722feb98b608783a7291 Mon Sep 17 00:00:00 2001 From: ccutullic Date: Tue, 8 Sep 2026 14:34:55 +0200 Subject: [PATCH 7/8] feat: generate a random name for temporary subdirectory --- interfaces/core/ZipBufferUtils.h | 11 +++++------ src/core/ZipBufferUtils.cpp | 28 +++++++++++++++++++--------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/interfaces/core/ZipBufferUtils.h b/interfaces/core/ZipBufferUtils.h index 13fdce43..0e1436c3 100644 --- a/interfaces/core/ZipBufferUtils.h +++ b/interfaces/core/ZipBufferUtils.h @@ -33,8 +33,7 @@ class ScopedTempDir { public: - ScopedTempDir() = delete; - ScopedTempDir(const std::string & subdirectory); + ScopedTempDir(); ~ScopedTempDir(); @@ -44,7 +43,7 @@ class ScopedTempDir { ScopedTempDir(ScopedTempDir&&) = delete; ScopedTempDir& operator=(ScopedTempDir&&) = delete; - const std::filesystem::path getPath() const; + const std::filesystem::path& getPath() const; const std::string getStringPath() const; private: @@ -74,13 +73,13 @@ class ZipBufferUtils { std::vector & compressedZipBuffer); /// @brief unzip the content of the input buffer and store the result in the destination path - /// @param[in] destinationPath path for unzipped data /// @param[in] compressedZipBuffer input buffer containing the zip data + /// @param[in] destinationPath path for unzipped data /// @return /// * FrameworkReturnCode::_SUCCESS if the process succeeds /// * else FrameworkReturnCode::_ERROR_ - static FrameworkReturnCode extract(const std::string & destinationPath, - const std::vector & compressedZipBuffer); + static FrameworkReturnCode extract(const std::vector & compressedZipBuffer, + const std::string & destinationPath); }; diff --git a/src/core/ZipBufferUtils.cpp b/src/core/ZipBufferUtils.cpp index 3a0f84e7..7c5ba556 100644 --- a/src/core/ZipBufferUtils.cpp +++ b/src/core/ZipBufferUtils.cpp @@ -1,16 +1,26 @@ #include "core/ZipBufferUtils.h" #include "core/Log.h" +#include namespace fs = std::filesystem; using namespace SolAR; -ScopedTempDir::ScopedTempDir(const std::string &subdirectory) +ScopedTempDir::ScopedTempDir() { - m_tempPath = fs::temp_directory_path(); - m_tempPath /= subdirectory; - // Create the temporary directory + fs::path base_path = fs::temp_directory_path(); + + // Generate a random name for temporary subdirectory + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution dis; + do { + std::string random_name = "tmp_" + std::to_string(dis(gen)); + m_tempPath = base_path / random_name; + } while (fs::exists(m_tempPath)); + + // Create the temporary subdirectory std::error_code ec; fs::create_directories(m_tempPath, ec); } @@ -21,7 +31,7 @@ ScopedTempDir::~ScopedTempDir() std::error_code ec; fs::remove_all(m_tempPath, ec); } -const fs::path ScopedTempDir::getPath() const +const fs::path& ScopedTempDir::getPath() const { return m_tempPath; } @@ -40,7 +50,7 @@ FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, compressedZipBuffer.clear(); // Get a temporary working directory - ScopedTempDir workingDir("compress"); + ScopedTempDir workingDir; LOG_DEBUG("ZipBufferUtils::compress - Working temporary path: {}", workingDir.getStringPath()); @@ -94,8 +104,8 @@ FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, return FrameworkReturnCode::_SUCCESS; } -FrameworkReturnCode ZipBufferUtils::extract(const std::string & destinationPath, - const std::vector & compressedZipBuffer) +FrameworkReturnCode ZipBufferUtils::extract(const std::vector & compressedZipBuffer, + const std::string & destinationPath) { LOG_DEBUG("ZipBufferUtils::extract - Destination path: {}", destinationPath); @@ -114,7 +124,7 @@ FrameworkReturnCode ZipBufferUtils::extract(const std::string & destinationPath, } // Get a temporary working directory - ScopedTempDir workingDir("extract"); + ScopedTempDir workingDir; LOG_DEBUG("ZipBufferUtils::extract - Working temporary path: {}", workingDir.getStringPath()); From e516bf78f94c6059d3f5e2a3bf1e6f1da7e1de18 Mon Sep 17 00:00:00 2001 From: ccutullic Date: Tue, 8 Sep 2026 17:35:14 +0200 Subject: [PATCH 8/8] feat: put ScopedTempDir class in a separate file + SolAR::util namespace --- SolARFramework.pri | 2 ++ interfaces/core/ScopedTempDir.h | 57 ++++++++++++++++++++++++++++++++ interfaces/core/ZipBufferUtils.h | 32 ++---------------- src/core/ScopedTempDir.cpp | 41 +++++++++++++++++++++++ src/core/ZipBufferUtils.cpp | 39 ++-------------------- 5 files changed, 104 insertions(+), 67 deletions(-) create mode 100644 interfaces/core/ScopedTempDir.h create mode 100644 src/core/ScopedTempDir.cpp diff --git a/SolARFramework.pri b/SolARFramework.pri index 8191519b..4b7dddf8 100644 --- a/SolARFramework.pri +++ b/SolARFramework.pri @@ -127,6 +127,7 @@ interfaces/api/tracking/IOpticalFlowEstimator.h \ interfaces/core/Log.h \ interfaces/core/Timer.h \ interfaces/core/Messages.h \ +interfaces/core/ScopedTempDir.h \ interfaces/core/SerializationDefinitions.h \ interfaces/core/SolARFramework.h \ interfaces/core/SolARFrameworkDefinitions.h \ @@ -191,6 +192,7 @@ src/api/map/IRectifyMap.cpp \ src/datastructure/RelocalizationInformation.cpp \ src/datastructure/StorageCapabilities.cpp \ src/core/Log.cpp \ +src/core/ScopedTempDir.cpp \ src/core/SolARFramework.cpp \ src/core/ZipBufferUtils.cpp \ src/datastructure/CameraParametersCollection.cpp \ diff --git a/interfaces/core/ScopedTempDir.h b/interfaces/core/ScopedTempDir.h new file mode 100644 index 00000000..cde16008 --- /dev/null +++ b/interfaces/core/ScopedTempDir.h @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) 2026 B-com http://www.b-com.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOLAR_SCOPEDTEMPDIR_H +#define SOLAR_SCOPEDTEMPDIR_H + +#include +#include + +namespace SolAR { +namespace util { + +/** + * @class ScopedTempDir + * @brief Create a temporary directory + * + */ +class ScopedTempDir { + +public: + + ScopedTempDir(); + + ~ScopedTempDir(); + + // Delete copy operations to prevent double deletion + ScopedTempDir(const ScopedTempDir&) = delete; + ScopedTempDir& operator=(const ScopedTempDir&) = delete; + ScopedTempDir(ScopedTempDir&&) = delete; + ScopedTempDir& operator=(ScopedTempDir&&) = delete; + + const std::filesystem::path& getPath() const; + const std::string getStringPath() const; + +private: + + std::filesystem::path m_tempPath; // Temporary working directory used to copy, zip or unzip data + +}; + +} // end of namespace util +} // end of namespace SolAR + +#endif // SOLAR_SCOPEDTEMPDIR_H diff --git a/interfaces/core/ZipBufferUtils.h b/interfaces/core/ZipBufferUtils.h index 0e1436c3..3be4048f 100644 --- a/interfaces/core/ZipBufferUtils.h +++ b/interfaces/core/ZipBufferUtils.h @@ -20,38 +20,9 @@ #include "core/Messages.h" #include #include -#include namespace SolAR { - -/** - * @class ScopedTempDir - * @brief Create a temporary directory - * - */ -class ScopedTempDir { - -public: - - ScopedTempDir(); - - ~ScopedTempDir(); - - // Delete copy operations to prevent double deletion - ScopedTempDir(const ScopedTempDir&) = delete; - ScopedTempDir& operator=(const ScopedTempDir&) = delete; - ScopedTempDir(ScopedTempDir&&) = delete; - ScopedTempDir& operator=(ScopedTempDir&&) = delete; - - const std::filesystem::path& getPath() const; - const std::string getStringPath() const; - -private: - - std::filesystem::path m_tempPath; // Temporary working directory used to copy, zip or unzip data - -}; - +namespace util { /** * @class ZipBufferUtils @@ -83,6 +54,7 @@ class ZipBufferUtils { }; +} // end of namespace util } // end of namespace SolAR #endif // SOLAR_ZIPBUFFERUTILS_H diff --git a/src/core/ScopedTempDir.cpp b/src/core/ScopedTempDir.cpp new file mode 100644 index 00000000..abc12aea --- /dev/null +++ b/src/core/ScopedTempDir.cpp @@ -0,0 +1,41 @@ +#include "core/ScopedTempDir.h" +#include + +namespace fs = std::filesystem; + +using namespace SolAR; +using namespace SolAR::util; + +ScopedTempDir::ScopedTempDir() +{ + fs::path base_path = fs::temp_directory_path(); + + // Generate a random name for temporary subdirectory + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution dis; + do { + std::string random_name = "tmp_" + std::to_string(dis(gen)); + m_tempPath = base_path / random_name; + } while (fs::exists(m_tempPath)); + + // Create the temporary subdirectory + std::error_code ec; + fs::create_directories(m_tempPath, ec); +} + +ScopedTempDir::~ScopedTempDir() +{ + // Delete the temporary directory (and its contents) + std::error_code ec; fs::remove_all(m_tempPath, ec); +} + +const fs::path& ScopedTempDir::getPath() const +{ + return m_tempPath; +} + +const std::string ScopedTempDir::getStringPath() const +{ + return m_tempPath.string(); +} diff --git a/src/core/ZipBufferUtils.cpp b/src/core/ZipBufferUtils.cpp index 7c5ba556..27c811ca 100644 --- a/src/core/ZipBufferUtils.cpp +++ b/src/core/ZipBufferUtils.cpp @@ -1,46 +1,11 @@ #include "core/ZipBufferUtils.h" +#include "core/ScopedTempDir.h" #include "core/Log.h" -#include namespace fs = std::filesystem; using namespace SolAR; - - -ScopedTempDir::ScopedTempDir() -{ - fs::path base_path = fs::temp_directory_path(); - - // Generate a random name for temporary subdirectory - std::random_device rd; - std::mt19937_64 gen(rd()); - std::uniform_int_distribution dis; - do { - std::string random_name = "tmp_" + std::to_string(dis(gen)); - m_tempPath = base_path / random_name; - } while (fs::exists(m_tempPath)); - - // Create the temporary subdirectory - std::error_code ec; - fs::create_directories(m_tempPath, ec); -} - -ScopedTempDir::~ScopedTempDir() -{ - // Delete the temporary directory (and its contents) - std::error_code ec; fs::remove_all(m_tempPath, ec); -} - -const fs::path& ScopedTempDir::getPath() const -{ - return m_tempPath; -} - -const std::string ScopedTempDir::getStringPath() const -{ - return m_tempPath.string(); -} - +using namespace SolAR::util; FrameworkReturnCode ZipBufferUtils::compress(const std::string & originalPath, std::vector & compressedZipBuffer)