mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-11 17:09:02 +08:00
Update rapidjson-amalgamation to include error/en.h and cursorstreamwrapper.h.
Now schema validation is getting to work.
This commit is contained in:
parent
f3ee08c595
commit
ddf0a0e83c
@ -70,6 +70,7 @@
|
||||
## For developer
|
||||
|
||||
Generate single rapidjson file using this node.js script: https://github.com/Tencent/rapidjson/issues/863
|
||||
Add `cursorstreamwrapper.h` and `error/en.h` inclusion in `rapidjson-all.h` before running merge script.
|
||||
|
||||
## TODOs
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// TODO(syoyo): Print extensions and extras for each glTF object.
|
||||
//
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#define TINYGLTF_ENABLE_SCHEMA_VALIDATOR
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "tiny_gltf.h"
|
||||
@ -640,8 +641,13 @@ int main(int argc, char **argv) {
|
||||
} else {
|
||||
std::cout << "Reading ASCII glTF" << std::endl;
|
||||
// assume ascii glTF.
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
ret =
|
||||
gltf_ctx.LoadASCIIFromFileWithValidation(&model, &err, &warn, input_filename.c_str());
|
||||
#else
|
||||
ret =
|
||||
gltf_ctx.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!warn.empty()) {
|
||||
|
@ -1581,7 +1581,7 @@ RAPIDJSON_NAMESPACE_END
|
||||
// End file:allocators.h
|
||||
|
||||
|
||||
// Begin file: document.h
|
||||
// Begin file: error/en.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
@ -1596,13 +1596,11 @@ RAPIDJSON_NAMESPACE_END
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_DOCUMENT_H_
|
||||
#define RAPIDJSON_DOCUMENT_H_
|
||||
|
||||
/*! \file document.h */
|
||||
#ifndef RAPIDJSON_ERROR_EN_H_
|
||||
#define RAPIDJSON_ERROR_EN_H_
|
||||
|
||||
|
||||
// Begin file: reader.h
|
||||
// Begin file: error.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
@ -1617,15 +1615,237 @@ RAPIDJSON_NAMESPACE_END
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_READER_H_
|
||||
#define RAPIDJSON_READER_H_
|
||||
|
||||
/*! \file reader.h */
|
||||
#ifndef RAPIDJSON_ERROR_ERROR_H_
|
||||
#define RAPIDJSON_ERROR_ERROR_H_
|
||||
|
||||
|
||||
// Begin file: allocators.h
|
||||
// Begin file: ../rapidjson.h
|
||||
// already included
|
||||
// End file:allocators.h
|
||||
// End file:../rapidjson.h
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
/*! \file error.h */
|
||||
|
||||
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_CHARTYPE
|
||||
|
||||
//! Character type of error messages.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
The default character type is \c char.
|
||||
On Windows, user can define this macro as \c TCHAR for supporting both
|
||||
unicode/non-unicode settings.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ERROR_CHARTYPE
|
||||
#define RAPIDJSON_ERROR_CHARTYPE char
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_STRING
|
||||
|
||||
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
By default this conversion macro does nothing.
|
||||
On Windows, user can define this macro as \c _T(x) for supporting both
|
||||
unicode/non-unicode settings.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ERROR_STRING
|
||||
#define RAPIDJSON_ERROR_STRING(x) x
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ParseErrorCode
|
||||
|
||||
//! Error code of parsing.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericReader::Parse, GenericReader::GetParseErrorCode
|
||||
*/
|
||||
enum ParseErrorCode {
|
||||
kParseErrorNone = 0, //!< No error.
|
||||
|
||||
kParseErrorDocumentEmpty, //!< The document is empty.
|
||||
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
|
||||
|
||||
kParseErrorValueInvalid, //!< Invalid value.
|
||||
|
||||
kParseErrorObjectMissName, //!< Missing a name for object member.
|
||||
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
|
||||
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
|
||||
|
||||
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
|
||||
|
||||
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
|
||||
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
|
||||
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
|
||||
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
|
||||
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
|
||||
|
||||
kParseErrorNumberTooBig, //!< Number too big to be stored in double.
|
||||
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
|
||||
kParseErrorNumberMissExponent, //!< Miss exponent in number.
|
||||
|
||||
kParseErrorTermination, //!< Parsing was terminated.
|
||||
kParseErrorUnspecificSyntaxError //!< Unspecific syntax error.
|
||||
};
|
||||
|
||||
//! Result of parsing (wraps ParseErrorCode)
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\code
|
||||
Document doc;
|
||||
ParseResult ok = doc.Parse("[42]");
|
||||
if (!ok) {
|
||||
fprintf(stderr, "JSON parse error: %s (%u)",
|
||||
GetParseError_En(ok.Code()), ok.Offset());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
\endcode
|
||||
\see GenericReader::Parse, GenericDocument::Parse
|
||||
*/
|
||||
struct ParseResult {
|
||||
//!! Unspecified boolean type
|
||||
typedef bool (ParseResult::*BooleanType)() const;
|
||||
public:
|
||||
//! Default constructor, no error.
|
||||
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
||||
//! Constructor to set an error.
|
||||
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
|
||||
|
||||
//! Get the error code.
|
||||
ParseErrorCode Code() const { return code_; }
|
||||
//! Get the error offset, if \ref IsError(), 0 otherwise.
|
||||
size_t Offset() const { return offset_; }
|
||||
|
||||
//! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
|
||||
operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
|
||||
//! Whether the result is an error.
|
||||
bool IsError() const { return code_ != kParseErrorNone; }
|
||||
|
||||
bool operator==(const ParseResult& that) const { return code_ == that.code_; }
|
||||
bool operator==(ParseErrorCode code) const { return code_ == code; }
|
||||
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
|
||||
|
||||
bool operator!=(const ParseResult& that) const { return !(*this == that); }
|
||||
bool operator!=(ParseErrorCode code) const { return !(*this == code); }
|
||||
friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; }
|
||||
|
||||
//! Reset error code.
|
||||
void Clear() { Set(kParseErrorNone); }
|
||||
//! Update error code and offset.
|
||||
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
|
||||
|
||||
private:
|
||||
ParseErrorCode code_;
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
//! Function pointer type of GetParseError().
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
|
||||
This is the prototype for \c GetParseError_X(), where \c X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
\code
|
||||
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
|
||||
\endcode
|
||||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ERROR_ERROR_H_
|
||||
|
||||
// End file:error.h
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
RAPIDJSON_DIAG_OFF(covered-switch-default)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! Maps error code of parsing into error message.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\param parseErrorCode Error code obtained in parsing.
|
||||
\return the error message.
|
||||
\note User can make a copy of this function for localization.
|
||||
Using switch-case is safer for future modification of error codes.
|
||||
*/
|
||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
|
||||
switch (parseErrorCode) {
|
||||
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||
|
||||
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
||||
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
||||
|
||||
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
||||
|
||||
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
||||
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
||||
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
||||
|
||||
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
||||
|
||||
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
||||
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
|
||||
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
|
||||
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
|
||||
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
|
||||
|
||||
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
|
||||
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
|
||||
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
|
||||
|
||||
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
||||
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ERROR_EN_H_
|
||||
|
||||
// End file:error/en.h
|
||||
|
||||
|
||||
// Begin file: cursorstreamwrapper.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://opensource.org/licenses/MIT
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed
|
||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_
|
||||
#define RAPIDJSON_CURSORSTREAMWRAPPER_H_
|
||||
|
||||
|
||||
// Begin file: stream.h
|
||||
@ -2584,6 +2804,121 @@ RAPIDJSON_NAMESPACE_END
|
||||
// End file:stream.h
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
//! Cursor stream wrapper for counting line and column number if error exists.
|
||||
/*!
|
||||
\tparam InputStream Any stream that implements Stream Concept
|
||||
*/
|
||||
template <typename InputStream, typename Encoding = UTF8<> >
|
||||
class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
|
||||
public:
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
CursorStreamWrapper(InputStream& is):
|
||||
GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
|
||||
|
||||
// counting line and column number
|
||||
Ch Take() {
|
||||
Ch ch = this->is_.Take();
|
||||
if(ch == '\n') {
|
||||
line_ ++;
|
||||
col_ = 0;
|
||||
} else {
|
||||
col_ ++;
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
//! Get the error line number, if error exists.
|
||||
size_t GetLine() const { return line_; }
|
||||
//! Get the error column number, if error exists.
|
||||
size_t GetColumn() const { return col_; }
|
||||
|
||||
private:
|
||||
size_t line_; //!< Current Line
|
||||
size_t col_; //!< Current Column
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_
|
||||
|
||||
// End file:cursorstreamwrapper.h
|
||||
|
||||
|
||||
// Begin file: document.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://opensource.org/licenses/MIT
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed
|
||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_DOCUMENT_H_
|
||||
#define RAPIDJSON_DOCUMENT_H_
|
||||
|
||||
/*! \file document.h */
|
||||
|
||||
|
||||
// Begin file: reader.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://opensource.org/licenses/MIT
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed
|
||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_READER_H_
|
||||
#define RAPIDJSON_READER_H_
|
||||
|
||||
/*! \file reader.h */
|
||||
|
||||
|
||||
// Begin file: allocators.h
|
||||
// already included
|
||||
// End file:allocators.h
|
||||
|
||||
|
||||
// Begin file: stream.h
|
||||
// already included
|
||||
// End file:stream.h
|
||||
|
||||
|
||||
// Begin file: encodedstream.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
@ -4582,172 +4917,7 @@ RAPIDJSON_DIAG_OFF(effc++)
|
||||
|
||||
|
||||
// Begin file: error/error.h
|
||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
// in compliance with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://opensource.org/licenses/MIT
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software distributed
|
||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_ERROR_ERROR_H_
|
||||
#define RAPIDJSON_ERROR_ERROR_H_
|
||||
|
||||
|
||||
// Begin file: ../rapidjson.h
|
||||
// already included
|
||||
// End file:../rapidjson.h
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
/*! \file error.h */
|
||||
|
||||
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_CHARTYPE
|
||||
|
||||
//! Character type of error messages.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
The default character type is \c char.
|
||||
On Windows, user can define this macro as \c TCHAR for supporting both
|
||||
unicode/non-unicode settings.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ERROR_CHARTYPE
|
||||
#define RAPIDJSON_ERROR_CHARTYPE char
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_STRING
|
||||
|
||||
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
By default this conversion macro does nothing.
|
||||
On Windows, user can define this macro as \c _T(x) for supporting both
|
||||
unicode/non-unicode settings.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ERROR_STRING
|
||||
#define RAPIDJSON_ERROR_STRING(x) x
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ParseErrorCode
|
||||
|
||||
//! Error code of parsing.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericReader::Parse, GenericReader::GetParseErrorCode
|
||||
*/
|
||||
enum ParseErrorCode {
|
||||
kParseErrorNone = 0, //!< No error.
|
||||
|
||||
kParseErrorDocumentEmpty, //!< The document is empty.
|
||||
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
|
||||
|
||||
kParseErrorValueInvalid, //!< Invalid value.
|
||||
|
||||
kParseErrorObjectMissName, //!< Missing a name for object member.
|
||||
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
|
||||
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
|
||||
|
||||
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
|
||||
|
||||
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
|
||||
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
|
||||
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
|
||||
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
|
||||
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
|
||||
|
||||
kParseErrorNumberTooBig, //!< Number too big to be stored in double.
|
||||
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
|
||||
kParseErrorNumberMissExponent, //!< Miss exponent in number.
|
||||
|
||||
kParseErrorTermination, //!< Parsing was terminated.
|
||||
kParseErrorUnspecificSyntaxError //!< Unspecific syntax error.
|
||||
};
|
||||
|
||||
//! Result of parsing (wraps ParseErrorCode)
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\code
|
||||
Document doc;
|
||||
ParseResult ok = doc.Parse("[42]");
|
||||
if (!ok) {
|
||||
fprintf(stderr, "JSON parse error: %s (%u)",
|
||||
GetParseError_En(ok.Code()), ok.Offset());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
\endcode
|
||||
\see GenericReader::Parse, GenericDocument::Parse
|
||||
*/
|
||||
struct ParseResult {
|
||||
//!! Unspecified boolean type
|
||||
typedef bool (ParseResult::*BooleanType)() const;
|
||||
public:
|
||||
//! Default constructor, no error.
|
||||
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
||||
//! Constructor to set an error.
|
||||
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
|
||||
|
||||
//! Get the error code.
|
||||
ParseErrorCode Code() const { return code_; }
|
||||
//! Get the error offset, if \ref IsError(), 0 otherwise.
|
||||
size_t Offset() const { return offset_; }
|
||||
|
||||
//! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
|
||||
operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
|
||||
//! Whether the result is an error.
|
||||
bool IsError() const { return code_ != kParseErrorNone; }
|
||||
|
||||
bool operator==(const ParseResult& that) const { return code_ == that.code_; }
|
||||
bool operator==(ParseErrorCode code) const { return code_ == code; }
|
||||
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
|
||||
|
||||
bool operator!=(const ParseResult& that) const { return !(*this == that); }
|
||||
bool operator!=(ParseErrorCode code) const { return !(*this == code); }
|
||||
friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; }
|
||||
|
||||
//! Reset error code.
|
||||
void Clear() { Set(kParseErrorNone); }
|
||||
//! Update error code and offset.
|
||||
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
|
||||
|
||||
private:
|
||||
ParseErrorCode code_;
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
//! Function pointer type of GetParseError().
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
|
||||
This is the prototype for \c GetParseError_X(), where \c X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
\code
|
||||
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
|
||||
\endcode
|
||||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ERROR_ERROR_H_
|
||||
|
||||
// End file:error/error.h
|
||||
|
||||
|
||||
@ -16733,3 +16903,4 @@ RAPIDJSON_DIAG_POP
|
||||
// Begin file: writer.h
|
||||
// already included
|
||||
// End file:writer.h
|
||||
|
||||
|
206
tiny_gltf.h
206
tiny_gltf.h
@ -921,13 +921,13 @@ class TinyGLTF {
|
||||
#pragma clang diagnostic ignored "-Wc++98-compat"
|
||||
#endif
|
||||
|
||||
TinyGLTF() : bin_data_(nullptr), bin_size_(0), is_binary_(false) {}
|
||||
TinyGLTF();
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
~TinyGLTF() {}
|
||||
~TinyGLTF();
|
||||
|
||||
///
|
||||
/// Loads glTF ASCII asset from a file.
|
||||
@ -1048,8 +1048,12 @@ class TinyGLTF {
|
||||
nullptr;
|
||||
#endif
|
||||
void *write_image_user_data_ = reinterpret_cast<void *>(&fs);
|
||||
|
||||
class PImpl;
|
||||
PImpl *pimpl_;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop // -Wpadded
|
||||
#endif
|
||||
@ -1200,7 +1204,7 @@ namespace tinygltf {
|
||||
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
// Include glTF Schema as embedded C string
|
||||
#include "glTF.schema.resolved.inc"
|
||||
#include "gltf.schema.resolved.inc"
|
||||
#endif
|
||||
|
||||
// Equals function for Value, for recursivity
|
||||
@ -1617,6 +1621,55 @@ std::string base64_decode(std::string const &encoded_string) {
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
class TinyGLTF::PImpl
|
||||
{
|
||||
public:
|
||||
|
||||
PImpl() {
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
validator_ = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
~PImpl()
|
||||
{
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
if (schema_doc_) {
|
||||
delete schema_doc_;
|
||||
}
|
||||
|
||||
if (schema_) {
|
||||
delete schema_;
|
||||
}
|
||||
|
||||
if (validator_) {
|
||||
delete validator_;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
|
||||
std::string schema_json_string_;
|
||||
rapidjson::Document *schema_doc_;
|
||||
rapidjson::SchemaDocument *schema_;
|
||||
rapidjson::SchemaValidator *validator_;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
TinyGLTF::TinyGLTF() : bin_data_(nullptr), bin_size_(0), is_binary_(false) {
|
||||
pimpl_ = new TinyGLTF::PImpl();
|
||||
}
|
||||
|
||||
TinyGLTF::~TinyGLTF()
|
||||
{
|
||||
if (pimpl_) {
|
||||
delete pimpl_;
|
||||
}
|
||||
}
|
||||
|
||||
static bool LoadExternalFile(std::vector<unsigned char> *out, std::string *err,
|
||||
std::string *warn, const std::string &filename,
|
||||
const std::string &basedir, bool required,
|
||||
@ -3722,13 +3775,25 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
||||
return false;
|
||||
}
|
||||
|
||||
// To enable error report with lines and columns,
|
||||
// We'll use CursorStreamWrapper.
|
||||
// https://github.com/Tencent/rapidjson/pull/1070
|
||||
// It looks StringStream does not have a constrcutor with (str, len),
|
||||
// so create a temporary string and ensure it ends with NULL character.
|
||||
// although this is a bit redundant...
|
||||
std::string in_str(str, length);
|
||||
|
||||
rapidjson::StringStream sis(in_str.c_str());
|
||||
|
||||
rapidjson::CursorStreamWrapper<rapidjson::StringStream> csw(sis);
|
||||
|
||||
rapidjson::Document v;
|
||||
|
||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
|
||||
defined(_CPPUNWIND)) && \
|
||||
!defined(TINYGLTF_NOEXCEPTION)
|
||||
try {
|
||||
v.Parse(str);
|
||||
v.ParseStream(csw);
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
if (err) {
|
||||
@ -3738,14 +3803,49 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
||||
}
|
||||
|
||||
if (v.HasParseError()) {
|
||||
// TODO(syoyo): Report error
|
||||
if (err) {
|
||||
std::stringstream ss;
|
||||
ss << "JSON parse error: (byte offset " << v.GetErrorOffset()
|
||||
<< ", line " << csw.GetLine()
|
||||
<< ", column " << csw.GetColumn()
|
||||
<< "): " << rapidjson::GetParseError_En(v.GetParseError());
|
||||
(*err) = ss.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
{
|
||||
v.Parse(str);
|
||||
v.ParseStream(csw);
|
||||
if (v.HasParseError()) {
|
||||
// TODO(syoyo): Report error
|
||||
if (err) {
|
||||
std::stringstream ss;
|
||||
ss << "JSON parse error: (byte offset " << v.GetErrorOffset()
|
||||
<< ", line " << csw.GetLine()
|
||||
<< ", column " << csw.GetColumn()
|
||||
<< "): " << rapidjson::GetParseError_En(v.GetParseError());
|
||||
(*err) = ss.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
if (pimpl_->validator_) {
|
||||
if (!v.Accept(*(pimpl_->validator_))) {
|
||||
// Input JSON is invalid according to the schema
|
||||
// Output diagnostic information
|
||||
rapidjson::StringBuffer sb;
|
||||
pimpl_->validator_->GetInvalidSchemaPointer().StringifyUriFragment(sb);
|
||||
|
||||
std::stringstream ss;
|
||||
printf("Invalid schema: %s\n", sb.GetString());
|
||||
ss << "glTF schema validation error. Invalid keyword: " << pimpl_->validator_->GetInvalidSchemaKeyword();
|
||||
sb.Clear();
|
||||
|
||||
if (err) {
|
||||
(*err) = ss.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4334,6 +4434,53 @@ bool TinyGLTF::LoadASCIIFromString(Model *model, std::string *err,
|
||||
check_sections);
|
||||
}
|
||||
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
bool TinyGLTF::LoadASCIIFromStringWithValidation(Model *model, std::string *err,
|
||||
std::string *warn, const char *str,
|
||||
unsigned int length,
|
||||
const std::string &base_dir,
|
||||
unsigned int check_sections) {
|
||||
is_binary_ = false;
|
||||
bin_data_ = nullptr;
|
||||
bin_size_ = 0;
|
||||
|
||||
if (!pimpl_->validator_) {
|
||||
|
||||
pimpl_->schema_json_string_ = std::string();
|
||||
|
||||
// Construct glTF JSON schema string.
|
||||
const size_t num_str = sizeof(kglTFSchemaStrings)/sizeof(kglTFSchemaStrings[0]);
|
||||
for (size_t i = 0; i < num_str; i++) {
|
||||
pimpl_->schema_json_string_ += std::string(kglTFSchemaStrings[i]);
|
||||
}
|
||||
|
||||
// Validate input glTF string
|
||||
if (pimpl_->schema_doc_) {
|
||||
delete pimpl_->schema_doc_;
|
||||
}
|
||||
pimpl_->schema_doc_ = new rapidjson::Document();
|
||||
pimpl_->schema_doc_->Parse(pimpl_->schema_json_string_.c_str(), pimpl_->schema_json_string_.size());
|
||||
|
||||
if (pimpl_->schema_doc_->HasParseError()) {
|
||||
if(err) {
|
||||
(*err) += "Internal error. Failed to parse glTF schema JSON.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pimpl_->schema_) {
|
||||
delete pimpl_->schema_;
|
||||
}
|
||||
pimpl_->schema_ = new rapidjson::SchemaDocument(*pimpl_->schema_doc_);
|
||||
|
||||
pimpl_->validator_ = new rapidjson::SchemaValidator(*pimpl_->schema_);
|
||||
}
|
||||
|
||||
return LoadFromString(model, err, warn, str, length, base_dir,
|
||||
check_sections);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TinyGLTF::LoadASCIIFromFile(Model *model, std::string *err,
|
||||
std::string *warn, const std::string &filename,
|
||||
unsigned int check_sections) {
|
||||
@ -4377,6 +4524,51 @@ bool TinyGLTF::LoadASCIIFromFile(Model *model, std::string *err,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(TINYGLTF_ENABLE_SCHEMA_VALIDATOR)
|
||||
bool TinyGLTF::LoadASCIIFromFileWithValidation(Model *model, std::string *err,
|
||||
std::string *warn, const std::string &filename,
|
||||
unsigned int check_sections) {
|
||||
std::stringstream ss;
|
||||
|
||||
if (fs.ReadWholeFile == nullptr) {
|
||||
// Programmer error, assert() ?
|
||||
ss << "Failed to read file: " << filename
|
||||
<< ": one or more FS callback not set" << std::endl;
|
||||
if (err) {
|
||||
(*err) = ss.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> data;
|
||||
std::string fileerr;
|
||||
bool fileread = fs.ReadWholeFile(&data, &fileerr, filename, fs.user_data);
|
||||
if (!fileread) {
|
||||
ss << "Failed to read file: " << filename << ": " << fileerr << std::endl;
|
||||
if (err) {
|
||||
(*err) = ss.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = data.size();
|
||||
if (sz == 0) {
|
||||
if (err) {
|
||||
(*err) = "Empty file.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string basedir = GetBaseDir(filename);
|
||||
|
||||
bool ret = LoadASCIIFromStringWithValidation(
|
||||
model, err, warn, reinterpret_cast<const char *>(&data.at(0)),
|
||||
static_cast<unsigned int>(data.size()), basedir, check_sections);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TinyGLTF::LoadBinaryFromMemory(Model *model, std::string *err,
|
||||
std::string *warn,
|
||||
const unsigned char *bytes,
|
||||
|
Loading…
x
Reference in New Issue
Block a user