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
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"${workspaceFolder}/build/third_party/asyncplusplus/install/include",
"${workspaceFolder}/build/third_party/earcut/install/include",
"${workspaceFolder}/build/third_party/bitsery/install/include",
"${workspaceFolder}/build/third_party/minizip/install/include",
"${workspaceFolder}/build/third_party/minizip/install/include/minizip-ng",
"${workspaceFolder}/build/third_party/nanoflann/install/include",
"${workspaceFolder}/build/third_party/pybind11/install/include",
"${workspaceFolder}/build/third_party/spdlog/install/include",
Expand All @@ -21,7 +21,7 @@
"${workspaceFolder}/build/third_party/asyncplusplus/install/include",
"${workspaceFolder}/build/third_party/earcut/install/include",
"${workspaceFolder}/build/third_party/bitsery/install/include",
"${workspaceFolder}/build/third_party/minizip/install/include",
"${workspaceFolder}/build/third_party/minizip/install/include/minizip-ng",
"${workspaceFolder}/build/third_party/nanoflann/install/include",
"${workspaceFolder}/build/third_party/pybind11/install/include",
"${workspaceFolder}/build/third_party/spdlog/install/include",
Expand Down
120 changes: 84 additions & 36 deletions src/geode/basic/zip_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
#include <fstream>
#include <string_view>

#include <mz.h>

Check failure on line 30 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:30:10 [clang-diagnostic-error]

'mz.h' file not found
#include <mz_strm.h>
#include <mz_strm_mem.h>
#include <mz_zip.h>
#include <mz_zip_rw.h>

