Merge branch 'master' into readFbxWeightsInConfig

pull/3460/head
Kim Kulling 2020-10-28 20:38:29 +01:00 committed by GitHub
commit 8c135f779e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 2794 additions and 2403 deletions

1
.github/FUNDING.yml vendored
View File

@ -1,3 +1,2 @@
patreon: assimp patreon: assimp
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4 custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
open_collective: assimp

View File

@ -578,10 +578,6 @@ ELSE ()
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER ) ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
ENDIF () ENDIF ()
#IF(NOT ASSIMP_HUNTER_ENABLED)
ADD_SUBDIRECTORY(contrib)
#ENDIF()
ADD_SUBDIRECTORY( code/ ) ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only # The viewer for windows only

View File

@ -139,7 +139,6 @@ void DNAParser::Parse() {
dna.structures.push_back(Structure()); dna.structures.push_back(Structure());
Structure &s = dna.structures.back(); Structure &s = dna.structures.back();
s.name = types[n].name; s.name = types[n].name;
//s.index = dna.structures.size()-1;
n = stream.GetI2(); n = stream.GetI2();
s.fields.reserve(n); s.fields.reserve(n);

View File

@ -84,9 +84,8 @@ class ObjectCache;
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct Error : DeadlyImportError { struct Error : DeadlyImportError {
template <typename... T> template <typename... T>
explicit Error(T&&... args) explicit Error(T &&...args) :
: DeadlyImportError(args...) DeadlyImportError(args...) {
{
} }
}; };
@ -187,7 +186,7 @@ struct Field {
}; };
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
/** Range of possible behaviours for fields absend in the input file. Some are /** Range of possible behaviors for fields absence in the input file. Some are
* mission critical so we need them, while others can silently be default * mission critical so we need them, while others can silently be default
* initialized and no animations are harmed. */ * initialized and no animations are harmed. */
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------

View File

