ADDED: Support compressed STEP and VRML files
This adds support for opening .stpZ, step.gz and .wrz files where the files have been compressed using ZIP or gzip according to the "standard" published by the MBx volunteer forum at https://www.cax-if.org/documents/rec_prac_file_compression_v12.pdf Fixes https://gitlab.com/kicad/code/kicad/issues/2479
This commit is contained in:
parent
d7b38d10c2
commit
a38c2aad1f
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2007-2018 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2007-2020 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
|
@ -595,6 +595,13 @@ find_package( GLM 0.9.8 REQUIRED )
|
|||
add_definitions( -DGLM_FORCE_CTOR_INIT )
|
||||
include_directories( SYSTEM ${GLM_INCLUDE_DIR} )
|
||||
|
||||
#
|
||||
# Find zlib library, required
|
||||
#
|
||||
find_package(ZLIB REQUIRED)
|
||||
check_find_package_result( ZLIB_FOUND "ZLIB" )
|
||||
include_directories( SYSTEM ${ZLIB_INCLUDE_DIRS} )
|
||||
|
||||
#
|
||||
# Find CURL library, required
|
||||
#
|
||||
|
|
|
@ -17,8 +17,12 @@ add_library( s3d_plugin_oce MODULE
|
|||
loadmodel.cpp
|
||||
)
|
||||
|
||||
target_link_libraries( s3d_plugin_oce kicad_3dsg ${OCC_LIBRARIES} ${wxWidgets_LIBRARIES} )
|
||||
target_link_libraries( s3d_plugin_oce kicad_3dsg ${OCC_LIBRARIES} ${wxWidgets_LIBRARIES} ${ZLIB_LIBRARIES} )
|
||||
|
||||
target_include_directories( s3d_plugin_oce PRIVATE
|
||||
$<TARGET_PROPERTY:gzip-hpp,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
if( APPLE )
|
||||
# puts library into the main kicad.app bundle in build tree
|
||||
set_target_properties( s3d_plugin_oce PROPERTIES
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -28,12 +29,12 @@
|
|||
#include <cstring>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
#if ( defined( DEBUG_OCE ) && DEBUG_OCE > 3 )
|
||||
#include <wx/filename.h>
|
||||
#endif
|
||||
#include <decompress.hpp>
|
||||
|
||||
#include <TDocStd_Document.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
@ -261,19 +262,24 @@ struct DATA
|
|||
enum FormatType
|
||||
{
|
||||
FMT_NONE = 0,
|
||||
FMT_STEP = 1,
|
||||
FMT_IGES = 2
|
||||
FMT_STEP,
|
||||
FMT_STPZ,
|
||||
FMT_IGES
|
||||
};
|
||||
|
||||
|
||||
FormatType fileType( const char* aFileName )
|
||||
{
|
||||
wxString fname( wxString::FromUTF8Unchecked( aFileName ) );
|
||||
wxFileInputStream ifile( fname );
|
||||
wxFileName fname( wxString::FromUTF8Unchecked( aFileName ) );
|
||||
wxFileInputStream ifile( fname.GetFullPath() );
|
||||
|
||||
if( !ifile.IsOk() )
|
||||
return FMT_NONE;
|
||||
|
||||
if( fname.GetExt().MakeUpper().EndsWith( "STPZ" ) ||
|
||||
fname.GetExt().MakeUpper().EndsWith( "GZ" ) )
|
||||
return FMT_STPZ;
|
||||
|
||||
char iline[82];
|
||||
memset( iline, 0, 82 );
|
||||
ifile.Read( iline, 82 );
|
||||
|
@ -451,6 +457,47 @@ bool readSTEP( Handle(TDocStd_Document)& m_doc, const char* fname )
|
|||
}
|
||||
|
||||
|
||||
bool readSTEPZ( Handle(TDocStd_Document)& m_doc, const char* aFileName )
|
||||
{
|
||||
wxFileName fname( wxString::FromUTF8Unchecked( aFileName ) );
|
||||
wxFileInputStream ifile( fname.GetFullPath() );
|
||||
|
||||
wxFileName outFile( fname );
|
||||
|
||||
outFile.SetPath( wxStandardPaths::Get().GetTempDir() );
|
||||
outFile.SetExt( "STEP" );
|
||||
|
||||
wxFileOffset size = ifile.GetLength();
|
||||
|
||||
if( size == wxInvalidOffset )
|
||||
return false;
|
||||
|
||||
{
|
||||
wxFileOutputStream ofile( outFile.GetFullPath() );
|
||||
|
||||
if( !ofile.IsOk() )
|
||||
return false;
|
||||
|
||||
char *buffer = new char[size];
|
||||
|
||||
ifile.Read( buffer, size);
|
||||
std::string expanded = gzip::decompress( buffer, size );
|
||||
|
||||
delete buffer;
|
||||
|
||||
ofile.Write( expanded.data(), expanded.size() );
|
||||
ofile.Close();
|
||||
}
|
||||
|
||||
bool retval = readSTEP( m_doc, outFile.GetFullPath() );
|
||||
|
||||
// Cleanup our temporary file
|
||||
wxRemoveFile( outFile.GetFullPath() );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
SCENEGRAPH* LoadModel( char const* filename )
|
||||
{
|
||||
DATA data;
|
||||
|
@ -473,6 +520,12 @@ SCENEGRAPH* LoadModel( char const* filename )
|
|||
return NULL;
|
||||
break;
|
||||
|
||||
case FMT_STPZ:
|
||||
if( !readSTEPZ( data.m_doc, filename ) )
|
||||
return NULL;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -30,6 +31,9 @@
|
|||
#include "plugins/3d/3d_plugin.h"
|
||||
#include "plugins/3dapi/ifsg_all.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
SCENEGRAPH* LoadModel( char const* filename );
|
||||
|
||||
#define PLUGIN_OCE_MAJOR 1
|
||||
|
@ -62,55 +66,23 @@ void GetPluginVersion( unsigned char* Major,
|
|||
return;
|
||||
}
|
||||
|
||||
// number of extensions supported
|
||||
#ifdef _WIN32
|
||||
#define NEXTS 4
|
||||
#else
|
||||
#define NEXTS 8
|
||||
#endif
|
||||
|
||||
// number of filter sets supported
|
||||
#define NFILS 2
|
||||
|
||||
static char ext0[] = "stp";
|
||||
static char ext1[] = "step";
|
||||
static char ext2[] = "igs";
|
||||
static char ext3[] = "iges";
|
||||
|
||||
#ifdef _WIN32
|
||||
static char fil0[] = "STEP (*.stp;*.step)|*.stp;*.step";
|
||||
static char fil1[] = "IGES (*.igs;*.iges)|*.igs;*.iges";
|
||||
#else
|
||||
static char ext4[] = "STP";
|
||||
static char ext5[] = "STEP";
|
||||
static char ext6[] = "IGS";
|
||||
static char ext7[] = "IGES";
|
||||
static char fil0[] = "STEP (*.stp;*.STP;*.step;*.STEP)|*.stp;*.STP;*.step;*.STEP";
|
||||
static char fil1[] = "IGES (*.igs;*.IGS;*.iges;*.IGES)|*.igs;*.IGS;*.iges;*.IGES";
|
||||
#endif
|
||||
|
||||
static struct FILE_DATA
|
||||
{
|
||||
char const* extensions[NEXTS];
|
||||
char const* filters[NFILS];
|
||||
std::vector<std::string> extensions;
|
||||
std::vector<std::string> filters;
|
||||
|
||||
FILE_DATA()
|
||||
{
|
||||
extensions[0] = ext0;
|
||||
extensions[1] = ext1;
|
||||
extensions[2] = ext2;
|
||||
extensions[3] = ext3;
|
||||
filters[0] = fil0;
|
||||
filters[1] = fil1;
|
||||
|
||||
#ifndef _WIN32
|
||||
extensions[4] = ext4;
|
||||
extensions[5] = ext5;
|
||||
extensions[6] = ext6;
|
||||
extensions[7] = ext7;
|
||||
#ifdef _WIN32
|
||||
extensions = { "stp","step","stpZ","step.gz","igs","iges" };
|
||||
filters = { "STEP (*.stp;*.step;*.stpZ;*.step.gz)|*.stp;*.step;*.stpZ;*.step.gz",
|
||||
"IGES (*.igs;*.iges)|*.igs;*.iges" };
|
||||
#else
|
||||
extensions = { "stp","STP","stpZ","STPZ","step","STEP","step.gz","STEP.GZ","igs","IGS","iges","IGES" };
|
||||
filters = { "STEP (*.stp;*.STP;*.stpZ;*.STPZ;*.step;*.STEP;*.step.gz;*.STEP.GZ)"
|
||||
"|*.stp;*.STP;*.stpZ;*.STPZ;*.step;*.STEP;*.step.gz;*.STEP.GZ",
|
||||
"IGES (*.igs;*.IGS;*.iges;*.IGES)|*.igs;*.IGS;*.iges;*.IGES" };
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} file_data;
|
||||
|
@ -118,31 +90,31 @@ static struct FILE_DATA
|
|||
|
||||
int GetNExtensions( void )
|
||||
{
|
||||
return NEXTS;
|
||||
return file_data.extensions.size();
|
||||
}
|
||||
|
||||
|
||||
char const* GetModelExtension( int aIndex )
|
||||
{
|
||||
if( aIndex < 0 || aIndex >= NEXTS )
|
||||
if( aIndex < 0 || aIndex >= int( file_data.extensions.size() ) )
|
||||
return NULL;
|
||||
|
||||
return file_data.extensions[aIndex];
|
||||
return file_data.extensions[aIndex].c_str();
|
||||
}
|
||||
|
||||
|
||||
int GetNFilters( void )
|
||||
{
|
||||
return NFILS;
|
||||
return file_data.filters.size();
|
||||
}
|
||||
|
||||
|
||||
char const* GetFileFilter( int aIndex )
|
||||
{
|
||||
if( aIndex < 0 || aIndex >= NFILS )
|
||||
if( aIndex < 0 || aIndex >= int( file_data.filters.size() ) )
|
||||
return NULL;
|
||||
|
||||
return file_data.filters[aIndex];
|
||||
return file_data.filters[aIndex].c_str();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,7 +65,11 @@ add_library( s3d_plugin_vrml MODULE
|
|||
x3d/x3d_transform.cpp
|
||||
)
|
||||
|
||||
target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} )
|
||||
target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} ${ZLIB_LIBRARIES} )
|
||||
|
||||
target_include_directories( s3d_plugin_vrml PRIVATE
|
||||
$<TARGET_PROPERTY:gzip-hpp,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
if( APPLE )
|
||||
# puts library into the main kicad.app bundle in build tree
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -40,8 +41,13 @@
|
|||
#include "x3d.h"
|
||||
#include <clocale>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <decompress.hpp>
|
||||
|
||||
|
||||
#define PLUGIN_VRML_MAJOR 1
|
||||
#define PLUGIN_VRML_MINOR 3
|
||||
|
@ -73,47 +79,24 @@ void GetPluginVersion( unsigned char* Major,
|
|||
return;
|
||||
}
|
||||
|
||||
// number of extensions supported
|
||||
#ifdef _WIN32
|
||||
#define NEXTS 2
|
||||
#else
|
||||
#define NEXTS 4
|
||||
#endif
|
||||
|
||||
// number of filter sets supported
|
||||
#define NFILS 2
|
||||
|
||||
static char ext0[] = "wrl";
|
||||
static char ext1[] = "x3d";
|
||||
|
||||
#ifdef _WIN32
|
||||
static char fil0[] = "VRML 1.0/2.0 (*.wrl)|*.wrl";
|
||||
static char fil1[] = "X3D (*.x3d)|*.x3d";
|
||||
#else
|
||||
static char ext2[] = "WRL";
|
||||
static char ext3[] = "X3D";
|
||||
static char fil0[] = "VRML 1.0/2.0 (*.wrl;*.WRL)|*.wrl;*.WRL";
|
||||
static char fil1[] = "X3D (*.x3d;*.X3D)|*.x3d;*.X3D";
|
||||
#endif
|
||||
|
||||
static struct FILE_DATA
|
||||
{
|
||||
char const* extensions[NEXTS];
|
||||
char const* filters[NFILS];
|
||||
std::vector<std::string> extensions;
|
||||
std::vector<std::string> filters;
|
||||
|
||||
FILE_DATA()
|
||||
{
|
||||
extensions[0] = ext0;
|
||||
extensions[1] = ext1;
|
||||
filters[0] = fil0;
|
||||
filters[1] = fil1;
|
||||
|
||||
#ifndef _WIN32
|
||||
extensions[2] = ext2;
|
||||
extensions[3] = ext3;
|
||||
#ifdef _WIN32
|
||||
extensions = { "wrl", "wrz", "x3d" };
|
||||
filters = { "VRML 1.0/2.0 (*.wrl;*.wrz)|*.wrl;*.wrz",
|
||||
"X3D (*.x3d)|*.x3d" };
|
||||
#else
|
||||
extensions = { "wrl", "WRL", "wrz", "WRZ", "x3d", "X3D" };
|
||||
filters = { "VRML 1.0/2.0 (*.wrl;*.WRL;*.wrz;*.WRZ)|*.wrl;*.WRL;*.wrz;*.WRZ",
|
||||
"X3D (*.x3d;*.X3D)|*.x3d;*.X3D" };
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} file_data;
|
||||
|
@ -121,31 +104,31 @@ static struct FILE_DATA
|
|||
|
||||
int GetNExtensions( void )
|
||||
{
|
||||
return NEXTS;
|
||||
return file_data.extensions.size();
|
||||
}
|
||||
|
||||
|
||||
char const* GetModelExtension( int aIndex )
|
||||
{
|
||||
if( aIndex < 0 || aIndex >= NEXTS )
|
||||
if( aIndex < 0 || aIndex >= int( file_data.extensions.size() ) )
|
||||
return NULL;
|
||||
|
||||
return file_data.extensions[aIndex];
|
||||
return file_data.extensions[aIndex].c_str();
|
||||
}
|
||||
|
||||
|
||||
int GetNFilters( void )
|
||||
{
|
||||
return NFILS;
|
||||
return file_data.filters.size();
|
||||
}
|
||||
|
||||
|
||||
char const* GetFileFilter( int aIndex )
|
||||
{
|
||||
if( aIndex < 0 || aIndex >= NFILS )
|
||||
if( aIndex < 0 || aIndex >= int( file_data.filters.size() ) )
|
||||
return NULL;
|
||||
|
||||
return file_data.filters[aIndex];
|
||||
return file_data.filters[aIndex].c_str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -179,6 +162,39 @@ SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline )
|
|||
{
|
||||
FILE_LINE_READER* modelFile = NULL;
|
||||
SCENEGRAPH* scene = NULL;
|
||||
wxString filename = aFileName;
|
||||
wxFileName tmpfilename;
|
||||
|
||||
if( aFileName.Upper().EndsWith( "WRZ" ) )
|
||||
{
|
||||
wxFileInputStream ifile( aFileName );
|
||||
tmpfilename = wxFileName( aFileName );
|
||||
tmpfilename.SetExt( "WRL" );
|
||||
|
||||
wxFileOffset size = ifile.GetLength();
|
||||
|
||||
if( size == wxInvalidOffset )
|
||||
return nullptr;
|
||||
|
||||
{
|
||||
wxFileOutputStream ofile( tmpfilename.GetFullPath() );
|
||||
|
||||
if( !ofile.IsOk() )
|
||||
return nullptr;
|
||||
|
||||
char *buffer = new char[size];
|
||||
|
||||
ifile.Read( buffer, size);
|
||||
std::string expanded = gzip::decompress( buffer, size );
|
||||
|
||||
delete buffer;
|
||||
|
||||
ofile.Write( expanded.data(), expanded.size() );
|
||||
ofile.Close();
|
||||
}
|
||||
|
||||
filename = tmpfilename.GetFullPath();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -196,6 +212,10 @@ SCENEGRAPH* LoadVRML( const wxString& aFileName, bool useInline )
|
|||
// VRML file processor
|
||||
WRLPROC proc( modelFile );
|
||||
|
||||
// Cleanup our temporary file
|
||||
if( tmpfilename.IsOk() )
|
||||
wxRemoveFile( tmpfilename.GetFullPath() );
|
||||
|
||||
if( proc.GetVRMLType() == VRML_V1 )
|
||||
{
|
||||
wxLogTrace( MASK_VRML, " * [INFO] Processing VRML 1.0 file\n" );
|
||||
|
|
|
@ -25,6 +25,7 @@ add_subdirectory( clipper )
|
|||
add_subdirectory( compoundfilereader )
|
||||
add_subdirectory( delaunator )
|
||||
add_subdirectory( dxflib_qcad )
|
||||
add_subdirectory( gzip-hpp )
|
||||
add_subdirectory( lemon )
|
||||
add_subdirectory( libcontext )
|
||||
add_subdirectory( markdown2html )
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
add_library( gzip-hpp INTERFACE )
|
||||
|
||||
target_include_directories( gzip-hpp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
|
||||
target_sources( gzip-hpp INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/decompress.hpp
|
||||
)
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
Copyright (c) 2017, Mapbox Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,113 @@
|
|||
#ifndef ZLIB_CONST
|
||||
#define ZLIB_CONST
|
||||
#endif
|
||||
|
||||
// zlib
|
||||
#include <zlib.h>
|
||||
|
||||
// std
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace gzip {
|
||||
|
||||
inline void decompress(const char* data,
|
||||
std::size_t size,
|
||||
std::string& output,
|
||||
std::size_t max_uncompressed_size = 0,
|
||||
std::size_t buffering_size = 0)
|
||||
{
|
||||
if (buffering_size == 0)
|
||||
{
|
||||
buffering_size = (size * 2) - (size / 2) + 16;
|
||||
}
|
||||
z_stream inflate_s;
|
||||
inflate_s.zalloc = Z_NULL;
|
||||
inflate_s.zfree = Z_NULL;
|
||||
inflate_s.opaque = Z_NULL;
|
||||
inflate_s.avail_in = 0;
|
||||
inflate_s.next_in = Z_NULL;
|
||||
|
||||
// The windowBits parameter is the base two logarithm of the window size (the size of the history buffer).
|
||||
// It should be in the range 8..15 for this version of the library.
|
||||
// Larger values of this parameter result in better compression at the expense of memory usage.
|
||||
// This range of values also changes the decoding type:
|
||||
// -8 to -15 for raw deflate
|
||||
// 8 to 15 for zlib
|
||||
// (8 to 15) + 16 for gzip
|
||||
// (8 to 15) + 32 to automatically detect gzip/zlib header
|
||||
constexpr int window_bits = 15 + 32; // auto with windowbits of 15
|
||||
|
||||
constexpr unsigned int max_uint = std::numeric_limits<unsigned int>::max();
|
||||
const unsigned int size_step = buffering_size > max_uint ? max_uint : static_cast<unsigned int>(buffering_size);
|
||||
if( max_uncompressed_size != 0 && size_step > max_uncompressed_size )
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"buffer size used during decompression of gzip will use more memory then allowed, "
|
||||
"either increase the limit or reduce the buffer size" );
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
if (inflateInit2(&inflate_s, window_bits) != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("inflate init failed");
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
inflate_s.next_in = reinterpret_cast<z_const Bytef*>(data);
|
||||
inflate_s.avail_in = static_cast<unsigned int>(size);
|
||||
std::string buffer(static_cast<std::size_t>(size_step), char());
|
||||
do
|
||||
{
|
||||
inflate_s.avail_out = size_step;
|
||||
inflate_s.next_out = reinterpret_cast<Bytef*>(&buffer[0]);
|
||||
const int ret = inflate(&inflate_s, Z_FINISH);
|
||||
if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR)
|
||||
{
|
||||
std::string error_msg = inflate_s.msg;
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error(error_msg);
|
||||
}
|
||||
if (max_uncompressed_size != 0 && (output.size() + size_step - inflate_s.avail_out) > max_uncompressed_size)
|
||||
{
|
||||
inflateEnd(&inflate_s);
|
||||
throw std::runtime_error("size of output string will use more memory then intended when decompressing");
|
||||
}
|
||||
output.append(buffer, 0, size_step - inflate_s.avail_out);
|
||||
} while (inflate_s.avail_out == 0);
|
||||
const int ret2 = inflateEnd(&inflate_s);
|
||||
if (ret2 != Z_OK)
|
||||
{
|
||||
throw std::runtime_error("Unexpected gzip decompression error, state of stream was inconsistent");
|
||||
}
|
||||
}
|
||||
|
||||
inline void decompress(std::string const& input,
|
||||
std::string& output,
|
||||
std::size_t max_uncompressed_size = 0,
|
||||
std::size_t buffering_size = 0)
|
||||
{
|
||||
return decompress(input.data(), input.size(), output, max_uncompressed_size, buffering_size);
|
||||
}
|
||||
|
||||
inline std::string decompress(const char* data,
|
||||
std::size_t size,
|
||||
std::size_t max_uncompressed_size = 0,
|
||||
std::size_t buffering_size = 0)
|
||||
{
|
||||
std::string output;
|
||||
decompress(data, size, output, max_uncompressed_size, buffering_size);
|
||||
return output;
|
||||
}
|
||||
|
||||
inline std::string decompress(std::string const& input,
|
||||
std::size_t max_uncompressed_size = 0,
|
||||
std::size_t buffering_size = 0)
|
||||
{
|
||||
std::string output;
|
||||
decompress(input.data(), input.size(), output, max_uncompressed_size, buffering_size);
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace gzip
|
Loading…
Reference in New Issue