浏览代码

Merge branch 'master' into SceneCombiner_Memory_Leaks

Kim Kulling 4 年之前
父节点
当前提交
7843b24e03
共有 44 个文件被更改,包括 1104 次插入266 次删除
  1. 1 1
      code/AssetLib/3DS/3DSConverter.cpp
  2. 1 1
      code/AssetLib/3DS/3DSLoader.cpp
  3. 1 1
      code/AssetLib/3MF/D3MFOpcPackage.cpp
  4. 2 2
      code/AssetLib/AC/ACLoader.h
  5. 1 1
      code/AssetLib/ASE/ASEParser.cpp
  6. 1 1
      code/AssetLib/Collada/ColladaLoader.cpp
  7. 1 1
      code/AssetLib/FBX/FBXMeshGeometry.cpp
  8. 4 4
      code/AssetLib/FBX/FBXParser.cpp
  9. 1 1
      code/AssetLib/FBX/FBXProperties.cpp
  10. 2 2
      code/AssetLib/IFC/IFCLoader.cpp
  11. 1 1
      code/AssetLib/Irr/IRRLoader.cpp
  12. 1 1
      code/AssetLib/Irr/IRRMeshLoader.cpp
  13. 1 1
      code/AssetLib/LWO/LWOFileData.h
  14. 1 1
      code/AssetLib/LWS/LWSLoader.h
  15. 1 1
      code/AssetLib/MD2/MD2NormalTable.h
  16. 1 1
      code/AssetLib/MDC/MDCNormalTable.h
  17. 1 1
      code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp
  18. 1 1
      code/AssetLib/MMD/MMDImporter.cpp
  19. 1 1
      code/AssetLib/MMD/MMDPmxParser.cpp
  20. 1 1
      code/AssetLib/OpenGEX/OpenGEXImporter.cpp
  21. 1 1
      code/AssetLib/OpenGEX/OpenGEXImporter.h
  22. 1 1
      code/AssetLib/Q3BSP/Q3BSPFileData.h
  23. 8 8
      code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp
  24. 1 1
      code/AssetLib/X/XFileHelper.h
  25. 1 1
      code/AssetLib/XGL/XGLLoader.cpp
  26. 1 1
      code/AssetLib/glTF/glTFAsset.h
  27. 1 1
      code/AssetLib/glTF2/glTF2Asset.h
  28. 1 1
      code/Common/BaseImporter.cpp
  29. 1 1
      code/Common/FileSystemFilter.h
  30. 3 3
      code/Common/Importer.cpp
  31. 1 1
      code/Common/scene.cpp
  32. 1 1
      code/PostProcessing/RemoveRedundantMaterials.h
  33. 0 58
      contrib/zip/.gitignore
  34. 29 15
      contrib/zip/CMakeLists.txt
  35. 132 17
      contrib/zip/README.md
  36. 45 29
      contrib/zip/src/miniz.h
  37. 704 63
      contrib/zip/src/zip.c
  38. 109 27
      contrib/zip/src/zip.h
  39. 34 7
      contrib/zip/test/CMakeLists.txt
  40. 1 0
      doc/Fileformats.md
  41. 1 1
      include/assimp/DefaultIOStream.h
  42. 1 1
      include/assimp/IOSystem.hpp
  43. 1 1
      include/assimp/Importer.hpp
  44. 1 1
      include/assimp/XmlParser.h

+ 1 - 1
code/AssetLib/3DS/3DSConverter.cpp

@@ -212,7 +212,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
         mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
 
         // Be sure this is only done for the first material
-        mBackgroundImage = std::string("");
+        mBackgroundImage = std::string();
     }
 
     // At first add the base ambient color of the scene to the material

+ 1 - 1
code/AssetLib/3DS/3DSLoader.cpp

@@ -164,7 +164,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
     mRootNode->mHierarchyIndex = -1;
     mRootNode->mParent = nullptr;
     mMasterScale = 1.0f;
-    mBackgroundImage = "";
+    mBackgroundImage = std::string();
     bHasBG = false;
     bIsPrj = false;
 

+ 1 - 1
code/AssetLib/3MF/D3MFOpcPackage.cpp

@@ -188,7 +188,7 @@ bool D3MFOpcPackage::validate() {
 std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
     XmlParser xmlParser;
     if (!xmlParser.parse(stream)) {
-        return "";
+        return std::string();
     }
 
     OpcPackageRelationshipReader reader(xmlParser);

+ 2 - 2
code/AssetLib/AC/ACLoader.h

@@ -123,9 +123,9 @@ public:
     struct Object {
         Object() :
                 type(World),
-                name(""),
+                name(),
                 children(),
-                texture(""),
+                texture(),
                 texRepeat(1.f, 1.f),
                 texOffset(0.0f, 0.0f),
                 rotation(),

+ 1 - 1
code/AssetLib/ASE/ASEParser.cpp

@@ -685,7 +685,7 @@ void Parser::ParseLV3MapBlock(Texture &map) {
                     // Files with 'None' as map name are produced by
                     // an Maja to ASE exporter which name I forgot ..
                     ASSIMP_LOG_WARN("ASE: Skipping invalid map entry");
-                    map.mMapName = "";
+                    map.mMapName = std::string();
                 }
 
                 continue;

+ 1 - 1
code/AssetLib/Collada/ColladaLoader.cpp

@@ -1241,7 +1241,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
                     continue;
                 }
                 entry.mTargetId = entry.mTransformId;
-                entry.mTransformId = "";
+                entry.mTransformId = std::string();
             }
 
             entry.mChannel = &(*cit);

+ 1 - 1
code/AssetLib/FBX/FBXMeshGeometry.cpp

@@ -330,7 +330,7 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
         }
 
         const Element* Name = source["Name"];
