Merge branch 'master' into fix-file-detection

pull/3796/head
Kim Kulling 2021-05-02 19:41:33 +02:00 committed by GitHub
commit f29828f657
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 1330 additions and 462 deletions

View File

@ -8,10 +8,10 @@ A library to import and export various 3d-model-formats including scene-post-pro
<img alt="Coverity Scan Build Status" <img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5607/badge.svg"/> src="https://scan.coverity.com/projects/5607/badge.svg"/>
</a> </a>
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master) [![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/5be56faac64f46fc941ac890fb4febef)](https://www.codacy.com/app/kimkulling/assimp?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/) [![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
<br> <br>

View File

@ -212,7 +212,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE); mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
// Be sure this is only done for the first material // 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 // At first add the base ambient color of the scene to the material

View File

@ -61,20 +61,10 @@ namespace D3DS {
#include <assimp/Compiler/pushpack1.h> #include <assimp/Compiler/pushpack1.h>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks /** Defines chunks and data structures.
* and data structures.
*/ */
class Discreet3DS { namespace Discreet3DS {
private:
Discreet3DS() AI_NO_EXCEPT {
// empty
}
~Discreet3DS() {
// empty
}
public:
//! data structure for a single chunk in a .3ds file //! data structure for a single chunk in a .3ds file
struct Chunk { struct Chunk {
uint16_t Flag; uint16_t Flag;
@ -314,7 +304,7 @@ public:
// camera sub-chunks // camera sub-chunks
CHUNK_CAM_RANGES = 0x4720 CHUNK_CAM_RANGES = 0x4720
}; };
}; }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing a 3ds mesh face */ /** Helper structure representing a 3ds mesh face */

View File

@ -164,7 +164,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
mRootNode->mHierarchyIndex = -1; mRootNode->mHierarchyIndex = -1;
mRootNode->mParent = nullptr; mRootNode->mParent = nullptr;
mMasterScale = 1.0f; mMasterScale = 1.0f;
mBackgroundImage = ""; mBackgroundImage = std::string();
bHasBG = false; bHasBG = false;
bIsPrj = false; bIsPrj = false;
@ -981,9 +981,9 @@ void Discreet3DSImporter::ParseMeshChunk() {
mMesh.mMat.a3 = stream->GetF4(); mMesh.mMat.a3 = stream->GetF4();
mMesh.mMat.b3 = stream->GetF4(); mMesh.mMat.b3 = stream->GetF4();
mMesh.mMat.c3 = stream->GetF4(); mMesh.mMat.c3 = stream->GetF4();
mMesh.mMat.d1 = stream->GetF4(); mMesh.mMat.a4 = stream->GetF4();
mMesh.mMat.d2 = stream->GetF4(); mMesh.mMat.b4 = stream->GetF4();
mMesh.mMat.d3 = stream->GetF4(); mMesh.mMat.c4 = stream->GetF4();
} break; } break;
case Discreet3DS::CHUNK_MAPLIST: { case Discreet3DS::CHUNK_MAPLIST: {

View File

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

View File

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

View File

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

View File

@ -88,7 +88,7 @@ using namespace Assimp::Blender;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static const aiImporterDesc blenderDesc = { static const aiImporterDesc blenderDesc = {
"Blender 3D Importer \nhttp://www.blender3d.org", "Blender 3D Importer (http://www.blender3d.org)",
"", "",
"", "",
"No animation support yet", "No animation support yet",

View File

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

View File

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

View File

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

View File

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

View File

@ -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, 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) { unsigned int nest = 0) {
for (const Schema_2x3::IfcProperty &property : set) { for (const Schema_2x3::IfcProperty &property : set) {
const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name; 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); ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
} }
} else { } else {
properties[key] = ""; properties[key] = std::string();
} }
} }
} }

View File

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

View File

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

View File

@ -502,7 +502,7 @@ struct Surface {
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 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), mVCMapType(AI_LWO_RGBA),
mIOR(1.f) // vakuum mIOR(1.f) // vakuum
, ,

View File

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

View File

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

View File

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

View File

