Skip to content

Commit 6f3cccd

Browse files
author
Steve Hanson
committed
remove debug std::cout, handle empty error object in example
1 parent 05e7b33 commit 6f3cccd

File tree

2 files changed

+52
-69
lines changed

2 files changed

+52
-69
lines changed

example/schemavalidator/schemavalidator.cpp

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "rapidjson/stringbuffer.h"
99
#include "rapidjson/prettywriter.h"
1010
#include <string>
11-
#include <regex>
1211
#include <iostream>
1312

1413
using namespace rapidjson;
@@ -21,87 +20,90 @@ static void CreateErrorMessages(const ValueType& errors, size_t depth, const cha
2120
// Convert GenericValue to std::string
2221
static std::string GetString(const ValueType& val) {
2322
std::string str("");
24-
if (val.IsString()) {
23+
if (val.IsString())
2524
str = val.GetString();
26-
} else if (val.IsDouble()) {
25+
else if (val.IsDouble())
2726
str = std::to_string(val.GetDouble());
28-
} else if (val.IsUint()) {
27+
else if (val.IsUint())
2928
str = std::to_string(val.GetUint());
30-
} else if (val.IsInt()) {
29+
else if (val.IsInt())
3130
str = std::to_string(val.GetInt());
32-
} else if (val.IsUint64()) {
31+
else if (val.IsUint64())
3332
str = std::to_string(val.GetUint64());
34-
} else if (val.IsInt64()) {
33+
else if (val.IsInt64())
3534
str = std::to_string(val.GetInt64());
36-
} else if (val.IsBool()) {
37-
str = std::to_string(val.GetBool());
38-
} else if (val.IsFloat()) {
35+
else if (val.IsBool() && val.GetBool())
36+
str = "true";
37+
else if (val.IsBool())
38+
str = "false";
39+
else if (val.IsFloat())
3940
str = std::to_string(val.GetFloat());
40-
}
4141
return str;
4242
}
4343

4444
// Create the error message for a named error
45-
// Expects the error object to contain at least member properties:
46-
// {
47-
// "errorCode": <code>,
48-
// "instanceRef": "<pointer>",
49-
// "schemaRef": "<pointer>"
50-
// }
45+
// The error object can either be empty or contain at least member properties:
46+
// {"errorCode": <code>, "instanceRef": "<pointer>", "schemaRef": "<pointer>" }
5147
// Additional properties may be present for use as inserts.
5248
// An "errors" property may be present if there are child errors.
5349
static void HandleError(const char* errorName, const ValueType& error, size_t depth, const char* context) {
50+
if (!error.ObjectEmpty()) {
5451
// Get error code and look up error message text (English)
5552
int code = error["errorCode"].GetInt();
5653
std::string message(GetValidateError_En(static_cast<ValidateErrorCode>(code)));
5754
// For each member property in the error, see if its name exists as an insert in the error message and if so replace with the stringified property value
5855
// So for example - "Number '%actual' is not a multiple of the 'multipleOf' value '%expected'." - we would expect "actual" and "expected" members.
59-
for (ValueType::ConstMemberIterator insertsItr = error.MemberBegin(); insertsItr != error.MemberEnd(); ++insertsItr) {
60-
std::string insertRegex("\\%");
61-
insertRegex += insertsItr->name.GetString(); // eg "\%actual"
62-
if (std::regex_search(message, std::regex(insertRegex))) {
63-
std::string insertString("");
64-
const ValueType &insert = insertsItr->value;
65-
if (insert.IsArray()) {
66-
// Member is an array so create comma-separated list of items for the insert string
67-
for (ValueType::ConstValueIterator itemsItr = insert.Begin(); itemsItr != insert.End(); ++itemsItr) {
68-
if (itemsItr != insert.Begin()) insertString += ",";
69-
insertString += GetString(*itemsItr);
70-
}
71-
} else {
72-
insertString += GetString(insert);
73-
}
74-
message = std::regex_replace(message, std::regex(insertRegex), insertString);
56+
for (ValueType::ConstMemberIterator insertsItr = error.MemberBegin();
57+
insertsItr != error.MemberEnd(); ++insertsItr) {
58+
std::string insertName("%");
59+
insertName += insertsItr->name.GetString(); // eg "%actual"
60+
size_t insertPos = message.find(insertName);
61+
if (insertPos != std::string::npos) {
62+
std::string insertString("");
63+
const ValueType &insert = insertsItr->value;
64+
if (insert.IsArray()) {
65+
// Member is an array so create comma-separated list of items for the insert string
66+
for (ValueType::ConstValueIterator itemsItr = insert.Begin(); itemsItr != insert.End(); ++itemsItr) {
67+
if (itemsItr != insert.Begin()) insertString += ",";
68+
insertString += GetString(*itemsItr);
69+
}
70+
} else {
71+
insertString += GetString(insert);
7572
}
73+
message.replace(insertPos, insertName.length(), insertString);
74+
}
7675
}
7776
// Output error message, references, context
78-
std::string indent(depth*2, ' ');
77+
std::string indent(depth * 2, ' ');
7978
std::cout << indent << "Error Name: " << errorName << std::endl;
8079
std::cout << indent << "Message: " << message.c_str() << std::endl;
8180
std::cout << indent << "Instance: " << error["instanceRef"].GetString() << std::endl;
8281
std::cout << indent << "Schema: " << error["schemaRef"].GetString() << std::endl;
83-
if (depth > 0 ) std::cout << indent << "Context: " << context << std::endl;
82+
if (depth > 0) std::cout << indent << "Context: " << context << std::endl;
8483
std::cout << std::endl;
8584

8685
// If child errors exist, apply the process recursively to each error structure.
8786
// This occurs for "oneOf", "allOf", "anyOf" and "dependencies" errors, so pass the error name as context.
8887
if (error.HasMember("errors")) {
89-
depth++;
90-
const ValueType& childErrors = error["errors"];
91-
if (childErrors.IsArray()) {
92-
// Array - each item is an error structure - example
93-
// "anyOf": {"errorCode": ..., "errors":[{"pattern": {"errorCode\": ...\"}}, {"pattern": {"errorCode\": ...}}]
94-
for (ValueType::ConstValueIterator errorsItr = childErrors.Begin(); errorsItr != childErrors.End(); ++errorsItr) {
95-
CreateErrorMessages(*errorsItr, depth, errorName);
96-
}
97-
} else if (childErrors.IsObject()) {
98-
// Object - each member is an error structure - example
99-
// "dependencies": {"errorCode": ..., "errors": {"address": {"required": {"errorCode": ...}}, "name": {"required": {"errorCode": ...}}}
100-
for (ValueType::ConstMemberIterator propsItr = childErrors.MemberBegin(); propsItr != childErrors.MemberEnd(); ++propsItr) {
101-
CreateErrorMessages(propsItr->value, depth, errorName);
102-
}
88+
depth++;
89+
const ValueType &childErrors = error["errors"];
90+
if (childErrors.IsArray()) {
91+
// Array - each item is an error structure - example
92+
// "anyOf": {"errorCode": ..., "errors":[{"pattern": {"errorCode\": ...\"}}, {"pattern": {"errorCode\": ...}}]
93+
for (ValueType::ConstValueIterator errorsItr = childErrors.Begin();
94+
errorsItr != childErrors.End(); ++errorsItr) {
95+
CreateErrorMessages(*errorsItr, depth, errorName);
96+
}
97+
} else if (childErrors.IsObject()) {
98+
// Object - each member is an error structure - example
99+
// "dependencies": {"errorCode": ..., "errors": {"address": {"required": {"errorCode": ...}}, "name": {"required": {"errorCode": ...}}}
100+
for (ValueType::ConstMemberIterator propsItr = childErrors.MemberBegin();
101+
propsItr != childErrors.MemberEnd(); ++propsItr) {
102+
CreateErrorMessages(propsItr->value, depth, errorName);
103103
}
104+
}
104105
}
106+
}
105107
}
106108

107109
// Create error message for all errors in an error structure

include/rapidjson/schema.h

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ class Schema {
471471
exclusiveMaximum_(false),
472472
defaultValueLength_(0)
473473
{
474-
//std::cout << "Schema constructor " << schemaDocument << std::endl; // SMH
475474
typedef typename ValueType::ConstValueIterator ConstValueIterator;
476475
typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
477476

@@ -903,7 +902,6 @@ class Schema {
903902
}
904903

905904
bool StartObject(Context& context) const {
906-
//std::cout << " schema StartObject" << std::endl; // SMH
907905
if (!(type_ & (1 << kObjectSchemaType))) {
908906
DisallowedType(context, GetObjectString());
909907
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
@@ -925,7 +923,6 @@ class Schema {
925923
}
926924

927925
bool Key(Context& context, const Ch* str, SizeType len, bool) const {
928-
//std::cout << " schema Key" << std::endl; // SMH
929926
if (patternProperties_) {
930927
context.patternPropertiesSchemaCount = 0;
931928
for (SizeType i = 0; i < patternPropertyCount_; i++)
@@ -977,7 +974,6 @@ class Schema {
977974
}
978975

979976
bool EndObject(Context& context, SizeType memberCount) const {
980-
//std::cout << " schema EndObject with members " << memberCount << std::endl; // SMH
981977
if (hasRequired_) {
982978
context.error_handler.StartMissingProperties();
983979
for (SizeType index = 0; index < propertyCount_; index++)
@@ -1025,7 +1021,6 @@ class Schema {
10251021
}
10261022

10271023
bool StartArray(Context& context) const {
1028-
//std::cout << " schema StartArray" << std::endl; // SMH
10291024
context.arrayElementIndex = 0;
10301025
context.inArray = true; // Ensure we note that we are in an array
10311026

@@ -1038,7 +1033,6 @@ class Schema {
10381033
}
10391034

10401035
bool EndArray(Context& context, SizeType elementCount) const {
1041-
//std::cout << " schema EndArray" << std::endl; // SMH
10421036
context.inArray = false;
10431037

10441038
if (elementCount < minItems_) {
@@ -1613,7 +1607,6 @@ class GenericSchemaDocument {
16131607
schemaMap_(allocator, kInitialSchemaMapSize),
16141608
schemaRef_(allocator, kInitialSchemaRefSize)
16151609
{
1616-
//std::cout << "schema document constructor " << root_ << std::endl; // SMH
16171610
if (!allocator_)
16181611
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
16191612

@@ -1884,7 +1877,6 @@ class GenericSchemaValidator :
18841877
, depth_(0)
18851878
#endif
18861879
{
1887-
//std::cout << "validator constructor" << std::endl; // SMH
18881880
}
18891881

18901882
//! Constructor with output handler.
@@ -1917,7 +1909,6 @@ class GenericSchemaValidator :
19171909
, depth_(0)
19181910
#endif
19191911
{
1920-
//std::cout << "validator constructor with handler" << std::endl; // SMH
19211912
}
19221913

19231914
//! Destructor.
@@ -2154,7 +2145,7 @@ class GenericSchemaValidator :
21542145
AddCurrentError(kValidateErrorType);
21552146
}
21562147
void NotAllOf(ISchemaValidator** subvalidators, SizeType count) {
2157-
// Treat allOf like oneOf and anyOf for clarity
2148+
// Treat allOf like oneOf and anyOf to match https://rapidjson.org/md_doc_schema.html#allOf-anyOf-oneOf
21582149
AddErrorArray(kValidateErrorAllOf, subvalidators, count);
21592150
//for (SizeType i = 0; i < count; ++i) {
21602151
// MergeError(static_cast<GenericSchemaValidator*>(subvalidators[i])->GetError());
@@ -2211,7 +2202,6 @@ RAPIDJSON_MULTILINEMACRO_END
22112202

22122203
#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
22132204
for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
2214-
/*std::cout << " ++Parallel context: " << context << std::endl;*/\
22152205
if (context->hasher)\
22162206
static_cast<HasherType*>(context->hasher)->method arg2;\
22172207
if (context->validators)\
@@ -2224,11 +2214,9 @@ RAPIDJSON_MULTILINEMACRO_END
22242214

22252215
#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
22262216
valid_ = (EndValue() || GetContinueOnErrors()) && (!outputHandler_ || outputHandler_->method arg2);\
2227-
/*std::cout << "### EndValue returns " << valid_ << std::endl;*/\
22282217
return valid_;
22292218

22302219
#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \
2231-
/*std::cout << "validator Value " << this << std::endl;*/\
22322220
RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
22332221
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\
22342222
RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2)
@@ -2246,14 +2234,12 @@ RAPIDJSON_MULTILINEMACRO_END
22462234
{ RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
22472235

22482236
bool StartObject() {
2249-
//std::cout << "validator StartObject " << this << std::endl; // SMH
22502237
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
22512238
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());
22522239
return valid_ = !outputHandler_ || outputHandler_->StartObject();
22532240
}
22542241

22552242
bool Key(const Ch* str, SizeType len, bool copy) {
2256-
//std::cout << "validator Key: " << str << " " << this << (valid_ ? " true" : " false") << std::endl; // SMH
22572243
if (!valid_) return false;
22582244
AppendToken(str, len);
22592245
if (!CurrentSchema().Key(CurrentContext(), str, len, copy) && !GetContinueOnErrors()) return valid_ = false;
@@ -2262,22 +2248,19 @@ RAPIDJSON_MULTILINEMACRO_END
22622248
}
22632249

22642250
bool EndObject(SizeType memberCount) {
2265-
//std::cout << "validator EndObject " << this << std::endl; // SMH
22662251
if (!valid_) return false;
22672252
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount));
22682253
if (!CurrentSchema().EndObject(CurrentContext(), memberCount) && !GetContinueOnErrors()) return valid_ = false;
22692254
RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));
22702255
}
22712256

22722257
bool StartArray() {
2273-
//std::cout << "validator StartArray " << this << std::endl; // SMH
22742258
RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));
22752259
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());
22762260
return valid_ = !outputHandler_ || outputHandler_->StartArray();
22772261
}
22782262

22792263
bool EndArray(SizeType elementCount) {
2280-
//std::cout << "validator EndArray " << this << std::endl; // SMH
22812264
if (!valid_) return false;
22822265
RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount));
22832266
if (!CurrentSchema().EndArray(CurrentContext(), elementCount) && !GetContinueOnErrors()) return valid_ = false;
@@ -2297,7 +2280,6 @@ RAPIDJSON_MULTILINEMACRO_END
22972280
#endif
22982281
&GetStateAllocator());
22992282
sv->SetValidateFlags(inheritContinueOnErrors ? GetValidateFlags() : GetValidateFlags() & ~kValidateContinueOnErrorFlag);
2300-
//std::cout << "***** New validator ***** " << sv << " " << sv->GetValidateFlags() << std::endl;
23012283
return sv;
23022284
}
23032285

@@ -2520,7 +2502,6 @@ RAPIDJSON_MULTILINEMACRO_END
25202502
}
25212503

25222504
void AddCurrentError(const ValidateErrorCode code, bool parent = false) {
2523-
//std::cout << "==== AddCurrentError ======= " << SchemaType::GetValidateErrorKeyword(code).GetString() << std::endl;
25242505
AddErrorCode(currentError_, code);
25252506
AddErrorInstanceLocation(currentError_, parent);
25262507
AddErrorSchemaLocation(currentError_);

0 commit comments

Comments
 (0)