Fix memory handling of xml-nodes in the parser.

pull/2966/head
Kim Kulling 2020-09-01 21:48:50 +02:00
parent 3c2133a3b9
commit 73fa2cbe88
10 changed files with 86 additions and 406 deletions

View File

@ -93,7 +93,7 @@ public:
std::vector<aiNode *> children;
std::string nodeName;
XmlNode node = *mXmlParser->getRootNode();
XmlNode node = mXmlParser->getRootNode();
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentNodeName = currentNode.name();

View File

@ -69,11 +69,8 @@ typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
class OpcPackageRelationshipReader {
public:
OpcPackageRelationshipReader(XmlParser &parser) {
XmlNode *root = parser.getRootNode();
if (nullptr != root) {
XmlNode node = *root;
ParseRootNode(node);
}
XmlNode root = parser.getRootNode();
ParseRootNode(root);
}
void ParseRootNode(XmlNode &node) {

View File

@ -118,13 +118,13 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
}
// generate a XML reader for it
pugi::xml_node *rootPtr = mXmlParser.parse(daefile.get());
if (nullptr == rootPtr) {
;
if (!mXmlParser.parse(daefile.get())) {
ThrowException("Unable to read file, malformed XML");
}
// start reading
XmlNode node = *rootPtr;
std::string name = rootPtr->name();
XmlNode node = mXmlParser.getRootNode();
std::string name = node.name();
ReadContents(node);
// read embedded textures
@ -159,19 +159,18 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
return file_list.front();
}
XmlParser manifestParser;
XmlNode *root = manifestParser.parse(manifestfile.get());
if (nullptr == root) {
if (!manifestParser.parse(manifestfile.get())) {
return std::string();
}
const std::string &name = root->name();
XmlNode root = manifestParser.getRootNode();
const std::string &name = root.name();
if (name != "dae_root") {
root = manifestParser.findNode("dae_root");
root = *manifestParser.findNode("dae_root");
if (nullptr == root) {
return std::string();
}
std::string v;
XmlParser::getValueAsString(*root, v);
XmlParser::getValueAsString(root, v);
aiString ai_str(v);
UriDecodePath(ai_str);
return std::string(ai_str.C_Str());

View File

@ -864,8 +864,10 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Construct the irrXML parser
XmlParser st;
pugi::xml_node *rootElement = st.parse(file.get());
// reader = createIrrXMLReader((IFileReadCallBack*) &st);
if (!st.parse( file.get() )) {
return;
}
pugi::xml_node rootElement = st.getRootNode();
// The root node of the scene
Node *root = new Node(Node::DUMMY);
@ -897,7 +899,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Parse the XML file
//while (reader->read()) {
for (pugi::xml_node child : rootElement->children())
for (pugi::xml_node child : rootElement.children())
switch (child.type()) {
case pugi::node_element:
if (!ASSIMP_stricmp(child.name(), "node")) {

View File

@ -139,9 +139,10 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// Construct the irrXML parser
XmlParser parser;
pugi::xml_node *root = parser.parse(file.get());
/*CIrrXML_IOStreamReader st(file.get());
reader = createIrrXMLReader((IFileReadCallBack*) &st);*/
if (!parser.parse( file.get() )) {
return;
}
XmlNode root = parser.getRootNode();
// final data
std::vector<aiMaterial *> materials;
@ -164,7 +165,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
bool useColors = false;
// Parse the XML file
for (pugi::xml_node child : root->children()) {
for (pugi::xml_node child : root.children()) {
if (child.type() == pugi::node_element) {
if (!ASSIMP_stricmp(child.name(), "buffer") && (curMat || curMesh)) {
// end of previous buffer. A material and a mesh should be there

View File

@ -225,12 +225,12 @@ MeshXml *OgreXmlSerializer::ImportMesh(XmlParser *parser) {
}
void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
XmlNode *root = mParser->getRootNode();
if (nullptr == root || std::string(nnMesh)!=root->name()) {
throw DeadlyImportError("Root node is <" + std::string(root->name()) + "> expecting <mesh>");
XmlNode root = mParser->getRootNode();
if (nullptr == root || std::string(nnMesh) != root.name()) {
throw DeadlyImportError("Root node is <" + std::string(root.name()) + "> expecting <mesh>");
}
for (XmlNode currentNode : root->children()) {
for (XmlNode currentNode : root.children()) {
const std::string currentName = currentNode.name();
if (currentName == nnSharedGeometry) {
mesh->sharedVertexData = new VertexDataXml();
@ -242,43 +242,8 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
} else if (currentName == nnSkeletonLink) {
}
}
/*if (NextNode() != nnMesh) {
}*/
ASSIMP_LOG_VERBOSE_DEBUG("Reading Mesh");
//NextNode();
// Root level nodes
/*while (m_currentNodeName == nnSharedGeometry ||
m_currentNodeName == nnSubMeshes ||
m_currentNodeName == nnSkeletonLink ||
m_currentNodeName == nnBoneAssignments ||
m_currentNodeName == nnLOD ||
m_currentNodeName == nnSubMeshNames ||
m_currentNodeName == nnExtremes ||
m_currentNodeName == nnPoses ||
m_currentNodeName == nnAnimations) {
if (m_currentNodeName == nnSharedGeometry) {
mesh->sharedVertexData = new VertexDataXml();
ReadGeometry(mesh->sharedVertexData);
} else if (m_currentNodeName == nnSubMeshes) {
NextNode();
while (m_currentNodeName == nnSubMesh) {
ReadSubMesh(mesh);
}
} else if (m_currentNodeName == nnBoneAssignments) {
ReadBoneAssignments(mesh->sharedVertexData);
} else if (m_currentNodeName == nnSkeletonLink) {
mesh->skeletonRef = ReadAttribute<std::string>("name");
ASSIMP_LOG_VERBOSE_DEBUG_F("Read skeleton link ", mesh->skeletonRef);
NextNode();
}
// Assimp incompatible/ignored nodes
else {
SkipCurrentNode();
}
}*/
}
void OgreXmlSerializer::ReadGeometry(XmlNode &node, VertexDataXml *dest) {
@ -291,10 +256,6 @@ void OgreXmlSerializer::ReadGeometry(XmlNode &node, VertexDataXml *dest) {
ReadGeometryVertexBuffer(currentNode, dest);
}
}
//NextNode();
/*while (m_currentNodeName == nnVertexBuffer) {
ReadGeometryVertexBuffer(dest);
}*/
}
void OgreXmlSerializer::ReadGeometryVertexBuffer(XmlNode &node, VertexDataXml *dest) {
@ -328,11 +289,6 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(XmlNode &node, VertexDataXml *d
}
}
/*bool warnBinormal = true;
bool warnColorDiffuse = true;
bool warnColorSpecular = true;*/
//NextNode();
for (XmlNode currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (positions && currentName == nnPosition) {
@ -363,84 +319,6 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(XmlNode &node, VertexDataXml *d
}
}
/*while (m_currentNodeName == nnVertex ||
m_currentNodeName == nnPosition ||
m_currentNodeName == nnNormal ||
m_currentNodeName == nnTangent ||
m_currentNodeName == nnBinormal ||
m_currentNodeName == nnTexCoord ||
m_currentNodeName == nnColorDiffuse ||
m_currentNodeName == nnColorSpecular) {
if (m_currentNodeName == nnVertex) {
NextNode();
}
/// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular
if (positions && m_currentNodeName == nnPosition) {
aiVector3D pos;
pos.x = ReadAttribute<float>(anX);
pos.y = ReadAttribute<float>(anY);
pos.z = ReadAttribute<float>(anZ);
dest->positions.push_back(pos);
} else if (normals && m_currentNodeName == nnNormal) {
aiVector3D normal;
normal.x = ReadAttribute<float>(anX);
normal.y = ReadAttribute<float>(anY);
normal.z = ReadAttribute<float>(anZ);
dest->normals.push_back(normal);
} else if (tangents && m_currentNodeName == nnTangent) {
aiVector3D tangent;
tangent.x = ReadAttribute<float>(anX);
tangent.y = ReadAttribute<float>(anY);
tangent.z = ReadAttribute<float>(anZ);
dest->tangents.push_back(tangent);
} else if (uvs > 0 && m_currentNodeName == nnTexCoord) {
for (auto &curUvs : dest->uvs) {
if (m_currentNodeName != nnTexCoord) {
throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex");
}
aiVector3D uv;
uv.x = ReadAttribute<float>("u");
uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form
curUvs.push_back(uv);
NextNode();
}
// Continue main loop as above already read next node
continue;
} else {
/// @todo Remove this stuff once implemented. We only want to log warnings once per element.
bool warn = true;
if (m_currentNodeName == nnBinormal) {
if (warnBinormal) {
warnBinormal = false;
} else {
warn = false;
}
} else if (m_currentNodeName == nnColorDiffuse) {
if (warnColorDiffuse) {
warnColorDiffuse = false;
} else {
warn = false;
}
} else if (m_currentNodeName == nnColorSpecular) {
if (warnColorSpecular) {
warnColorSpecular = false;
} else {
warn = false;
}
}
if (warn) {
ASSIMP_LOG_WARN_F("Vertex buffer attribute read not implemented for element: ", m_currentNodeName);
}
}*/
// Advance
//NextNode();
//}
// Sanity checks
if (dest->positions.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->positions.size() << " positions when should have read " << dest->count);
@ -525,57 +403,6 @@ void OgreXmlSerializer::ReadSubMesh(XmlNode &node, MeshXml *mesh) {
}
}
/*NextNode();
while (m_currentNodeName == nnFaces ||
m_currentNodeName == nnGeometry ||
m_currentNodeName == nnTextures ||
m_currentNodeName == nnBoneAssignments) {
if (m_currentNodeName == nnFaces) {
submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount);
submesh->indexData->faces.reserve(submesh->indexData->faceCount);
NextNode();
while (m_currentNodeName == nnFace) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
face.mIndices[0] = ReadAttribute<uint32_t>(anV1);
face.mIndices[1] = ReadAttribute<uint32_t>(anV2);
face.mIndices[2] = ReadAttribute<uint32_t>(anV3);
/// @todo Support quads if Ogre even supports them in XML (I'm not sure but I doubt it)
if (!quadWarned && HasAttribute(anV4)) {
ASSIMP_LOG_WARN("Submesh <face> has quads with <v4>, only triangles are supported at the moment!");
quadWarned = true;
}
submesh->indexData->faces.push_back(face);
// Advance
NextNode();
}
if (submesh->indexData->faces.size() == submesh->indexData->faceCount) {
ASSIMP_LOG_VERBOSE_DEBUG_F(" - Faces ", submesh->indexData->faceCount);
} else {
throw DeadlyImportError(Formatter::format() << "Read only " << submesh->indexData->faces.size() << " faces when should have read " << submesh->indexData->faceCount);
}
} else if (m_currentNodeName == nnGeometry) {
if (submesh->usesSharedVertexData) {
throw DeadlyImportError("Found <geometry> in <submesh> when use shared geometry is true. Invalid mesh file.");
}
submesh->vertexData = new VertexDataXml();
ReadGeometry(submesh->vertexData);
} else if (m_currentNodeName == nnBoneAssignments) {
ReadBoneAssignments(submesh->vertexData);
}
// Assimp incompatible/ignored nodes
else {
SkipCurrentNode();
}
}*/
submesh->index = static_cast<unsigned int>(mesh->subMeshes.size());
mesh->subMeshes.push_back(submesh);
}
@ -603,19 +430,6 @@ void OgreXmlSerializer::ReadBoneAssignments(XmlNode &node, VertexDataXml *dest)
}
}
/*NextNode();
while (m_currentNodeName == nnVertexBoneAssignment) {
VertexBoneAssignment ba;
ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex);
ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex);
ba.weight = ReadAttribute<float>(anWeight);
dest->boneAssignments.push_back(ba);
influencedVertices.insert(ba.vertexIndex);
NextNode();
}*/
/** Normalize bone weights.
Some exporters won't care if the sum of all bone weights
for a single vertex equals 1 or not, so validate here. */
@ -662,8 +476,8 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
Skeleton *skeleton = new Skeleton();
OgreXmlSerializer serializer(xmlParser.get());
XmlNode *root = xmlParser->getRootNode();
serializer.ReadSkeleton(*root, skeleton);
XmlNode root = xmlParser->getRootNode();
serializer.ReadSkeleton(root, skeleton);
mesh->skeleton = skeleton;
return true;
}
@ -680,12 +494,9 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
Skeleton *skeleton = new Skeleton();
OgreXmlSerializer serializer(xmlParser.get());
XmlNode *root = xmlParser->getRootNode();
if (nullptr == root) {
return false;
}
XmlNode root = xmlParser->getRootNode();
serializer.ReadSkeleton(*root, skeleton);
serializer.ReadSkeleton(root, skeleton);
mesh->skeleton = skeleton;
return true;
@ -736,22 +547,6 @@ void OgreXmlSerializer::ReadSkeleton(XmlNode &node, Skeleton *skeleton) {
ReadAnimations(currentNode, skeleton);
}
}
/*NextNode();
// Root level nodes
while (m_currentNodeName == nnBones ||
m_currentNodeName == nnBoneHierarchy ||
m_currentNodeName == nnAnimations ||
m_currentNodeName == nnAnimationLinks) {
if (m_currentNodeName == nnBones)
ReadBones(skeleton);
else if (m_currentNodeName == nnBoneHierarchy)
ReadBoneHierarchy(skeleton);
else if (m_currentNodeName == nnAnimations)
ReadAnimations(skeleton);
else
SkipCurrentNode();
}*/
}
void OgreXmlSerializer::ReadAnimations(XmlNode &node, Skeleton *skeleton) {
@ -778,22 +573,6 @@ void OgreXmlSerializer::ReadAnimations(XmlNode &node, Skeleton *skeleton) {
}
}
}
/* NextNode();
while (m_currentNodeName == nnAnimation) {
Animation *anim = new Animation(skeleton);
anim->name = ReadAttribute<std::string>("name");
anim->length = ReadAttribute<float>("length");
if (NextNode() != nnTracks) {
throw DeadlyImportError(Formatter::format() << "No <tracks> found in <animation> " << anim->name);
}
ReadAnimationTracks(anim);
skeleton->animations.push_back(anim);
ASSIMP_LOG_VERBOSE_DEBUG_F(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)");
}*/
}
void OgreXmlSerializer::ReadAnimationTracks(XmlNode &node, Animation *dest) {
@ -815,20 +594,6 @@ void OgreXmlSerializer::ReadAnimationTracks(XmlNode &node, Animation *dest) {
}
}
/*NextNode();
while (m_currentNodeName == nnTrack) {
VertexAnimationTrack track;
track.type = VertexAnimationTrack::VAT_TRANSFORM;
track.boneName = ReadAttribute<std::string>("bone");
if (NextNode() != nnKeyFrames) {
throw DeadlyImportError(Formatter::format() << "No <keyframes> found in <track> " << dest->name);
}
ReadAnimationKeyFrames(dest, &track);
dest->tracks.push_back(track);
}*/
}
void OgreXmlSerializer::ReadAnimationKeyFrames(XmlNode &node, Animation *anim, VertexAnimationTrack *dest) {
@ -873,46 +638,6 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(XmlNode &node, Animation *anim, V
}
dest->transformKeyFrames.push_back(keyframe);
}
/*NextNode();
while (m_currentNodeName == nnKeyFrame) {
TransformKeyFrame keyframe;
keyframe.timePos = ReadAttribute<float>("time");
NextNode();
while (m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale) {
if (m_currentNodeName == nnTranslate) {
keyframe.position.x = ReadAttribute<float>(anX);
keyframe.position.y = ReadAttribute<float>(anY);
keyframe.position.z = ReadAttribute<float>(anZ);
} else if (m_currentNodeName == nnRotate) {
float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) {
throw DeadlyImportError("No axis specified for keyframe rotation in animation " + anim->name);
}
aiVector3D axis;
axis.x = ReadAttribute<float>(anX);
axis.y = ReadAttribute<float>(anY);
axis.z = ReadAttribute<float>(anZ);
if (axis.Equal(zeroVec)) {
axis.x = 1.0f;
if (angle != 0) {
ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name);
}
}
keyframe.rotation = aiQuaternion(axis, angle);
} else if (m_currentNodeName == nnScale) {
keyframe.scale.x = ReadAttribute<float>(anX);
keyframe.scale.y = ReadAttribute<float>(anY);
keyframe.scale.z = ReadAttribute<float>(anZ);
}
NextNode();
}
dest->transformKeyFrames.push_back(keyframe);
}*/
}
void OgreXmlSerializer::ReadBoneHierarchy(XmlNode &node, Skeleton *skeleton) {
@ -937,20 +662,6 @@ void OgreXmlSerializer::ReadBoneHierarchy(XmlNode &node, Skeleton *skeleton) {
}
}
/*while (NextNode() == nnBoneParent) {
const std::string name = ReadAttribute<std::string>("bone");
const std::string parentName = ReadAttribute<std::string>("parent");
Bone *bone = skeleton->BoneByName(name);
Bone *parent = skeleton->BoneByName(parentName);
if (bone && parent)
parent->AddChild(bone);
else
throw DeadlyImportError("Failed to find bones for parenting: Child " + name + " for parent " + parentName);
}*/
// Calculate bone matrices for root bones. Recursively calculates their children.
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
Bone *bone = skeleton->bones[i];
@ -1014,54 +725,6 @@ void OgreXmlSerializer::ReadBones(XmlNode &node, Skeleton *skeleton) {
}
}
/*NextNode();
while (m_currentNodeName == nnBone) {
Bone *bone = new Bone();
bone->id = ReadAttribute<uint16_t>("id");
bone->name = ReadAttribute<std::string>("name");
NextNode();
while (m_currentNodeName == nnPosition ||
m_currentNodeName == nnRotation ||
m_currentNodeName == nnScale) {
if (m_currentNodeName == nnPosition) {
bone->position.x = ReadAttribute<float>(anX);
bone->position.y = ReadAttribute<float>(anY);
bone->position.z = ReadAttribute<float>(anZ);
} else if (m_currentNodeName == nnRotation) {
float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) {
throw DeadlyImportError(Formatter::format() << "No axis specified for bone rotation in bone " << bone->id);
}
aiVector3D axis;
axis.x = ReadAttribute<float>(anX);
axis.y = ReadAttribute<float>(anY);
axis.z = ReadAttribute<float>(anZ);
bone->rotation = aiQuaternion(axis, angle);
} else if (m_currentNodeName == nnScale) {
/// @todo Implement taking scale into account in matrix/pose calculations!
if (HasAttribute("factor")) {
float factor = ReadAttribute<float>("factor");
bone->scale.Set(factor, factor, factor);
} else {
if (HasAttribute(anX))
bone->scale.x = ReadAttribute<float>(anX);
if (HasAttribute(anY))
bone->scale.y = ReadAttribute<float>(anY);
if (HasAttribute(anZ))
bone->scale.z = ReadAttribute<float>(anZ);
}
}
NextNode();
}
skeleton->bones.push_back(bone);
}*/
// Order bones by Id
std::sort(skeleton->bones.begin(), skeleton->bones.end(), BoneCompare);