-        m_uvNames[index] = "";
+        m_uvNames[index] = std::string();
         if(Name) {
             m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
         }

+ 4 - 4
code/AssetLib/FBX/FBXParser.cpp

@@ -462,7 +462,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
 
     if (t.Type() != TokenType_DATA) {
         err_out = "expected TOK_DATA token";
-        return "";
+        return std::string();
     }
 
     if(t.IsBinary())
@@ -470,7 +470,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
         const char* data = t.begin();
         if (data[0] != 'S') {
             err_out = "failed to parse S(tring), unexpected data type (binary)";
-            return "";
+            return std::string();
         }
 
         // read string length
@@ -484,13 +484,13 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
     const size_t length = static_cast<size_t>(t.end() - t.begin());
     if(length < 2) {
         err_out = "token is too short to hold a string";
-        return "";
+        return std::string();
     }
 
     const char* s = t.begin(), *e = t.end() - 1;
     if (*s != '\"' || *e != '\"') {
         err_out = "expected double quoted string";
-        return "";
+        return std::string();
     }
 
     return std::string(s+1,length-2);

+ 1 - 1
code/AssetLib/FBX/FBXProperties.cpp

@@ -155,7 +155,7 @@ std::string PeekPropertyName(const Element& element)
     ai_assert(element.KeyToken().StringContents() == "P");
     const TokenList& tok = element.Tokens();
     if(tok.size() < 4) {
-        return "";
+        return std::string();
     }
 
     return ParseTokenAsString(*tok[0]);

+ 2 - 2
code/AssetLib/IFC/IFCLoader.cpp

@@ -567,7 +567,7 @@ typedef std::map<std::string, std::string> Metadata;
 
 // ------------------------------------------------------------------------------------------------
 void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcProperty>, 1, 0> &set, ConversionData &conv, Metadata &properties,
-        const std::string &prefix = "",
+        const std::string &prefix = std::string(),
         unsigned int nest = 0) {
     for (const Schema_2x3::IfcProperty &property : set) {
         const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
@@ -618,7 +618,7 @@ void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcPr
                 ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
             }
         } else {
-            properties[key] = "";
+            properties[key] = std::string();
         }
     }
 }

+ 1 - 1
code/AssetLib/Irr/IRRLoader.cpp

@@ -859,7 +859,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 
 	// Check whether we can read from the file
 	if (file.get() == nullptr) {
-		throw DeadlyImportError("Failed to open IRR file " + pFile + "");
+		throw DeadlyImportError("Failed to open IRR file " + pFile);
 	}
 
 	// Construct the irrXML parser

+ 1 - 1
code/AssetLib/Irr/IRRMeshLoader.cpp

@@ -135,7 +135,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
 
 	// Check whether we can read from the file
 	if (file.get() == NULL)
-		throw DeadlyImportError("Failed to open IRRMESH file " + pFile + "");
+		throw DeadlyImportError("Failed to open IRRMESH file " + pFile);
 
 	// Construct the irrXML parser
 	XmlParser parser;

+ 1 - 1
code/AssetLib/LWO/LWOFileData.h