Expand All @@ -38,7 +39,7 @@
namespace
{
std::filesystem::path create_directory(
std::string_view file, std::string_view temp_filename )

Check warning on line 42 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:42:9 [bugprone-easily-swappable-parameters]

2 adjacent parameters of 'create_directory' of similar type ('std::string_view') are easily swapped by mistake
{
const auto file_string = geode::to_string( file );
auto directory = std::filesystem::path{ file_string }.parent_path()
Expand All @@ -50,38 +51,36 @@

namespace geode
{
class ZipFile::Impl

Check warning on line 54 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:54:20 [cppcoreguidelines-special-member-functions]

class 'Impl' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
{
public:
Impl( std::string_view file, std::string_view archive_temp_filename )
{
directory_ = create_directory( file, archive_temp_filename );
writer_ = mz_zip_writer_create();

Check warning on line 60 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:60:13 [cppcoreguidelines-prefer-member-initializer]

'writer_' should be initialized in a member initializer of the constructor
mz_zip_writer_set_compress_method(
writer_, MZ_COMPRESS_METHOD_STORE );
const auto status = mz_zip_writer_open_file(
writer_, to_string( file ).c_str(), 0, 0 );
if( status != MZ_OK )
{
std::filesystem::remove_all( directory_ );
throw OpenGeodeBasicException( nullptr,
OpenGeodeException::TYPE::internal,
"[ZipFile] Error opening zip for writing." );
"[ZipFile] Error opening zip for writing (", status, ")" );
}
}

~Impl()
{
std::filesystem::remove_all( directory_ );
const auto status = mz_zip_writer_close( writer_ );
if( status != MZ_OK )
if( writer_ )

Check warning on line 75 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:75:17 [readability-implicit-bool-conversion]

implicit conversion 'void *' -> 'bool'
{
Logger::error( "[ZipFile] Error closing zip for writing" );
mz_zip_writer_close( writer_ );
mz_zip_writer_delete( &writer_ );
}
mz_zip_writer_delete( &writer_ );
std::filesystem::remove_all( directory_ );
}

void archive_files( absl::Span< const std::string_view >& files ) const
void archive_files( absl::Span< const std::string_view > files ) const
{
for( const auto& file : files )
{
Expand All @@ -96,15 +95,15 @@
writer_, file_path.string().c_str(), nullptr, 0, 1 );
if( status != MZ_OK )
{
std::filesystem::remove_all( directory_ );
throw OpenGeodeBasicException( nullptr,
OpenGeodeException::TYPE::internal,
"[ZipFile::archive_file] Error adding path to zip" );
"[ZipFile::archive_file] Error adding path to zip (",
status, ")" );
}
std::filesystem::remove( file_path );
}

std::string directory() const

Check warning on line 106 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:106:9 [modernize-use-nodiscard]

function 'directory' should be marked [[nodiscard]]
{
return directory_.string();
}
Expand Down Expand Up @@ -138,18 +137,20 @@
return impl_->directory();
}

class UnzipFile::Impl

Check warning on line 140 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:140:22 [cppcoreguidelines-special-member-functions]

class 'Impl' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
{
public:
Impl( std::string_view file, std::string_view unarchive_temp_filename )

Check warning on line 143 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:143:9 [cppcoreguidelines-pro-type-member-init]

constructor does not initialize these fields: zip_data_
{
directory_ = create_directory( file, unarchive_temp_filename );
reader_ = mz_zip_reader_create();
const auto status =
mz_zip_reader_open_file( reader_, to_string( file ).c_str() );
if( status != MZ_OK )
if( !load_zip_into_memory( file ) )
{
throw OpenGeodeBasicException( nullptr,
OpenGeodeException::TYPE::internal,
"[UnzipFile] Failed to read zip file into memory" );
}
if( !open_reader() )
{
std::filesystem::remove_all( directory_ );
throw OpenGeodeBasicException( nullptr,
OpenGeodeException::TYPE::internal,
"[UnzipFile] Error opening zip for reading" );
Expand All @@ -158,38 +159,56 @@

~Impl()
{
if( reader_ )

Check warning on line 162 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:162:17 [readability-implicit-bool-conversion]

implicit conversion 'void *' -> 'bool'
{
mz_zip_reader_close( reader_ );
mz_zip_reader_delete( &reader_ );
reader_ = nullptr;
}
if( memory_stream_ )

Check warning on line 168 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:168:17 [readability-implicit-bool-conversion]

implicit conversion 'void *' -> 'bool'
{
mz_stream_close( memory_stream_ );
mz_stream_delete( &memory_stream_ );
memory_stream_ = nullptr;
}
std::filesystem::remove_all( directory_ );
mz_zip_reader_close( reader_ );
mz_zip_reader_delete( &reader_ );
}

void extract_all() const
{
auto status = mz_zip_reader_goto_first_entry( reader_ );
constexpr size_t BUF_SIZE = 1024 * 1024; // 1 MB

Check warning on line 179 in src/geode/basic/zip_file.cpp

View workflow job for this annotation

GitHub Actions / test / tidy

src/geode/basic/zip_file.cpp:179:41 [bugprone-implicit-widening-of-multiplication-result]

performing an implicit widening conversion to type 'const size_t' (aka 'const unsigned long') of a multiplication performed in type 'int'
std::vector< uint8_t > buffer( BUF_SIZE );
int status = mz_zip_reader_goto_first_entry( reader_ );
while( status == MZ_OK )
{
mz_zip_file* file_info{ nullptr };
status = mz_zip_reader_entry_get_info( reader_, &file_info );
if( status != MZ_OK )
mz_zip_file* info = nullptr;
mz_zip_reader_entry_get_info( reader_, &info );
if( !info )
{
std::filesystem::remove_all( directory_ );
throw OpenGeodeBasicException( nullptr,
OpenGeodeException::TYPE::internal,
"[UnzipFile::extract_all] Error getting entry info in "
"zip file" );
status = mz_zip_reader_goto_next_entry( reader_ );
continue;
}

auto file = directory_ / file_info->filename;
status = mz_zip_reader_entry_save_file(
reader_, file.string().c_str() );
if( status != MZ_OK )
auto out_path = directory_ / info->filename;
std::filesystem::create_directories( out_path.parent_path() );
FILE* f = fopen( out_path.string().c_str(), "wb" );
if( !f )
{
std::filesystem::remove_all( directory_ );
throw OpenGeodeBasicException( nullptr,
OpenGeodeException::TYPE::internal,
"[UnzipFile::extract_all] Error extracting entry "
"file" );
status = mz_zip_reader_goto_next_entry( reader_ );
continue;
}
status = mz_zip_reader_entry_open( reader_ );
if( status == MZ_OK )
{
int32_t bytes_read = 0;
while( ( bytes_read = mz_zip_reader_entry_read(
reader_, buffer.data(), BUF_SIZE ) )
> 0 )
{
fwrite( buffer.data(), 1, bytes_read, f );
}
mz_zip_reader_entry_close( reader_ );
}
fclose( f );
status = mz_zip_reader_goto_next_entry( reader_ );
}
}
Expand All @@ -199,9 +218,38 @@
return directory_.string();
}

private:
bool load_zip_into_memory( std::string_view file )
{
std::ifstream ifs(
to_string( file ), std::ios::binary | std::ios::ate );
if( !ifs.is_open() )
{
return false;
}
auto size = ifs.tellg();
zip_data_.resize( static_cast< size_t >( size ) );
ifs.seekg( 0 );
ifs.read( reinterpret_cast< char* >( zip_data_.data() ), size );
return ifs.good();
}

bool open_reader()
{
memory_stream_ = mz_stream_mem_create();
mz_stream_mem_set_buffer( memory_stream_,
static_cast< void* >( zip_data_.data() ),
static_cast< int32_t >( zip_data_.size() ) );
reader_ = mz_zip_reader_create();
return mz_zip_reader_open( reader_, memory_stream_ ) == MZ_OK;
}

private:
std::filesystem::path directory_;
std::vector< uint8_t > zip_data_;

void* reader_{ nullptr };
void* memory_stream_{ nullptr };
};

UnzipFile::UnzipFile(
Expand Down
Loading