@ -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 generate_unique_name = [&](const std::string &base_name) -> std::string {
auto *duplicate_info = &names_to_duplicates[base_name]; auto *duplicate_info = &names_to_duplicates[base_name];
std::string new_name = ""; std::string new_name;
bool found_identical_name; bool found_identical_name;
bool tried_with_base_name_only = false; bool tried_with_base_name_only = false;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -130,7 +130,7 @@ struct Mesh {
std::vector<Bone> mBones; 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 ) : mName( pName )
, mPositions() , mPositions()
, mPosFaces() , mPosFaces()

View File

@ -142,7 +142,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// check whether we can read from the file // check whether we can read from the file
if (stream.get() == NULL) { 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 // see if its compressed, if so uncompress it

View File

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

View File

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

View File

@ -162,6 +162,9 @@ inline static bool ReadValue(Value &val, T &out) {
template <class T> template <class T>
inline static bool ReadMember(Value &obj, const char *id, T &out) { inline static bool ReadMember(Value &obj, const char *id, T &out) {
if (!obj.IsObject()) {
return false;
}
Value::MemberIterator it = obj.FindMember(id); Value::MemberIterator it = obj.FindMember(id);
if (it != obj.MemberEnd()) { if (it != obj.MemberEnd()) {
return ReadHelper<T>::Read(it->value, out); return ReadHelper<T>::Read(it->value, out);
@ -176,6 +179,9 @@ inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
} }
inline Value *FindMember(Value &val, const char *id) { inline Value *FindMember(Value &val, const char *id) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(id); Value::MemberIterator it = val.FindMember(id);
return (it != val.MemberEnd()) ? &it->value : nullptr; return (it != val.MemberEnd()) ? &it->value : nullptr;
} }
@ -193,6 +199,9 @@ inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const ch
// Look-up functions with type checks. Context and extra context help the user identify the problem if there's an error. // Look-up functions with type checks. Context and extra context help the user identify the problem if there's an error.
inline Value *FindStringInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) { inline Value *FindStringInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId); Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) { if (it == val.MemberEnd()) {
return nullptr; return nullptr;
@ -204,6 +213,9 @@ inline Value *FindStringInContext(Value &val, const char *memberId, const char*
} }
inline Value *FindNumberInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) { inline Value *FindNumberInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId); Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) { if (it == val.MemberEnd()) {
return nullptr; return nullptr;
@ -215,6 +227,9 @@ inline Value *FindNumberInContext(Value &val, const char *memberId, const char*
} }
inline Value *FindUIntInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) { inline Value *FindUIntInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId); Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) { if (it == val.MemberEnd()) {
return nullptr; return nullptr;
@ -226,6 +241,9 @@ inline Value *FindUIntInContext(Value &val, const char *memberId, const char* co
} }
inline Value *FindArrayInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) { inline Value *FindArrayInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId); Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) { if (it == val.MemberEnd()) {
return nullptr; return nullptr;
@ -237,6 +255,9 @@ inline Value *FindArrayInContext(Value &val, const char *memberId, const char* c
} }
inline Value *FindObjectInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) { inline Value *FindObjectInContext(Value &val, const char *memberId, const char* context, const char* extraContext = nullptr) {
if (!val.IsObject()) {
return nullptr;
}
Value::MemberIterator it = val.FindMember(memberId); Value::MemberIterator it = val.FindMember(memberId);
if (it == val.MemberEnd()) { if (it == val.MemberEnd()) {
return nullptr; return nullptr;
@ -886,7 +907,7 @@ inline void Accessor::Read(Value &obj, Asset &r) {
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE); componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
{ {
const Value* countValue = FindUInt(obj, "count"); const Value* countValue = FindUInt(obj, "count");
if (!countValue || countValue->GetInt() < 1) if (!countValue || countValue->GetUint() < 1)
{ {
throw DeadlyImportError("A strictly positive count value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")"); throw DeadlyImportError("A strictly positive count value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
} }
@ -1105,7 +1126,9 @@ inline Accessor::Indexer::Indexer(Accessor &acc) :
template <class T> template <class T>
T Accessor::Indexer::GetValue(int i) { T Accessor::Indexer::GetValue(int i) {
ai_assert(data); ai_assert(data);
ai_assert(i * stride < accessor.GetMaxByteSize()); if (i * stride >= accessor.GetMaxByteSize()) {
throw DeadlyImportError("GLTF: Invalid index ", i, ", count out of range for buffer with stride ", stride, " and size ", accessor.GetMaxByteSize(), ".");
}
// Ensure that the memcpy doesn't overwrite the local. // Ensure that the memcpy doesn't overwrite the local.
const size_t sizeToCopy = std::min(elemSize, sizeof(T)); const size_t sizeToCopy = std::min(elemSize, sizeof(T));
T value = T(); T value = T();

View File

@ -1172,7 +1172,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
static const float kMillisecondsFromSeconds = 1000.f; static const float kMillisecondsFromSeconds = 1000.f;
if (samplers.translation) { if (samplers.translation && samplers.translation->input && samplers.translation->output) {
float *times = nullptr; float *times = nullptr;
samplers.translation->input->ExtractData(times); samplers.translation->input->ExtractData(times);
aiVector3D *values = nullptr; aiVector3D *values = nullptr;
@ -1196,7 +1196,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
anim->mPositionKeys->mValue.z = node.translation.value[2]; anim->mPositionKeys->mValue.z = node.translation.value[2];
} }
if (samplers.rotation) { if (samplers.rotation && samplers.rotation->input && samplers.rotation->output) {
float *times = nullptr; float *times = nullptr;
samplers.rotation->input->ExtractData(times); samplers.rotation->input->ExtractData(times);
aiQuaternion *values = nullptr; aiQuaternion *values = nullptr;
@ -1224,7 +1224,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
anim->mRotationKeys->mValue.w = node.rotation.value[3]; anim->mRotationKeys->mValue.w = node.rotation.value[3];
} }
if (samplers.scale) { if (samplers.scale && samplers.scale->input && samplers.scale->output) {
float *times = nullptr; float *times = nullptr;
samplers.scale->input->ExtractData(times); samplers.scale->input->ExtractData(times);
aiVector3D *values = nullptr; aiVector3D *values = nullptr;

View File

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

View File

@ -90,9 +90,11 @@ DefaultIOStream::~DefaultIOStream() {
size_t DefaultIOStream::Read(void *pvBuffer, size_t DefaultIOStream::Read(void *pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) { size_t pCount) {
if (0 == pCount) {
return 0;
}
ai_assert(nullptr != pvBuffer); ai_assert(nullptr != pvBuffer);
ai_assert(0 != pSize); ai_assert(0 != pSize);
ai_assert(0 != pCount);
return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0); return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
} }

View File

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

View File

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

View File

@ -359,7 +359,7 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vector<At
// generate the output texture list + an offset table for all texture indices // generate the output texture list + an offset table for all texture indices
if (dest->mNumTextures) { if (dest->mNumTextures) {
aiTexture **pip = dest->mTextures = new aiTexture *[dest->mNumMaterials]; aiTexture **pip = dest->mTextures = new aiTexture *[dest->mNumTextures];
cnt = 0; cnt = 0;
for (unsigned int n = 0; n < src.size(); ++n) { for (unsigned int n = 0; n < src.size(); ++n) {
SceneHelper *cur = &src[n]; SceneHelper *cur = &src[n];
@ -638,6 +638,8 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vector<At
deleteMe->mMaterials = nullptr; deleteMe->mMaterials = nullptr;
delete[] deleteMe->mAnimations; delete[] deleteMe->mAnimations;
deleteMe->mAnimations = nullptr; deleteMe->mAnimations = nullptr;
delete[] deleteMe->mTextures;
deleteMe->mTextures = nullptr;
deleteMe->mRootNode = nullptr; deleteMe->mRootNode = nullptr;

View File

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

View File

@ -81,7 +81,7 @@ public:
/** @brief Set list of fixed (inmutable) materials /** @brief Set list of fixed (inmutable) materials
* @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST * @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; mConfigFixedMaterials = fixed;
} }

View File

@ -135,7 +135,9 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin(); std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
aiMesh *const mesh = pScene->mMeshes[i]; aiMesh *const mesh = pScene->mMeshes[i];
ai_assert(0 != mesh->mPrimitiveTypes); if (mesh->mPrimitiveTypes == 0) {
throw DeadlyImportError("Mesh with invalid primitive type: ", mesh->mName.C_Str());
}
// if there's just one primitive type in the mesh there's nothing to do for us // if there's just one primitive type in the mesh there's nothing to do for us
unsigned int num = 0; unsigned int num = 0;

View File

@ -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/

View File

@ -1,26 +1,29 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.4)
project(zip project(zip
LANGUAGES C LANGUAGES C
VERSION "0.1.18") VERSION "0.1.19")
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
set(CMAKE_VERBOSE_MAKEFILE ON)
option(CMAKE_DISABLE_TESTING "Disable test creation" OFF) 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 # zip
set(SRC src/miniz.h src/zip.h src/zip.c) 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 target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include> $<INSTALL_INTERFACE:include>
@ -34,6 +37,17 @@ if (NOT CMAKE_DISABLE_TESTING)
add_sanitizers(${PROJECT_NAME} ${test_out}) add_sanitizers(${PROJECT_NAME} ${test_out})
endif() 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) { # Installation (https://github.com/forexample/package-example) {

View File

@ -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. 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) [![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 # The Idea
@ -155,10 +154,52 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'r');
zip_close(zip); 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 * List of all zip entries
```c ```c
struct zip_t *zip = zip_open("foo.zip", 0, 'r'); 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) { for (i = 0; i < n; ++i) {
zip_entry_openbyindex(zip, i); zip_entry_openbyindex(zip, i);
{ {
@ -172,6 +213,49 @@ for (i = 0; i < n; ++i) {
zip_close(zip); 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 # Bindings
Compile zip library as a dynamic library. Compile zip library as a dynamic library.
```shell ```shell
@ -181,7 +265,7 @@ $ cmake -DBUILD_SHARED_LIBS=true ..
$ make $ make
``` ```
### Go (cgo) ### [Go](https://golang.org) (cgo)
```go ```go
package main package main
@ -211,7 +295,7 @@ func main() {
} }
``` ```
### Rust (ffi) ### [Rust](https://www.rust-lang.org) (ffi)
```rust ```rust
extern crate libc; extern crate libc;
use std::ffi::CString; use std::ffi::CString;
@ -236,7 +320,7 @@ extern "C" {
} }
fn main() { 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 mode: libc::c_char = 'w' as libc::c_char;
let entryname = CString::new("test.txt").unwrap(); 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. Install _ffi_ gem.
```shell ```shell
$ gem install ffi $ gem install ffi
@ -291,7 +375,7 @@ Zip.zip_entry_close(ptr)
Zip.zip_close(ptr) Zip.zip_close(ptr)
``` ```
### Python (cffi) ### [Python](https://www.python.org) (cffi)
Install _cffi_ package Install _cffi_ package
```shell ```shell
$ pip install cffi $ pip install cffi
@ -325,7 +409,36 @@ Zip.zip_entry_close(ptr)
Zip.zip_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 The language comes with RingZip based on this library
```ring ```ring
load "ziplib.ring" load "ziplib.ring"
@ -342,13 +455,15 @@ new Zip {
} }
``` ```
# Contribution Rules/Coding Standards # Check out more cool projects which use this library:
No need to throw away your coding style, just do your best to follow default clang-format style. - [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.
Apply `clang-format` to the source files before commit: - [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.
```sh - [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.
for file in $(git ls-files | \grep -E '\.(c|h)$' | \grep -v -- '#') - [PowerToys](https://github.com/microsoft/PowerToys): Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity.
do - [The Ring Programming Language](https://ring-lang.github.io): Innovative and practical general-purpose multi-paradigm language.
clang-format -i $file - [The V Programming Language](https://github.com/vlang/v): Simple, fast, safe, compiled. For developing maintainable software.
done - [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)

View File

@ -400,7 +400,7 @@ typedef enum {
#ifndef MINIZ_NO_ZLIB_APIS #ifndef MINIZ_NO_ZLIB_APIS
// Heap allocation callbacks. // 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. // items/size is size_t, not unsigned long.
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
typedef void (*mz_free_func)(void *opaque, void *address); typedef void (*mz_free_func)(void *opaque, void *address);
@ -2194,7 +2194,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r,
} else } else
tree_cur = pTable->m_tree[-tree_cur - 1]; 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; pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
} }
if (r->m_type == 2) { 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 #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4121 4127 4244)
#pragma warning(disable : 4204) // nonstandard extension used : non-constant #pragma warning(disable : 4204) // nonstandard extension used : non-constant
// aggregate initializer (also supported by GNU // aggregate initializer (also supported by GNU
// C and C99, so no big deal) // 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); pLen_out, 6, MZ_FALSE);
} }
#ifdef _MSC_VER
#pragma warning(pop)
#endif
// ------------------- .ZIP archive reading // ------------------- .ZIP archive reading
#ifndef MINIZ_NO_ARCHIVE_APIS #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 <stdio.h>
#include <sys/stat.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) { static FILE *mz_fopen(const char *pFilename, const char *pMode) {
FILE *pFile = NULL; wchar_t *wFilename = str2wstr(pFilename);
fopen_s(&pFile, pFilename, pMode); wchar_t *wMode = str2wstr(pMode);
FILE *pFile = _wfopen(wFilename, wMode);
free(wFilename);
free(wMode);
return pFile; return pFile;
} }
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
FILE *pFile = NULL; wchar_t *wPath = str2wstr(pPath);
if (freopen_s(&pFile, pPath, pMode, pStream)) wchar_t *wMode = str2wstr(pMode);
return NULL; FILE *pFile = _wfreopen(wPath, wMode, pStream);
free(wPath);
free(wMode);
return pFile; return pFile;
} }
#ifndef MINIZ_NO_TIME #ifndef MINIZ_NO_TIME
#include <sys/utime.h> #include <sys/utime.h>
#endif #endif
@ -4144,7 +4163,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
#include <sys/utime.h> #include <sys/utime.h>
#endif #endif
#define MZ_FILE FILE #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_FCLOSE fclose
#define MZ_FREAD fread #define MZ_FREAD fread
#define MZ_FWRITE fwrite #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_STRUCT _stat
#define MZ_FILE_STAT _stat #define MZ_FILE_STAT _stat
#define MZ_FFLUSH fflush #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 #define MZ_DELETE_FILE remove
#elif defined(__TINYC__) #elif defined(__TINYC__)
#ifndef MINIZ_NO_TIME #ifndef MINIZ_NO_TIME
@ -5361,13 +5380,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
} else { } else {
// Temporarily allocate a read buffer. // Temporarily allocate a read buffer.
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); 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)) if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
#endif
return MZ_FALSE; return MZ_FALSE;
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
(size_t)read_buf_size))) (size_t)read_buf_size)))
return MZ_FALSE; 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); uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; 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)) if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
#endif
return NULL; return NULL;
if (NULL == if (NULL ==
(pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) (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)) { if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
// The file is stored or the caller has requested the compressed data. // The file is stored or the caller has requested the compressed data.
if (pZip->m_pState->m_pMem) { 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))) && if (((sizeof(size_t) == sizeof(mz_uint32))) &&
(file_stat.m_comp_size > 0xFFFFFFFF)) (file_stat.m_comp_size > 0xFFFFFFFF))
#endif
return MZ_FALSE; return MZ_FALSE;
if (pCallback(pOpaque, out_buf_ofs, pRead_buf, if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
(size_t)file_stat.m_comp_size) != file_stat.m_comp_size) (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
status = TINFL_STATUS_FAILED; 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) if (!pZip->m_file_offset_alignment)
return 0; return 0;
n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); 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); (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_uint32 ext_attributes) {
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
mz_uint16 method = 0, dos_time = 0, dos_date = 0; mz_uint16 method = 0, dos_time = 0, dos_date = 0;
#ifndef MINIZ_NO_TIME
time_t file_modified_time; time_t file_modified_time;
#endif
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0, mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
comp_size = 0; comp_size = 0;
size_t archive_name_size; 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)) comment_size + archive_name_size) > 0xFFFFFFFF))
return MZ_FALSE; return MZ_FALSE;
#ifndef MINIZ_NO_TIME
memset(&file_modified_time, 0, sizeof(file_modified_time)); memset(&file_modified_time, 0, sizeof(file_modified_time));
if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
return MZ_FALSE; return MZ_FALSE;
mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date); mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
#endif
pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
if (!pSrc_file) if (!pSrc_file)
@ -6814,6 +6826,10 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
return p; return p;
} }
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // #ifndef MINIZ_NO_STDIO #endif // #ifndef MINIZ_NO_STDIO
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS

File diff suppressed because it is too large Load Diff

View File

@ -15,19 +15,11 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4127 )
#endif //_MSC_VER
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \ #if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
!defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) && \
!defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DECLARED)
// 64-bit Windows is the only mainstream platform // 64-bit Windows is the only mainstream platform
// where sizeof(long) != sizeof(void*) // where sizeof(long) != sizeof(void*)
#ifdef _WIN64 #ifdef _WIN64
@ -35,15 +27,6 @@ typedef long long ssize_t; /* byte count or error */
#else #else
typedef long ssize_t; /* byte count or error */ typedef long ssize_t; /* byte count or error */
#endif #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 #endif
#ifndef MAX_PATH #ifndef MAX_PATH
@ -64,9 +47,49 @@ typedef long ssize_t; /* byte count or error */
/** /**
* Default zip compression level. * Default zip compression level.
*/ */
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6 #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 * @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. * @note ensure supplied output buffer is large enough.
* zip_entry_size function (returns uncompressed size for the current * zip_entry_size function (returns uncompressed size for the current
* entry) can be handy to estimate how big buffer is needed. for large * entry) can be handy to estimate how big buffer is needed.
* entries, please take a look at zip_entry_extract function. * For large entries, please take a look at zip_entry_extract function.
* *
* @return the return code - the number of bytes actually read on success. * @return the return code - the number of bytes actually read on success.
* Otherwise a -1 on error (e.g. bufsize is not large enough). * 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 * @return the return code - the number of entries on success, negative number
* (< 0) on error. * (< 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. * 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); void *arg);
/** @} */ /** @} */
#ifdef _MSC_VER
#pragma warning(pop)
#endif //_MSC_VER
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,11 +1,38 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.4)
# test # tests
set(test_out test.out) 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) set(test_append_out test_append.out)
target_link_libraries(${test_out} zip) 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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -209,9 +209,14 @@ enum aiPostProcessSteps
/** <hr>Removes the node graph and pre-transforms all vertices with /** <hr>Removes the node graph and pre-transforms all vertices with
* the local transformation matrices of their nodes. * the local transformation matrices of their nodes.
* *
* The output scene still contains nodes, however there is only a * If the resulting scene can be reduced to a single mesh, with a single
* root node with children, each one referencing only one mesh, * material, no lights, and no cameras, then the output scene will contain
* and each mesh referencing one material. For rendering, you can * only a root node (with no children) that references the single mesh.
* Otherwise, the output scene will be reduced to a root node with a single
* level of child nodes, each one referencing one mesh, and each mesh
* referencing one material.
*
* In either case, for rendering, you can
* simply render all meshes in order - you don't need to pay * simply render all meshes in order - you don't need to pay
* attention to local transformations and the node hierarchy. * attention to local transformations and the node hierarchy.
* Animations are removed during this step. * Animations are removed during this step.

View File

@ -130,10 +130,11 @@ int SaveAsBMP(FILE *file, const aiTexel *data, unsigned int width, unsigned int
s[0] = t->b; s[0] = t->b;
s[1] = t->g; s[1] = t->g;
s[2] = t->r; s[2] = t->r;
if (4 == numc) if (4 == numc) {
s[3] = t->a; s[3] = t->a;
} }
} }
}
BITMAPFILEHEADER header; BITMAPFILEHEADER header;
header.bfType = 'B' | (int('M') << 8u); header.bfType = 'B' | (int('M') << 8u);
@ -296,7 +297,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) {
// check whether the requested texture is existing // check whether the requested texture is existing
if (texIdx >= scene->mNumTextures) { if (texIdx >= scene->mNumTextures) {
::printf("assimp extract: Texture %i requested, but there are just %i textures\n", ::printf("assimp extract: Texture %u requested, but there are just %i textures\n",
texIdx, scene->mNumTextures); texIdx, scene->mNumTextures);
return AssimpCmdExtractError::TextureIndexIsOutOfRange; return AssimpCmdExtractError::TextureIndexIsOutOfRange;
} }
@ -325,7 +326,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) {
// if the texture is a compressed one, we'll export // if the texture is a compressed one, we'll export
// it to its native file format // it to its native file format
if (!tex->mHeight) { if (!tex->mHeight) {
printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n", printf("assimp extract: Texture %u is compressed (%s). Writing native file format.\n",
i, tex->achFormatHint); i, tex->achFormatHint);
// modify file extension // modify file extension
@ -350,7 +351,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) {
} }
::fclose(p); ::fclose(p);
printf("assimp extract: Wrote texture %i to %s\n", i, out_cpy.c_str()); printf("assimp extract: Wrote texture %u to %s\n", i, out_cpy.c_str());
if (texIdx != 0xffffffff) { if (texIdx != 0xffffffff) {
return m; return m;
} }