@ -106,51 +106,18 @@ class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter
public: public:
BlenderImporter(); BlenderImporter();
~BlenderImporter(); ~BlenderImporter();
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
public:
// --------------------
bool CanRead( const std::string& pFile,
IOSystem* pIOHandler,
bool checkSig
) const;
protected: protected:
// --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// --------------------
void GetExtensionList(std::set<std::string>& app); void GetExtensionList(std::set<std::string>& app);
// --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
// -------------------- void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr<IOStream> stream);
void InternReadFile( const std::string& pFile, void ExtractScene(Blender::Scene& out, const Blender::FileDatabase& file);
aiScene* pScene, void ConvertBlendFile(aiScene* out, const Blender::Scene& in, const Blender::FileDatabase& file);
IOSystem* pIOHandler
);
// --------------------
void ParseBlendFile(Blender::FileDatabase& out,
std::shared_ptr<IOStream> stream
);
// --------------------
void ExtractScene(Blender::Scene& out,
const Blender::FileDatabase& file
);
// --------------------
void ConvertBlendFile(aiScene* out,
const Blender::Scene& in,
const Blender::FileDatabase& file
);
private: private:
// --------------------
aiNode* ConvertNode(const Blender::Scene& in, aiNode* ConvertNode(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
Blender::ConversionData& conv_info, Blender::ConversionData& conv_info,

View File

@ -155,7 +155,7 @@ struct World : ElemBase {
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct MVert : ElemBase { struct MVert : ElemBase {
float co[3] FAIL; float co[3] FAIL;
float no[3] FAIL; // readed as short and divided through / 32767.f float no[3] FAIL; // read as short and divided through / 32767.f
char flag; char flag;
int mat_nr WARN; int mat_nr WARN;
int bweight; int bweight;
@ -228,7 +228,10 @@ struct TFace : ElemBase {
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
struct MTFace : ElemBase { struct MTFace : ElemBase {
MTFace() : MTFace() :
flag(0), mode(0), tile(0), unwrap(0) { flag(0),
mode(0),
tile(0),
unwrap(0) {
} }
float uv[4][2] FAIL; float uv[4][2] FAIL;

View File

@ -573,7 +573,7 @@ bool ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial &
index_str = index_str.substr(1, std::string::npos); index_str = index_str.substr(1, std::string::npos);
try { try {
index = (unsigned int)strtoul10_64(index_str.c_str()); index = (unsigned int)strtoul10_64<DeadlyExportError>(index_str.c_str());
} catch (std::exception &error) { } catch (std::exception &error) {
throw DeadlyExportError(error.what()); throw DeadlyExportError(error.what());
} }

View File

@ -1,5 +1,3 @@
/** Helper structures for the Collada loader */
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -40,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** Helper structures for the Collada loader */
#include "ColladaHelper.h" #include "ColladaHelper.h"

View File

@ -1,12 +1,9 @@
/** Helper structures for the Collada loader */
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -42,12 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** Helper structures for the Collada loader */
#ifndef AI_COLLADAHELPER_H_INC #ifndef AI_COLLADAHELPER_H_INC
#define AI_COLLADAHELPER_H_INC #define AI_COLLADAHELPER_H_INC
#include <assimp/light.h> #include <assimp/light.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/mesh.h> #include <assimp/mesh.h>
#include <stdint.h> #include <stdint.h>
#include <map> #include <map>
#include <set> #include <set>
@ -58,14 +58,14 @@ struct aiMaterial;
namespace Assimp { namespace Assimp {
namespace Collada { namespace Collada {
/** Collada file versions which evolved during the years ... */ /// Collada file versions which evolved during the years ...
enum FormatVersion { enum FormatVersion {
FV_1_5_n, FV_1_5_n,
FV_1_4_n, FV_1_4_n,
FV_1_3_n FV_1_3_n
}; };
/** Transformation types that can be applied to a node */ /// Transformation types that can be applied to a node
enum TransformType { enum TransformType {
TF_LOOKAT, TF_LOOKAT,
TF_ROTATE, TF_ROTATE,
@ -75,7 +75,7 @@ enum TransformType {
TF_MATRIX TF_MATRIX
}; };
/** Different types of input data to a vertex or face */ /// Different types of input data to a vertex or face
enum InputType { enum InputType {
IT_Invalid, IT_Invalid,
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data. IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
@ -87,38 +87,39 @@ enum InputType {
IT_Bitangent IT_Bitangent
}; };
/** Supported controller types */ /// Supported controller types
enum ControllerType { enum ControllerType {
Skin, Skin,
Morph Morph
}; };
/** Supported morph methods */ /// Supported morph methods
enum MorphMethod { enum MorphMethod {
Normalized, Normalized,
Relative Relative
}; };
/** Common metadata keys as <Collada, Assimp> */ /// Common metadata keys as <Collada, Assimp>
typedef std::pair<std::string, std::string> MetaKeyPair; using MetaKeyPair = std::pair<std::string, std::string>;
typedef std::vector<MetaKeyPair> MetaKeyPairVector; using MetaKeyPairVector = std::vector<MetaKeyPair>;
// Collada as lower_case (native) /// Collada as lower_case (native)
const MetaKeyPairVector &GetColladaAssimpMetaKeys(); const MetaKeyPairVector &GetColladaAssimpMetaKeys();
// Collada as CamelCase (used by Assimp for consistency) // Collada as CamelCase (used by Assimp for consistency)
const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase(); const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase();
/** Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool" */ /// Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool"
void ToCamelCase(std::string &text); void ToCamelCase(std::string &text);
/** Contains all data for one of the different transformation types */ /// Contains all data for one of the different transformation types
struct Transform { struct Transform {
std::string mID; ///< SID of the transform step, by which anim channels address their target node std::string mID; ///< SID of the transform step, by which anim channels address their target node
TransformType mType; TransformType mType;
ai_real f[16]; ///< Interpretation of data depends on the type of the transformation ai_real f[16]; ///< Interpretation of data depends on the type of the transformation
}; };
/** A collada camera. */ /// A collada camera.
struct Camera { struct Camera {
Camera() : Camera() :
mOrtho(false), mOrtho(false),
@ -128,22 +129,22 @@ struct Camera {
mZNear(0.1f), mZNear(0.1f),
mZFar(1000.f) {} mZFar(1000.f) {}
// Name of camera /// Name of camera
std::string mName; std::string mName;
// True if it is an orthografic camera /// True if it is an orthographic camera
bool mOrtho; bool mOrtho;
//! Horizontal field of view in degrees /// Horizontal field of view in degrees
ai_real mHorFov; ai_real mHorFov;
//! Vertical field of view in degrees /// Vertical field of view in degrees
ai_real mVerFov; ai_real mVerFov;
//! Screen aspect /// Screen aspect
ai_real mAspect; ai_real mAspect;
//! Near& far z /// Near& far z
ai_real mZNear, mZFar; ai_real mZNear, mZFar;
}; };
@ -162,27 +163,27 @@ struct Light {
mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET), mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
mIntensity(1.f) {} mIntensity(1.f) {}
//! Type of the light source aiLightSourceType + ambient /// Type of the light source aiLightSourceType + ambient
unsigned int mType; unsigned int mType;
//! Color of the light /// Color of the light
aiColor3D mColor; aiColor3D mColor;
//! Light attenuation /// Light attenuation
ai_real mAttConstant, mAttLinear, mAttQuadratic; ai_real mAttConstant, mAttLinear, mAttQuadratic;
//! Spot light falloff /// Spot light falloff
ai_real mFalloffAngle; ai_real mFalloffAngle;
ai_real mFalloffExponent; ai_real mFalloffExponent;
// ----------------------------------------------------- // -----------------------------------------------------
// FCOLLADA extension from here // FCOLLADA extension from here
//! ... related stuff from maja and max extensions /// ... related stuff from maja and max extensions
ai_real mPenumbraAngle; ai_real mPenumbraAngle;
ai_real mOuterAngle; ai_real mOuterAngle;
//! Common light intensity /// Common light intensity
ai_real mIntensity; ai_real mIntensity;
}; };
@ -192,30 +193,29 @@ struct InputSemanticMapEntry {
mSet(0), mSet(0),
mType(IT_Invalid) {} mType(IT_Invalid) {}
//! Index of set, optional /// Index of set, optional
unsigned int mSet; unsigned int mSet;
//! Type of referenced vertex input /// Type of referenced vertex input
InputType mType; InputType mType;
}; };
/** Table to map from effect to vertex input semantics */ /// Table to map from effect to vertex input semantics
struct SemanticMappingTable { struct SemanticMappingTable {
//! Name of material /// Name of material
std::string mMatName; std::string mMatName;
//! List of semantic map commands, grouped by effect semantic name /// List of semantic map commands, grouped by effect semantic name
std::map<std::string, InputSemanticMapEntry> mMap; std::map<std::string, InputSemanticMapEntry> mMap;
//! For std::find /// For std::find
bool operator==(const std::string &s) const { bool operator==(const std::string &s) const {
return s == mMatName; return s == mMatName;
} }
}; };
/** A reference to a mesh inside a node, including materials assigned to the various subgroups. /// A reference to a mesh inside a node, including materials assigned to the various subgroups.
* The ID refers to either a mesh or a controller which specifies the mesh /// The ID refers to either a mesh or a controller which specifies the mesh
*/
struct MeshInstance { struct MeshInstance {
///< ID of the mesh or controller to be instanced ///< ID of the mesh or controller to be instanced
std::string mMeshOrController; std::string mMeshOrController;
@ -224,25 +224,25 @@ struct MeshInstance {
std::map<std::string, SemanticMappingTable> mMaterials; std::map<std::string, SemanticMappingTable> mMaterials;
}; };
/** A reference to a camera inside a node*/ /// A reference to a camera inside a node
struct CameraInstance { struct CameraInstance {
///< ID of the camera ///< ID of the camera
std::string mCamera; std::string mCamera;
}; };
/** A reference to a light inside a node*/ /// A reference to a light inside a node
struct LightInstance { struct LightInstance {
///< ID of the camera ///< ID of the camera
std::string mLight; std::string mLight;
}; };
/** A reference to a node inside a node*/ /// A reference to a node inside a node
struct NodeInstance { struct NodeInstance {
///< ID of the node ///< ID of the node
std::string mNode; std::string mNode;
}; };
/** A node in a scene hierarchy */ /// A node in a scene hierarchy
struct Node { struct Node {
std::string mName; std::string mName;
std::string mID; std::string mID;
@ -250,52 +250,53 @@ struct Node {
Node *mParent; Node *mParent;
std::vector<Node *> mChildren; std::vector<Node *> mChildren;
/** Operations in order to calculate the resulting transformation to parent. */ /// Operations in order to calculate the resulting transformation to parent.
std::vector<Transform> mTransforms; std::vector<Transform> mTransforms;
/** Meshes at this node */ /// Meshes at this node
std::vector<MeshInstance> mMeshes; std::vector<MeshInstance> mMeshes;
/** Lights at this node */ /// Lights at this node
std::vector<LightInstance> mLights; std::vector<LightInstance> mLights;
/** Cameras at this node */ /// Cameras at this node
std::vector<CameraInstance> mCameras; std::vector<CameraInstance> mCameras;
/** Node instances at this node */ /// Node instances at this node
std::vector<NodeInstance> mNodeInstances; std::vector<NodeInstance> mNodeInstances;
/** Root-nodes: Name of primary camera, if any */ /// Root-nodes: Name of primary camera, if any
std::string mPrimaryCamera; std::string mPrimaryCamera;
//! Constructor. Begin with a zero parent /// Constructor. Begin with a zero parent
Node() : Node() :
mParent(nullptr) { mParent(nullptr) {
// empty // empty
} }
//! Destructor: delete all children subsequently /// Destructor: delete all children subsequently
~Node() { ~Node() {
for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) {
delete *it; delete *it;
} }
}
}; };
/** Data source array: either floats or strings */ /// Data source array: either floats or strings
struct Data { struct Data {
bool mIsStringArray; bool mIsStringArray;
std::vector<ai_real> mValues; std::vector<ai_real> mValues;
std::vector<std::string> mStrings; std::vector<std::string> mStrings;
}; };
/** Accessor to a data array */ /// Accessor to a data array
struct Accessor { struct Accessor {
size_t mCount; // in number of objects size_t mCount; // in number of objects
size_t mSize; // size of an object, in elements (floats or strings, mostly 1) size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
size_t mOffset; // in number of values size_t mOffset; // in number of values
size_t mStride; // Stride in number of values size_t mStride; // Stride in number of values
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore. std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on. size_t mSubOffset[4]; // Sub-offset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component. // For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
std::string mSource; // URL of the source array std::string mSource; // URL of the source array
mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else
@ -310,12 +311,12 @@ struct Accessor {
} }
}; };
/** A single face in a mesh */ /// A single face in a mesh
struct Face { struct Face {
std::vector<size_t> mIndices; std::vector<size_t> mIndices;
}; };
/** An input channel for mesh data, referring to a single accessor */ /// An input channel for mesh data, referring to a single accessor
struct InputChannel { struct InputChannel {
InputType mType; // Type of the data InputType mType; // Type of the data
size_t mIndex; // Optional index, if multiple sets of the same data type are given size_t mIndex; // Optional index, if multiple sets of the same data type are given
@ -331,19 +332,20 @@ struct InputChannel {
} }
}; };
/** Subset of a mesh with a certain material */ /// Subset of a mesh with a certain material
struct SubMesh { struct SubMesh {
std::string mMaterial; ///< subgroup identifier std::string mMaterial; ///< subgroup identifier
size_t mNumFaces; ///< number of faces in this submesh size_t mNumFaces; ///< number of faces in this sub-mesh
}; };
/** Contains data for a single mesh */ /// Contains data for a single mesh
struct Mesh { struct Mesh {
Mesh(const std::string &id) : Mesh(const std::string &id) :
mId(id) { mId(id) {
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mNumUVComponents[i] = 2; mNumUVComponents[i] = 2;
} }
}
const std::string mId; const std::string mId;
std::string mName; std::string mName;
@ -373,11 +375,11 @@ struct Mesh {
// necessary for bone weight assignment // necessary for bone weight assignment
std::vector<size_t> mFacePosIndices; std::vector<size_t> mFacePosIndices;
// Submeshes in this mesh, each with a given material // Sub-meshes in this mesh, each with a given material
std::vector<SubMesh> mSubMeshes; std::vector<SubMesh> mSubMeshes;
}; };
/** Which type of primitives the ReadPrimitives() function is going to read */ /// Which type of primitives the ReadPrimitives() function is going to read
enum PrimitiveType { enum PrimitiveType {
Prim_Invalid, Prim_Invalid,
Prim_Lines, Prim_Lines,
@ -389,7 +391,7 @@ enum PrimitiveType {
Prim_Polygon Prim_Polygon
}; };
/** A skeleton controller to deform a mesh with the use of joints */ /// A skeleton controller to deform a mesh with the use of joints
struct Controller { struct Controller {
// controller type // controller type
ControllerType mType; ControllerType mType;
@ -424,25 +426,25 @@ struct Controller {
std::string mMorphWeight; std::string mMorphWeight;
}; };
/** A collada material. Pretty much the only member is a reference to an effect. */ /// A collada material. Pretty much the only member is a reference to an effect.
struct Material { struct Material {
std::string mName; std::string mName;
std::string mEffect; std::string mEffect;
}; };
/** Type of the effect param */ /// Type of the effect param
enum ParamType { enum ParamType {
Param_Sampler, Param_Sampler,
Param_Surface Param_Surface
}; };
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */ /// A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them
struct EffectParam { struct EffectParam {
ParamType mType; ParamType mType;
std::string mReference; // to which other thing the param is referring to. std::string mReference; // to which other thing the param is referring to.
}; };
/** Shading type supported by the standard effect spec of Collada */ /// Shading type supported by the standard effect spec of Collada
enum ShadeType { enum ShadeType {
Shade_Invalid, Shade_Invalid,
Shade_Constant, Shade_Constant,
@ -451,7 +453,7 @@ enum ShadeType {
Shade_Blinn Shade_Blinn
}; };
/** Represents a texture sampler in collada */ /// Represents a texture sampler in collada
struct Sampler { struct Sampler {
Sampler() : Sampler() :
mWrapU(true), mWrapU(true),
@ -463,77 +465,66 @@ struct Sampler {
mWeighting(1.f), mWeighting(1.f),
mMixWithPrevious(1.f) {} mMixWithPrevious(1.f) {}
/** Name of image reference /// Name of image reference
*/
std::string mName; std::string mName;
/** Wrap U? /// Wrap U?
*/
bool mWrapU; bool mWrapU;
/** Wrap V? /// Wrap V?
*/
bool mWrapV; bool mWrapV;
/** Mirror U? /// Mirror U?
*/
bool mMirrorU; bool mMirrorU;
/** Mirror V? /// Mirror V?
*/
bool mMirrorV; bool mMirrorV;
/** Blend mode /// Blend mode
*/
aiTextureOp mOp; aiTextureOp mOp;
/** UV transformation /// UV transformation
*/
aiUVTransform mTransform; aiUVTransform mTransform;
/** Name of source UV channel /// Name of source UV channel
*/
std::string mUVChannel; std::string mUVChannel;
/** Resolved UV channel index or UINT_MAX if not known /// Resolved UV channel index or UINT_MAX if not known
*/
unsigned int mUVId; unsigned int mUVId;
// OKINO/MAX3D extensions from here // OKINO/MAX3D extensions from here
// ------------------------------------------------------- // -------------------------------------------------------
/** Weighting factor /// Weighting factor
*/
ai_real mWeighting; ai_real mWeighting;
/** Mixing factor from OKINO /// Mixing factor from OKINO
*/
ai_real mMixWithPrevious; ai_real mMixWithPrevious;
}; };
/** A collada effect. Can contain about anything according to the Collada spec, /// A collada effect. Can contain about anything according to the Collada spec,
but we limit our version to a reasonable subset. */ /// but we limit our version to a reasonable subset.
struct Effect { struct Effect {
// Shading mode /// Shading mode
ShadeType mShadeType; ShadeType mShadeType;
// Colors /// Colors
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular, aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
mTransparent, mReflective; mTransparent, mReflective;
// Textures /// Textures
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular, Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
mTexTransparent, mTexBump, mTexReflective; mTexTransparent, mTexBump, mTexReflective;
// Scalar factory /// Scalar factory
ai_real mShininess, mRefractIndex, mReflectivity; ai_real mShininess, mRefractIndex, mReflectivity;
ai_real mTransparency; ai_real mTransparency;
bool mHasTransparency; bool mHasTransparency;
bool mRGBTransparency; bool mRGBTransparency;
bool mInvertTransparency; bool mInvertTransparency;
// local params referring to each other by their SID /// local params referring to each other by their SID
typedef std::map<std::string, Collada::EffectParam> ParamLibrary; using ParamLibrary = std::map<std::string, Collada::EffectParam>;
ParamLibrary mParams; ParamLibrary mParams;
// MAX3D extensions // MAX3D extensions
@ -561,65 +552,64 @@ struct Effect {
} }
}; };
/** An image, meaning texture */ /// An image, meaning texture
struct Image { struct Image {
std::string mFileName; std::string mFileName;
/** Embedded image data */ /// Embedded image data
std::vector<uint8_t> mImageData; std::vector<uint8_t> mImageData;
/** File format hint of embedded image data */ /// File format hint of embedded image data
std::string mEmbeddedFormat; std::string mEmbeddedFormat;
}; };
/** An animation channel. */ /// An animation channel.
struct AnimationChannel { struct AnimationChannel {
/** URL of the data to animate. Could be about anything, but we support only the /// URL of the data to animate. Could be about anything, but we support only the
* "NodeID/TransformID.SubElement" notation /// "NodeID/TransformID.SubElement" notation
*/
std::string mTarget; std::string mTarget;
/** Source URL of the time values. Collada calls them "input". Meh. */ /// Source URL of the time values. Collada calls them "input". Meh.
std::string mSourceTimes; std::string mSourceTimes;
/** Source URL of the value values. Collada calls them "output". */ /// Source URL of the value values. Collada calls them "output".
std::string mSourceValues; std::string mSourceValues;
/** Source URL of the IN_TANGENT semantic values. */ /// Source URL of the IN_TANGENT semantic values.
std::string mInTanValues; std::string mInTanValues;
/** Source URL of the OUT_TANGENT semantic values. */ /// Source URL of the OUT_TANGENT semantic values.
std::string mOutTanValues; std::string mOutTanValues;
/** Source URL of the INTERPOLATION semantic values. */ /// Source URL of the INTERPOLATION semantic values.
std::string mInterpolationValues; std::string mInterpolationValues;
}; };
/** An animation. Container for 0-x animation channels or 0-x animations */ /// An animation. Container for 0-x animation channels or 0-x animations
struct Animation { struct Animation {
/** Anim name */ /// Anim name
std::string mName; std::string mName;
/** the animation channels, if any */ /// the animation channels, if any
std::vector<AnimationChannel> mChannels; std::vector<AnimationChannel> mChannels;
/** the sub-animations, if any */ /// the sub-animations, if any
std::vector<Animation *> mSubAnims; std::vector<Animation *> mSubAnims;
/** Destructor */ /// Destructor
~Animation() { ~Animation() {
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
delete *it; delete *it;
} }
}
/** Collect all channels in the animation hierarchy into a single channel list. */ /// Collect all channels in the animation hierarchy into a single channel list.
void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) { void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) {
channels.insert(channels.end(), mChannels.begin(), mChannels.end()); channels.insert(channels.end(), mChannels.begin(), mChannels.end());
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) { for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
Animation *pAnim = (*it); Animation *pAnim = (*it);
pAnim->CollectChannelsRecursively(channels); pAnim->CollectChannelsRecursively(channels);
} }
} }
/** Combine all single-channel animations' channel into the same (parent) animation channel list. */ /// Combine all single-channel animations' channel into the same (parent) animation channel list.
void CombineSingleChannelAnimations() { void CombineSingleChannelAnimations() {
CombineSingleChannelAnimationsRecursively(this); CombineSingleChannelAnimationsRecursively(this);
} }
@ -658,9 +648,9 @@ struct Animation {
} }
}; };
/** Description of a collada animation channel which has been determined to affect the current node */ /// Description of a collada animation channel which has been determined to affect the current node
struct ChannelEntry { struct ChannelEntry {
const Collada::AnimationChannel *mChannel; ///> the source channel const Collada::AnimationChannel *mChannel; ///< the source channel
std::string mTargetId; std::string mTargetId;
std::string mTransformId; // the ID of the transformation step of the node which is influenced std::string mTransformId; // the ID of the transformation step of the node which is influenced
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to size_t mTransformIndex; // Index into the node's transform chain to apply the channel to

View File

@ -55,12 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <math.h>
#include <time.h>
#include <algorithm>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <memory>
#include <numeric> #include <numeric>
namespace Assimp { namespace Assimp {
@ -331,14 +328,16 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
// Resolve UV channels // Resolve UV channels
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) { void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) {
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel); std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
if (it != table.mMap.end()) { if (it == table.mMap.end()) {
return;
}
if (it->second.mType != Collada::IT_Texcoord) { if (it->second.mType != Collada::IT_Texcoord) {
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping"); ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
} }
sampler.mUVId = it->second.mSet; sampler.mUVId = it->second.mSet;
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Builds lights for the given node and references them // Builds lights for the given node and references them

View File

@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaParser.h" #include "ColladaParser.h"
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/TinyFormatter.h>
#include <assimp/ZipArchiveIOSystem.h> #include <assimp/ZipArchiveIOSystem.h>
#include <assimp/commonMetaData.h> #include <assimp/commonMetaData.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
@ -56,14 +55,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <stdarg.h>
#include <memory>
#include <sstream>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Collada; using namespace Assimp::Collada;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static void ReportWarning(const char *msg, ...) {
ai_assert(nullptr != msg);
va_list args;
va_start(args, msg);
char szBuffer[3000];
const int iLen = vsprintf(szBuffer, msg, args);
ai_assert(iLen > 0);
va_end(args);
ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen));
}
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
for (size_t i = 0; i < key_renaming.size(); ++i) {
if (key_renaming[i].first == collada_key) {
found_index = i;
return true;
}
}
found_index = std::numeric_limits<size_t>::max();
return false;
}
static void readUrlAttribute(XmlNode &node, std::string &url) {
url.clear();
if (!XmlParser::getStdStrAttribute(node, "url", url)) {
return;
}
if (url[0] != '#') {
throw DeadlyImportError("Unknown reference format");
}
url = url.c_str() + 1;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
@ -256,36 +288,36 @@ void ColladaParser::ReadContents(XmlNode &node) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the structure of the file // Reads the structure of the file
void ColladaParser::ReadStructure(XmlNode &node) { void ColladaParser::ReadStructure(XmlNode &node) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string name = std::string(currentNode.name()); const std::string &currentName = std::string(currentNode.name());
ASSIMP_LOG_DEBUG("last name" + name); if (currentName == "asset") {
if (name == "asset")
ReadAssetInfo(currentNode); ReadAssetInfo(currentNode);
else if (name == "library_animations") } else if (currentName == "library_animations") {
ReadAnimationLibrary(currentNode); ReadAnimationLibrary(currentNode);
else if (name == "library_animation_clips") } else if (currentName == "library_animation_clips") {
ReadAnimationClipLibrary(currentNode); ReadAnimationClipLibrary(currentNode);
else if (name == "library_controllers") } else if (currentName == "library_controllers") {
ReadControllerLibrary(currentNode); ReadControllerLibrary(currentNode);
else if (name == "library_images") } else if (currentName == "library_images") {
ReadImageLibrary(currentNode); ReadImageLibrary(currentNode);
else if (name == "library_materials") } else if (currentName == "library_materials") {
ReadMaterialLibrary(currentNode); ReadMaterialLibrary(currentNode);
else if (name == "library_effects") } else if (currentName == "library_effects") {
ReadEffectLibrary(currentNode); ReadEffectLibrary(currentNode);
else if (name == "library_geometries") } else if (currentName == "library_geometries") {
ReadGeometryLibrary(currentNode); ReadGeometryLibrary(currentNode);
else if (name == "library_visual_scenes") } else if (currentName == "library_visual_scenes") {
ReadSceneLibrary(currentNode); ReadSceneLibrary(currentNode);
else if (name == "library_lights") } else if (currentName == "library_lights") {
ReadLightLibrary(currentNode); ReadLightLibrary(currentNode);
else if (name == "library_cameras") } else if (currentName == "library_cameras") {
ReadCameraLibrary(currentNode); ReadCameraLibrary(currentNode);
else if (name == "library_nodes") } else if (currentName == "library_nodes") {
ReadSceneNode(currentNode, nullptr); /* some hacking to reuse this piece of code */ ReadSceneNode(currentNode, nullptr); /* some hacking to reuse this piece of code */
else if (name == "scene") } else if (currentName == "scene") {
ReadScene(currentNode); ReadScene(currentNode);
} }
}
PostProcessRootAnimations(); PostProcessRootAnimations();
PostProcessControllers(); PostProcessControllers();
@ -298,17 +330,16 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string name = currentNode.name(); const std::string &currentName = currentNode.name();
if (name == "unit") { if (currentName == "unit") {
pugi::xml_attribute attr = currentNode.attribute("meter");
mUnitSize = 1.f; mUnitSize = 1.f;
if (attr) { XmlParser::getFloatAttribute(node, "meter", mUnitSize);
mUnitSize = static_cast<ai_real>(attr.as_double()); } else if (currentName == "up_axis") {
}
} else if (name == "up_axis") {
std::string v; std::string v;
XmlParser::getValueAsString(currentNode, v); if (!XmlParser::getValueAsString(currentNode, v)) {
continue;
}
if (v == "X_UP") { if (v == "X_UP") {
mUpDirection = UP_X; mUpDirection = UP_X;
} else if (v == "Z_UP") { } else if (v == "Z_UP") {
@ -316,9 +347,9 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
} else { } else {
mUpDirection = UP_Y; mUpDirection = UP_Y;
} }
} else if (name == "contributor") { } else if (currentName == "contributor") {
for (XmlNode currentChldNode : currentNode.children()) { for (XmlNode currentChildNode : currentNode.children()) {
ReadMetaDataItem(currentChldNode, mAssetMetaData); ReadMetaDataItem(currentChildNode, mAssetMetaData);
} }
} else { } else {
ReadMetaDataItem(currentNode, mAssetMetaData); ReadMetaDataItem(currentNode, mAssetMetaData);
@ -326,30 +357,20 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
} }
} }
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
for (size_t i = 0; i < key_renaming.size(); ++i) {
if (key_renaming[i].first == collada_key) {
found_index = i;
return true;
}
}
found_index = std::numeric_limits<size_t>::max();
return false;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a single string metadata item // Reads a single string metadata item
void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) { void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase(); const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
const std::string name = node.name(); const std::string name = node.name();
if (name.empty()) { if (name.empty()) {
return; return;
} }
std::string v; std::string v;
if (XmlParser::getValueAsString(node, v)) { if (!XmlParser::getValueAsString(node, v)) {
return;
}
trim(v); trim(v);
aiString aistr; aiString aistr;
aistr.Set(v); aistr.Set(v);
@ -364,7 +385,6 @@ void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
metadata.emplace(camel_key_str, aistr); metadata.emplace(camel_key_str, aistr);
} }
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the animation clips // Reads the animation clips
@ -374,14 +394,8 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
} }
std::string animName; std::string animName;
pugi::xml_attribute nameAttr = node.attribute("name"); if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
if (nameAttr) { if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
animName = nameAttr.as_string();
} else {
pugi::xml_attribute idAttr = node.attribute("id");
if (idAttr) {
animName = idAttr.as_string();
} else {
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size()); animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
} }
} }
@ -389,17 +403,12 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
std::pair<std::string, std::vector<std::string>> clip; std::pair<std::string, std::vector<std::string>> clip;
clip.first = animName; clip.first = animName;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "instance_animation") { if (currentName == "instance_animation") {
pugi::xml_attribute url = currentNode.attribute("url"); std::string url;
if (url) { readUrlAttribute(node, url);
const std::string urlName = url.as_string(); clip.second.push_back(url);
if (urlName[0] != '#') {
throw DeadlyImportError("Unknown reference format");
}
clip.second.push_back(url.as_string());
}
} }
if (clip.second.size() > 0) { if (clip.second.size() > 0) {
@ -469,8 +478,8 @@ void ColladaParser::ReadAnimationLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "animation") { if (currentName == "animation") {
ReadAnimation(currentNode, &mAnims); ReadAnimation(currentNode, &mAnims);
} }
@ -486,17 +495,14 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
// an <animation> element may be a container for grouping sub-elements or an animation channel // an <animation> element may be a container for grouping sub-elements or an animation channel
// this is the channel collection by ID, in case it has channels // this is the channel collection by ID, in case it has channels
typedef std::map<std::string, AnimationChannel> ChannelMap; using ChannelMap = std::map<std::string, AnimationChannel> ;
ChannelMap channels; ChannelMap channels;
// this is the anim container in case we're a container // this is the anim container in case we're a container
Animation *anim = nullptr; Animation *anim = nullptr;
// optional name given as an attribute // optional name given as an attribute
std::string animName; std::string animName;
pugi::xml_attribute nameAttr = node.attribute("name"); if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
if (nameAttr) {
animName = nameAttr.as_string();
} else {
animName = "animation"; animName = "animation";
} }
@ -506,8 +512,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
animID = idAttr.as_string(); animID = idAttr.as_string();
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "animation") { if (currentName == "animation") {
if (!anim) { if (!anim) {
anim = new Animation; anim = new Animation;
@ -520,23 +526,21 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
} else if (currentName == "source") { } else if (currentName == "source") {
ReadSource(currentNode); ReadSource(currentNode);
} else if (currentName == "sampler") { } else if (currentName == "sampler") {
pugi::xml_attribute sampler_id = currentNode.attribute("id"); std::string id;
if (sampler_id) { if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
std::string id = sampler_id.as_string();
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
// have it read into a channel // have it read into a channel
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
ReadAnimationSampler(currentNode, newChannel->second); ReadAnimationSampler(currentNode, newChannel->second);
} else if (currentName == "channel") { } else if (currentName == "channel") {
pugi::xml_attribute target = currentNode.attribute("target"); std::string source_name, target;
pugi::xml_attribute source = currentNode.attribute("source"); XmlParser::getStdStrAttribute(currentNode, "source", source_name);
std::string source_name = source.as_string(); XmlParser::getStdStrAttribute(currentNode, "target", target);
if (source_name[0] == '#') { if (source_name[0] == '#') {
source_name = source_name.substr(1, source_name.size() - 1); source_name = source_name.substr(1, source_name.size() - 1);
} }
ChannelMap::iterator cit = channels.find(source_name); ChannelMap::iterator cit = channels.find(source_name);
if (cit != channels.end()) { if (cit != channels.end()) {
cit->second.mTarget = target.as_string(); cit->second.mTarget = target;
} }
} }
} }
@ -563,8 +567,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an animation sampler into the given anim channel // Reads an animation sampler into the given anim channel
void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) { void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "input") { if (currentName == "input") {
if (XmlParser::hasAttribute(currentNode, "semantic")) { if (XmlParser::hasAttribute(currentNode, "semantic")) {
std::string semantic, sourceAttr; std::string semantic, sourceAttr;
@ -577,21 +581,22 @@ void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChanne
} }
source++; source++;
if (semantic == "INPUT") if (semantic == "INPUT") {
pChannel.mSourceTimes = source; pChannel.mSourceTimes = source;
else if (semantic == "OUTPUT") } else if (semantic == "OUTPUT") {
pChannel.mSourceValues = source; pChannel.mSourceValues = source;
else if (semantic == "IN_TANGENT") } else if (semantic == "IN_TANGENT") {
pChannel.mInTanValues = source; pChannel.mInTanValues = source;
else if (semantic == "OUT_TANGENT") } else if (semantic == "OUT_TANGENT") {
pChannel.mOutTanValues = source; pChannel.mOutTanValues = source;
else if (semantic == "INTERPOLATION") } else if (semantic == "INTERPOLATION") {
pChannel.mInterpolationValues = source; pChannel.mInterpolationValues = source;
} }
} }
} }
} }
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the skeleton controller library // Reads the skeleton controller library
@ -604,7 +609,6 @@ void ColladaParser::ReadControllerLibrary(XmlNode &node) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName != "controller") { if (currentName != "controller") {
continue; continue;
;
} }
std::string id = node.attribute("id").as_string(); std::string id = node.attribute("id").as_string();
mControllerLibrary[id] = Controller(); mControllerLibrary[id] = Controller();
@ -618,7 +622,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
// initial values // initial values
pController.mType = Skin; pController.mType = Skin;
pController.mMethod = Normalized; pController.mMethod = Normalized;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "morph") { if (currentName == "morph") {
pController.mType = Morph; pController.mType = Morph;
@ -670,8 +674,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the joint definitions for the given controller // Reads the joint definitions for the given controller
void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) { void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "input") { if (currentName == "input") {
const char *attrSemantic = currentNode.attribute("semantic").as_string(); const char *attrSemantic = currentNode.attribute("semantic").as_string();
const char *attrSource = currentNode.attribute("source").as_string(); const char *attrSource = currentNode.attribute("source").as_string();
@ -698,8 +702,8 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
int vertexCount=0; int vertexCount=0;
XmlParser::getIntAttribute(node, "count", vertexCount); XmlParser::getIntAttribute(node, "count", vertexCount);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "input") { if (currentName == "input") {
InputChannel channel; InputChannel channel;
@ -763,9 +767,9 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string name = currentNode.name(); const std::string &currentName = currentNode.name();
if (name == "image") { if (currentName == "image") {
std::string id = currentNode.attribute("id").as_string(); std::string id = currentNode.attribute("id").as_string();
mImageLibrary[id] = Image(); mImageLibrary[id] = Image();
@ -778,7 +782,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an image entry into the given image // Reads an image entry into the given image
void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) { void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string currentName = currentNode.name();
if (currentName == "image") { if (currentName == "image") {
// Ignore // Ignore
@ -798,23 +802,6 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
if (!pImage.mFileName.length()) { if (!pImage.mFileName.length()) {
pImage.mFileName = "unknown_texture"; pImage.mFileName = "unknown_texture";
} }
} else if (mFormat == FV_1_5_n) {
// make sure we skip over mip and array initializations, which
// we don't support, but which could confuse the loader if
// they're not skipped.
//int v = currentNode.attribute("ref").as_int();
/* if (v y) {
ASSIMP_LOG_WARN("Collada: Ignoring texture array index");
continue;
}*/
//v = currentNode.attribute("mip_index").as_int();
/*if (attrib != -1 && v > 0) {
ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer");
continue;
}*/
// TODO: correctly jump over cube and volume maps?
} }
} else if (mFormat == FV_1_5_n) { } else if (mFormat == FV_1_5_n) {
std::string value; std::string value;
@ -861,8 +848,7 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
} }
std::map<std::string, int> names; std::map<std::string, int> names;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name();
std::string id = currentNode.attribute("id").as_string(); std::string id = currentNode.attribute("id").as_string();
std::string name = currentNode.attribute("name").as_string(); std::string name = currentNode.attribute("name").as_string();
mMaterialLibrary[id] = Material(); mMaterialLibrary[id] = Material();
@ -891,14 +877,16 @@ void ColladaParser::ReadLightLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "light") { if (currentName == "light") {
std::string id = currentNode.attribute("id").as_string(); std::string id;
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
ReadLight(currentNode, mLightLibrary[id] = Light()); ReadLight(currentNode, mLightLibrary[id] = Light());
} }
} }
} }
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the camera library // Reads the camera library
@ -907,14 +895,20 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "camera") { if (currentName == "camera") {
std::string id = currentNode.attribute("id").as_string(); std::string id;
if (!XmlParser::getStdStrAttribute(currentNode, "id", id)) {
continue;
}
// create an entry and store it in the library under its ID // create an entry and store it in the library under its ID
Camera &cam = mCameraLibrary[id]; Camera &cam = mCameraLibrary[id];
std::string name = currentNode.attribute("name").as_string(); std::string name;
if (!XmlParser::getStdStrAttribute(currentNode, "name", name)) {
continue;
}
if (!name.empty()) { if (!name.empty()) {
cam.mName = name; cam.mName = name;
} }
@ -926,14 +920,12 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a material entry into the given material // Reads a material entry into the given material
void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) { void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
for (XmlNode currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "instance_effect") { if (currentName == "instance_effect") {
const char *url = currentNode.attribute("url").as_string(); std::string url;
if (url[0] != '#') { readUrlAttribute(currentNode, url);
throw DeadlyImportError("Unknown reference format"); pMaterial.mEffect = url.c_str();
}
pMaterial.mEffect = url + 1;
} }
} }
} }
@ -1032,7 +1024,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "effect") { if (currentName == "effect") {
// read ID. Do I have to repeat my ranting about "optional" attributes? // read ID. Do I have to repeat my ranting about "optional" attributes?
@ -1051,7 +1043,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an effect entry into the given effect // Reads an effect entry into the given effect
void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "profile_COMMON") { if (currentName == "profile_COMMON") {
ReadEffectProfileCommon(currentNode, pEffect); ReadEffectProfileCommon(currentNode, pEffect);
@ -1256,8 +1248,6 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
} else if (currentName == "technique") { } else if (currentName == "technique") {
std::string profile; std::string profile;
XmlParser::getStdStrAttribute(currentNode, "profile", profile); XmlParser::getStdStrAttribute(currentNode, "profile", profile);
//const int _profile = GetAttribute("profile");
//const char *profile = mReader->getAttributeValue(_profile);
// Some extensions are quite useful ... ReadSamplerProperties processes // Some extensions are quite useful ... ReadSamplerProperties processes
// several extensions in MAYA, OKINO and MAX3D profiles. // several extensions in MAYA, OKINO and MAX3D profiles.
@ -1330,7 +1320,7 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) {
if (node.empty()) { if (node.empty()) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "geometry") { if (currentName == "geometry") {
// read ID. Another entry which is "optional" by design but obligatory in reality // read ID. Another entry which is "optional" by design but obligatory in reality
@ -1359,7 +1349,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
if (node.empty()) { if (node.empty()) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "mesh") { if (currentName == "mesh") {
ReadMesh(currentNode, pMesh); ReadMesh(currentNode, pMesh);
@ -1383,7 +1373,9 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
ReadSource(currentNode); ReadSource(currentNode);
} else if (currentName == "vertices") { } else if (currentName == "vertices") {
ReadVertexData(currentNode, pMesh); ReadVertexData(currentNode, pMesh);
} else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" || currentName == "polygons" || currentName == "polylist" || currentName == "trifans" || currentName == "tristrips") { } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" ||
currentName == "polygons" || currentName == "polylist" || currentName == "trifans" ||
currentName == "tristrips") {
ReadIndexData(currentNode, pMesh); ReadIndexData(currentNode, pMesh);
} }
} }
@ -1541,16 +1533,11 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
acc.mSubOffset[1] = acc.mParams.size(); acc.mSubOffset[1] = acc.mParams.size();
else if (name == "P") else if (name == "P")
acc.mSubOffset[2] = acc.mParams.size(); acc.mSubOffset[2] = acc.mParams.size();
// else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size();
/* 4D uv coordinates are not supported in Assimp */
/* Generic extra data, interpreted as UV data, too*/ /* Generic extra data, interpreted as UV data, too*/
else if (name == "U") else if (name == "U")
acc.mSubOffset[0] = acc.mParams.size(); acc.mSubOffset[0] = acc.mParams.size();
else if (name == "V") else if (name == "V")
acc.mSubOffset[1] = acc.mParams.size(); acc.mSubOffset[1] = acc.mParams.size();
//else
// DefaultLogger::get()->warn( format() << "Unknown accessor parameter \"" << name << "\". Ignoring data channel." );
} }
if (XmlParser::hasAttribute(currentNode, "type")) { if (XmlParser::hasAttribute(currentNode, "type")) {
// read data type // read data type
@ -1575,7 +1562,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) { void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about // extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID); XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "input") { if (currentName == "input") {
ReadInputChannel(currentNode, pMesh.mPerVertexData); ReadInputChannel(currentNode, pMesh.mPerVertexData);
@ -1778,7 +1765,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
} else { } else {
throw DeadlyImportError("Expected different index count in <p> element."); throw DeadlyImportError("Expected different index count in <p> element.");
} }
} else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0) { } else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0) {
throw DeadlyImportError("Expected different index count in <p> element."); throw DeadlyImportError("Expected different index count in <p> element.");
} }
@ -2030,7 +2016,7 @@ void ColladaParser::ReadSceneLibrary(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "visual_scene") { if (currentName == "visual_scene") {
// read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then? // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
@ -2197,11 +2183,8 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) { void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) {
//XmlNodeIterator xmlIt(node);
//xmlIt.collectChildrenPreOrder(node);
//XmlNode currentNode;
std::string name = node.name(); std::string name = node.name();
for (XmlNode currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "bind_vertex_input") { if (currentName == "bind_vertex_input") {
Collada::InputSemanticMapEntry vn; Collada::InputSemanticMapEntry vn;
@ -2296,8 +2279,8 @@ void ColladaParser::ReadScene(XmlNode &node) {
return; return;
} }
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (XmlNode &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "instance_visual_scene") { if (currentName == "instance_visual_scene") {
// should be the first and only occurrence // should be the first and only occurrence
if (mRootNode) { if (mRootNode) {
@ -2321,20 +2304,6 @@ void ColladaParser::ReadScene(XmlNode &node) {
} }
} }
void ColladaParser::ReportWarning(const char *msg, ...) {
ai_assert(nullptr != msg);
va_list args;
va_start(args, msg);
char szBuffer[3000];
const int iLen = vsprintf(szBuffer, msg, args);
ai_assert(iLen > 0);
va_end(args);
ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen));
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Calculates the resulting transformation from all the given transform steps // Calculates the resulting transformation from all the given transform steps
aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform> &pTransforms) const { aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform> &pTransforms) const {

View File

@ -243,8 +243,6 @@ protected:
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
protected: protected:
void ReportWarning(const char *msg, ...);
/** Calculates the resulting transformation from all the given transform steps */ /** Calculates the resulting transformation from all the given transform steps */
aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const; aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
@ -260,56 +258,55 @@ protected:
std::string mFileName; std::string mFileName;
// XML reader, member for everyday use // XML reader, member for everyday use
//irr::io::IrrXMLReader *mReader;
XmlParser mXmlParser; XmlParser mXmlParser;
/** All data arrays found in the file by ID. Might be referred to by actually /** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */ everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary; using DataLibrary = std::map<std::string, Collada::Data> ;
DataLibrary mDataLibrary; DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */ /** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary; using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
AccessorLibrary mAccessorLibrary; AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */ /** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh *> MeshLibrary; using MeshLibrary = std::map<std::string, Collada::Mesh *>;
MeshLibrary mMeshLibrary; MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */ /** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node *> NodeLibrary; using NodeLibrary = std::map<std::string, Collada::Node *>;
NodeLibrary mNodeLibrary; NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */ /** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary; using ImageLibrary = std::map<std::string, Collada::Image> ;
ImageLibrary mImageLibrary; ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */ /** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary; using EffectLibrary = std::map<std::string, Collada::Effect> ;
EffectLibrary mEffectLibrary; EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */ /** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary; using MaterialLibrary = std::map<std::string, Collada::Material> ;
MaterialLibrary mMaterialLibrary; MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */ /** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary; using LightLibrary = std::map<std::string, Collada::Light> ;
LightLibrary mLightLibrary; LightLibrary mLightLibrary;
/** Camera library: surface material by ID */ /** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary; using CameraLibrary = std::map<std::string, Collada::Camera> ;
CameraLibrary mCameraLibrary; CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */ /** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary; using ControllerLibrary = std::map<std::string, Collada::Controller> ;
ControllerLibrary mControllerLibrary; ControllerLibrary mControllerLibrary;
/** Animation library: animation references by ID */ /** Animation library: animation references by ID */
typedef std::map<std::string, Collada::Animation *> AnimationLibrary; using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
AnimationLibrary mAnimationLibrary; AnimationLibrary mAnimationLibrary;
/** Animation clip library: clip animation references by ID */ /** Animation clip library: clip animation references by ID */
typedef std::vector<std::pair<std::string, std::vector<std::string>>> AnimationClipLibrary; using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
AnimationClipLibrary mAnimationClipLibrary; AnimationClipLibrary mAnimationClipLibrary;
/** Pointer to the root node. Don't delete, it just points to one of /** Pointer to the root node. Don't delete, it just points to one of
@ -334,13 +331,6 @@ protected:
Collada::FormatVersion mFormat; Collada::FormatVersion mFormat;
}; };
// ------------------------------------------------------------------------------------------------
// Check for element match
/*inline bool ColladaParser::IsElement(const char *pName) const {
ai_assert(mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp(mReader->getNodeName(), pName) == 0;
}*/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Finds the item in the given library by its reference, throws if not found // Finds the item in the given library by its reference, throws if not found
template <typename Type> template <typename Type>

View File

@ -188,6 +188,11 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// size relative to cm // size relative to cm
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
if (size_relative_to_cm == 0.0)
{
// BaseImporter later asserts that fileScale is non-zero.
ThrowException("The UnitScaleFactor must be non-zero");
}
// Set FBX file scale is relative to CM must be converted to M for // Set FBX file scale is relative to CM must be converted to M for
// assimp universal format (M) // assimp universal format (M)

View File

@ -86,7 +86,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
std::string templateName; std::string templateName;
// lower-case shading because Blender (for example) writes "Phong" // lower-case shading because Blender (for example) writes "Phong"
std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower<char>); std::transform(shading.data(), shading.data() + shading.size(), std::addressof(shading[0]), Assimp::ToLower<char>);
if(shading == "phong") { if(shading == "phong") {
templateName = "Material.FbxSurfacePhong"; templateName = "Material.FbxSurfacePhong";
} }

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -45,13 +44,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "PostProcessing/MakeVerboseFormat.h" #include "PostProcessing/MakeVerboseFormat.h"
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/DefaultLogger.hpp>
#include <openddlparser/OpenDDLParser.h>
#include <assimp/scene.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <openddlparser/OpenDDLParser.h>
#include <vector> #include <vector>
@ -218,18 +217,15 @@ static void propId2StdString( Property *prop, std::string &name, std::string &ke
#else #else
name = prop->m_key->m_buffer; name = prop->m_key->m_buffer;
#endif #endif
if ( Value::ddl_string == prop->m_value->m_type ) { if (Value::ValueType::ddl_string == prop->m_value->m_type) {
key = prop->m_value->getString(); key = prop->m_value->getString();
} }
} }
} }
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
OpenGEXImporter::VertexContainer::VertexContainer() OpenGEXImporter::VertexContainer::VertexContainer() :
: m_numColors( 0 ) m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() {
, m_colors( nullptr )
, m_numUVComps()
, m_textureCoords() {
// empty // empty
} }
@ -243,10 +239,10 @@ OpenGEXImporter::VertexContainer::~VertexContainer() {
} }
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector<std::string> &names ) OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector<std::string> &names) :
: m_node( node ) m_node(node),
, m_type( type ) m_type(type),
, m_Names( names ) { m_Names(names) {
// empty // empty
} }
@ -256,26 +252,26 @@ OpenGEXImporter::RefInfo::~RefInfo() {
} }
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
OpenGEXImporter::OpenGEXImporter() OpenGEXImporter::OpenGEXImporter() :
: m_root( nullptr ) m_root(nullptr),
, m_nodeChildMap() m_nodeChildMap(),
, m_meshCache() m_meshCache(),
, m_mesh2refMap() m_mesh2refMap(),
, m_material2refMap() m_material2refMap(),
, m_ctx( nullptr ) m_ctx(nullptr),
, m_metrics() m_metrics(),
, m_currentNode( nullptr ) m_currentNode(nullptr),
, m_currentVertices() m_currentVertices(),
, m_currentMesh( nullptr ) m_currentMesh(nullptr),
, m_currentMaterial( nullptr ) m_currentMaterial(nullptr),
, m_currentLight( nullptr ) m_currentLight(nullptr),
, m_currentCamera( nullptr ) m_currentCamera(nullptr),
, m_tokenType( Grammar::NoneType ) m_tokenType(Grammar::NoneType),
, m_materialCache() m_materialCache(),
, m_cameraCache() m_cameraCache(),
, m_lightCache() m_lightCache(),
, m_nodeStack() m_nodeStack(),
, m_unresolvedRefStack() { m_unresolvedRefStack() {
// empty // empty
} }
@ -443,17 +439,17 @@ void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene * /*pScene*/ ) {
Property *prop(node->getProperties()); Property *prop(node->getProperties());
while (nullptr != prop) { while (nullptr != prop) {
if (nullptr != prop->m_key) { if (nullptr != prop->m_key) {
if( Value::ddl_string == prop->m_value->m_type ) { if (Value::ValueType::ddl_string == prop->m_value->m_type) {
std::string valName((char *)prop->m_value->m_data); std::string valName((char *)prop->m_value->m_data);
int type(Grammar::isValidMetricType(valName.c_str())); int type(Grammar::isValidMetricType(valName.c_str()));
if (Grammar::NoneType != type) { if (Grammar::NoneType != type) {
Value *val(node->getValue()); Value *val(node->getValue());
if (nullptr != val) { if (nullptr != val) {
if( Value::ddl_float == val->m_type ) { if (Value::ValueType::ddl_float == val->m_type) {
m_metrics[type].m_floatValue = val->getFloat(); m_metrics[type].m_floatValue = val->getFloat();
} else if( Value::ddl_int32 == val->m_type ) { } else if (Value::ValueType::ddl_int32 == val->m_type) {
m_metrics[type].m_intValue = val->getInt32(); m_metrics[type].m_intValue = val->getInt32();
} else if( Value::ddl_string == val->m_type ) { } else if (Value::ValueType::ddl_string == val->m_type) {
m_metrics[type].m_stringValue = std::string(val->getString()); m_metrics[type].m_stringValue = std::string(val->getString());
} else { } else {
throw DeadlyImportError("OpenGEX: invalid data type for Metric node."); throw DeadlyImportError("OpenGEX: invalid data type for Metric node.");
@ -475,14 +471,13 @@ void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene * /*pScene*/ ) {
Value *val(node->getValue()); Value *val(node->getValue());
if (nullptr != val) { if (nullptr != val) {
if( Value::ddl_string != val->m_type ) { if (Value::ValueType::ddl_string != val->m_type) {
throw DeadlyImportError("OpenGEX: invalid data type for value in node name."); throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
return; return;
} }
const std::string name(val->getString()); const std::string name(val->getString());
if( m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken if (m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken || m_tokenType == Grammar::CameraNodeToken) {
|| m_tokenType == Grammar::CameraNodeToken ) {
m_currentNode->mName.Set(name.c_str()); m_currentNode->mName.Set(name.c_str());
} else if (m_tokenType == Grammar::MaterialToken) { } else if (m_tokenType == Grammar::MaterialToken) {
aiString aiName; aiString aiName;

View File

@ -554,6 +554,16 @@ inline void BufferView::Read(Value &obj, Asset &r) {
byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0)); byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
byteLength = MemberOrDefault(obj, "byteLength", size_t(0)); byteLength = MemberOrDefault(obj, "byteLength", size_t(0));
byteStride = MemberOrDefault(obj, "byteStride", 0u); byteStride = MemberOrDefault(obj, "byteStride", 0u);
// Check length
if ((byteOffset + byteLength) > buffer->byteLength) {
const uint8_t val_size = 64;
char val[val_size];
ai_snprintf(val, val_size, "%llu, %llu", (unsigned long long)byteOffset, (unsigned long long)byteLength);
throw DeadlyImportError("GLTF: Buffer view with offset/length (", val, ") is out of range.");
}
} }
inline uint8_t *BufferView::GetPointer(size_t accOffset) { inline uint8_t *BufferView::GetPointer(size_t accOffset) {
@ -627,6 +637,17 @@ inline void Accessor::Read(Value &obj, Asset &r) {
const char *typestr; const char *typestr;
type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR; type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
// Check length
unsigned long long byteLength = (unsigned long long)GetBytesPerComponent() * (unsigned long long)count;
if ((byteOffset + byteLength) > bufferView->byteLength || (bufferView->byteOffset + byteOffset + byteLength) > bufferView->buffer->byteLength) {
const uint8_t val_size = 64;
char val[val_size];
ai_snprintf(val, val_size, "%llu, %llu", (unsigned long long)byteOffset, (unsigned long long)byteLength);
throw DeadlyImportError("GLTF: Accessor with offset/length (", val, ") is out of range.");
}
if (Value *sparseValue = FindObject(obj, "sparse")) { if (Value *sparseValue = FindObject(obj, "sparse")) {
sparse.reset(new Sparse); sparse.reset(new Sparse);
// count // count
@ -1115,7 +1136,10 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
Mesh::AccessorList *vec = 0; Mesh::AccessorList *vec = 0;
if (GetAttribVector(prim, attr, vec, undPos)) { if (GetAttribVector(prim, attr, vec, undPos)) {
size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0; size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
if ((*vec).size() <= idx) (*vec).resize(idx + 1); if ((*vec).size() != idx) {
throw DeadlyImportError("GLTF: Invalid attribute: ", attr, ". All indices for indexed attribute semantics must start with 0 and be continuous positive integers: TEXCOORD_0, TEXCOORD_1, etc.");
}
(*vec).resize(idx + 1);
(*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint()); (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
} }
} }

View File

@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
// Actually just a dummy, used by the compiler to build the precompiled header. // Actually just a dummy, used by the compiler to build the pre-compiled header.
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include <assimp/scene.h> #include <assimp/scene.h>
@ -51,13 +51,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
// Legal information string - don't remove this. // Legal information string - don't remove this.
static const char *LEGAL_INFORMATION = static const char *LEGAL_INFORMATION =
"Open Asset Import Library (Assimp).\n" "Open Asset Import Library (Assimp).\n"
"A free C/C++ library to import various 3D file formats into applications\n\n" "A free C/C++ library to import various 3D file formats into applications\n\n"
"(c) 2006-2020, assimp team\n" "(c) 2006-2020, assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n" "License under the terms and conditions of the 3-clause BSD license\n"
"http://assimp.org\n"; "https://www.assimp.org\n";
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get legal string // Get legal string

View File

@ -1 +0,0 @@

View File

@ -6,20 +6,12 @@ SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} ) SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} )
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" ) SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON )
option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF ) option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF )
option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON ) option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON )
option( COVERALLS "Generate coveralls data" OFF ) option( COVERALLS "Generate coveralls data" OFF )
if ( DDL_USE_CPP11 ) set(CMAKE_CXX_STANDARD 11)
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set( OPENDDL_CXXFLAGS -std=c++0x )
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set( OPENDDL_CXXFLAGS --std=c++11 )
endif()
else( DDL_USE_CPP11 )
add_definitions( -DOPENDDL_NO_USE_CPP11 )
endif( DDL_USE_CPP11)
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX ) if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
find_package(Threads) find_package(Threads)
@ -31,6 +23,11 @@ if ( DDL_STATIC_LIBRARY )
add_definitions( -DOPENDDL_STATIC_LIBARY ) add_definitions( -DOPENDDL_STATIC_LIBARY )
endif() endif()
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING")
add_definitions(-DGTEST_HAS_TR1_TUPLE=0)
endif()
add_definitions( -DOPENDDLPARSER_BUILD ) add_definitions( -DOPENDDLPARSER_BUILD )
add_definitions( -D_VARIADIC_MAX=10 ) add_definitions( -D_VARIADIC_MAX=10 )
add_definitions( -DGTEST_HAS_PTHREAD=0 ) add_definitions( -DGTEST_HAS_PTHREAD=0 )
@ -49,7 +46,7 @@ link_directories(
${CMAKE_HOME_DIRECTORY}/lib ${CMAKE_HOME_DIRECTORY}/lib
) )
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ) SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib ) SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin ) SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
@ -97,6 +94,7 @@ SET ( openddl_parser_src
include/openddlparser/OpenDDLStream.h include/openddlparser/OpenDDLStream.h
include/openddlparser/DDLNode.h include/openddlparser/DDLNode.h
include/openddlparser/Value.h include/openddlparser/Value.h
include/openddlparser/TPoolAllocator.h
README.md README.md
) )
@ -123,7 +121,6 @@ SET ( gtest_src
${GTEST_PATH}/src/gtest-test-part.cc ${GTEST_PATH}/src/gtest-test-part.cc
${GTEST_PATH}/src/gtest-typed-test.cc ${GTEST_PATH}/src/gtest-typed-test.cc
${GTEST_PATH}/src/gtest.cc ${GTEST_PATH}/src/gtest.cc
${GTEST_PATH}/src/gtest_main.cc
) )
SET( openddl_parser_unittest_src SET( openddl_parser_unittest_src
@ -137,7 +134,10 @@ SET( openddl_parser_unittest_src
test/OpenDDLIntegrationTest.cpp test/OpenDDLIntegrationTest.cpp
test/ValueTest.cpp test/ValueTest.cpp
test/OpenDDLDefectsTest.cpp test/OpenDDLDefectsTest.cpp
test/OssFuzzTest.cpp
test/main.cpp
) )
add_definitions(-DOPENDDL_TEST_DATA="${CMAKE_CURRENT_LIST_DIR}/test/TestData")
SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} ) SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} )
SOURCE_GROUP( gtest FILES ${gtest_src} ) SOURCE_GROUP( gtest FILES ${gtest_src} )

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/ -----------------------------------------------------------------------------------------------*/
#include <openddlparser/DDLNode.h> #include <openddlparser/DDLNode.h>
#include <openddlparser/OpenDDLParser.h> #include <openddlparser/OpenDDLParser.h>
#include <openddlparser/OpenDDLStream.h>
#include <algorithm> #include <algorithm>
@ -30,13 +31,12 @@ BEGIN_ODDLPARSER_NS
DDLNode::DllNodeList DDLNode::s_allocatedNodes; DDLNode::DllNodeList DDLNode::s_allocatedNodes;
template <class T> template <class T>
inline inline static void releaseDataType(T *ptr) {
static void releaseDataType( T *ptr ) { if (nullptr == ptr) {
if( ddl_nullptr == ptr ) {
return; return;
} }
T *current( ddl_nullptr ); T *current(nullptr);
while (ptr) { while (ptr) {
current = ptr; current = ptr;
ptr = ptr->m_next; ptr = ptr->m_next;
@ -45,23 +45,23 @@ static void releaseDataType( T *ptr ) {
} }
static void releaseReferencedNames(Reference *ref) { static void releaseReferencedNames(Reference *ref) {
if( ddl_nullptr == ref ) { if (nullptr == ref) {
return; return;
} }
delete ref; delete ref;
} }
DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent ) DDLNode::DDLNode(const std::string &type, const std::string &name, size_t idx, DDLNode *parent) :
: m_type( type ) m_type(type),
, m_name( name ) m_name(name),
, m_parent( parent ) m_parent(parent),
, m_children() m_children(),
, m_properties( ddl_nullptr ) m_properties(nullptr),
, m_value( ddl_nullptr ) m_value(nullptr),
, m_dtArrayList( ddl_nullptr ) m_dtArrayList(nullptr),
, m_references( ddl_nullptr ) m_references(nullptr),
, m_idx( idx ) { m_idx(idx) {
if (m_parent) { if (m_parent) {
m_parent->m_children.push_back(this); m_parent->m_children.push_back(this);
} }
@ -73,9 +73,9 @@ DDLNode::~DDLNode() {
releaseReferencedNames(m_references); releaseReferencedNames(m_references);
delete m_dtArrayList; delete m_dtArrayList;
m_dtArrayList = ddl_nullptr; m_dtArrayList = nullptr;
if (s_allocatedNodes[m_idx] == this) { if (s_allocatedNodes[m_idx] == this) {
s_allocatedNodes[ m_idx ] = ddl_nullptr; s_allocatedNodes[m_idx] = nullptr;
} }
for (size_t i = 0; i < m_children.size(); i++) { for (size_t i = 0; i < m_children.size(); i++) {
delete m_children[i]; delete m_children[i];
@ -88,18 +88,18 @@ void DDLNode::attachParent( DDLNode *parent ) {
} }
m_parent = parent; m_parent = parent;
if( ddl_nullptr != m_parent ) { if (nullptr != m_parent) {
m_parent->m_children.push_back(this); m_parent->m_children.push_back(this);
} }
} }
void DDLNode::detachParent() { void DDLNode::detachParent() {
if( ddl_nullptr != m_parent ) { if (nullptr != m_parent) {
DDLNodeIt it = std::find(m_parent->m_children.begin(), m_parent->m_children.end(), this); DDLNodeIt it = std::find(m_parent->m_children.begin(), m_parent->m_children.end(), this);
if (m_parent->m_children.end() != it) { if (m_parent->m_children.end() != it) {
m_parent->m_children.erase(it); m_parent->m_children.erase(it);
} }
m_parent = ddl_nullptr; m_parent = nullptr;
} }
} }
@ -128,7 +128,7 @@ const std::string &DDLNode::getName() const {
} }
void DDLNode::setProperties(Property *prop) { void DDLNode::setProperties(Property *prop) {
if(m_properties!=ddl_nullptr) if (m_properties != nullptr)
delete m_properties; delete m_properties;
m_properties = prop; m_properties = prop;
} }
@ -139,24 +139,24 @@ Property *DDLNode::getProperties() const {
bool DDLNode::hasProperty(const std::string &name) { bool DDLNode::hasProperty(const std::string &name) {
const Property *prop(findPropertyByName(name)); const Property *prop(findPropertyByName(name));
return ( ddl_nullptr != prop ); return (nullptr != prop);
} }
bool DDLNode::hasProperties() const { bool DDLNode::hasProperties() const {
return( ddl_nullptr != m_properties ); return (nullptr != m_properties);
} }
Property *DDLNode::findPropertyByName(const std::string &name) { Property *DDLNode::findPropertyByName(const std::string &name) {
if (name.empty()) { if (name.empty()) {
return ddl_nullptr; return nullptr;
} }
if( ddl_nullptr == m_properties ) { if (nullptr == m_properties) {
return ddl_nullptr; return nullptr;
} }
Property *current(m_properties); Property *current(m_properties);
while( ddl_nullptr != current ) { while (nullptr != current) {
int res = strncmp(current->m_key->m_buffer, name.c_str(), name.size()); int res = strncmp(current->m_key->m_buffer, name.c_str(), name.size());
if (0 == res) { if (0 == res) {
return current; return current;
@ -164,7 +164,7 @@ Property *DDLNode::findPropertyByName( const std::string &name ) {
current = current->m_next; current = current->m_next;
} }
return ddl_nullptr; return nullptr;
} }
void DDLNode::setValue(Value *val) { void DDLNode::setValue(Value *val) {
@ -191,8 +191,18 @@ Reference *DDLNode::getReferences() const {
return m_references; return m_references;
} }
void DDLNode::dump(IOStreamBase &/*stream*/) { void DDLNode::dump(IOStreamBase &stream) {
// Todo! if (!stream.isOpen()) {
return;
}
const std::string &type = this->getType();
stream.write("type = " + type);
Value::Iterator it(getValue());
while (it.hasNext()) {
Value *v = it.getNext();
v->dump(stream);
}
} }
DDLNode *DDLNode::create(const std::string &type, const std::string &name, DDLNode *parent) { DDLNode *DDLNode::create(const std::string &type, const std::string &name, DDLNode *parent) {

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -20,16 +20,16 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/ -----------------------------------------------------------------------------------------------*/
#include <openddlparser/OpenDDLCommon.h>
#include <openddlparser/DDLNode.h> #include <openddlparser/DDLNode.h>
#include <openddlparser/OpenDDLCommon.h>
#include <openddlparser/Value.h> #include <openddlparser/Value.h>
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
Text::Text( const char *buffer, size_t numChars ) Text::Text(const char *buffer, size_t numChars) :
: m_capacity( 0 ) m_capacity(0),
, m_len( 0 ) m_len(0),
, m_buffer( ddl_nullptr ) { m_buffer(nullptr) {
set(buffer, numChars); set(buffer, numChars);
} }
@ -39,7 +39,7 @@ Text::~Text() {
void Text::clear() { void Text::clear() {
delete[] m_buffer; delete[] m_buffer;
m_buffer = ddl_nullptr; m_buffer = nullptr;
m_capacity = 0; m_capacity = 0;
m_len = 0; m_len = 0;
} }
@ -74,15 +74,14 @@ bool Text::operator == ( const Text &rhs ) const {
return (0 == res); return (0 == res);
} }
Name::Name( NameType type, Text *id ) Name::Name(NameType type, Text *id) :
: m_type( type ) m_type(type), m_id(id) {
, m_id( id ) {
// empty // empty
} }
Name::~Name() { Name::~Name() {
delete m_id; delete m_id;
m_id = ddl_nullptr; m_id = nullptr;
} }
Name::Name(const Name &name) { Name::Name(const Name &name) {
@ -90,17 +89,13 @@ Name::Name( const Name &name ){
m_id = new Text(name.m_id->m_buffer, name.m_id->m_len); m_id = new Text(name.m_id->m_buffer, name.m_id->m_len);
} }
Reference::Reference() :
m_numRefs(0), m_referencedName(nullptr) {
Reference::Reference()
: m_numRefs( 0 )
, m_referencedName( ddl_nullptr ) {
// empty // empty
} }
Reference::Reference( size_t numrefs, Name **names ) Reference::Reference(size_t numrefs, Name **names) :
: m_numRefs( numrefs ) m_numRefs(numrefs), m_referencedName(nullptr) {
, m_referencedName( ddl_nullptr ) {
if (numrefs > 0) { if (numrefs > 0) {
m_referencedName = new Name *[numrefs]; m_referencedName = new Name *[numrefs];
for (size_t i = 0; i < numrefs; i++) { for (size_t i = 0; i < numrefs; i++) {
@ -124,7 +119,7 @@ Reference::~Reference() {
} }
m_numRefs = 0; m_numRefs = 0;
delete[] m_referencedName; delete[] m_referencedName;
m_referencedName = ddl_nullptr; m_referencedName = nullptr;
} }
size_t Reference::sizeInBytes() { size_t Reference::sizeInBytes() {
@ -135,7 +130,7 @@ size_t Reference::sizeInBytes() {
size_t size(0); size_t size(0);
for (size_t i = 0; i < m_numRefs; i++) { for (size_t i = 0; i < m_numRefs; i++) {
Name *name(m_referencedName[i]); Name *name(m_referencedName[i]);
if ( ddl_nullptr != name ) { if (nullptr != name) {
size += name->m_id->m_len; size += name->m_id->m_len;
} }
} }
@ -143,60 +138,53 @@ size_t Reference::sizeInBytes() {
return size; return size;
} }
Property::Property( Text *id ) Property::Property(Text *id) :
: m_key( id ) m_key(id), m_value(nullptr), m_ref(nullptr), m_next(nullptr) {
, m_value( ddl_nullptr )
, m_ref( ddl_nullptr )
, m_next( ddl_nullptr ) {
// empty // empty
} }
Property::~Property() { Property::~Property() {
delete m_key; delete m_key;
if(m_value!=ddl_nullptr) if (m_value != nullptr)
delete m_value; delete m_value;
if(m_ref!=ddl_nullptr) if (m_ref != nullptr)
delete (m_ref); delete (m_ref);
if(m_next!=ddl_nullptr) if (m_next != nullptr)
delete m_next; delete m_next;
} }
DataArrayList::DataArrayList() DataArrayList::DataArrayList() :
: m_numItems( 0 ) m_numItems(0), m_dataList(nullptr), m_next(nullptr), m_refs(nullptr), m_numRefs(0) {
, m_dataList( ddl_nullptr )
, m_next( ddl_nullptr )
, m_refs(ddl_nullptr)
, m_numRefs(0){
// empty // empty
} }
DataArrayList::~DataArrayList() { DataArrayList::~DataArrayList() {
delete m_dataList; delete m_dataList;
if(m_next!=ddl_nullptr) if (m_next != nullptr)
delete m_next; delete m_next;
if(m_refs!=ddl_nullptr) if (m_refs != nullptr)
delete m_refs; delete m_refs;
} }
size_t DataArrayList::size() { size_t DataArrayList::size() {
size_t result(0); size_t result(0);
if ( ddl_nullptr == m_next ) { if (nullptr == m_next) {
if ( m_dataList != ddl_nullptr ) { if (m_dataList != nullptr) {
result = 1; result = 1;
} }
return result; return result;
} }
DataArrayList *n(m_next); DataArrayList *n(m_next);
while( ddl_nullptr != n ) { while (nullptr != n) {
result++; result++;
n = n->m_next; n = n->m_next;
} }
return result; return result;
} }
Context::Context() Context::Context() :
: m_root( ddl_nullptr ) { m_root(nullptr) {
// empty // empty
} }
@ -206,7 +194,7 @@ Context::~Context() {
void Context::clear() { void Context::clear() {
delete m_root; delete m_root;
m_root = ddl_nullptr; m_root = nullptr;
} }
END_ODDLPARSER_NS END_ODDLPARSER_NS

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -20,10 +20,10 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/ -----------------------------------------------------------------------------------------------*/
#include <openddlparser/OpenDDLExport.h>
#include <openddlparser/DDLNode.h> #include <openddlparser/DDLNode.h>
#include <openddlparser/Value.h> #include <openddlparser/OpenDDLExport.h>
#include <openddlparser/OpenDDLParser.h> #include <openddlparser/OpenDDLParser.h>
#include <openddlparser/Value.h>
#include <sstream> #include <sstream>
@ -33,9 +33,8 @@ struct DDLNodeIterator {
const DDLNode::DllNodeList &m_childs; const DDLNode::DllNodeList &m_childs;
size_t m_idx; size_t m_idx;
DDLNodeIterator( const DDLNode::DllNodeList &childs ) DDLNodeIterator(const DDLNode::DllNodeList &childs) :
: m_childs( childs ) m_childs(childs), m_idx(0) {
, m_idx( 0 ) {
// empty // empty
} }
@ -62,27 +61,27 @@ static void writeLineEnd( std::string &statement ) {
statement += "\n"; statement += "\n";
} }
OpenDDLExport::OpenDDLExport( IOStreamBase *stream ) OpenDDLExport::OpenDDLExport(IOStreamBase *stream) :
: m_stream( stream ) { m_stream(stream) {
if (ddl_nullptr == m_stream) { if (nullptr == m_stream) {
m_stream = new IOStreamBase(); m_stream = new IOStreamBase();
} }
} }
OpenDDLExport::~OpenDDLExport() { OpenDDLExport::~OpenDDLExport() {
if (ddl_nullptr != m_stream) { if (nullptr != m_stream) {
m_stream->close(); m_stream->close();
} }
delete m_stream; delete m_stream;
} }
bool OpenDDLExport::exportContext(Context *ctx, const std::string &filename) { bool OpenDDLExport::exportContext(Context *ctx, const std::string &filename) {
if( ddl_nullptr == ctx ) { if (nullptr == ctx) {
return false; return false;
} }
DDLNode *root(ctx->m_root); DDLNode *root(ctx->m_root);
if ( ddl_nullptr == root ) { if (nullptr == root) {
return true; return true;
} }
@ -98,7 +97,7 @@ bool OpenDDLExport::exportContext( Context *ctx, const std::string &filename ) {
} }
bool OpenDDLExport::handleNode(DDLNode *node) { bool OpenDDLExport::handleNode(DDLNode *node) {
if( ddl_nullptr == node ) { if (nullptr == node) {
return true; return true;
} }
@ -106,12 +105,12 @@ bool OpenDDLExport::handleNode( DDLNode *node ) {
if (childs.empty()) { if (childs.empty()) {
return true; return true;
} }
DDLNode *current( ddl_nullptr ); DDLNode *current(nullptr);
DDLNodeIterator it(childs); DDLNodeIterator it(childs);
std::string statement; std::string statement;
bool success(true); bool success(true);
while (it.getNext(&current)) { while (it.getNext(&current)) {
if( ddl_nullptr != current ) { if (nullptr != current) {
success |= writeNode(current, statement); success |= writeNode(current, statement);
if (!handleNode(current)) { if (!handleNode(current)) {
success = false; success = false;
@ -123,7 +122,7 @@ bool OpenDDLExport::handleNode( DDLNode *node ) {
} }
bool OpenDDLExport::writeToStream(const std::string &statement) { bool OpenDDLExport::writeToStream(const std::string &statement) {
if (ddl_nullptr == m_stream ) { if (nullptr == m_stream) {
return false; return false;
} }
@ -135,20 +134,21 @@ bool OpenDDLExport::writeToStream( const std::string &statement ) {
} }
bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
bool success(true);
writeNodeHeader(node, statement); writeNodeHeader(node, statement);
if (node->hasProperties()) { if (node->hasProperties()) {
writeProperties( node, statement ); success |= writeProperties(node, statement);
} }
writeLineEnd(statement); writeLineEnd(statement);
statement = "}"; statement = "}";
DataArrayList *al(node->getDataArrayList()); DataArrayList *al(node->getDataArrayList());
if ( ddl_nullptr != al ) { if (nullptr != al) {
writeValueType(al->m_dataList->m_type, al->m_numItems, statement); writeValueType(al->m_dataList->m_type, al->m_numItems, statement);
writeValueArray(al, statement); writeValueArray(al, statement);
} }
Value *v(node->getValue()); Value *v(node->getValue());
if (ddl_nullptr != v ) { if (nullptr != v) {
writeValueType(v->m_type, 1, statement); writeValueType(v->m_type, 1, statement);
statement = "{"; statement = "{";
writeLineEnd(statement); writeLineEnd(statement);
@ -165,7 +165,7 @@ bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) {
} }
bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) {
if (ddl_nullptr == node) { if (nullptr == node) {
return false; return false;
} }
@ -181,21 +181,21 @@ bool OpenDDLExport::writeNodeHeader( DDLNode *node, std::string &statement ) {
} }
bool OpenDDLExport::writeProperties(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeProperties(DDLNode *node, std::string &statement) {
if ( ddl_nullptr == node ) { if (nullptr == node) {
return false; return false;
} }
Property *prop(node->getProperties()); Property *prop(node->getProperties());
// if no properties are there, return // if no properties are there, return
if ( ddl_nullptr == prop ) { if (nullptr == prop) {
return true; return true;
} }
if ( ddl_nullptr != prop ) { if (nullptr != prop) {
// for instance (attrib = "position", bla=2) // for instance (attrib = "position", bla=2)
statement += "("; statement += "(";
bool first(true); bool first(true);
while ( ddl_nullptr != prop ) { while (nullptr != prop) {
if (!first) { if (!first) {
statement += ", "; statement += ", ";
} else { } else {
@ -214,7 +214,7 @@ bool OpenDDLExport::writeProperties( DDLNode *node, std::string &statement ) {
} }
bool OpenDDLExport::writeValueType(Value::ValueType type, size_t numItems, std::string &statement) { bool OpenDDLExport::writeValueType(Value::ValueType type, size_t numItems, std::string &statement) {
if ( Value::ddl_types_max == type) { if (Value::ValueType::ddl_types_max == type) {
return false; return false;
} }
@ -234,114 +234,92 @@ bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std:
} }
bool OpenDDLExport::writeValue(Value *val, std::string &statement) { bool OpenDDLExport::writeValue(Value *val, std::string &statement) {
if (ddl_nullptr == val) { if (nullptr == val) {
return false; return false;
} }
switch (val->m_type) { switch (val->m_type) {
case Value::ddl_bool: case Value::ValueType::ddl_bool:
if (true == val->getBool()) { if (true == val->getBool()) {
statement += "true"; statement += "true";
} else { } else {
statement += "false"; statement += "false";
} }
break; break;
case Value::ddl_int8: case Value::ValueType::ddl_int8 : {
{
std::stringstream stream; std::stringstream stream;
const int i = static_cast<int>(val->getInt8()); const int i = static_cast<int>(val->getInt8());
stream << i; stream << i;
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_int16: {
case Value::ddl_int16:
{
std::stringstream stream; std::stringstream stream;
char buffer[256]; char buffer[256];
::memset(buffer, '\0', 256 * sizeof(char)); ::memset(buffer, '\0', 256 * sizeof(char));
sprintf(buffer, "%d", val->getInt16()); sprintf(buffer, "%d", val->getInt16());
statement += buffer; statement += buffer;
} } break;
break; case Value::ValueType::ddl_int32: {
case Value::ddl_int32:
{
std::stringstream stream; std::stringstream stream;
char buffer[256]; char buffer[256];
::memset(buffer, '\0', 256 * sizeof(char)); ::memset(buffer, '\0', 256 * sizeof(char));
const int i = static_cast<int>(val->getInt32()); const int i = static_cast<int>(val->getInt32());
sprintf(buffer, "%d", i); sprintf(buffer, "%d", i);
statement += buffer; statement += buffer;
} } break;
break; case Value::ValueType::ddl_int64: {
case Value::ddl_int64:
{
std::stringstream stream; std::stringstream stream;
const int i = static_cast<int>(val->getInt64()); const int i = static_cast<int>(val->getInt64());
stream << i; stream << i;
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_unsigned_int8: {
case Value::ddl_unsigned_int8:
{
std::stringstream stream; std::stringstream stream;
const int i = static_cast<unsigned int>(val->getUnsignedInt8()); const int i = static_cast<unsigned int>(val->getUnsignedInt8());
stream << i; stream << i;
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_unsigned_int16: {
case Value::ddl_unsigned_int16:
{
std::stringstream stream; std::stringstream stream;
const int i = static_cast<unsigned int>(val->getUnsignedInt16()); const int i = static_cast<unsigned int>(val->getUnsignedInt16());
stream << i; stream << i;
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_unsigned_int32: {
case Value::ddl_unsigned_int32:
{
std::stringstream stream; std::stringstream stream;
const int i = static_cast<unsigned int>(val->getUnsignedInt32()); const int i = static_cast<unsigned int>(val->getUnsignedInt32());
stream << i; stream << i;
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_unsigned_int64: {
case Value::ddl_unsigned_int64:
{
std::stringstream stream; std::stringstream stream;
const int i = static_cast<unsigned int>(val->getUnsignedInt64()); const int i = static_cast<unsigned int>(val->getUnsignedInt64());
stream << i; stream << i;
statement += stream.str(); statement += stream.str();
} } break;
case Value::ValueType::ddl_half:
break; break;
case Value::ddl_half: case Value::ValueType::ddl_float: {
break;
case Value::ddl_float:
{
std::stringstream stream; std::stringstream stream;
stream << val->getFloat(); stream << val->getFloat();
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_double: {
case Value::ddl_double:
{
std::stringstream stream; std::stringstream stream;
stream << val->getDouble(); stream << val->getDouble();
statement += stream.str(); statement += stream.str();
} } break;
break; case Value::ValueType::ddl_string: {
case Value::ddl_string:
{
std::stringstream stream; std::stringstream stream;
stream << val->getString(); stream << val->getString();
statement += "\""; statement += "\"";
statement += stream.str(); statement += stream.str();
statement += "\""; statement += "\"";
} } break;
case Value::ValueType::ddl_ref:
break; break;
case Value::ddl_ref: case Value::ValueType::ddl_none:
break; case Value::ValueType::ddl_types_max:
case Value::ddl_none:
case Value::ddl_types_max:
default: default:
break; break;
} }
@ -350,7 +328,7 @@ bool OpenDDLExport::writeValue( Value *val, std::string &statement ) {
} }
bool OpenDDLExport::writeValueArray(DataArrayList *al, std::string &statement) { bool OpenDDLExport::writeValueArray(DataArrayList *al, std::string &statement) {
if (ddl_nullptr == al) { if (nullptr == al) {
return false; return false;
} }
@ -359,12 +337,13 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement )
} }
DataArrayList *nextDataArrayList = al; DataArrayList *nextDataArrayList = al;
while (ddl_nullptr != nextDataArrayList) {
if (ddl_nullptr != nextDataArrayList) {
statement += "{ ";
Value *nextValue(nextDataArrayList->m_dataList); Value *nextValue(nextDataArrayList->m_dataList);
while (nullptr != nextDataArrayList) {
if (nullptr != nextDataArrayList) {
statement += "{ ";
nextValue = nextDataArrayList->m_dataList;
size_t idx(0); size_t idx(0);
while (ddl_nullptr != nextValue) { while (nullptr != nextValue) {
if (idx > 0) { if (idx > 0) {
statement += ", "; statement += ", ";
} }
@ -381,4 +360,3 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement )
} }
END_ODDLPARSER_NS END_ODDLPARSER_NS

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -20,26 +20,25 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/ -----------------------------------------------------------------------------------------------*/
#include <openddlparser/OpenDDLParser.h>
#include <openddlparser/OpenDDLExport.h> #include <openddlparser/OpenDDLExport.h>
#include <openddlparser/OpenDDLParser.h>
#include <math.h>
#include <algorithm>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <algorithm>
#include <memory>
#include <math.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif // _WIN32 #endif // _WIN32
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
static const char *Version = "0.4.0"; static const char *Version = "0.4.0";
namespace Grammar { namespace Grammar {
static const char *OpenBracketToken = "{"; static const char *OpenBracketToken = "{";
static const char *CloseBracketToken = "}"; static const char *CloseBracketToken = "}";
static const char *OpenPropertyToken = "("; static const char *OpenPropertyToken = "(";
@ -50,7 +49,7 @@ namespace Grammar {
static const char *BoolFalse = "false"; static const char *BoolFalse = "false";
static const char *CommaSeparator = ","; static const char *CommaSeparator = ",";
static const char *PrimitiveTypeToken[ Value::ddl_types_max ] = { static const char *PrimitiveTypeToken[(size_t)Value::ValueType::ddl_types_max] = {
"bool", "bool",
"int8", "int8",
"int16", "int16",
@ -69,12 +68,13 @@ namespace Grammar {
} // Namespace Grammar } // Namespace Grammar
const char *getTypeToken(Value::ValueType type) { const char *getTypeToken(Value::ValueType type) {
return Grammar::PrimitiveTypeToken[ type ]; return Grammar::PrimitiveTypeToken[(size_t)type];
} }
static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
std::stringstream stream; std::stringstream stream;
stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl; stream << "Invalid token \"" << *in << "\""
<< " expected \"" << exp << "\"" << std::endl;
std::string full(in); std::string full(in);
std::string part(full.substr(0, 50)); std::string part(full.substr(0, 50));
stream << part; stream << part;
@ -82,8 +82,8 @@ static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParse
} }
static bool isIntegerType(Value::ValueType integerType) { static bool isIntegerType(Value::ValueType integerType) {
if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && if (integerType != Value::ValueType::ddl_int8 && integerType != Value::ValueType::ddl_int16 &&
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { integerType != Value::ValueType::ddl_int32 && integerType != Value::ValueType::ddl_int64) {
return false; return false;
} }
@ -91,8 +91,8 @@ static bool isIntegerType( Value::ValueType integerType ) {
} }
static bool isUnsignedIntegerType(Value::ValueType integerType) { static bool isUnsignedIntegerType(Value::ValueType integerType) {
if( integerType != Value::ddl_unsigned_int8 && integerType != Value::ddl_unsigned_int16 && if (integerType != Value::ValueType::ddl_unsigned_int8 && integerType != Value::ValueType::ddl_unsigned_int16 &&
integerType != Value::ddl_unsigned_int32 && integerType != Value::ddl_unsigned_int64 ) { integerType != Value::ValueType::ddl_unsigned_int32 && integerType != Value::ValueType::ddl_unsigned_int64) {
return false; return false;
} }
@ -100,14 +100,8 @@ static bool isUnsignedIntegerType( Value::ValueType integerType ) {
} }
static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) { static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) {
// Basic checks if (nullptr == id || nullptr == parser || id->m_buffer == nullptr) {
if( ddl_nullptr == id || ddl_nullptr == parser ) { return nullptr;
return ddl_nullptr;
}
// If the buffer is empty ( an empty node ) return nullptr
if ( ddl_nullptr == id->m_buffer ) {
return ddl_nullptr;
} }
const std::string type(id->m_buffer); const std::string type(id->m_buffer);
@ -135,18 +129,16 @@ static void logMessage( LogSeverity severity, const std::string &msg ) {
std::cout << log; std::cout << log;
} }
OpenDDLParser::OpenDDLParser() OpenDDLParser::OpenDDLParser() :
: m_logCallback( logMessage ) m_logCallback(logMessage),
, m_buffer() m_buffer(),
, m_stack() m_stack(),
, m_context( ddl_nullptr ) { m_context(nullptr) {
// empty // empty
} }
OpenDDLParser::OpenDDLParser( const char *buffer, size_t len ) OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) :
: m_logCallback( &logMessage ) m_logCallback(&logMessage), m_buffer(), m_context(nullptr) {
, m_buffer()
, m_context( ddl_nullptr ) {
if (0 != len) { if (0 != len) {
setBuffer(buffer, len); setBuffer(buffer, len);
} }
@ -157,7 +149,7 @@ OpenDDLParser::~OpenDDLParser() {
} }
void OpenDDLParser::setLogCallback(logCallback callback) { void OpenDDLParser::setLogCallback(logCallback callback) {
if( ddl_nullptr != callback ) { if (nullptr != callback) {
// install user-specific log callback // install user-specific log callback
m_logCallback = callback; m_logCallback = callback;
} else { } else {
@ -188,7 +180,7 @@ void OpenDDLParser::setBuffer( const std::vector<char> &buffer ) {
const char *OpenDDLParser::getBuffer() const { const char *OpenDDLParser::getBuffer() const {
if (m_buffer.empty()) { if (m_buffer.empty()) {
return ddl_nullptr; return nullptr;
} }
return &m_buffer[0]; return &m_buffer[0];
@ -200,23 +192,38 @@ size_t OpenDDLParser::getBufferSize() const {
void OpenDDLParser::clear() { void OpenDDLParser::clear() {
m_buffer.resize(0); m_buffer.resize(0);
if( ddl_nullptr != m_context ) { if (nullptr != m_context) {
delete m_context; delete m_context;
m_context=ddl_nullptr; m_context = nullptr;
} }
// DDLNode::releaseNodes(); // DDLNode::releaseNodes();
} }
bool OpenDDLParser::validate() {
if (m_buffer.empty()) {
return true;
}
if (!isCharacter(m_buffer[0]) && !isNumeric(m_buffer[0])) {
return false;
}
return true;
}
bool OpenDDLParser::parse() { bool OpenDDLParser::parse() {
if (m_buffer.empty()) { if (m_buffer.empty()) {
return false; return false;
} }
normalizeBuffer(m_buffer); normalizeBuffer(m_buffer);
if (!validate()) {
return false;
}
m_context = new Context; m_context = new Context;
m_context->m_root = DDLNode::create( "root", "", ddl_nullptr ); m_context->m_root = DDLNode::create("root", "", nullptr);
pushNode(m_context->m_root); pushNode(m_context->m_root);
// do the main parsing // do the main parsing
@ -225,7 +232,7 @@ bool OpenDDLParser::parse() {
size_t pos(current - &m_buffer[0]); size_t pos(current - &m_buffer[0]);
while (pos < m_buffer.size()) { while (pos < m_buffer.size()) {
current = parseNextNode(current, end); current = parseNextNode(current, end);
if ( current == ddl_nullptr ) { if (current == nullptr) {
return false; return false;
} }
pos = current - &m_buffer[0]; pos = current - &m_buffer[0];
@ -234,7 +241,7 @@ bool OpenDDLParser::parse() {
} }
bool OpenDDLParser::exportContext(Context *ctx, const std::string &filename) { bool OpenDDLParser::exportContext(Context *ctx, const std::string &filename) {
if( ddl_nullptr == ctx ) { if (nullptr == ctx) {
return false; return false;
} }
@ -251,8 +258,8 @@ char *OpenDDLParser::parseNextNode( char *in, char *end ) {
#ifdef DEBUG_HEADER_NAME #ifdef DEBUG_HEADER_NAME
static void dumpId(Identifier *id) { static void dumpId(Identifier *id) {
if( ddl_nullptr != id ) { if (nullptr != id) {
if ( ddl_nullptr != id->m_text.m_buffer ) { if (nullptr != id->m_text.m_buffer) {
std::cout << id->m_text.m_buffer << std::endl; std::cout << id->m_text.m_buffer << std::endl;
} }
} }
@ -260,11 +267,11 @@ static void dumpId( Identifier *id ) {
#endif #endif
char *OpenDDLParser::parseHeader(char *in, char *end) { char *OpenDDLParser::parseHeader(char *in, char *end) {
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
Text *id( ddl_nullptr ); Text *id(nullptr);
in = OpenDDLParser::parseIdentifier(in, end, &id); in = OpenDDLParser::parseIdentifier(in, end, &id);
#ifdef DEBUG_HEADER_NAME #ifdef DEBUG_HEADER_NAME
@ -272,57 +279,54 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
#endif // DEBUG_HEADER_NAME #endif // DEBUG_HEADER_NAME
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if( ddl_nullptr != id ) { if (nullptr != id) {
// store the node // store the node
DDLNode *node(createDDLNode(id, this)); DDLNode *node(createDDLNode(id, this));
if( ddl_nullptr != node ) { if (nullptr != node) {
pushNode(node); pushNode(node);
} else { } else {
std::cerr << "nullptr returned by creating DDLNode." << std::endl; std::cerr << "nullptr returned by creating DDLNode." << std::endl;
} }
delete id; delete id;
Name *name_(ddl_nullptr); Name *name(nullptr);
in = OpenDDLParser::parseName(in, end, &name_); in = OpenDDLParser::parseName(in, end, &name);
std::unique_ptr<Name> name(name_); if (nullptr != name && nullptr != node && nullptr != name->m_id->m_buffer) {
if( ddl_nullptr != name && ddl_nullptr != node ) {
const std::string nodeName(name->m_id->m_buffer); const std::string nodeName(name->m_id->m_buffer);
node->setName(nodeName); node->setName(nodeName);
delete name;
} }
Property *first(nullptr);
std::unique_ptr<Property> first;
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == Grammar::OpenPropertyToken[0]) { if (*in == Grammar::OpenPropertyToken[0]) {
in++; in++;
std::unique_ptr<Property> prop, prev; Property *prop(nullptr), *prev(nullptr);
while (*in != Grammar::ClosePropertyToken[0] && in != end) { while (*in != Grammar::ClosePropertyToken[0] && in != end) {
Property *prop_(ddl_nullptr); in = OpenDDLParser::parseProperty(in, end, &prop);
in = OpenDDLParser::parseProperty(in, end, &prop_);
prop.reset(prop_);
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) { if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback); logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback);
return ddl_nullptr; return nullptr;
} }
if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) { if (nullptr != prop && *in != Grammar::CommaSeparator[0]) {
if (ddl_nullptr == first) { if (nullptr == first) {
first = std::move(prop); first = prop;
} }
if (ddl_nullptr != prev) { if (nullptr != prev) {
prev->m_next = prop.release(); prev->m_next = prop;
} }
prev = std::move(prop); prev = prop;
} }
} }
++in; ++in;
} }
// set the properties // set the properties
if (first && ddl_nullptr != node) { if (nullptr != first && nullptr != node) {
node->setProperties(first.release()); node->setProperties(first);
} }
} }
@ -330,7 +334,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
} }
char *OpenDDLParser::parseStructure(char *in, char *end) { char *OpenDDLParser::parseStructure(char *in, char *end) {
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -340,15 +344,16 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
// loop over all children ( data and nodes ) // loop over all children ( data and nodes )
do { do {
in = parseStructureBody(in, end, error); in = parseStructureBody(in, end, error);
if(in == ddl_nullptr){ if (in == nullptr) {
return ddl_nullptr; return nullptr;
} }
} while (*in != *Grammar::CloseBracketToken); } while (*in != *Grammar::CloseBracketToken);
++in; ++in;
} else { } else {
++in; ++in;
logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback); logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback);
return ddl_nullptr; error = true;
return nullptr;
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
@ -361,24 +366,24 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
} }
static void setNodeValues(DDLNode *currentNode, Value *values) { static void setNodeValues(DDLNode *currentNode, Value *values) {
if( ddl_nullptr != values ){ if (nullptr != values) {
if( ddl_nullptr != currentNode ) { if (nullptr != currentNode) {
currentNode->setValue(values); currentNode->setValue(values);
} }
} }
} }
static void setNodeReferences(DDLNode *currentNode, Reference *refs) { static void setNodeReferences(DDLNode *currentNode, Reference *refs) {
if( ddl_nullptr != refs ) { if (nullptr != refs) {
if( ddl_nullptr != currentNode ) { if (nullptr != currentNode) {
currentNode->setReferences(refs); currentNode->setReferences(refs);
} }
} }
} }
static void setNodeDataArrayList(DDLNode *currentNode, DataArrayList *dtArrayList) { static void setNodeDataArrayList(DDLNode *currentNode, DataArrayList *dtArrayList) {
if( ddl_nullptr != dtArrayList ) { if (nullptr != dtArrayList) {
if( ddl_nullptr != currentNode ) { if (nullptr != currentNode) {
currentNode->setDataArrayList(dtArrayList); currentNode->setDataArrayList(dtArrayList);
} }
} }
@ -390,16 +395,16 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
Value::ValueType type( Value::ddl_none ); Value::ValueType type(Value::ValueType::ddl_none);
size_t arrayLen(0); size_t arrayLen(0);
in = OpenDDLParser::parsePrimitiveDataType(in, end, type, arrayLen); in = OpenDDLParser::parsePrimitiveDataType(in, end, type, arrayLen);
if( Value::ddl_none != type ) { if (Value::ValueType::ddl_none != type) {
// parse a primitive data type // parse a primitive data type
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == Grammar::OpenBracketToken[0]) { if (*in == Grammar::OpenBracketToken[0]) {
Reference *refs( ddl_nullptr ); Reference *refs(nullptr);
DataArrayList *dtArrayList( ddl_nullptr ); DataArrayList *dtArrayList(nullptr);
Value *values( ddl_nullptr ); Value *values(nullptr);
if (1 == arrayLen) { if (1 == arrayLen) {
size_t numRefs(0), numValues(0); size_t numRefs(0), numValues(0);
in = parseDataList(in, end, type, &values, numValues, &refs, numRefs); in = parseDataList(in, end, type, &values, numValues, &refs, numRefs);
@ -417,7 +422,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in != '}') { if (*in != '}') {
logInvalidTokenError(in, std::string(Grammar::CloseBracketToken), m_logCallback); logInvalidTokenError(in, std::string(Grammar::CloseBracketToken), m_logCallback);
return ddl_nullptr; return nullptr;
} else { } else {
//in++; //in++;
} }
@ -430,7 +435,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
} }
void OpenDDLParser::pushNode(DDLNode *node) { void OpenDDLParser::pushNode(DDLNode *node) {
if( ddl_nullptr == node ) { if (nullptr == node) {
return; return;
} }
@ -439,7 +444,7 @@ void OpenDDLParser::pushNode( DDLNode *node ) {
DDLNode *OpenDDLParser::popNode() { DDLNode *OpenDDLParser::popNode() {
if (m_stack.empty()) { if (m_stack.empty()) {
return ddl_nullptr; return nullptr;
} }
DDLNode *topNode(top()); DDLNode *topNode(top());
@ -449,7 +454,7 @@ DDLNode *OpenDDLParser::popNode() {
DDLNode *OpenDDLParser::top() { DDLNode *OpenDDLParser::top() {
if (m_stack.empty()) { if (m_stack.empty()) {
return ddl_nullptr; return nullptr;
} }
DDLNode *top(m_stack.back()); DDLNode *top(m_stack.back());
@ -457,8 +462,8 @@ DDLNode *OpenDDLParser::top() {
} }
DDLNode *OpenDDLParser::getRoot() const { DDLNode *OpenDDLParser::getRoot() const {
if( ddl_nullptr == m_context ) { if (nullptr == m_context) {
return ddl_nullptr; return nullptr;
} }
return m_context->m_root; return m_context->m_root;
@ -485,7 +490,6 @@ void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
++readIdx; ++readIdx;
} }
++readIdx; ++readIdx;
++readIdx;
} else if (!isComment<char>(c, end) && !isNewLine(*c)) { } else if (!isComment<char>(c, end) && !isNewLine(*c)) {
newBuffer.push_back(buffer[readIdx]); newBuffer.push_back(buffer[readIdx]);
} else { } else {
@ -502,8 +506,8 @@ void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
} }
char *OpenDDLParser::parseName(char *in, char *end, Name **name) { char *OpenDDLParser::parseName(char *in, char *end, Name **name) {
*name = ddl_nullptr; *name = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -518,8 +522,8 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
ntype = LocalName; ntype = LocalName;
} }
in++; in++;
Name *currentName( ddl_nullptr ); Name *currentName(nullptr);
Text *id( ddl_nullptr ); Text *id(nullptr);
in = parseIdentifier(in, end, &id); in = parseIdentifier(in, end, &id);
if (id) { if (id) {
currentName = new Name(ntype, id); currentName = new Name(ntype, id);
@ -532,13 +536,16 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
} }
char *OpenDDLParser::parseIdentifier(char *in, char *end, Text **id) { char *OpenDDLParser::parseIdentifier(char *in, char *end, Text **id) {
*id = ddl_nullptr; *id = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
// ignore blanks // ignore blanks
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (in == end) {
return in;
}
// staring with a number is forbidden // staring with a number is forbidden
if (isNumeric<const char>(*in)) { if (isNumeric<const char>(*in)) {
@ -564,14 +571,14 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
} }
char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len) { char *OpenDDLParser::parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len) {
type = Value::ddl_none; type = Value::ValueType::ddl_none;
len = 0; len = 0;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
size_t prim_len(0); size_t prim_len(0);
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { for (size_t i = 0; i < (size_t) Value::ValueType::ddl_types_max; i++) {
prim_len = strlen(Grammar::PrimitiveTypeToken[i]); prim_len = strlen(Grammar::PrimitiveTypeToken[i]);
if (0 == strncmp(in, Grammar::PrimitiveTypeToken[i], prim_len)) { if (0 == strncmp(in, Grammar::PrimitiveTypeToken[i], prim_len)) {
type = static_cast<Value::ValueType>(i); type = static_cast<Value::ValueType>(i);
@ -579,7 +586,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
} }
} }
if( Value::ddl_none == type ) { if (Value::ValueType::ddl_none == type) {
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
return in; return in;
} else { } else {
@ -604,18 +611,18 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
len = 1; len = 1;
} }
if (!ok) { if (!ok) {
type = Value::ddl_none; type = Value::ValueType::ddl_none;
} }
return in; return in;
} }
char *OpenDDLParser::parseReference(char *in, char *end, std::vector<Name *> &names) { char *OpenDDLParser::parseReference(char *in, char *end, std::vector<Name *> &names) {
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
Name *nextName( ddl_nullptr ); Name *nextName(nullptr);
in = parseName(in, end, &nextName); in = parseName(in, end, &nextName);
if (nextName) { if (nextName) {
names.push_back(nextName); names.push_back(nextName);
@ -636,8 +643,8 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &na
} }
char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) { char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) {
*boolean = ddl_nullptr; *boolean = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -653,13 +660,13 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean )
if (0 != res) { if (0 != res) {
res = ::strncmp(Grammar::BoolFalse, start, strlen(Grammar::BoolFalse)); res = ::strncmp(Grammar::BoolFalse, start, strlen(Grammar::BoolFalse));
if (0 != res) { if (0 != res) {
*boolean = ddl_nullptr; *boolean = nullptr;
return in; return in;
} }
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); *boolean = ValueAllocator::allocPrimData(Value::ValueType::ddl_bool);
(*boolean)->setBool(false); (*boolean)->setBool(false);
} else { } else {
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool ); *boolean = ValueAllocator::allocPrimData(Value::ValueType::ddl_bool);
(*boolean)->setBool(true); (*boolean)->setBool(true);
} }
@ -667,8 +674,8 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean )
} }
char *OpenDDLParser::parseIntegerLiteral(char *in, char *end, Value **integer, Value::ValueType integerType) { char *OpenDDLParser::parseIntegerLiteral(char *in, char *end, Value **integer, Value::ValueType integerType) {
*integer = ddl_nullptr; *integer = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -685,35 +692,35 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
if (isNumeric(*start)) { if (isNumeric(*start)) {
#ifdef OPENDDL_NO_USE_CPP11 #ifdef OPENDDL_NO_USE_CPP11
const int64 value(atol(start)); // maybe not really 64bit as atoll is but exists without c++11 const int64 value(atol(start)); // maybe not really 64bit as atoll is but exists without c++11
const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) ); const uint64 uvalue(strtoul(start, nullptr, 10));
#else #else
const int64 value(atoll(start)); const int64 value(atoll(start));
const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) ); const uint64 uvalue(strtoull(start, nullptr, 10));
#endif #endif
*integer = ValueAllocator::allocPrimData(integerType); *integer = ValueAllocator::allocPrimData(integerType);
switch (integerType) { switch (integerType) {
case Value::ddl_int8: case Value::ValueType::ddl_int8:
(*integer)->setInt8((int8)value); (*integer)->setInt8((int8)value);
break; break;
case Value::ddl_int16: case Value::ValueType::ddl_int16:
(*integer)->setInt16((int16)value); (*integer)->setInt16((int16)value);
break; break;
case Value::ddl_int32: case Value::ValueType::ddl_int32:
(*integer)->setInt32((int32)value); (*integer)->setInt32((int32)value);
break; break;
case Value::ddl_int64: case Value::ValueType::ddl_int64:
(*integer)->setInt64((int64)value); (*integer)->setInt64((int64)value);
break; break;
case Value::ddl_unsigned_int8: case Value::ValueType::ddl_unsigned_int8:
(*integer)->setUnsignedInt8((uint8)uvalue); (*integer)->setUnsignedInt8((uint8)uvalue);
break; break;
case Value::ddl_unsigned_int16: case Value::ValueType::ddl_unsigned_int16:
(*integer)->setUnsignedInt16((uint16)uvalue); (*integer)->setUnsignedInt16((uint16)uvalue);
break; break;
case Value::ddl_unsigned_int32: case Value::ValueType::ddl_unsigned_int32:
(*integer)->setUnsignedInt32((uint32)uvalue); (*integer)->setUnsignedInt32((uint32)uvalue);
break; break;
case Value::ddl_unsigned_int64: case Value::ValueType::ddl_unsigned_int64:
(*integer)->setUnsignedInt64((uint64)uvalue); (*integer)->setUnsignedInt64((uint64)uvalue);
break; break;
default: default:
@ -725,8 +732,8 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
} }
char *OpenDDLParser::parseFloatingLiteral(char *in, char *end, Value **floating, Value::ValueType floatType) { char *OpenDDLParser::parseFloatingLiteral(char *in, char *end, Value **floating, Value::ValueType floatType) {
*floating = ddl_nullptr; *floating = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -754,13 +761,13 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
} }
if (ok) { if (ok) {
if ( floatType == Value::ddl_double ) { if (floatType == Value::ValueType::ddl_double) {
const double value(atof(start)); const double value(atof(start));
*floating = ValueAllocator::allocPrimData( Value::ddl_double ); *floating = ValueAllocator::allocPrimData(Value::ValueType::ddl_double);
(*floating)->setDouble(value); (*floating)->setDouble(value);
} else { } else {
const float value((float)atof(start)); const float value((float)atof(start));
*floating = ValueAllocator::allocPrimData( Value::ddl_float ); *floating = ValueAllocator::allocPrimData(Value::ValueType::ddl_float);
(*floating)->setFloat(value); (*floating)->setFloat(value);
} }
} }
@ -769,8 +776,8 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
} }
char *OpenDDLParser::parseStringLiteral(char *in, char *end, Value **stringData) { char *OpenDDLParser::parseStringLiteral(char *in, char *end, Value **stringData) {
*stringData = ddl_nullptr; *stringData = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -785,7 +792,7 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData
++len; ++len;
} }
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len ); *stringData = ValueAllocator::allocPrimData(Value::ValueType::ddl_string, len);
::strncpy((char *)(*stringData)->m_data, start, len); ::strncpy((char *)(*stringData)->m_data, start, len);
(*stringData)->m_data[len] = '\0'; (*stringData)->m_data[len] = '\0';
++in; ++in;
@ -795,15 +802,15 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData
} }
static void createPropertyWithData(Text *id, Value *primData, Property **prop) { static void createPropertyWithData(Text *id, Value *primData, Property **prop) {
if( ddl_nullptr != primData ) { if (nullptr != primData) {
(*prop) = new Property(id); (*prop) = new Property(id);
(*prop)->m_value = primData; (*prop)->m_value = primData;
} }
} }
char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) { char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) {
*data = ddl_nullptr; *data = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
@ -842,8 +849,8 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
++start; ++start;
} }
*data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 ); *data = ValueAllocator::allocPrimData(Value::ValueType::ddl_unsigned_int64);
if( ddl_nullptr != *data ) { if (nullptr != *data) {
(*data)->setUnsignedInt64(value); (*data)->setUnsignedInt64(value);
} }
@ -851,20 +858,20 @@ char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
} }
char *OpenDDLParser::parseProperty(char *in, char *end, Property **prop) { char *OpenDDLParser::parseProperty(char *in, char *end, Property **prop) {
*prop = ddl_nullptr; *prop = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
Text *id( ddl_nullptr ); Text *id = nullptr;
in = parseIdentifier(in, end, &id); in = parseIdentifier(in, end, &id);
if( ddl_nullptr != id ) { if (nullptr != id) {
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == '=') { if (*in == '=') {
++in; ++in;
in = getNextToken(in, end); in = getNextToken(in, end);
Value *primData( ddl_nullptr ); Value *primData(nullptr);
if (isInteger(in, end)) { if (isInteger(in, end)) {
in = parseIntegerLiteral(in, end, &primData); in = parseIntegerLiteral(in, end, &primData);
createPropertyWithData(id, primData, prop); createPropertyWithData(id, primData, prop);
@ -893,20 +900,20 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, Value **data, char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, Value **data,
size_t &numValues, Reference **refs, size_t &numRefs) { size_t &numValues, Reference **refs, size_t &numRefs) {
*data = ddl_nullptr; *data = nullptr;
numValues = numRefs = 0; numValues = numRefs = 0;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == '{') { if (*in == '{') {
++in; ++in;
Value *current( ddl_nullptr ), *prev( ddl_nullptr ); Value *current(nullptr), *prev(nullptr);
while ('}' != *in) { while ('}' != *in) {
current = ddl_nullptr; current = nullptr;
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if ( Value::ddl_ref == type ) { if (Value::ValueType::ddl_ref == type) {
std::vector<Name *> names; std::vector<Name *> names;
in = parseReference(in, end, names); in = parseReference(in, end, names);
if (!names.empty()) { if (!names.empty()) {
@ -914,7 +921,7 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
*refs = ref; *refs = ref;
numRefs = names.size(); numRefs = names.size();
} }
} else if ( Value::ddl_none == type ) { } else if (Value::ValueType::ddl_none == type) {
if (isInteger(in, end)) { if (isInteger(in, end)) {
in = parseIntegerLiteral(in, end, &current); in = parseIntegerLiteral(in, end, &current);
} else if (isFloat(in, end)) { } else if (isFloat(in, end)) {
@ -926,22 +933,22 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
} }
} else { } else {
switch (type) { switch (type) {
case Value::ddl_int8: case Value::ValueType::ddl_int8:
case Value::ddl_int16: case Value::ValueType::ddl_int16:
case Value::ddl_int32: case Value::ValueType::ddl_int32:
case Value::ddl_int64: case Value::ValueType::ddl_int64:
case Value::ddl_unsigned_int8: case Value::ValueType::ddl_unsigned_int8:
case Value::ddl_unsigned_int16: case Value::ValueType::ddl_unsigned_int16:
case Value::ddl_unsigned_int32: case Value::ValueType::ddl_unsigned_int32:
case Value::ddl_unsigned_int64: case Value::ValueType::ddl_unsigned_int64:
in = parseIntegerLiteral(in, end, &current, type); in = parseIntegerLiteral(in, end, &current, type);
break; break;
case Value::ddl_half: case Value::ValueType::ddl_half:
case Value::ddl_float: case Value::ValueType::ddl_float:
case Value::ddl_double: case Value::ValueType::ddl_double:
in = parseFloatingLiteral(in, end, &current, type); in = parseFloatingLiteral(in, end, &current, type);
break; break;
case Value::ddl_string: case Value::ValueType::ddl_string:
in = parseStringLiteral(in, end, &current); in = parseStringLiteral(in, end, &current);
break; break;
default: default:
@ -949,8 +956,8 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
} }
} }
if( ddl_nullptr != current ) { if (nullptr != current) {
if( ddl_nullptr == *data ) { if (nullptr == *data) {
*data = current; *data = current;
prev = current; prev = current;
} else { } else {
@ -984,33 +991,33 @@ static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues
char *OpenDDLParser::parseDataArrayList(char *in, char *end, Value::ValueType type, char *OpenDDLParser::parseDataArrayList(char *in, char *end, Value::ValueType type,
DataArrayList **dataArrayList) { DataArrayList **dataArrayList) {
if ( ddl_nullptr == dataArrayList ) { if (nullptr == dataArrayList) {
return in; return in;
} }
*dataArrayList = ddl_nullptr; *dataArrayList = nullptr;
if( ddl_nullptr == in || in == end ) { if (nullptr == in || in == end) {
return in; return in;
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == Grammar::OpenBracketToken[0]) { if (*in == Grammar::OpenBracketToken[0]) {
++in; ++in;
Value *currentValue( ddl_nullptr ); Value *currentValue(nullptr);
Reference *refs( ddl_nullptr ); Reference *refs(nullptr);
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); DataArrayList *prev(nullptr), *currentDataList(nullptr);
do { do {
size_t numRefs(0), numValues(0); size_t numRefs(0), numValues(0);
currentValue = ddl_nullptr; currentValue = nullptr;
in = parseDataList(in, end, type, &currentValue, numValues, &refs, numRefs); in = parseDataList(in, end, type, &currentValue, numValues, &refs, numRefs);
if( ddl_nullptr != currentValue || 0 != numRefs ) { if (nullptr != currentValue || 0 != numRefs) {
if( ddl_nullptr == prev ) { if (nullptr == prev) {
*dataArrayList = createDataArrayList(currentValue, numValues, refs, numRefs); *dataArrayList = createDataArrayList(currentValue, numValues, refs, numRefs);
prev = *dataArrayList; prev = *dataArrayList;
} else { } else {
currentDataList = createDataArrayList(currentValue, numValues, refs, numRefs); currentDataList = createDataArrayList(currentValue, numValues, refs, numRefs);
if( ddl_nullptr != prev ) { if (nullptr != prev) {
prev->m_next = currentDataList; prev->m_next = currentDataList;
prev = currentDataList; prev = currentDataList;
} }

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -37,22 +37,22 @@ std::string StreamFormatterBase::format(const std::string &statement) {
return tmp; return tmp;
} }
IOStreamBase::IOStreamBase(StreamFormatterBase *formatter) IOStreamBase::IOStreamBase(StreamFormatterBase *formatter) :
: m_formatter(formatter) m_formatter(formatter),
, m_file(ddl_nullptr) { m_file(nullptr) {
if (ddl_nullptr == m_formatter) { if (nullptr == m_formatter) {
m_formatter = new StreamFormatterBase; m_formatter = new StreamFormatterBase;
} }
} }
IOStreamBase::~IOStreamBase() { IOStreamBase::~IOStreamBase() {
delete m_formatter; delete m_formatter;
m_formatter = ddl_nullptr; m_formatter = nullptr;
} }
bool IOStreamBase::open(const std::string &name) { bool IOStreamBase::open(const std::string &name) {
m_file = ::fopen(name.c_str(), "a"); m_file = ::fopen(name.c_str(), "a");
if (m_file == ddl_nullptr) { if (m_file == nullptr) {
return false; return false;
} }
@ -60,22 +60,22 @@ bool IOStreamBase::open(const std::string &name) {
} }
bool IOStreamBase::close() { bool IOStreamBase::close() {
if (ddl_nullptr == m_file) { if (nullptr == m_file) {
return false; return false;
} }
::fclose(m_file); ::fclose(m_file);
m_file = ddl_nullptr; m_file = nullptr;
return true; return true;
} }
bool IOStreamBase::isOpen() const { bool IOStreamBase::isOpen() const {
return ( ddl_nullptr != m_file ); return (nullptr != m_file);
} }
size_t IOStreamBase::read(size_t sizeToRead, std::string &statement) { size_t IOStreamBase::read(size_t sizeToRead, std::string &statement) {
if (ddl_nullptr == m_file) { if (nullptr == m_file) {
return 0; return 0;
} }
@ -86,7 +86,7 @@ size_t IOStreamBase::read( size_t sizeToRead, std::string &statement ) {
} }
size_t IOStreamBase::write(const std::string &statement) { size_t IOStreamBase::write(const std::string &statement) {
if (ddl_nullptr == m_file) { if (nullptr == m_file) {
return 0; return 0;
} }
std::string formatStatement = m_formatter->format(statement); std::string formatStatement = m_formatter->format(statement);

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -20,30 +20,30 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/ -----------------------------------------------------------------------------------------------*/
#include <openddlparser/OpenDDLStream.h>
#include <openddlparser/Value.h> #include <openddlparser/Value.h>
#include <iostream>
#include <cassert> #include <cassert>
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
static Value::Iterator end( ddl_nullptr ); static Value::Iterator end(nullptr);
Value::Iterator::Iterator() Value::Iterator::Iterator() :
: m_start( ddl_nullptr ) m_start(nullptr),
, m_current( ddl_nullptr ) { m_current(nullptr) {
// empty // empty
} }
Value::Iterator::Iterator( Value *start ) Value::Iterator::Iterator(Value *start) :
: m_start( start ) m_start(start),
, m_current( start ) { m_current(start) {
// empty // empty
} }
Value::Iterator::Iterator( const Iterator &rhs ) Value::Iterator::Iterator(const Iterator &rhs) :
: m_start( rhs.m_start ) m_start(rhs.m_start),
, m_current( rhs.m_current ) { m_current(rhs.m_current) {
// empty // empty
} }
@ -52,15 +52,15 @@ Value::Iterator::~Iterator() {
} }
bool Value::Iterator::hasNext() const { bool Value::Iterator::hasNext() const {
if( ddl_nullptr == m_current ) { if (nullptr == m_current) {
return false; return false;
} }
return ( ddl_nullptr != m_current->getNext() ); return (nullptr != m_current->getNext());
} }
Value *Value::Iterator::getNext() { Value *Value::Iterator::getNext() {
if (!hasNext()) { if (!hasNext()) {
return ddl_nullptr; return nullptr;
} }
Value *v(m_current->getNext()); Value *v(m_current->getNext());
@ -70,7 +70,7 @@ Value *Value::Iterator::getNext() {
} }
const Value::Iterator Value::Iterator::operator++(int) { const Value::Iterator Value::Iterator::operator++(int) {
if( ddl_nullptr == m_current ) { if (nullptr == m_current) {
return end; return end;
} }
@ -81,7 +81,7 @@ const Value::Iterator Value::Iterator::operator++( int ) {
} }
Value::Iterator &Value::Iterator::operator++() { Value::Iterator &Value::Iterator::operator++() {
if( ddl_nullptr == m_current ) { if (nullptr == m_current) {
return end; return end;
} }
@ -95,145 +95,144 @@ bool Value::Iterator::operator == ( const Iterator &rhs ) const {
} }
Value *Value::Iterator::operator->() const { Value *Value::Iterator::operator->() const {
if(ddl_nullptr == m_current ) { if (nullptr == m_current) {
return ddl_nullptr; return nullptr;
} }
return m_current; return m_current;
} }
Value::Value( ValueType type ) Value::Value(ValueType type) :
: m_type( type ) m_type(type),
, m_size( 0 ) m_size(0),
, m_data( ddl_nullptr ) m_data(nullptr),
, m_next( ddl_nullptr ) { m_next(nullptr) {
// empty // empty
} }
Value::~Value() { Value::~Value() {
if(m_data!=ddl_nullptr) { if (m_data != nullptr) {
if (m_type == ddl_ref ) { if (m_type == ValueType::ddl_ref) {
Reference *tmp = (Reference *)m_data; Reference *tmp = (Reference *)m_data;
if (tmp != ddl_nullptr) if (tmp != nullptr)
delete tmp; delete tmp;
} else } else
delete[] m_data; delete[] m_data;
} }
if(m_next!=ddl_nullptr) if (m_next != nullptr)
delete m_next; delete m_next;
} }
void Value::setBool(bool value) { void Value::setBool(bool value) {
assert( ddl_bool == m_type ); assert(ValueType::ddl_bool == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
bool Value::getBool() { bool Value::getBool() {
assert( ddl_bool == m_type ); assert(ValueType::ddl_bool == m_type);
return (*m_data == 1); return (*m_data == 1);
} }
void Value::setInt8(int8 value) { void Value::setInt8(int8 value) {
assert( ddl_int8 == m_type ); assert(ValueType::ddl_int8 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
int8 Value::getInt8() { int8 Value::getInt8() {
assert( ddl_int8 == m_type ); assert(ValueType::ddl_int8 == m_type);
return (int8)(*m_data); return (int8)(*m_data);
} }
void Value::setInt16(int16 value) { void Value::setInt16(int16 value) {
assert( ddl_int16 == m_type ); assert(ValueType::ddl_int16 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
int16 Value::getInt16() { int16 Value::getInt16() {
assert( ddl_int16 == m_type ); assert(ValueType::ddl_int16 == m_type);
int16 i; int16 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setInt32(int32 value) { void Value::setInt32(int32 value) {
assert( ddl_int32 == m_type ); assert(ValueType::ddl_int32 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
int32 Value::getInt32() { int32 Value::getInt32() {
assert( ddl_int32 == m_type ); assert(ValueType::ddl_int32 == m_type);
int32 i; int32 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setInt64(int64 value) { void Value::setInt64(int64 value) {
assert( ddl_int64 == m_type ); assert(ValueType::ddl_int64 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
int64 Value::getInt64() { int64 Value::getInt64() {
assert( ddl_int64 == m_type ); assert(ValueType::ddl_int64 == m_type);
int64 i; int64 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setUnsignedInt8(uint8 value) { void Value::setUnsignedInt8(uint8 value) {
assert( ddl_unsigned_int8 == m_type ); assert(ValueType::ddl_unsigned_int8 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
uint8 Value::getUnsignedInt8() const { uint8 Value::getUnsignedInt8() const {
assert( ddl_unsigned_int8 == m_type ); assert(ValueType::ddl_unsigned_int8 == m_type);
uint8 i; uint8 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setUnsignedInt16(uint16 value) { void Value::setUnsignedInt16(uint16 value) {
assert( ddl_unsigned_int16 == m_type ); assert(ValueType::ddl_unsigned_int16 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
uint16 Value::getUnsignedInt16() const { uint16 Value::getUnsignedInt16() const {
assert( ddl_unsigned_int16 == m_type ); assert(ValueType::ddl_unsigned_int16 == m_type);
uint16 i; uint16 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setUnsignedInt32(uint32 value) { void Value::setUnsignedInt32(uint32 value) {
assert( ddl_unsigned_int32 == m_type ); assert(ValueType::ddl_unsigned_int32 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
uint32 Value::getUnsignedInt32() const { uint32 Value::getUnsignedInt32() const {
assert( ddl_unsigned_int32 == m_type ); assert(ValueType::ddl_unsigned_int32 == m_type);
uint32 i; uint32 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setUnsignedInt64(uint64 value) { void Value::setUnsignedInt64(uint64 value) {
assert( ddl_unsigned_int64 == m_type ); assert(ValueType::ddl_unsigned_int64 == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
uint64 Value::getUnsignedInt64() const { uint64 Value::getUnsignedInt64() const {
assert( ddl_unsigned_int64 == m_type ); assert(ValueType::ddl_unsigned_int64 == m_type);
uint64 i; uint64 i;
::memcpy(&i, m_data, m_size); ::memcpy(&i, m_data, m_size);
return i; return i;
} }
void Value::setFloat(float value) { void Value::setFloat(float value) {
assert( ddl_float == m_type ); assert(ValueType::ddl_float == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
float Value::getFloat() const { float Value::getFloat() const {
if( m_type == ddl_float ) { if (m_type == ValueType::ddl_float) {
float v; float v;
::memcpy(&v, m_data, m_size); ::memcpy(&v, m_data, m_size);
return (float)v; return (float)v;
@ -245,17 +244,16 @@ float Value::getFloat() const {
} }
void Value::setDouble(double value) { void Value::setDouble(double value) {
assert( ddl_double == m_type ); assert(ValueType::ddl_double == m_type);
::memcpy(m_data, &value, m_size); ::memcpy(m_data, &value, m_size);
} }
double Value::getDouble() const { double Value::getDouble() const {
if ( m_type == ddl_double ) { if (m_type == ValueType::ddl_double) {
double v; double v;
::memcpy(&v, m_data, m_size); ::memcpy(&v, m_data, m_size);
return (float)v; return (float)v;
} } else {
else {
double tmp; double tmp;
::memcpy(&tmp, m_data, 4); ::memcpy(&tmp, m_data, 4);
return (double)tmp; return (double)tmp;
@ -263,23 +261,23 @@ double Value::getDouble() const {
} }
void Value::setString(const std::string &str) { void Value::setString(const std::string &str) {
assert( ddl_string == m_type ); assert(ValueType::ddl_string == m_type);
::memcpy(m_data, str.c_str(), str.size()); ::memcpy(m_data, str.c_str(), str.size());
m_data[str.size()] = '\0'; m_data[str.size()] = '\0';
} }
const char *Value::getString() const { const char *Value::getString() const {
assert( ddl_string == m_type ); assert(ValueType::ddl_string == m_type);
return (const char *)m_data; return (const char *)m_data;
} }
void Value::setRef(Reference *ref) { void Value::setRef(Reference *ref) {
assert( ddl_ref == m_type ); assert(ValueType::ddl_ref == m_type);
if ( ddl_nullptr != ref ) { if (nullptr != ref) {
const size_t sizeInBytes(ref->sizeInBytes()); const size_t sizeInBytes(ref->sizeInBytes());
if (sizeInBytes > 0) { if (sizeInBytes > 0) {
if ( ddl_nullptr != m_data ) { if (nullptr != m_data) {
delete[] m_data; delete[] m_data;
} }
@ -289,57 +287,57 @@ void Value::setRef( Reference *ref ) {
} }
Reference *Value::getRef() const { Reference *Value::getRef() const {
assert( ddl_ref == m_type ); assert(ValueType::ddl_ref == m_type);
return (Reference *)m_data; return (Reference *)m_data;
} }
void Value::dump( IOStreamBase &/*stream*/ ) { void Value::dump(IOStreamBase &stream) {
switch (m_type) { switch (m_type) {
case ddl_none: case ValueType::ddl_none:
std::cout << "None" << std::endl; stream.write("None\n");
break; break;
case ddl_bool: case ValueType::ddl_bool:
std::cout << getBool() << std::endl; stream.write(std::to_string(getBool()) + "\n");
break; break;
case ddl_int8: case ValueType::ddl_int8:
std::cout << getInt8() << std::endl; stream.write(std::to_string(getInt8()) + "\n");
break; break;
case ddl_int16: case ValueType::ddl_int16:
std::cout << getInt16() << std::endl; stream.write(std::to_string(getInt16()) + "\n");
break; break;
case ddl_int32: case ValueType::ddl_int32:
std::cout << getInt32() << std::endl; stream.write(std::to_string(getInt32()) + "\n");
break; break;
case ddl_int64: case ValueType::ddl_int64:
std::cout << getInt64() << std::endl; stream.write(std::to_string(getInt64()) + "\n");
break; break;
case ddl_unsigned_int8: case ValueType::ddl_unsigned_int8:
std::cout << "Not supported" << std::endl; stream.write("Not supported\n");
break; break;
case ddl_unsigned_int16: case ValueType::ddl_unsigned_int16:
std::cout << "Not supported" << std::endl; stream.write("Not supported\n");
break; break;
case ddl_unsigned_int32: case ValueType::ddl_unsigned_int32:
std::cout << "Not supported" << std::endl; stream.write("Not supported\n");
break; break;
case ddl_unsigned_int64: case ValueType::ddl_unsigned_int64:
std::cout << "Not supported" << std::endl; stream.write("Not supported\n");
break; break;
case ddl_half: case ValueType::ddl_half:
std::cout << "Not supported" << std::endl; stream.write("Not supported\n");
break; break;
case ddl_float: case ValueType::ddl_float:
std::cout << getFloat() << std::endl; stream.write(std::to_string(getFloat()) + "\n");
break; break;
case ddl_double: case ValueType::ddl_double:
std::cout << getDouble() << std::endl; stream.write(std::to_string(getDouble()) + "\n");
break; break;
case ddl_string: case ValueType::ddl_string:
std::cout << getString() << std::endl; stream.write(std::string(getString()) + "\n");
break; break;
case ddl_ref: case ValueType::ddl_ref:
std::cout << "Not supported" << std::endl; stream.write("Not supported\n");
break; break;
default: default:
break; break;
@ -357,7 +355,7 @@ Value *Value::getNext() const {
size_t Value::size() const { size_t Value::size() const {
size_t result = 1; size_t result = 1;
Value *n = m_next; Value *n = m_next;
while( n!=ddl_nullptr) { while (n != nullptr) {
result++; result++;
n = n->m_next; n = n->m_next;
} }
@ -365,56 +363,56 @@ size_t Value::size() const{
} }
Value *ValueAllocator::allocPrimData(Value::ValueType type, size_t len) { Value *ValueAllocator::allocPrimData(Value::ValueType type, size_t len) {
if( type == Value::ddl_none || Value::ddl_types_max == type ) { if (type == Value::ValueType::ddl_none || Value::ValueType::ddl_types_max == type) {
return ddl_nullptr; return nullptr;
} }
Value *data = new Value(type); Value *data = new Value(type);
switch (type) { switch (type) {
case Value::ddl_bool: case Value::ValueType::ddl_bool:
data->m_size = sizeof(bool); data->m_size = sizeof(bool);
break; break;
case Value::ddl_int8: case Value::ValueType::ddl_int8:
data->m_size = sizeof(int8); data->m_size = sizeof(int8);
break; break;
case Value::ddl_int16: case Value::ValueType::ddl_int16:
data->m_size = sizeof(int16); data->m_size = sizeof(int16);
break; break;
case Value::ddl_int32: case Value::ValueType::ddl_int32:
data->m_size = sizeof(int32); data->m_size = sizeof(int32);
break; break;
case Value::ddl_int64: case Value::ValueType::ddl_int64:
data->m_size = sizeof(int64); data->m_size = sizeof(int64);
break; break;
case Value::ddl_unsigned_int8: case Value::ValueType::ddl_unsigned_int8:
data->m_size = sizeof(uint8); data->m_size = sizeof(uint8);
break; break;
case Value::ddl_unsigned_int16: case Value::ValueType::ddl_unsigned_int16:
data->m_size = sizeof(uint16); data->m_size = sizeof(uint16);
break; break;
case Value::ddl_unsigned_int32: case Value::ValueType::ddl_unsigned_int32:
data->m_size = sizeof(uint32); data->m_size = sizeof(uint32);
break; break;
case Value::ddl_unsigned_int64: case Value::ValueType::ddl_unsigned_int64:
data->m_size = sizeof(uint64); data->m_size = sizeof(uint64);
break; break;
case Value::ddl_half: case Value::ValueType::ddl_half:
data->m_size = sizeof(short); data->m_size = sizeof(short);
break; break;
case Value::ddl_float: case Value::ValueType::ddl_float:
data->m_size = sizeof(float); data->m_size = sizeof(float);
break; break;
case Value::ddl_double: case Value::ValueType::ddl_double:
data->m_size = sizeof(double); data->m_size = sizeof(double);
break; break;
case Value::ddl_string: case Value::ValueType::ddl_string:
data->m_size = sizeof(char) * (len + 1); data->m_size = sizeof(char) * (len + 1);
break; break;
case Value::ddl_ref: case Value::ValueType::ddl_ref:
data->m_size = 0; data->m_size = 0;
break; break;
case Value::ddl_none: case Value::ValueType::ddl_none:
case Value::ddl_types_max: case Value::ValueType::ddl_types_max:
default: default:
break; break;
} }
@ -433,7 +431,7 @@ void ValueAllocator::releasePrimData( Value **data ) {
} }
delete *data; delete *data;
*data = ddl_nullptr; *data = nullptr;
} }
END_ODDLPARSER_NS END_ODDLPARSER_NS

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -24,8 +24,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <openddlparser/OpenDDLCommon.h> #include <openddlparser/OpenDDLCommon.h>
#include <vector>
#include <string> #include <string>
#include <vector>
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
@ -148,10 +148,10 @@ public:
/// @param name [in] The name for the new DDLNode instance. /// @param name [in] The name for the new DDLNode instance.
/// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there. /// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
/// @return The new created node instance. /// @return The new created node instance.
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr ); static DDLNode *create(const std::string &type, const std::string &name, DDLNode *parent = nullptr);
private: private:
DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr ); DDLNode(const std::string &type, const std::string &name, size_t idx, DDLNode *parent = nullptr);
DDLNode(); DDLNode();
DDLNode(const DDLNode &) ddl_no_copy; DDLNode(const DDLNode &) ddl_no_copy;
DDLNode &operator=(const DDLNode &) ddl_no_copy; DDLNode &operator=(const DDLNode &) ddl_no_copy;

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -23,8 +23,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <vector>
#include <string> #include <string>
#include <vector>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -56,13 +56,13 @@ BEGIN_ODDLPARSER_NS
// We will use C++11 optional // We will use C++11 optional
#ifndef OPENDDL_NO_USE_CPP11 #ifndef OPENDDL_NO_USE_CPP11
// All C++11 constructs // All C++11 constructs
# define ddl_nullptr nullptr #define nullptr nullptr
#define ddl_override override #define ddl_override override
#define ddl_final final #define ddl_final final
#define ddl_no_copy = delete #define ddl_no_copy = delete
#else #else
// Fall-back for older compilers // Fall-back for older compilers
# define ddl_nullptr NULL #define nullptr NULL
#define ddl_override #define ddl_override
#define ddl_final #define ddl_final
#define ddl_no_copy #define ddl_no_copy
@ -88,14 +88,14 @@ typedef uint64_t uint64_impl;
#endif #endif
// OpenDDL-specific data typedefs // OpenDDL-specific data typedefs
typedef signed char int8; ///< Signed integer, 1 byte using int8 = signed char; ///< Signed integer, 1 byte
typedef signed short int16; ///< Signed integer, 2 byte using int16 = signed short; ///< Signed integer, 2 byte
typedef signed int int32; ///< Signed integer, 4 byte using int32 = signed int; ///< Signed integer, 4 byte
typedef int64_impl int64; ///< Signed integer, 8 byte using int64 = int64_impl; ///< Signed integer, 8 byte
typedef unsigned char uint8; ///< Unsigned integer, 1 byte using uint8 = unsigned char; ///< Unsigned integer, 1 byte
typedef unsigned short uint16; ///< Unsigned integer, 2 byte using uint16 = unsigned short ; ///< Unsigned integer, 2 byte
typedef unsigned int uint32; ///< Unsigned integer, 4 byte using uint32 = unsigned int; ///< Unsigned integer, 4 byte
typedef uint64_impl uint64; ///< Unsigned integer, 8 byte using uint64 = uint64_impl ; ///< Unsigned integer, 8 byte
/// @brief Stores a text. /// @brief Stores a text.
/// ///
@ -153,7 +153,6 @@ struct DLL_ODDLPARSER_EXPORT Name {
~Name(); ~Name();
private: private:
Name &operator=(const Name &) ddl_no_copy; Name &operator=(const Name &) ddl_no_copy;
}; };

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -40,7 +40,7 @@ class IOStreamBase;
class DLL_ODDLPARSER_EXPORT OpenDDLExport { class DLL_ODDLPARSER_EXPORT OpenDDLExport {
public: public:
/// @brief The class constructor /// @brief The class constructor
OpenDDLExport( IOStreamBase *stream = ddl_nullptr ); OpenDDLExport(IOStreamBase *stream = nullptr);
/// @brief The class destructor. /// @brief The class destructor.
~OpenDDLExport(); ~OpenDDLExport();

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -22,13 +22,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/ -----------------------------------------------------------------------------------------------*/
#pragma once #pragma once
#include <openddlparser/OpenDDLCommon.h>
#include <openddlparser/DDLNode.h> #include <openddlparser/DDLNode.h>
#include <openddlparser/OpenDDLCommon.h>
#include <openddlparser/OpenDDLParserUtils.h> #include <openddlparser/OpenDDLParserUtils.h>
#include <openddlparser/Value.h> #include <openddlparser/Value.h>
#include <vector>
#include <string> #include <string>
#include <vector>
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
@ -40,12 +40,7 @@ struct Reference;
struct Property; struct Property;
template <class T> template <class T>
inline inline bool isEmbeddedCommentOpenTag(T *in, T *end) {
bool isEmbeddedCommentOpenTag( T *in, T *end ) {
if ( in == end ) {
return false;
}
if (in == '/' && in + 1 == '*') { if (in == '/' && in + 1 == '*') {
return true; return true;
} }
@ -59,10 +54,9 @@ bool isEmbeddedCommentOpenTag( T *in, T *end ) {
/// @return Pointer showing to the next token or the end of the buffer. /// @return Pointer showing to the next token or the end of the buffer.
/// @detail Will not increase buffer when already a valid buffer was found. /// @detail Will not increase buffer when already a valid buffer was found.
template <class T> template <class T>
inline inline T *lookForNextToken(T *in, T *end) {
T *lookForNextToken( T *in, T *end ) {
while ((in != end) && (isSpace(*in) || isNewLine(*in) || ',' == *in)) { while ((in != end) && (isSpace(*in) || isNewLine(*in) || ',' == *in)) {
in++; ++in;
} }
return in; return in;
} }
@ -73,12 +67,11 @@ T *lookForNextToken( T *in, T *end ) {
/// @return Pointer showing to the next token or the end of the buffer. /// @return Pointer showing to the next token or the end of the buffer.
/// @detail Will increase buffer by a minimum of one. /// @detail Will increase buffer by a minimum of one.
template <class T> template <class T>
inline inline T *getNextToken(T *in, T *end) {
T *getNextToken( T *in, T *end ) {
T *tmp(in); T *tmp(in);
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (tmp == in) { if (tmp == in) {
in++; ++in;
} }
return in; return in;
} }
@ -147,11 +140,14 @@ public:
/// @brief Clears all parser data, including buffer and active context. /// @brief Clears all parser data, including buffer and active context.
void clear(); void clear();
bool validate();
/// @brief Starts the parsing of the OpenDDL-file. /// @brief Starts the parsing of the OpenDDL-file.
/// @return True in case of success, false in case of an error. /// @return True in case of success, false in case of an error.
/// @remark In case of errors check log. /// @remark In case of errors check log.
bool parse(); bool parse();
bool exportContext(Context *ctx, const std::string &filename); bool exportContext(Context *ctx, const std::string &filename);
/// @brief Returns the root node. /// @brief Returns the root node.
@ -176,8 +172,8 @@ public: // parser helpers
static char *parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len); static char *parsePrimitiveDataType(char *in, char *end, Value::ValueType &type, size_t &len);
static char *parseReference(char *in, char *end, std::vector<Name *> &names); static char *parseReference(char *in, char *end, std::vector<Name *> &names);
static char *parseBooleanLiteral(char *in, char *end, Value **boolean); static char *parseBooleanLiteral(char *in, char *end, Value **boolean);
static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 ); static char *parseIntegerLiteral(char *in, char *end, Value **integer, Value::ValueType integerType = Value::ValueType::ddl_int32);
static char *parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType= Value::ddl_float ); static char *parseFloatingLiteral(char *in, char *end, Value **floating, Value::ValueType floatType = Value::ValueType::ddl_float);
static char *parseStringLiteral(char *in, char *end, Value **stringData); static char *parseStringLiteral(char *in, char *end, Value **stringData);
static char *parseHexaLiteral(char *in, char *end, Value **data); static char *parseHexaLiteral(char *in, char *end, Value **data);
static char *parseProperty(char *in, char *end, Property **prop); static char *parseProperty(char *in, char *end, Property **prop);

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -27,53 +27,307 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
template <class T> template <class T>
inline inline bool isUpperCase(T in) {
bool isUpperCase( T in ) {
return (in >= 'A' && in <= 'Z'); return (in >= 'A' && in <= 'Z');
} }
template <class T> template <class T>
inline inline bool isLowerCase(T in) {
bool isLowerCase( T in ) {
return (in >= 'a' && in <= 'z'); return (in >= 'a' && in <= 'z');
} }
template <class T> template <class T>
inline inline bool isSpace(const T in) {
bool isSpace( const T in ) {
return (' ' == in || '\t' == in); return (' ' == in || '\t' == in);
} }
template <class T> template <class T>
inline inline bool isNewLine(const T in) {
bool isNewLine( const T in ) {
return ('\n' == in || ('\r' == in)); return ('\n' == in || ('\r' == in));
} }
template <class T> template <class T>
inline inline bool isSeparator(T in) {
bool isSeparator( T in ) {
if (isSpace(in) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in) { if (isSpace(in) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in) {
return true; return true;
} }
return false; return false;
} }
static const unsigned char chartype_table[256] = {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 0-15
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 16-31
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 32-47
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
0,
0,
0,
0,
0, // 48-63
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 64-79
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 80-95
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 96-111
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // 112-127
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, // > 127
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};
template <class T> template <class T>
inline inline bool isNumeric(const T in) {
bool isNumeric( const T in ) { return (chartype_table[static_cast<size_t>(in)] == 1);
return ( in >= '0' && in <= '9' );
} }
template <class T> template <class T>
inline inline bool isNotEndOfToken(T *in, T *end) {
bool isNotEndOfToken( T *in, T *end ) {
return ('}' != *in && ',' != *in && !isSpace(*in) && ')' != *in && in != end); return ('}' != *in && ',' != *in && !isSpace(*in) && ')' != *in && in != end);
} }
template <class T> template <class T>
inline inline bool isInteger(T *in, T *end) {
bool isInteger( T *in, T *end ) {
if (in != end) { if (in != end) {
if (*in == '-') { if (*in == '-') {
++in; ++in;
@ -93,8 +347,7 @@ bool isInteger( T *in, T *end ) {
} }
template <class T> template <class T>
inline inline bool isFloat(T *in, T *end) {
bool isFloat( T *in, T *end ) {
if (in != end) { if (in != end) {
if (*in == '-') { if (*in == '-') {
++in; ++in;
@ -135,20 +388,17 @@ bool isFloat( T *in, T *end ) {
} }
template <class T> template <class T>
inline inline bool isCharacter(const T in) {
bool isCharacter( const T in ) {
return ((in >= 'a' && in <= 'z') || (in >= 'A' && in <= 'Z')); return ((in >= 'a' && in <= 'z') || (in >= 'A' && in <= 'Z'));
} }
template <class T> template <class T>
inline inline bool isStringLiteral(const T in) {
bool isStringLiteral( const T in ) {
return (in == '\"'); return (in == '\"');
} }
template <class T> template <class T>
inline inline bool isHexLiteral(T *in, T *end) {
bool isHexLiteral( T *in, T *end ) {
if (*in == '0') { if (*in == '0') {
if (in + 1 != end) { if (in + 1 != end) {
if (*(in + 1) == 'x' || *(in + 1) == 'X') { if (*(in + 1) == 'x' || *(in + 1) == 'X') {
@ -161,8 +411,7 @@ bool isHexLiteral( T *in, T *end ) {
} }
template <class T> template <class T>
inline inline bool isReference(T *in, T *end) {
bool isReference( T *in, T *end ) {
if (*in == 'r') { if (*in == 'r') {
if (*(in + 1) == 'e') { if (*(in + 1) == 'e') {
if (*(in + 2) == 'f') { if (*(in + 2) == 'f') {
@ -177,14 +426,12 @@ bool isReference( T *in, T *end ) {
} }
template <class T> template <class T>
inline inline bool isEndofLine(const T in) {
bool isEndofLine( const T in ) {
return ('\n' == in); return ('\n' == in);
} }
template <class T> template <class T>
inline inline static T *getNextSeparator(T *in, T *end) {
static T *getNextSeparator( T *in, T *end ) {
while (!isSeparator(*in) || in == end) { while (!isSeparator(*in) || in == end) {
++in; ++in;
} }
@ -193,8 +440,7 @@ static T *getNextSeparator( T *in, T *end ) {
static const int ErrorHex2Decimal = 9999999; static const int ErrorHex2Decimal = 9999999;
inline inline int hex2Decimal(char in) {
int hex2Decimal( char in ) {
if (isNumeric(in)) { if (isNumeric(in)) {
return (in - 48); return (in - 48);
} }
@ -210,8 +456,7 @@ int hex2Decimal( char in ) {
} }
template <class T> template <class T>
inline inline bool isComment(T *in, T *end) {
bool isComment( T *in, T *end ) {
if (*in == '/') { if (*in == '/') {
if (in + 1 != end) { if (in + 1 != end) {
if (*(in + 1) == '/') { if (*(in + 1) == '/') {
@ -229,8 +474,7 @@ bool isComment( T *in, T *end ) {
} }
template <class T> template <class T>
inline inline bool isCommentOpenTag(T *in, T *end) {
bool isCommentOpenTag(T *in, T *end ) {
if (*in == '/') { if (*in == '/') {
if (in + 1 != end) { if (in + 1 != end) {
if (*(in + 1) == '*') { if (*(in + 1) == '*') {
@ -243,8 +487,7 @@ bool isCommentOpenTag(T *in, T *end ) {
} }
template <class T> template <class T>
inline inline bool isCommentCloseTag(T *in, T *end) {
bool isCommentCloseTag(T *in, T *end) {
if (*in == '*') { if (*in == '*') {
if (in + 1 != end) { if (in + 1 != end) {
if (*(in + 1) == '/') { if (*(in + 1) == '/') {
@ -257,4 +500,3 @@ bool isCommentCloseTag(T *in, T *end) {
} }
END_ODDLPARSER_NS END_ODDLPARSER_NS

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -38,7 +38,7 @@ public:
/// @brief The class destructor, virtual. /// @brief The class destructor, virtual.
virtual ~StreamFormatterBase(); virtual ~StreamFormatterBase();
/// @brief Will format the sring and return the new formatted result. /// @brief Will format the string and return the new formatted result.
/// @param statement [in] The string to reformat. /// @param statement [in] The string to reformat.
/// @return The reformatted result. /// @return The reformatted result.
virtual std::string format(const std::string &statement); virtual std::string format(const std::string &statement);
@ -52,7 +52,7 @@ class DLL_ODDLPARSER_EXPORT IOStreamBase {
public: public:
/// @brief The class constructor with the formatter. /// @brief The class constructor with the formatter.
/// @param formatter [in] The formatter to use. /// @param formatter [in] The formatter to use.
explicit IOStreamBase(StreamFormatterBase *formatter = ddl_nullptr); explicit IOStreamBase(StreamFormatterBase *formatter = nullptr);
/// @brief The class destructor, virtual. /// @brief The class destructor, virtual.
virtual ~IOStreamBase(); virtual ~IOStreamBase();

View File

@ -0,0 +1,226 @@
/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)
Copyright (c) 2014-2019 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------------------------*/
#pragma once
#include <openddlparser/OpenDDLCommon.h>
#include <string>
BEGIN_ODDLPARSER_NS
//-------------------------------------------------------------------------------------------------
/// @class TPoolAllocator
/// @ingroup CPPCore
///
/// @brief This class implements a simple pool-based allocation scheme.
/// Initially you have to define its size. Each allocation will be done from this initially created
/// pool. You have to release all pooled instances after the usage.
/// This allocation scheme is fast and does no call any new-calls during the lifetime of the
/// allocator.
//-------------------------------------------------------------------------------------------------
template <class T>
class TPoolAllocator {
public:
TPoolAllocator();
TPoolAllocator(size_t numItems);
~TPoolAllocator();
T *alloc();
void release();
void reserve(size_t size);
void clear();
size_t capacity() const;
size_t reservedMem() const;
size_t freeMem() const;
void dumpAllocations(std::string &allocs);
void resize(size_t growSize);
CPPCORE_NONE_COPYING(TPoolAllocator)
private:
struct Pool {
size_t m_poolsize;
T *m_pool;
size_t m_currentIdx;
Pool *m_next;
Pool() :
m_poolsize(0u), m_pool(nullptr), m_currentIdx(0u), m_next(nullptr) {
// empty
}
Pool(size_t numItems, Pool *prev) :
m_poolsize(numItems), m_pool(nullptr), m_currentIdx(0u), m_next(prev) {
m_pool = new T[m_poolsize];
}
~Pool() {
delete[] m_pool;
m_pool = nullptr;
}
CPPCORE_NONE_COPYING(Pool)
};
Pool *getFreePool() {
Pool *current(m_freeList);
if (nullptr != m_freeList) {
m_freeList = m_freeList->m_next;
}
return current;
}
Pool *m_first;
Pool *m_current;
Pool *m_freeList;
size_t m_capacity;
};
template <class T>
inline TPoolAllocator<T>::TPoolAllocator() :
m_first(nullptr), m_current(nullptr), m_freeList(nullptr), m_capacity(0L) {
// empty
}
template <class T>
inline TPoolAllocator<T>::TPoolAllocator(size_t numItems) :
m_first(nullptr), m_current(nullptr), m_freeList(nullptr), m_capacity(0L) {
m_first = new Pool(numItems);
m_capacity += numItems;
m_current = m_first;
}
template <class T>
inline TPoolAllocator<T>::~TPoolAllocator() {
clear();
}
template <class T>
inline T *TPoolAllocator<T>::alloc() {
if (nullptr == m_current) {
return nullptr;
}
if (m_current->m_currentIdx == m_current->m_poolsize) {
resize(m_current->m_poolsize);
}
T *ptr(&m_current->m_pool[m_current->m_currentIdx]);
m_current->m_currentIdx++;
return ptr;
}
template <class T>
inline void TPoolAllocator<T>::release() {
if (nullptr == m_current) {
return;
}
Pool *current(m_first);
while (nullptr != current) {
current->m_currentIdx = 0;
current = current->m_next;
}
m_freeList = m_first->m_next;
m_current = m_first;
}
template <class T>
inline void TPoolAllocator<T>::reserve(size_t size) {
clear();
m_first = new Pool(size, nullptr);
m_current = m_first;
m_current->m_pool = new T[size];
m_current->m_poolsize = size;
m_capacity = size;
}
template <class T>
inline void TPoolAllocator<T>::clear() {
if (nullptr == m_current) {
return;
}
Pool *next(m_first);
while (nullptr != next) {
Pool *current = next;
next = current->m_next;
delete current;
}
m_current = nullptr;
m_freeList = nullptr;
}
template <class T>
inline size_t TPoolAllocator<T>::capacity() const {
return m_capacity;
}
template <class T>
inline size_t TPoolAllocator<T>::reservedMem() const {
return m_capacity * sizeof(T);
}
template <class T>
inline size_t TPoolAllocator<T>::freeMem() const {
if (nullptr == m_current) {
return 0L;
}
return (m_current->m_poolsize - m_current->m_currentIdx);
}
template <class T>
inline void TPoolAllocator<T>::dumpAllocations(std::string &allocs) {
allocs.clear();
allocs += "Number allocations = ";
allocs += std::to_string(m_current->m_currentIdx);
allocs += "\n";
}
template <class T>
inline void TPoolAllocator<T>::resize(size_t growSize) {
if (nullptr != m_current) {
if (growSize < m_current->m_poolsize) {
return;
}
}
if (nullptr == m_first) {
m_first = new Pool(growSize, nullptr);
m_current = m_first;
m_capacity += m_current->m_poolsize;
} else {
Pool *pool = getFreePool();
if (nullptr == pool) {
pool = new Pool(growSize, nullptr);
m_capacity += growSize;
}
m_current->m_next = pool;
m_current = m_current->m_next;
}
}
END_ODDLPARSER_NS

View File

@ -1,7 +1,7 @@
/*----------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2015 Kim Kulling Copyright (c) 2014-2020 Kim Kulling
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -101,7 +101,7 @@ public:
}; };
/// @brief This enum describes the data type stored in the value. /// @brief This enum describes the data type stored in the value.
enum ValueType { enum class ValueType {
ddl_none = -1, ///< Nothing specified ddl_none = -1, ///< Nothing specified
ddl_bool = 0, ///< A boolean type ddl_bool = 0, ///< A boolean type
ddl_int8, ///< Integer type, 8 bytes ddl_int8, ///< Integer type, 8 bytes

View File

@ -49,12 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/defs.h> #include <assimp/defs.h>
#include <sstream>
#include <stdarg.h> #include <stdarg.h>
#include <cstdlib>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <cstdlib>
#include <locale> #include <locale>
#include <sstream>
#ifdef _MSC_VER #ifdef _MSC_VER
#define AI_SIZEFMT "%Iu" #define AI_SIZEFMT "%Iu"
@ -107,8 +107,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// @param value The value to write into the std::string. /// @param value The value to write into the std::string.
/// @return The value as a std::string /// @return The value as a std::string
template <typename T> template <typename T>
AI_FORCE_INLINE AI_FORCE_INLINE std::string to_string(T value) {
std::string to_string( T value ) {
std::ostringstream os; std::ostringstream os;
os << value; os << value;
@ -142,8 +141,7 @@ float ai_strtof( const char *begin, const char *end ) {
/// @param toConvert Value to convert /// @param toConvert Value to convert
/// @return The hexadecimal string, is empty in case of an error. /// @return The hexadecimal string, is empty in case of an error.
template <class T> template <class T>
AI_FORCE_INLINE AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) {
std::string DecimalToHexa( T toConvert ) {
std::string result; std::string result;
std::stringstream ss; std::stringstream ss;
ss << std::hex << toConvert; ss << std::hex << toConvert;
@ -174,21 +172,22 @@ AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head)
} }
// trim from start (in place) // trim from start (in place)
inline void ltrim(std::string &s) { AI_FORCE_INLINE void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
return !std::isspace(ch); return !std::isspace(ch);
})); }));
} }
// trim from end (in place) // trim from end (in place)
inline void rtrim(std::string &s) { AI_FORCE_INLINE void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !std::isspace(ch); return !std::isspace(ch);
}).base(), s.end()); }).base(),
s.end());
} }
// trim from both ends (in place) // trim from both ends (in place)
inline void trim(std::string &s) { AI_FORCE_INLINE void trim(std::string &s) {
ltrim(s); ltrim(s);
rtrim(s); rtrim(s);
} }

View File

@ -190,6 +190,16 @@ public:
} }
static inline bool getDoubleAttribute( XmlNode &xmlNode, const char *name, double &val ) {
pugi::xml_attribute attr = xmlNode.attribute(name);
if (attr.empty()) {
return false;
}
val = attr.as_double();
return true;
}
static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
pugi::xml_attribute attr = xmlNode.attribute(name); pugi::xml_attribute attr = xmlNode.attribute(name);
if (attr.empty()) { if (attr.empty()) {

View File

@ -24,11 +24,11 @@
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <stdint.h> #include <stdint.h>
#include <stdexcept>
#include <assimp/defs.h> #include <assimp/defs.h>
#include "StringComparison.h" #include "StringComparison.h"
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Exceptional.h>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <stdint.h> # include <stdint.h>
@ -185,13 +185,15 @@ unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
// Special version of the function, providing higher accuracy and safety // Special version of the function, providing higher accuracy and safety
// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows. // It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
template<typename ExceptionType = DeadlyImportError>
inline inline
uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) { uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) {
unsigned int cur = 0; unsigned int cur = 0;
uint64_t value = 0; uint64_t value = 0;
if ( *in < '0' || *in > '9' ) { if ( *in < '0' || *in > '9' ) {
throw std::invalid_argument( std::string( "The string \"" ) + in + "\" cannot be converted into a value." ); // The string is known to be bad, so don't risk printing the whole thing.
throw ExceptionType("The string \"", std::string(in).substr(0, 100), "\" cannot be converted into a value." );
} }
for ( ;; ) { for ( ;; ) {
@ -237,6 +239,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
// signed variant of strtoul10_64 // signed variant of strtoul10_64
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
template<typename ExceptionType = DeadlyImportError>
inline inline
int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) { int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) {
bool inv = (*in == '-'); bool inv = (*in == '-');
@ -244,7 +247,7 @@ int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inou
++in; ++in;
} }
int64_t value = strtoul10_64(in, out, max_inout); int64_t value = strtoul10_64<ExceptionType>(in, out, max_inout);
if (inv) { if (inv) {
value = -value; value = -value;
} }
@ -259,7 +262,7 @@ int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inou
//! about 6 times faster than atof in win32. //! about 6 times faster than atof in win32.
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org. // If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
template<typename Real> template<typename Real, typename ExceptionType = DeadlyImportError>
inline inline
const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) { const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) {
Real f = 0; Real f = 0;
@ -289,13 +292,14 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
if (!(c[0] >= '0' && c[0] <= '9') && if (!(c[0] >= '0' && c[0] <= '9') &&
!((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) { !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) {
throw std::invalid_argument("Cannot parse string " // The string is known to be bad, so don't risk printing the whole thing.
"as real number: does not start with digit " throw ExceptionType("Cannot parse string \"", std::string(c).substr(0, 100),
"\" as a real number: does not start with digit "
"or decimal point followed by digit."); "or decimal point followed by digit.");
} }
if (*c != '.' && (! check_comma || c[0] != ',')) { if (*c != '.' && (! check_comma || c[0] != ',')) {
f = static_cast<Real>( strtoul10_64 ( c, &c) ); f = static_cast<Real>( strtoul10_64<ExceptionType> ( c, &c) );
} }
if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') { if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') {
@ -310,7 +314,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
// number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between // number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between
// 1 and 15. // 1 and 15.
unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS; unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS;
double pl = static_cast<double>( strtoul10_64 ( c, &c, &diff )); double pl = static_cast<double>( strtoul10_64<ExceptionType> ( c, &c, &diff ));
pl *= fast_atof_table[diff]; pl *= fast_atof_table[diff];
f += static_cast<Real>( pl ); f += static_cast<Real>( pl );
@ -332,7 +336,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
// The reason float constants are used here is that we've seen cases where compilers // The reason float constants are used here is that we've seen cases where compilers
// would perform such casts on compile-time constants at runtime, which would be // would perform such casts on compile-time constants at runtime, which would be
// bad considering how frequently fast_atoreal_move<float> is called in Assimp. // bad considering how frequently fast_atoreal_move<float> is called in Assimp.
Real exp = static_cast<Real>( strtoul10_64(c, &c) ); Real exp = static_cast<Real>( strtoul10_64<ExceptionType>(c, &c) );
if (einv) { if (einv) {
exp = -exp; exp = -exp;
} }
@ -348,26 +352,29 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
// The same but more human. // The same but more human.
template<typename ExceptionType = DeadlyImportError>
inline inline
ai_real fast_atof(const char* c) { ai_real fast_atof(const char* c) {
ai_real ret(0.0); ai_real ret(0.0);
fast_atoreal_move<ai_real>(c, ret); fast_atoreal_move<ai_real, ExceptionType>(c, ret);
return ret; return ret;
} }
template<typename ExceptionType = DeadlyImportError>
inline inline
ai_real fast_atof( const char* c, const char** cout) { ai_real fast_atof( const char* c, const char** cout) {
ai_real ret(0.0); ai_real ret(0.0);
*cout = fast_atoreal_move<ai_real>(c, ret); *cout = fast_atoreal_move<ai_real, ExceptionType>(c, ret);
return ret; return ret;
} }
template<typename ExceptionType = DeadlyImportError>
inline inline
ai_real fast_atof( const char** inout) { ai_real fast_atof( const char** inout) {
ai_real ret(0.0); ai_real ret(0.0);
*inout = fast_atoreal_move<ai_real>(*inout, ret); *inout = fast_atoreal_move<ai_real, ExceptionType>(*inout, ret);
return ret; return ret;
} }

View File

@ -48,7 +48,7 @@ using namespace Assimp;
class utOpenGEXImportExport : public AbstractImportExportBase { class utOpenGEXImportExport : public AbstractImportExportBase {
public: public:
virtual bool importerTest() { bool importerTest() override {
Assimp::Importer importer; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OpenGEX/Example.ogex", 0); const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OpenGEX/Example.ogex", 0);
return nullptr != scene; return nullptr != scene;