@@ -502,7 +502,7 @@ struct Surface {
     Surface() :
             mColor(0.78431f, 0.78431f, 0.78431f), bDoubleSided(false), mDiffuseValue(1.f), mSpecularValue(0.f), mTransparency(0.f), mGlossiness(0.4f), mLuminosity(0.f), mColorHighlights(0.f), mMaximumSmoothAngle(0.f) // 0 == not specified, no smoothing
             ,
-            mVCMap(""),
+            mVCMap(),
             mVCMapType(AI_LWO_RGBA),
             mIOR(1.f) // vakuum
             ,

+ 1 - 1
code/AssetLib/LWS/LWSLoader.h

@@ -88,7 +88,7 @@ struct NodeDesc {
             id(),
             number(0),
             parent(0),
-            name(""),
+            name(),
             isPivotSet(false),
             lightColor(1.f, 1.f, 1.f),
             lightIntensity(1.f),

+ 1 - 1
code/AssetLib/MD2/MD2NormalTable.h

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define AI_MDL_NORMALTABLE_H_INC
 
 
-float g_avNormals[162][3] = {
+const float g_avNormals[162][3] = {
 { -0.525731f,  0.000000f,  0.850651f },
 { -0.442863f,  0.238856f,  0.864188f },
 { -0.295242f,  0.000000f,  0.955423f },

+ 1 - 1
code/AssetLib/MDC/MDCNormalTable.h

@@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define MDC_NORMAL_TABLE_INCLUDED
 
 /* mdc decoding normal table */
-float mdcNormals[ 256 ][ 3 ] =
+const float mdcNormals[ 256 ][ 3 ] =
 {
     { 1.000000f, 0.000000f, 0.000000f },
     { 0.980785f, 0.195090f, 0.000000f },

+ 1 - 1
code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp

@@ -95,7 +95,7 @@ void UniqueNameGenerator::make_unique(std::vector<std::string> &names) {
     auto generate_unique_name = [&](const std::string &base_name) -> std::string {
         auto *duplicate_info = &names_to_duplicates[base_name];
 
-        std::string new_name = "";
+        std::string new_name;
 
         bool found_identical_name;
         bool tried_with_base_name_only = false;

+ 1 - 1
code/AssetLib/MMD/MMDImporter.cpp

@@ -75,7 +75,7 @@ using namespace std;
 //  Default constructor
 MMDImporter::MMDImporter() :
         m_Buffer(),
-        m_strAbsPath("") {
+        m_strAbsPath() {
     DefaultIOSystem io;
     m_strAbsPath = io.getOsSeparator();
 }

+ 1 - 1
code/AssetLib/MMD/MMDPmxParser.cpp

@@ -91,7 +91,7 @@ namespace pmx
 		std::vector<char> buffer;
 		if (size == 0)
 		{
-			return std::string("");
+			return std::string();
 		}
 		buffer.reserve(size);
 		stream->read((char*) buffer.data(), size);

+ 1 - 1
code/AssetLib/OpenGEX/OpenGEXImporter.cpp

@@ -206,7 +206,7 @@ USE_ODDLPARSER_NS
 
 //------------------------------------------------------------------------------------------------
 static void propId2StdString(Property *prop, std::string &name, std::string &key) {
-    name = key = "";
+    name = key = std::string();
     if (nullptr == prop) {
         return;
     }

+ 1 - 1
code/AssetLib/OpenGEX/OpenGEXImporter.h

@@ -79,7 +79,7 @@ struct MetricInfo {
     int m_intValue;
 
     MetricInfo()
-    : m_stringValue( "" )
+    : m_stringValue( )
     , m_floatValue( 0.0f )
     , m_intValue( -1 ) {
         // empty

+ 1 - 1
code/AssetLib/Q3BSP/Q3BSPFileData.h

@@ -178,7 +178,7 @@ struct Q3BSPModel {
         m_Textures(),
         m_Lightmaps(),
         m_EntityData(),
-        m_ModelName( "" )
+        m_ModelName()
     {
         // empty
     }

+ 8 - 8
code/AssetLib/Q3BSP/Q3BSPFileImporter.cpp

@@ -113,7 +113,7 @@ static void extractIds(const std::string &key, int &id1, int &id2) {
 // ------------------------------------------------------------------------------------------------
 //  Local helper function to normalize filenames.
 static void normalizePathName(const std::string &rPath, std::string &normalizedPath) {
-    normalizedPath = "";
+    normalizedPath = std::string();
     if (rPath.empty()) {
         return;
     }
@@ -183,7 +183,7 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene,
         throw DeadlyImportError("Failed to open file ", rFile, ".");
     }
 
-    std::string archiveName(""), mapName("");
+    std::string archiveName, mapName;
     separateMapName(rFile, archiveName, mapName);
 
     if (mapName.empty()) {
@@ -202,8 +202,8 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene,
 // ------------------------------------------------------------------------------------------------
 //  Separates the map name from the import name.
 void Q3BSPFileImporter::separateMapName(const std::string &importName, std::string &archiveName, std::string &mapName) {
-    archiveName = "";
-    mapName = "";
+    archiveName = std::string();
+    mapName = std::string();
     if (importName.empty()) {
         return;
     }
@@ -221,7 +221,7 @@ void Q3BSPFileImporter::separateMapName(const std::string &importName, std::stri
 // ------------------------------------------------------------------------------------------------
 //  Returns the first map in the map archive.
 bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, std::string &mapName) {
-    mapName = "";
+    mapName = std::string();
     std::vector<std::string> fileList;
     bspArchive.getFileListExtension(fileList, "bsp");
     if (fileList.empty()) {
@@ -440,7 +440,7 @@ void Q3BSPFileImporter::createMaterials(const Q3BSP::Q3BSPModel *pModel, aiScene
         if (-1 != textureId) {
             sQ3BSPTexture *pTexture = pModel->m_Textures[textureId];
             if (nullptr != pTexture) {
-                std::string tmp("*"), texName("");
+                std::string tmp("*"), texName;
                 tmp += pTexture->strName;
                 tmp += ".jpg";
                 normalizePathName(tmp, texName);
@@ -512,7 +512,7 @@ size_t Q3BSPFileImporter::countTriangles(const std::vector<Q3BSP::sQ3BSPFace *>
 // ------------------------------------------------------------------------------------------------
 //  Creates the faces-to-material map.
 void Q3BSPFileImporter::createMaterialMap(const Q3BSP::Q3BSPModel *pModel) {
-    std::string key("");
+    std::string key;
     std::vector<sQ3BSPFace *> *pCurFaceArray = nullptr;
     for (size_t idx = 0; idx < pModel->m_Faces.size(); idx++) {
         Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[idx];
@@ -660,7 +660,7 @@ bool Q3BSPFileImporter::expandFile(ZipArchiveIOSystem *pArchive, const std::stri
 
     if (rExtList.empty()) {
         rFile = rFilename;
-        rExt = "";
+        rExt = std::string();
         return true;
     }
 

+ 1 - 1
code/AssetLib/X/XFileHelper.h

@@ -130,7 +130,7 @@ struct Mesh {
 
     std::vector<Bone> mBones;
 
-    explicit Mesh(const std::string &pName = "") AI_NO_EXCEPT
+    explicit Mesh(const std::string &pName = std::string()) AI_NO_EXCEPT
     : mName( pName )
     , mPositions()
     , mPosFaces()

+ 1 - 1
code/AssetLib/XGL/XGLLoader.cpp

@@ -142,7 +142,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 
 	// check whether we can read from the file
 	if (stream.get() == NULL) {
-		throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile + "");
+		throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile);
 	}
 
 	// see if its compressed, if so uncompress it

+ 1 - 1
code/AssetLib/glTF/glTFAsset.h

@@ -1033,7 +1033,7 @@ namespace glTF
 
         AssetMetadata()
             : premultipliedAlpha(false)
-            , version("")
+            , version()
         {
         }
     };

+ 1 - 1
code/AssetLib/glTF2/glTF2Asset.h

@@ -1071,7 +1071,7 @@ struct AssetMetadata {
     void Read(Document &doc);
 
     AssetMetadata() :
-            version("") {}
+            version() {}
 };
 
 //

+ 1 - 1
code/Common/BaseImporter.cpp

@@ -271,7 +271,7 @@ std::string BaseImporter::GetExtension(const std::string &file) {
 
     // no file extension at all
     if (pos == std::string::npos) {
-        return "";
+        return std::string();
     }
 
     // thanks to Andy Maloney for the hint

+ 1 - 1
code/Common/FileSystemFilter.h

@@ -76,7 +76,7 @@ public:
         if (std::string::npos != (ss2 = mBase.find_last_of("\\/")))  {
             mBase.erase(ss2,mBase.length()-ss2);
         } else {
-            mBase = "";
+            mBase = std::string();
         }
 
         // make sure the directory is terminated properly

+ 3 - 3
code/Common/Importer.cpp

@@ -149,7 +149,7 @@ void AllocateFromAssimpHeap::operator delete[] ( void* data)    {
 Importer::Importer()
  : pimpl( new ImporterPimpl ) {
     pimpl->mScene = nullptr;
-    pimpl->mErrorString = "";
+    pimpl->mErrorString = std::string();
 
     // Allocate a default IO handler
     pimpl->mIOHandler = new DefaultIOSystem;
@@ -387,7 +387,7 @@ void Importer::FreeScene( ) {
     delete pimpl->mScene;
     pimpl->mScene = nullptr;
 
-    pimpl->mErrorString = "";
+    pimpl->mErrorString = std::string();
     pimpl->mException = std::exception_ptr();
     ASSIMP_END_EXCEPTION_REGION(void);
 }
@@ -434,7 +434,7 @@ aiScene* Importer::GetOrphanedScene() {
     ASSIMP_BEGIN_EXCEPTION_REGION();
     pimpl->mScene = nullptr;
 
-    pimpl->mErrorString = ""; // reset error string
+    pimpl->mErrorString = std::string();
     pimpl->mException = std::exception_ptr();
     ASSIMP_END_EXCEPTION_REGION(aiScene*);
     

+ 1 - 1
code/Common/scene.cpp

@@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/scene.h>
 
 aiNode::aiNode()
-: mName("")
+: mName()
 , mParent(nullptr)
 , mNumChildren(0)
 , mChildren(nullptr)

+ 1 - 1
code/PostProcessing/RemoveRedundantMaterials.h

@@ -81,7 +81,7 @@ public:
     /** @brief Set list of fixed (inmutable) materials
      *  @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
      */
-    void SetFixedMaterialsString(const std::string& fixed = "") {
+    void SetFixedMaterialsString(const std::string& fixed = std::string()) {
         mConfigFixedMaterials = fixed;
     }
 

+ 0 - 58
contrib/zip/.gitignore

@@ -1,58 +0,0 @@
-/build/
-/test/build/
-/xcodeproj/
-.vscode/
-
-# Object files
-*.o
-*.ko
-*.obj
-*.elf
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Libraries
-*.lib
-*.a
-*.la
-*.lo
-
-# Shared objects (inc. Windows DLLs)
-*.dll
-*.so
-*.so.*
-*.dylib
-*.suo
-
-# Executables
-*.exe
-*.out
-*.app
-*.i*86
-*.x86_64
-*.hex
-
-# Temporary
-*.swp
-.DS_Store
-
-# CMake
-CMakeScripts
-*.cmake
-
-# Xcode
-*.build
-*.xcodeproj
-zip.sln
-zip.vcxproj.filters
-zip.vcxproj
-ALL_BUILD.vcxproj.filters
-ALL_BUILD.vcxproj
-CMakeFiles/
-zip.dir/
-test/test.exe.vcxproj.filters
-test/test.exe.vcxproj
-test/test.exe.dir/
-

+ 29 - 15
contrib/zip/CMakeLists.txt

@@ -1,26 +1,29 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.4)
 
 project(zip
   LANGUAGES C
-  VERSION "0.1.18")
+  VERSION "0.1.19")
 set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
-
+set(CMAKE_VERBOSE_MAKEFILE ON)
 option(CMAKE_DISABLE_TESTING "Disable test creation" OFF)
 
-if (MSVC)
-  # Use secure functions by default and suppress warnings about "deprecated" functions
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
-elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
-        "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
-        "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Werror -pedantic")
-endif (MSVC)
-
 # zip
 set(SRC src/miniz.h src/zip.h src/zip.c)
-add_library(${PROJECT_NAME} ${SRC})
+
+# this is the "object library" target: compiles the sources only once
+add_library(OBJLIB OBJECT ${SRC})
+# shared libraries need PIC
+set_property(TARGET OBJLIB PROPERTY POSITION_INDEPENDENT_CODE 1)
+
+# static and shared libraries built from the same object files
+if (BUILD_SHARED_LIBS)
+  add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:OBJLIB>)
+  include(GenerateExportHeader)
+  generate_export_header(${PROJECT_NAME})
+else()
+  add_library(${PROJECT_NAME} STATIC $<TARGET_OBJECTS:OBJLIB>)
+endif()
+
 target_include_directories(${PROJECT_NAME} PUBLIC
   $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
   $<INSTALL_INTERFACE:include>
@@ -34,6 +37,17 @@ if (NOT CMAKE_DISABLE_TESTING)
   add_sanitizers(${PROJECT_NAME} ${test_out})
 endif()
 
+if (MSVC)
+  # Use secure functions by default and suppress warnings about "deprecated" functions
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
+elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
+        "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
+        "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror -pedantic -Wno-deprecated")
+endif (MSVC)
+
 ####
 # Installation (https://github.com/forexample/package-example) {
 

+ 132 - 17
contrib/zip/README.md

@@ -2,7 +2,6 @@
 This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
 
 [![Build](https://github.com/kuba--/zip/workflows/build/badge.svg)](https://github.com/kuba--/zip/actions?query=workflow%3Abuild)
-[![Version](https://badge.fury.io/gh/kuba--%2Fzip.svg)](https://github.com/kuba--/zip/releases)
 
 
 # The Idea
@@ -155,10 +154,52 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'r');
 zip_close(zip);
 ```
 
+* Create a new zip archive in memory (stream API).
+
+```c
+char *outbuf = NULL;
+size_t outbufsize = 0;
+
+const char *inbuf = "Append some data here...\0";
+struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
+{
+    zip_entry_open(zip, "foo-1.txt");
+    {
+        zip_entry_write(zip, inbuf, strlen(inbuf));
+    }
+    zip_entry_close(zip);
+
+    /* copy compressed stream into outbuf */
+    zip_stream_copy(zip, (void **)&outbuf, &outbufsize);
+}
+zip_stream_close(zip);
+
+free(outbuf);
+```
+
+* Extract a zip entry into a memory (stream API).
+
+```c
+char *buf = NULL;
+ssize_t bufsize = 0;
+
+struct zip_t *zip = zip_stream_open(zipstream, zipstreamsize, 0, 'r');
+{
+    zip_entry_open(zip, "foo-1.txt");
+    {
+        zip_entry_read(zip, (void **)&buf, &bufsize);
+    }
+    zip_entry_close(zip);
+}
+zip_stream_close(zip);
+
+free(buf);
+```
+
 * List of all zip entries
 ```c
 struct zip_t *zip = zip_open("foo.zip", 0, 'r');
-int i, n = zip_total_entries(zip);
+int i, n = zip_entries_total(zip);
 for (i = 0; i < n; ++i) {
     zip_entry_openbyindex(zip, i);
     {
@@ -172,6 +213,49 @@ for (i = 0; i < n; ++i) {
 zip_close(zip);
 ```
 
+* Compress folder (recursively)
+```c
+void zip_walk(struct zip_t *zip, const char *path) {
+    DIR *dir;
+    struct dirent *entry;
+    char fullpath[MAX_PATH];
+    struct stat s;
+
+    memset(fullpath, 0, MAX_PATH);
+    dir = opendir(path);
+    assert(dir);
+
+    while ((entry = readdir(dir))) {
+      // skip "." and ".."
+      if (!strcmp(entry->d_name, ".\0") || !strcmp(entry->d_name, "..\0"))
+        continue;
+
+      snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
+      stat(fullpath, &s);
+      if (S_ISDIR(s.st_mode))
+        zip_walk(zip, fullpath);
+      else {
+        zip_entry_open(zip, fullpath);
+        zip_entry_fwrite(zip, fullpath);
+        zip_entry_close(zip);
+      }
+    }
+
+    closedir(dir);
+}
+```
+
+* Deletes zip archive entries.
+```c
+char *entries[] = {"unused.txt", "remove.ini", "delete.me"};
+
+struct zip_t *zip = zip_open("foo.zip", 0, 'd');
+{
+    zip_entries_delete(zip, entries, 3);
+}
+zip_close(zip);
+```
+
 # Bindings
 Compile zip library as a dynamic library.
 ```shell
@@ -181,7 +265,7 @@ $ cmake -DBUILD_SHARED_LIBS=true ..
 $ make
 ```
 
-### Go (cgo)
+### [Go](https://golang.org) (cgo)
 ```go
 package main
 
@@ -211,7 +295,7 @@ func main() {
 }
 ```
 
-### Rust (ffi)
+### [Rust](https://www.rust-lang.org) (ffi)
 ```rust
 extern crate libc;
 use std::ffi::CString;
@@ -236,7 +320,7 @@ extern "C" {
 }
 
 fn main() {
-    let path = CString::new("/tmp/test.zip").unwrap();
+    let path = CString::new("/tmp/rust.zip").unwrap();
     let mode: libc::c_char = 'w' as libc::c_char;
 
     let entryname = CString::new("test.txt").unwrap();
@@ -258,7 +342,7 @@ fn main() {
 }
 ```
 
-### Ruby (ffi)
+### [Ruby](http://www.ruby-lang.org) (ffi)
 Install _ffi_ gem.
 ```shell
 $ gem install ffi
@@ -291,7 +375,7 @@ Zip.zip_entry_close(ptr)
 Zip.zip_close(ptr)
 ```
 
-### Python (cffi)
+### [Python](https://www.python.org) (cffi)
 Install _cffi_ package
 ```shell
 $ pip install cffi
@@ -325,7 +409,36 @@ Zip.zip_entry_close(ptr)
 Zip.zip_close(ptr)
 ```
 
-### Ring
+### [Never](https://never-lang.readthedocs.io/) (ffi)
+```never
+extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr
+extern "libzip.so" func zip_close(zip: c_ptr) -> void
+
+extern "libzip.so" func zip_entry_open(zip: c_ptr, entryname: string) -> int
+extern "libzip.so" func zip_entry_close(zip: c_ptr) -> int
+extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int
+extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int
+
+func main() -> int
+{
+    let content = "Test content"
+
+    let zip = zip_open("/tmp/never.zip", 6, 'w');
+
+    zip_entry_open(zip, "test.file");
+    zip_entry_fwrite(zip, "/tmp/test.txt");
+    zip_entry_close(zip);
+
+    zip_entry_open(zip, "test.content");
+    zip_entry_write(zip, content, length(content));
+    zip_entry_close(zip);
+
+    zip_close(zip);
+    0
+}
+```
+
+### [Ring](http://ring-lang.net)
 The language comes with RingZip based on this library
 ```ring
 load "ziplib.ring"
@@ -342,13 +455,15 @@ new Zip {
 }
 ```
 
-# Contribution Rules/Coding Standards
-No need to throw away your coding style, just do your best to follow default clang-format style.
-Apply `clang-format` to the source files before commit:
-```sh
-for file in $(git ls-files | \grep -E '\.(c|h)$' | \grep -v -- '#')
-do
-    clang-format -i $file
-done
-```
+# Check out more cool projects which use this library:
+- [Filament](https://github.com/google/filament): Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
+- [Hermes JS Engine](https://github.com/facebook/hermes): Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode.
+- [Open Asset Import Library](https://github.com/assimp/assimp): A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
+- [PowerToys](https://github.com/microsoft/PowerToys): Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity.
+- [The Ring Programming Language](https://ring-lang.github.io): Innovative and practical general-purpose multi-paradigm language.
+- [The V Programming Language](https://github.com/vlang/v): Simple, fast, safe, compiled. For developing maintainable software.
+- [TIC-80](https://github.com/nesbox/TIC-80): TIC-80 is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games.
+- [Urho3D](https://github.com/urho3d/Urho3D): Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D.
+- [Vcpkg](https://github.com/microsoft/vcpkg): Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS.
+- [and more...](https://grep.app/search?q=kuba--/zip)
 

+ 45 - 29
contrib/zip/src/miniz.h

@@ -400,7 +400,7 @@ typedef enum {
 #ifndef MINIZ_NO_ZLIB_APIS
 
 // Heap allocation callbacks.
-// Note that mz_alloc_func parameter types purpsosely differ from zlib's:
+// Note that mz_alloc_func parameter types purposely differ from zlib's:
 // items/size is size_t, not unsigned long.
 typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
 typedef void (*mz_free_func)(void *opaque, void *address);
@@ -2194,7 +2194,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r,
             } else
               tree_cur = pTable->m_tree[-tree_cur - 1];
           }
-          tree_cur -= ((rev_code >>= 1) & 1);
+          rev_code >>= 1;
+          tree_cur -= (rev_code & 1);
           pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
         }
         if (r->m_type == 2) {
@@ -3970,6 +3971,7 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits,
 
 #ifdef _MSC_VER
 #pragma warning(push)
+#pragma warning(disable : 4121 4127 4244)
 #pragma warning(disable : 4204) // nonstandard extension used : non-constant
                                 // aggregate initializer (also supported by GNU
                                 // C and C99, so no big deal)
@@ -4098,10 +4100,6 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
                                                     pLen_out, 6, MZ_FALSE);
 }
 
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
 // ------------------- .ZIP archive reading
 
 #ifndef MINIZ_NO_ARCHIVE_APIS
@@ -4112,18 +4110,39 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
 #include <stdio.h>
 #include <sys/stat.h>
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__MINGW32__)
+
+#include <windows.h>
+
+static wchar_t *str2wstr(const char *str) {
+  int len = (int) strlen(str) + 1;
+  wchar_t *wstr = malloc(len * sizeof(wchar_t));
+  MultiByteToWideChar(CP_UTF8, 0, str, len * sizeof(char), wstr, len);
+  return wstr;
+}
+
 static FILE *mz_fopen(const char *pFilename, const char *pMode) {
-  FILE *pFile = NULL;
-  fopen_s(&pFile, pFilename, pMode);
+  wchar_t *wFilename = str2wstr(pFilename);
+  wchar_t *wMode = str2wstr(pMode);
+  FILE *pFile = _wfopen(wFilename, wMode);
+
+  free(wFilename);
+  free(wMode);
+
   return pFile;
 }
+
 static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
-  FILE *pFile = NULL;
-  if (freopen_s(&pFile, pPath, pMode, pStream))
-    return NULL;
+  wchar_t *wPath = str2wstr(pPath);
+  wchar_t *wMode = str2wstr(pMode);
+  FILE *pFile = _wfreopen(wPath, wMode, pStream);
+
+  free(wPath);
+  free(wMode);
+
   return pFile;
 }
+
 #ifndef MINIZ_NO_TIME
 #include <sys/utime.h>
 #endif
@@ -4144,7 +4163,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
 #include <sys/utime.h>
 #endif
 #define MZ_FILE FILE
-#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FOPEN(f, m) mz_fopen
 #define MZ_FCLOSE fclose
 #define MZ_FREAD fread
 #define MZ_FWRITE fwrite
@@ -4153,7 +4172,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
 #define MZ_FILE_STAT_STRUCT _stat
 #define MZ_FILE_STAT _stat
 #define MZ_FFLUSH fflush
-#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_FREOPEN(f, m, s) mz_freopen
 #define MZ_DELETE_FILE remove
 #elif defined(__TINYC__)
 #ifndef MINIZ_NO_TIME
@@ -5361,13 +5380,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
   } else {
     // Temporarily allocate a read buffer.
     read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
-#if defined(_MSC_VER) && !defined(__clang__)
-    if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
-        (read_buf_size > 0x7FFFFFFF))
-#else
     if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
-#endif
       return MZ_FALSE;
+
     if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
                                             (size_t)read_buf_size)))
       return MZ_FALSE;
@@ -5454,11 +5469,7 @@ void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index,
   uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
 
   alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
-#if defined(_MSC_VER) && !defined(__clang__)
-  if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
-#else
   if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
-#endif
     return NULL;
   if (NULL ==
       (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
@@ -5560,14 +5571,10 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
   if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
     // The file is stored or the caller has requested the compressed data.
     if (pZip->m_pState->m_pMem) {
-#if defined (_MSC_VER) && !defined(__clang__)
-      if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
-          (file_stat.m_comp_size > 0xFFFFFFFF))
-#else
       if (((sizeof(size_t) == sizeof(mz_uint32))) &&
           (file_stat.m_comp_size > 0xFFFFFFFF))
-#endif
         return MZ_FALSE;
+
       if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
                     (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
         status = TINFL_STATUS_FAILED;
@@ -6085,7 +6092,7 @@ mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) {
   if (!pZip->m_file_offset_alignment)
     return 0;
   n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
-  return (mz_uint)(pZip->m_file_offset_alignment - n) &
+  return (pZip->m_file_offset_alignment - n) &
          (pZip->m_file_offset_alignment - 1);
 }
 
@@ -6289,7 +6296,10 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
                                mz_uint32 ext_attributes) {
   mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
   mz_uint16 method = 0, dos_time = 0, dos_date = 0;
+#ifndef MINIZ_NO_TIME
   time_t file_modified_time;
+#endif
+
   mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
                                                         comp_size = 0;
   size_t archive_name_size;
@@ -6326,10 +6336,12 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
         comment_size + archive_name_size) > 0xFFFFFFFF))
     return MZ_FALSE;
 
+#ifndef MINIZ_NO_TIME
   memset(&file_modified_time, 0, sizeof(file_modified_time));
   if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
     return MZ_FALSE;
   mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
+#endif
 
   pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
   if (!pSrc_file)
@@ -6814,6 +6826,10 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
   return p;
 }
 
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
 #endif // #ifndef MINIZ_NO_STDIO
 
 #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS

文件差异内容过多而无法显示
+ 704 - 63
contrib/zip/src/zip.c


+ 109 - 27
contrib/zip/src/zip.h

@@ -15,19 +15,11 @@
 #include <string.h>
 #include <sys/types.h>
 
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4127 )
-#endif //_MSC_VER
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) &&               \
-    !defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) &&              \
-    !defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DECLARED)
-
+#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
 // 64-bit Windows is the only mainstream platform
 // where sizeof(long) != sizeof(void*)
 #ifdef _WIN64
@@ -35,15 +27,6 @@ typedef long long ssize_t; /* byte count or error */
 #else
 typedef long ssize_t; /* byte count or error */
 #endif
-
-#define _SSIZE_T_DEFINED
-#define _SSIZE_T_DEFINED_
-#define __DEFINED_ssize_t
-#define __ssize_t_defined
-#define _SSIZE_T
-#define _SSIZE_T_
-#define _SSIZE_T_DECLARED
-
 #endif
 
 #ifndef MAX_PATH
@@ -64,9 +47,49 @@ typedef long ssize_t; /* byte count or error */
 /**
  * Default zip compression level.
  */
-
 #define ZIP_DEFAULT_COMPRESSION_LEVEL 6
 
+/**
+ * Error codes
+ */
+#define ZIP_ENOINIT -1      // not initialized
+#define ZIP_EINVENTNAME -2  // invalid entry name
+#define ZIP_ENOENT -3       // entry not found
+#define ZIP_EINVMODE -4     // invalid zip mode
+#define ZIP_EINVLVL -5      // invalid compression level
+#define ZIP_ENOSUP64 -6     // no zip 64 support
+#define ZIP_EMEMSET -7      // memset error
+#define ZIP_EWRTENT -8      // cannot write data to entry
+#define ZIP_ETDEFLINIT -9   // cannot initialize tdefl compressor
+#define ZIP_EINVIDX -10     // invalid index
+#define ZIP_ENOHDR -11      // header not found
+#define ZIP_ETDEFLBUF -12   // cannot flush tdefl buffer
+#define ZIP_ECRTHDR -13     // cannot create entry header
+#define ZIP_EWRTHDR -14     // cannot write entry header
+#define ZIP_EWRTDIR -15     // cannot write to central dir
+#define ZIP_EOPNFILE -16    // cannot open file
+#define ZIP_EINVENTTYPE -17 // invalid entry type
+#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
+#define ZIP_ENOFILE -19     // file not found
+#define ZIP_ENOPERM -20     // no permission
+#define ZIP_EOOMEM -21      // out of memory
+#define ZIP_EINVZIPNAME -22 // invalid zip archive name
+#define ZIP_EMKDIR -23      // make dir error
+#define ZIP_ESYMLINK -24    // symlink error
+#define ZIP_ECLSZIP -25     // close archive error
+#define ZIP_ECAPSIZE -26    // capacity size too small
+#define ZIP_EFSEEK -27      // fseek error
+#define ZIP_EFREAD -28      // fread error
+#define ZIP_EFWRITE -29     // fwrite error
+
+/**
+ * Looks up the error message string coresponding to an error number.
+ * @param errnum error number
+ * @return error message string coresponding to errnum or NULL if error is not
+ * found.
+ */
+extern const char *zip_strerror(int errnum);
+
 /**
  * @struct zip_t
  *
@@ -242,8 +265,8 @@ extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
  *
  * @note ensure supplied output buffer is large enough.
  *       zip_entry_size function (returns uncompressed size for the current
- *       entry) can be handy to estimate how big buffer is needed. for large
- * entries, please take a look at zip_entry_extract function.
+ *       entry) can be handy to estimate how big buffer is needed.
+ *       For large entries, please take a look at zip_entry_extract function.
  *
  * @return the return code - the number of bytes actually read on success.
  *         Otherwise a -1 on error (e.g. bufsize is not large enough).
@@ -285,7 +308,71 @@ zip_entry_extract(struct zip_t *zip,
  * @return the return code - the number of entries on success, negative number
  *         (< 0) on error.
  */
-extern int zip_total_entries(struct zip_t *zip);
+extern int zip_entries_total(struct zip_t *zip);
+
+/**
+ * Deletes zip archive entries.
+ *
+ * @param zip zip archive handler.
+ * @param entries array of zip archive entries to be deleted.
+ * @param len the number of entries to be deleted.
+ * @return the number of deleted entries, or negative number (< 0) on error.
+ */
+extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
+                              size_t len);
+
+/**
+ * Extracts a zip archive stream into directory.
+ *
+ * If on_extract is not NULL, the callback will be called after
+ * successfully extracted each zip entry.
+ * Returning a negative value from the callback will cause abort and return an
+ * error. The last argument (void *arg) is optional, which you can use to pass
+ * data to the on_extract callback.
+ *
+ * @param stream zip archive stream.
+ * @param size stream size.
+ * @param dir output directory.
+ * @param on_extract on extract callback.
+ * @param arg opaque pointer.
+ *
+ * @return the return code - 0 on success, negative number (< 0) on error.
+ */
+extern int zip_stream_extract(const char *stream, size_t size, const char *dir,
+                              int (*on_extract)(const char *filename,
+                                                void *arg),
+                              void *arg);
+
+/**
+ * Opens zip archive stream into memory.
+ *
+ * @param stream zip archive stream.
+ * @param size stream size.
+ *
+ * @return the zip archive handler or NULL on error
+ */
+extern struct zip_t *zip_stream_open(const char *stream, size_t size, int level,
+                                     char mode);
+
+/**
+ * Copy zip archive stream output buffer.
+ *
+ * @param zip zip archive handler.
+ * @param buf output buffer. User should free buf.
+ * @param bufsize output buffer size (in bytes).
+ *
+ * @return copy size
+ */
+extern ssize_t zip_stream_copy(struct zip_t *zip, void **buf, ssize_t *bufsize);
+
+/**
+ * Close zip archive releases resources.
+ *
+ * @param zip zip archive handler.
+ *
+ * @return
+ */
+extern void zip_stream_close(struct zip_t *zip);
 
 /**
  * Creates a new archive and puts files into a single zip archive.
@@ -319,11 +406,6 @@ extern int zip_extract(const char *zipname, const char *dir,
                        void *arg);
 
 /** @} */
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif //_MSC_VER
-
 #ifdef __cplusplus
 }
 #endif

+ 34 - 7
contrib/zip/test/CMakeLists.txt

@@ -1,11 +1,38 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.4)
 
-# test
-set(test_out test.out)
+# tests
+set(test_write_out test_write.out)
+add_executable(${test_write_out} test_write.c)
+target_link_libraries(${test_write_out} zip)
+add_test(NAME ${test_write_out} COMMAND ${test_write_out})
+set(test_write_out ${test_write_out} PARENT_SCOPE)
 
-add_executable(${test_out} test.c)
-target_link_libraries(${test_out} zip)
+set(test_append_out test_append.out)
+add_executable(${test_append_out} test_append.c)
+target_link_libraries(${test_append_out} zip)
+add_test(NAME ${test_append_out} COMMAND ${test_append_out})
+set(test_append_out ${test_append_out} PARENT_SCOPE)
 
-add_test(NAME ${test_out} COMMAND ${test_out})
+set(test_read_out test_read.out)
+add_executable(${test_read_out} test_read.c)
+target_link_libraries(${test_read_out} zip)
+add_test(NAME ${test_read_out} COMMAND ${test_read_out})
+set(test_read_out ${test_read_out} PARENT_SCOPE)
 
-set(test_out ${test_out} PARENT_SCOPE)
+set(test_extract_out test_extract.out)
+add_executable(${test_extract_out} test_extract.c)
+target_link_libraries(${test_extract_out} zip)
+add_test(NAME ${test_extract_out} COMMAND ${test_extract_out})
+set(test_extract_out ${test_extract_out} PARENT_SCOPE)
+
+set(test_entry_out test_entry.out)
+add_executable(${test_entry_out} test_entry.c)
+target_link_libraries(${test_entry_out} zip)
+add_test(NAME ${test_entry_out} COMMAND ${test_entry_out})
+set(test_entry_out ${test_entry_out} PARENT_SCOPE)
+
+set(test_permissions_out test_permissions.out)
+add_executable(${test_permissions_out} test_permissions.c)
+target_link_libraries(${test_permissions_out} zip)
+add_test(NAME ${test_permissions_out} COMMAND ${test_permissions_out})
+set(test_permissions_out ${test_permissions_out} PARENT_SCOPE)

+ 1 - 0
doc/Fileformats.md

@@ -81,6 +81,7 @@ __Exporters__:
 - JSON (for WebGl, via https://github.com/acgessler/assimp2json)
 - ASSBIN
 - STEP
+- [PBRTv4](https://github.com/mmp/pbrt-v4)
 - glTF 1.0 (partial)
 - glTF 2.0 (partial)
 - 3MF ( experimental )

+ 1 - 1
include/assimp/DefaultIOStream.h

@@ -119,7 +119,7 @@ private:
 AI_FORCE_INLINE
 DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
 : mFile(nullptr)
-, mFilename("")
+, mFilename()
 , mCachedSize(SIZE_MAX) {
     // empty
 }

+ 1 - 1
include/assimp/IOSystem.hpp

@@ -294,7 +294,7 @@ bool IOSystem::PushDirectory( const std::string &path ) {
 AI_FORCE_INLINE
 const std::string &IOSystem::CurrentDirectory() const {
     if ( m_pathStack.empty() ) {
-        static const std::string Dummy("");
+        static const std::string Dummy;
         return Dummy;
     }
     return m_pathStack[ m_pathStack.size()-1 ];

+ 1 - 1
include/assimp/Importer.hpp

@@ -286,7 +286,7 @@ public:
      * @see GetPropertyInteger()
      */
     std::string GetPropertyString(const char *szName,
-            const std::string &sErrorReturn = "") const;
+            const std::string &sErrorReturn = std::string()) const;
 
     // -------------------------------------------------------------------
     /** Get a matrix configuration property

+ 1 - 1
include/assimp/XmlParser.h

@@ -239,7 +239,7 @@ public:
     }
 
     static inline bool getValueAsString( XmlNode &node, std::string &text ) {
-        text = "";
+        text = std::string();
         if (node.empty()) {
             return false;
         }

部分文件因为文件数量过多而无法显示