View File

@ -199,27 +199,18 @@ void XGLImporter::InternReadFile(const std::string &pFile,
#endif
}
// construct the irrXML parser
/*CIrrXML_IOStreamReader st(stream.get());
m_reader.reset( createIrrXMLReader( ( IFileReadCallBack* ) &st ) );*/
// parse the XML file
mXmlParser = new XmlParser;
XmlNode *root = mXmlParser->parse(stream.get());
if (nullptr == root) {
if (!mXmlParser->parse(stream.get())) {
return;
}
// parse the XML file
XmlNode root = mXmlParser->getRootNode();
TempScope scope;
if (!ASSIMP_stricmp(root->name(), "world")) {
if (!ASSIMP_stricmp(root.name(), "world")) {
ReadWorld(scope);
}
/* while (ReadElement()) {
if (!ASSIMP_stricmp(m_reader->getNodeName(),"world")) {
ReadWorld(scope);
}
}*/
std::vector<aiMesh *> &meshes = scope.meshes_linear;
std::vector<aiMaterial *> &materials = scope.materials_linear;
if (!meshes.size() || !materials.size()) {
@ -249,8 +240,8 @@ void XGLImporter::InternReadFile(const std::string &pFile,
// ------------------------------------------------------------------------------------------------
void XGLImporter::ReadWorld(TempScope &scope) {
XmlNode *root = mXmlParser->getRootNode();
for (XmlNode &node : root->children()) {
XmlNode root = mXmlParser->getRootNode();
for (XmlNode &node : root.children()) {
const std::string &s = node.name();
// XXX right now we'd skip <lighting> if it comes after
// <object> or <mesh>
@ -261,7 +252,7 @@ void XGLImporter::ReadWorld(TempScope &scope) {
}
}
aiNode *const nd = ReadObject( *root, scope, true);
aiNode *const nd = ReadObject(root, scope, true);
if (!nd) {
ThrowException("failure reading <world>");
}

View File

@ -79,7 +79,6 @@ class TXmlParser {
public:
TXmlParser() :
mDoc(nullptr),
mRoot(nullptr),
mData() {
// empty
}
@ -90,7 +89,6 @@ public:
void clear() {
mData.resize(0);
mRoot = nullptr;
delete mDoc;
mDoc = nullptr;
}
@ -117,34 +115,33 @@ public:
return nullptr != findNode(name);
}
TNodeType *parse(IOStream *stream) {
mRoot = nullptr;
bool parse(IOStream *stream) {
if (nullptr == stream) {
return nullptr;
return false;
}
bool result = false;
mData.resize(stream->FileSize());
stream->Read(&mData[0], mData.size(), 1);
mDoc = new pugi::xml_document();
pugi::xml_parse_result result = mDoc->load_string(&mData[0], pugi::parse_full);
if (result.status == pugi::status_ok) {
pugi::xml_node root = mDoc->document_element();
mRoot = &root;
pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
if (parse_result.status == pugi::status_ok) {
result = true;
}
return mRoot;
return result;
}
pugi::xml_document *getDocument() const {
return mDoc;
}
const TNodeType *getRootNode() const {
return mRoot;
const TNodeType getRootNode() const {
return mDoc->root();
}
TNodeType *getRootNode() {
return mRoot;
TNodeType getRootNode() {
return mDoc->root();
}
static inline bool hasNode(XmlNode &node, const char *name) {
@ -222,7 +219,6 @@ public:
private:
pugi::xml_document *mDoc;
TNodeType *mRoot;
TNodeType mCurrent;
std::vector<char> mData;
};
@ -268,6 +264,14 @@ public:
return true;
}
size_t size() const {
return mNodes.size();
}
bool isEmpty() const {
return mNodes.empty();
}
void clear() {
if (mNodes.empty()) {
return;

View File

@ -56,14 +56,33 @@ protected:
};
TEST_F(utXmlParser, parse_xml_test) {
DefaultIOSystem ioSystem;
XmlParser parser;
std::string filename = ASSIMP_TEST_MODELS_DIR "/3D/box_a.3d";
IOStream *stream = ioSystem.Open(filename.c_str(), "rb");
std::string filename = ASSIMP_TEST_MODELS_DIR "/x3d/ComputerKeyboard.x3d";
IOStream *stream = mIoSystem.Open(filename.c_str(), "rb");
bool result = parser.parse(stream);
EXPECT_TRUE(result);
mIoSystem.Close(stream);
}
TEST_F(utXmlParser, parse_xml_and_traverse_test) {
XmlParser parser;
std::string filename = ASSIMP_TEST_MODELS_DIR "/x3d/ComputerKeyboard.x3d";
IOStream *stream = mIoSystem.Open(filename.c_str(), "rb");
bool result = parser.parse(stream);
EXPECT_TRUE(result);
XmlNode root = parser.getRootNode();
std::string name = root.name();
std::string name1 = root.name();
EXPECT_NE(nullptr, root);
mIoSystem.Close(stream);
std::string name2 = root.name();
XmlNodeIterator nodeIt(root);
EXPECT_TRUE(nodeIt.isEmpty());
nodeIt.collectChildrenPreOrder(root);
const size_t numNodes = nodeIt.size();
bool empty = nodeIt.isEmpty();
EXPECT_FALSE(empty);
EXPECT_NE(numNodes, 0U);
}

View File

@ -50,9 +50,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class utD3MFImporterExporter : public AbstractImportExportBase {
public:
virtual bool importerTest() {
bool importerTest() override {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3MF/box.3mf", aiProcess_ValidateDataStructure);
if (nullptr == scene) {
return false;
}
EXPECT_EQ(1u, scene->mNumMeshes);
aiMesh *mesh = scene->mMeshes[0];
EXPECT_NE(nullptr, mesh);
@ -64,7 +68,7 @@ public:
#ifndef ASSIMP_BUILD_NO_EXPORT
virtual bool exporterTest() {
bool exporterTest() override {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3MF/box.3mf", 0);