Add workaround for parsing glTF schemas

This commit is contained in:
Syoyo Fujita 2017-11-25 19:55:28 +09:00
parent e59de221ff
commit a415cf477c
3 changed files with 54 additions and 17 deletions

View File

@ -34,7 +34,8 @@ using nlohmann::json_schema_draft4::json_validator;
static void usage(const char *name) static void usage(const char *name)
{ {
std::cerr << "Usage: " << name << " <schema> < <document>\n"; std::cerr << "Usage: " << name << " <gltf file> <gltf schema dir>\n";
std::cerr << " schema dir : $glTF/specification/2.0/schema\n";
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -45,6 +46,7 @@ static void usage(const char *name)
assert(r.undefined_refs.size() == 0); assert(r.undefined_refs.size() == 0);
#endif #endif
#if 0
static void loader(const json_uri &uri, json &schema) static void loader(const json_uri &uri, json &schema)
{ {
std::fstream lf("." + uri.path()); std::fstream lf("." + uri.path());
@ -57,16 +59,16 @@ static void loader(const json_uri &uri, json &schema)
throw e; throw e;
} }
} }
#endif
int main(int argc, char *argv[]) bool validate(const std::string &schema_dir, const std::string &filename)
{ {
if (argc != 2) std::string gltf_schema = schema_dir + "/glTF.schema.json";
usage(argv[0]);
std::fstream f(argv[1]); std::fstream f(gltf_schema);
if (!f.good()) { if (!f.good()) {
std::cerr << "could not open " << argv[1] << " for reading\n"; std::cerr << "could not open " << gltf_schema << " for reading\n";
usage(argv[0]); return false;
} }
// 1) Read the schema for the document you want to validate // 1) Read the schema for the document you want to validate
@ -75,11 +77,24 @@ int main(int argc, char *argv[])
f >> schema; f >> schema;
} catch (std::exception &e) { } catch (std::exception &e) {
std::cerr << e.what() << " at " << f.tellp() << " - while parsing the schema\n"; std::cerr << e.what() << " at " << f.tellp() << " - while parsing the schema\n";
return EXIT_FAILURE; return false;
} }
// 2) create the validator and // 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 { try {
// insert this schema as the root to the validator // 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 // 3) do the actual validation of the document
json document; json document;
std::fstream d(filename);
if (!d.good()) {
std::cerr << "could not open " << filename << " for reading\n";
return false;
}
try { try {
std::cin >> document; d >> document;
validator.validate(document); validator.validate(document);
} catch (std::exception &e) { } catch (std::exception &e) {
std::cerr << "schema validation failed\n"; std::cerr << "schema validation failed\n";
std::cerr << e.what() << " at offset: " << std::cin.tellg() << "\n"; std::cerr << e.what() << " at offset: " << d.tellg() << "\n";
return EXIT_FAILURE; return false;
} }
std::cerr << "document is valid\n"; 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;
} }

View File

@ -86,8 +86,11 @@ void json_uri::from_string(const std::string &uri)
auto path = url.substr(pos); auto path = url.substr(pos);
if (path[0] == '/') // if it starts with a / it is root-path if (path[0] == '/') // if it starts with a / it is root-path
path_ = path; path_ = path;
else // otherwise it is a subfolder else { // otherwise it is a subfolder
path_.append(path); // HACK(syoyo): Force append '/' for glTF json schemas
path_ = path;
//path_.append(path);
}
pointer_ = json_pointer(""); pointer_ = json_pointer("");
} }

View File

@ -278,7 +278,9 @@ void json_validator::insert_schema(const json &input, const json_uri &id)
// check whether all schema-references are new // check whether all schema-references are new
for (auto &sref : r.schema_refs) { for (auto &sref : r.schema_refs) {
if (schema_refs_.find(sref.first) != schema_refs_.end()) 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 // no undefined references and no duplicated schema - store the schema
schema_store_.push_back(schema); schema_store_.push_back(schema);