From 19894c78066fcf30c13a125c983ed9694ba68da2 Mon Sep 17 00:00:00 2001 From: Luke San Antonio Date: Tue, 14 Jun 2016 21:19:51 -0400 Subject: [PATCH] Add function to parse string dictionaries A string dictionary in the glTF spec is called a "dictionary object of strings." For example: mesh.primitives.attributes, technique.attributes, and technique.uniforms. --- tiny_gltf_loader.h | 71 +++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/tiny_gltf_loader.h b/tiny_gltf_loader.h index 12f89d4..bb5a294 100644 --- a/tiny_gltf_loader.h +++ b/tiny_gltf_loader.h @@ -860,6 +860,54 @@ static bool ParseStringArrayProperty(std::vector *ret, return true; } +static bool ParseStringMapProperty(std::map *ret, + std::string *err, + const picojson::object &o, + const std::string &property, + bool required) { + picojson::object::const_iterator it = o.find(property); + if (it == o.end()) { + if (required) { + if (err) { + (*err) += "'" + property + "' property is missing.\n"; + } + } + return false; + } + + // Make sure we are dealing with an object / dictionary. + if (!it->second.is()) { + if (required) { + if (err) { + (*err) += "'" + property + "' property is not an object.\n"; + } + } + return false; + } + + ret->clear(); + const picojson::object &dict = it->second.get(); + + picojson::object::const_iterator dictIt(dict.begin()); + picojson::object::const_iterator dictItEnd(dict.end()); + + for(; dictIt != dictItEnd; ++dictIt) { + // Check that the value is a string. + if(!dictIt->second.is()) { + if(required) { + if(err) { + (*err) += "'" + property + "' value is not a string.\n"; + } + } + return false; + } + + // Insert into the list. + (*ret)[dictIt->first] = dictIt->second.get(); + } + return true; +} + static bool ParseKHRBinaryExtension(const picojson::object &o, std::string *err, std::string *buffer_view, std::string *mime_type, int *image_width, @@ -1308,26 +1356,9 @@ static bool ParsePrimitive(Primitive *primitive, std::string *err, primitive->indices = ""; ParseStringProperty(&primitive->indices, err, o, "indices", false); - primitive->attributes.clear(); - picojson::object::const_iterator attribsObject = o.find("attributes"); - if ((attribsObject != o.end()) && - (attribsObject->second).is()) { - const picojson::object &attribs = - (attribsObject->second).get(); - picojson::object::const_iterator it(attribs.begin()); - picojson::object::const_iterator itEnd(attribs.end()); - for (; it != itEnd; it++) { - const std::string &name = it->first; - if (!(it->second).is()) { - if (err) { - (*err) += "attribute expects string value.\n"; - } - return false; - } - const std::string &value = (it->second).get(); - - primitive->attributes[name] = value; - } + if(!ParseStringMapProperty(&primitive->attributes, err, o, + "attributes", true)) { + return false; } return true;