From a415cf477c441b99ea3ba42b12e27c06cd4b9de7 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 25 Nov 2017 19:55:28 +0900 Subject: [PATCH] Add workaround for parsing glTF schemas --- examples/validator/app/tinygltf-validate.cc | 60 ++++++++++++++++----- examples/validator/src/json-uri.cpp | 7 ++- examples/validator/src/json-validator.cpp | 4 +- 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/examples/validator/app/tinygltf-validate.cc b/examples/validator/app/tinygltf-validate.cc index 055f19b..def5577 100644 --- a/examples/validator/app/tinygltf-validate.cc +++ b/examples/validator/app/tinygltf-validate.cc @@ -34,7 +34,8 @@ using nlohmann::json_schema_draft4::json_validator; static void usage(const char *name) { - std::cerr << "Usage: " << name << " < \n"; + std::cerr << "Usage: " << name << " \n"; + std::cerr << " schema dir : $glTF/specification/2.0/schema\n"; exit(EXIT_FAILURE); } @@ -45,6 +46,7 @@ static void usage(const char *name) assert(r.undefined_refs.size() == 0); #endif +#if 0 static void loader(const json_uri &uri, json &schema) { std::fstream lf("." + uri.path()); @@ -57,17 +59,17 @@ static void loader(const json_uri &uri, json &schema) throw e; } } +#endif -int main(int argc, char *argv[]) +bool validate(const std::string &schema_dir, const std::string &filename) { - if (argc != 2) - usage(argv[0]); + std::string gltf_schema = schema_dir + "/glTF.schema.json"; - std::fstream f(argv[1]); + std::fstream f(gltf_schema); if (!f.good()) { - std::cerr << "could not open " << argv[1] << " for reading\n"; - usage(argv[0]); - } + std::cerr << "could not open " << gltf_schema << " for reading\n"; + return false; + } // 1) Read the schema for the document you want to validate json schema; @@ -75,11 +77,24 @@ int main(int argc, char *argv[]) f >> schema; } catch (std::exception &e) { std::cerr << e.what() << " at " << f.tellp() << " - while parsing the schema\n"; - return EXIT_FAILURE; + return false; } // 2) create the validator and - json_validator validator(loader, [](const std::string &, const std::string &) {}); + json_validator validator([&schema_dir](const json_uri &uri, json &schema) { + std::cout << "uri.url : " << uri.url() << std::endl; + std::cout << "uri.path : " << uri.path() << std::endl; + + std::fstream lf(schema_dir + "/" + uri.path()); + if (!lf.good()) + throw std::invalid_argument("could not open " + uri.url() + " tried with " + uri.path()); + + try { + lf >> schema; + } catch (std::exception &e) { + throw e; + } + }, [](const std::string &, const std::string &) {}); try { // insert this schema as the root to the validator @@ -93,16 +108,33 @@ int main(int argc, char *argv[]) // 3) do the actual validation of the document json document; + std::fstream d(filename); + if (!d.good()) { + std::cerr << "could not open " << filename << " for reading\n"; + return false; + } + try { - std::cin >> document; + d >> document; validator.validate(document); } catch (std::exception &e) { std::cerr << "schema validation failed\n"; - std::cerr << e.what() << " at offset: " << std::cin.tellg() << "\n"; - return EXIT_FAILURE; + std::cerr << e.what() << " at offset: " << d.tellg() << "\n"; + return false; } std::cerr << "document is valid\n"; - return EXIT_SUCCESS; + return true; + +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) + usage(argv[0]); + + bool ret = validate(argv[1], argv[2]); + + return ret ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/examples/validator/src/json-uri.cpp b/examples/validator/src/json-uri.cpp index e480fce..2dc6113 100644 --- a/examples/validator/src/json-uri.cpp +++ b/examples/validator/src/json-uri.cpp @@ -86,8 +86,11 @@ void json_uri::from_string(const std::string &uri) auto path = url.substr(pos); if (path[0] == '/') // if it starts with a / it is root-path path_ = path; - else // otherwise it is a subfolder - path_.append(path); + else { // otherwise it is a subfolder + // HACK(syoyo): Force append '/' for glTF json schemas + path_ = path; + //path_.append(path); + } pointer_ = json_pointer(""); } diff --git a/examples/validator/src/json-validator.cpp b/examples/validator/src/json-validator.cpp index cb26ca2..3358805 100644 --- a/examples/validator/src/json-validator.cpp +++ b/examples/validator/src/json-validator.cpp @@ -278,7 +278,9 @@ void json_validator::insert_schema(const json &input, const json_uri &id) // check whether all schema-references are new for (auto &sref : r.schema_refs) { if (schema_refs_.find(sref.first) != schema_refs_.end()) - throw std::invalid_argument("schema " + sref.first.to_string() + " already present in validator."); + // HACK(syoyo): Skip duplicated schema. + break; + //throw std::invalid_argument("schema " + sref.first.to_string() + " already present in validator."); } // no undefined references and no duplicated schema - store the schema schema_store_.push_back(schema);