Skip to content

Commit 858117d

Browse files
committed
Fix bug in checking scalar against multiple types/subtypes
Fix inclusion of schemaIteratorRef & schemaHandlerRef in error messages Fixed bug in get_colors method for ObjWavefront Fixed various bugs in handling of colors for ObjWavefront
1 parent bb76cc2 commit 858117d

File tree

3 files changed

+143
-89
lines changed

3 files changed

+143
-89
lines changed

include/rapidjson/helpers.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,33 @@ void ObjWavefront::fromPly(const Ply& p) {
2626
if ((*name) == "vertex") {
2727
for (std::vector<PlyElement>::const_iterator it = p.elements.find(*name)->second.elements.begin();
2828
it != p.elements.find(*name)->second.elements.end(); it++) {
29-
this->add_element("v", it->get_double_array());
29+
ObjElement* ito = this->add_element("v", it->get_double_array(true));
30+
if (it->colors.size() > 0) {
31+
std::vector<uint8_t> icolors = it->get_colors_array();
32+
ito->add_colors(icolors.data(), static_cast<SizeType>(icolors.size()));
33+
}
3034
nvert++;
3135
}
3236
} else if ((*name) == "face") {
3337
for (std::vector<PlyElement>::const_iterator it = p.elements.find(*name)->second.elements.begin();
34-
it != p.elements.find(*name)->second.elements.end(); it++)
35-
this->add_element("f", it->get_int_array(nvert));
38+
it != p.elements.find(*name)->second.elements.end(); it++) {
39+
this->add_element("f", it->get_int_array(nvert, true));
40+
// Face colors not supported
41+
// if (it->colors.size() > 0) {
42+
// std::vector<uint8_t> icolors = it->get_colors_array();
43+
// ito->add_colors(icolors.data(), static_cast<SizeType>(icolors.size()));
44+
// }
45+
}
3646
} else if ((*name) == "edge") {
3747
for (std::vector<PlyElement>::const_iterator it = p.elements.find(*name)->second.elements.begin();
38-
it != p.elements.find(*name)->second.elements.end(); it++)
48+
it != p.elements.find(*name)->second.elements.end(); it++) {
3949
this->add_element("l", it->get_int_array(nvert));
50+
// Edge colors not supported
51+
// if (it->colors.size() > 0) {
52+
// std::vector<uint8_t> icolors = it->get_colors_array();
53+
// ito->add_colors(icolors.data(), static_cast<SizeType>(icolors.size()));
54+
// }
55+
}
4056
} else
4157
RAPIDJSON_ASSERT(((*name) == "vertex") ||
4258
((*name) == "face") ||

include/rapidjson/obj.h

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,15 @@ inline bool is_equal_vectors(const std::vector<T>& a, const std::vector<T>& b) {
205205
struct ObjPropertyType {
206206
public:
207207
ObjPropertyType(void* mem0, std::string name0, uint16_t flag0, size_t idx0=0) :
208-
mem(mem0), first(name0), second(flag0), idx(idx0), missing(false), is_index(false) {
208+
mem(mem0), first(name0), second(flag0), idx(idx0), missing(false), is_index(false), is_color(false) {
209209
is_index = (first.size() > 6 && (first.substr(first.size() - 6) == "_index"));
210+
is_color = (first == "red" ||
211+
first == "green" ||
212+
first == "blue");
210213
}
211214
ObjPropertyType(const ObjPropertyType& other) :
212215
mem(other.mem), first(other.first), second(other.second), idx(other.idx),
213-
missing(other.missing), is_index(other.is_index) {}
216+
missing(other.missing), is_index(other.is_index), is_color(other.is_color) {}
214217
//! \brief Copy assignment.
215218
ObjPropertyType& operator=(const ObjPropertyType& other) {
216219
mem = other.mem;
@@ -219,6 +222,7 @@ struct ObjPropertyType {
219222
idx = other.idx;
220223
missing = other.missing;
221224
is_index = other.is_index;
225+
is_color = other.is_color;
222226
return *this;
223227
}
224228
void* mem;
@@ -227,6 +231,7 @@ struct ObjPropertyType {
227231
size_t idx;
228232
bool missing;
229233
bool is_index;
234+
bool is_color;
230235

231236
//! \brief Determine if the property contains a vector of values.
232237
//! \return true if it contains a vector, false otherwise.
@@ -291,6 +296,22 @@ struct ObjPropertyType {
291296
/*! \param dec If true and the property is an index, it will be decremented. */ \
292297
/*! \return true if successful, false otherwise. */ \
293298
bool index(const size_t index, T& out, bool dec=false) const
299+
//! \brief Set a non-integer color
300+
//! \tparam T Type of source value.
301+
//! \param val Value to copy.
302+
//! \param inc If true and the property is an index, it will be incremented.
303+
//! \return true if successful, false otherwise.
304+
template<typename T>
305+
RAPIDJSON_DISABLEIF_RETURN((COMPATIBLE_WITH_INT(T)), (bool))
306+
setColor(const T& val, bool inc);
307+
//! \brief Set an integer color
308+
//! \tparam T Type of source value.
309+
//! \param val Value to copy.
310+
//! \param inc If true and the property is an index, it will be incremented.
311+
//! \return true if successful, false otherwise.
312+
template<typename T>
313+
RAPIDJSON_ENABLEIF_RETURN((COMPATIBLE_WITH_INT(T)), (bool))
314+
setColor(const T& val, bool inc);
294315
//! \brief Set the property values by copying from a vector.
295316
//! \tparam T Type in source vector.
296317
//! \param val Vector of values to copy from.
@@ -302,7 +323,7 @@ struct ObjPropertyType {
302323
COMPATIBLE_WITH_SURF(T)> >), (bool))
303324
set(const std::vector<T>& val, bool inc=false);
304325
//! \brief Set the property value.
305-
//! \tparam T Type of source valuue.
326+
//! \tparam T Type of source value.
306327
//! \param val Value to copy.
307328
//! \param inc If true and the property is an index, it will be incremented.
308329
//! \return true if successful, false otherwise.
@@ -1181,6 +1202,19 @@ std::istream & operator >> (std::istream &in, ObjRefSurface &p)
11811202
return false; \
11821203
}
11831204
template<typename T>
1205+
RAPIDJSON_DISABLEIF_RETURN((COMPATIBLE_WITH_INT(T)), (bool))
1206+
ObjPropertyType::setColor(const T& val, bool inc) {
1207+
if ((!mem) || second & ObjTypeList) return false;
1208+
RAPIDJSON_HANDLE_PROPERTY_TYPES_(HANDLE_SCALAR_SET_)
1209+
return true;
1210+
}
1211+
template<typename T>
1212+
RAPIDJSON_ENABLEIF_RETURN((COMPATIBLE_WITH_INT(T)), (bool))
1213+
ObjPropertyType::setColor(const T& val, bool inc) {
1214+
double valF = static_cast<double>(val) / 255.0;
1215+
return setColor(valF, inc);
1216+
}
1217+
template<typename T>
11841218
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<COMPATIBLE_WITH_STRING(T),
11851219
internal::OrExpr<COMPATIBLE_WITH_CURV(T),
11861220
COMPATIBLE_WITH_SURF(T)> >), (bool))
@@ -1194,6 +1228,9 @@ RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<COMPATIBLE_WITH_STRING(T),
11941228
internal::OrExpr<COMPATIBLE_WITH_CURV(T),
11951229
COMPATIBLE_WITH_SURF(T)> >), (bool))
11961230
ObjPropertyType::set(const T& val, bool inc) {
1231+
if (is_color) {
1232+
return setColor(val, inc);
1233+
}
11971234
if ((!mem) || second & ObjTypeList) return false;
11981235
RAPIDJSON_HANDLE_PROPERTY_TYPES_(HANDLE_SCALAR_SET_)
11991236
return true;
@@ -3142,9 +3179,9 @@ class ObjVertex : public ObjElement {
31423179
void get_colors_array(std::vector<uint8_t>& out,
31433180
uint8_t defaultValue=0) const OVERRIDE_CXX11 {
31443181
if (color.is_set) {
3145-
out.push_back(static_cast<uint8_t>(color.r/255.0));
3146-
out.push_back(static_cast<uint8_t>(color.g/255.0));
3147-
out.push_back(static_cast<uint8_t>(color.b/255.0));
3182+
out.push_back(static_cast<uint8_t>(color.r * 255.0));
3183+
out.push_back(static_cast<uint8_t>(color.g * 255.0));
3184+
out.push_back(static_cast<uint8_t>(color.b * 255.0));
31483185
} else {
31493186
out.push_back(defaultValue);
31503187
out.push_back(defaultValue);

include/rapidjson/schema.h

Lines changed: 80 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7058,30 +7058,8 @@ class Schema {
70587058
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
70597059
}
70607060

7061-
if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
7062-
SizeType count;
7063-
if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
7064-
if (count < minLength_) {
7065-
context.error_handler.TooShort(str, length, minLength_);
7066-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinLength);
7067-
}
7068-
if (count > maxLength_) {
7069-
context.error_handler.TooLong(str, length, maxLength_);
7070-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxLength);
7071-
}
7072-
}
7073-
}
7074-
7075-
if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
7076-
#ifdef RAPIDJSON_YGGDRASIL
7077-
context.error_handler.DoesNotMatch(str, length,
7078-
patternStr_.GetString(),
7079-
patternStr_.GetStringLength());
7080-
#else // RAPIDJSON_YGGDRASIL
7081-
context.error_handler.DoesNotMatch(str, length);
7082-
#endif // RAPIDJSON_YGGDRASIL
7083-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPattern);
7084-
}
7061+
if (!CheckString(context, str, length))
7062+
return false;
70857063

70867064
#ifdef RAPIDJSON_YGGDRASIL
70877065
if ((yggtype_ & ((1 << kYggPythonClassSchemaType) |
@@ -7121,28 +7099,50 @@ class Schema {
71217099
const ValueType v(vs->value.GetString(), vs->value.GetStringLength(),
71227100
allocator);
71237101
bool isScalar = (v == GetScalarString());
7124-
if (isScalar && (yggtype_ & (1 << kYggScalarSchemaType))) {
7125-
if (!(CheckSubType(context, *schema) &&
7126-
CheckPrecision(context, *schema) &&
7127-
CheckUnits(context, *schema) &&
7128-
CheckEncoding(context, *schema))) {
7129-
CLEANUP_;
7130-
return false;
7102+
if (isScalar && ((yggtype_ & (1 << kYggScalarSchemaType)) ||
7103+
(type_ & (1 << kNumberSchemaType)) ||
7104+
(type_ & (1 << kIntegerSchemaType)) ||
7105+
(type_ & (1 << kStringSchemaType)))) {
7106+
unsigned int validSubtypes = 0;
7107+
if (yggtype_ & (1 << kYggScalarSchemaType))
7108+
validSubtypes = validSubtypes | subtype_;
7109+
if (type_ & (1 << kNumberSchemaType))
7110+
validSubtypes = validSubtypes | (1 << kYggFloatSchemaSubType);
7111+
if (type_ & (1 << kIntegerSchemaType))
7112+
validSubtypes = validSubtypes | (1 << kYggIntSchemaSubType);
7113+
if (type_ & (1 << kStringSchemaType))
7114+
validSubtypes = validSubtypes | (1 << kYggStringSchemaSubType);
7115+
if (!CheckSubType(context, *schema, validSubtypes)) {
7116+
CLEANUP_;
7117+
return false;
71317118
}
7132-
} else if (isScalar && (type_ & (1 << kNumberSchemaType))) {
7133-
if (!(CheckSubType(context, *schema, (1 << kYggFloatSchemaSubType)) &&
7134-
CheckPrecision(context, *schema, SValue(8).Move()))) {
7135-
CLEANUP_;
7136-
return false;
7119+
if (yggtype_ & (1 << kYggScalarSchemaType)) {
7120+
if (!(CheckSubType(context, *schema, validSubtypes) &&
7121+
CheckPrecision(context, *schema) &&
7122+
CheckUnits(context, *schema) &&
7123+
CheckEncoding(context, *schema))) {
7124+
CLEANUP_;
7125+
return false;
7126+
}
71377127
}
7138-
} else if (isScalar && (type_ & (1 << kIntegerSchemaType))) {
7139-
if (!(CheckSubType(context, *schema, (1 << kYggIntSchemaSubType)) &&
7140-
CheckPrecision(context, *schema, SValue(8).Move()))) {
7141-
CLEANUP_;
7142-
return false;
7128+
// if (type_ & ((1 << kNumberSchemaType) |
7129+
// (1 << kIntegerSchemaType))) {
7130+
// if (!CheckPrecision(context, *schema, SValue(8).Move())) {
7131+
// CLEANUP_;
7132+
// return false;
7133+
// }
7134+
// }
7135+
typename YggSchemaValueType::ConstMemberIterator vsub = schema->FindMember(GetSubTypeString());
7136+
if ((type_ & (1 << kStringSchemaType)) &&
7137+
vsub != schema->MemberEnd() &&
7138+
vsub->value == YggSchemaValueType::GetStringSubTypeString()) {
7139+
if (!CheckString(context, str, length)) {
7140+
CLEANUP_;
7141+
return false;
7142+
}
71437143
}
71447144
} else if (((v == Get1DArrayString()) || (v == GetNDArrayString())) &&
7145-
(yggtype_ & (1 << kYggNDArraySchemaType))) {
7145+
(yggtype_ & (1 << kYggNDArraySchemaType))) {
71467146
if (!(CheckSubType(context, *schema) &&
71477147
CheckPrecision(context, *schema) &&
71487148
CheckUnits(context, *schema) &&
@@ -7185,43 +7185,12 @@ class Schema {
71857185
context.error_handler.InvalidObjWavefront(str, length);
71867186
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorObjWavefront);
71877187
}
7188-
} else if ((v == GetScalarString() || v == GetStringString()) &&
7189-
(type_ & (1 << kStringSchemaType)) &&
7190-
(yggtype_ == 0)) {
7191-
typename YggSchemaValueType::ConstMemberIterator vsub = schema->FindMember(GetSubTypeString());
7192-
if ((v == GetStringString()) ||
7193-
(vsub != schema->MemberEnd() && vsub->value == YggSchemaValueType::GetStringSubTypeString())) {
7194-
if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
7195-
SizeType count;
7196-
if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
7197-
if (count < minLength_) {
7198-
CLEANUP_;
7199-
context.error_handler.TooShort(str, length, minLength_);
7200-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinLength);
7201-
}
7202-
if (count > maxLength_) {
7203-
CLEANUP_;
7204-
context.error_handler.TooLong(str, length, maxLength_);
7205-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxLength);
7206-
}
7207-
}
7208-
}
7209-
7210-
if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
7211-
CLEANUP_;
7212-
#ifdef RAPIDJSON_YGGDRASIL
7213-
context.error_handler.DoesNotMatch(str, length,
7214-
patternStr_.GetString(),
7215-
patternStr_.GetStringLength());
7216-
#else // RAPIDJSON_YGGDRASIL
7217-
context.error_handler.DoesNotMatch(str, length);
7218-
#endif // RAPIDJSON_YGGDRASIL
7219-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPattern);
7220-
}
7221-
} else {
7222-
CLEANUP_;
7223-
YggDisallowedType(context, v);
7224-
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorType);
7188+
} else if (v == GetStringString() &&
7189+
(type_ & (1 << kStringSchemaType)) &&
7190+
(yggtype_ == 0)) {
7191+
if (!CheckString(context, str, length)) {
7192+
CLEANUP_;
7193+
return false;
72257194
}
72267195
} else {
72277196
CLEANUP_;
@@ -8752,6 +8721,34 @@ class Schema {
87528721
return false;
87538722
return true;
87548723
}
8724+
bool CheckString(Context& context, const Ch* str, SizeType length) const {
8725+
if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
8726+
SizeType count;
8727+
if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
8728+
if (count < minLength_) {
8729+
context.error_handler.TooShort(str, length, minLength_);
8730+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMinLength);
8731+
}
8732+
if (count > maxLength_) {
8733+
context.error_handler.TooLong(str, length, maxLength_);
8734+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorMaxLength);
8735+
}
8736+
}
8737+
}
8738+
8739+
if (pattern_ && !IsPatternMatch(pattern_, str, length)) {
8740+
#ifdef RAPIDJSON_YGGDRASIL
8741+
context.error_handler.DoesNotMatch(str, length,
8742+
patternStr_.GetString(),
8743+
patternStr_.GetStringLength());
8744+
#else // RAPIDJSON_YGGDRASIL
8745+
context.error_handler.DoesNotMatch(str, length);
8746+
#endif // RAPIDJSON_YGGDRASIL
8747+
RAPIDJSON_INVALID_KEYWORD_RETURN(kValidateErrorPattern);
8748+
}
8749+
return true;
8750+
}
8751+
87558752
bool CheckSubType(Context& context, const ValueType* subtype_str,
87568753
const bool has_encoding) const {
87578754
return CheckSubType(context, subtype_str, has_encoding, subtype_);
@@ -12755,6 +12752,10 @@ class GenericSchemaValidator :
1275512752
return false;
1275612753
MemberIter iRef = err->FindMember(GetInstanceRefString());
1275712754
MemberIter sRef = err->FindMember(GetSchemaRefString());
12755+
if (iRef == err->MemberEnd())
12756+
iRef = err->FindMember(GetSchemaIteratorRefString());
12757+
if (sRef == err->MemberEnd())
12758+
sRef = err->FindMember(GetSchemaHandlerRefString());
1275812759
if (iRef != err->MemberEnd()) {
1275912760
switch ((ValidateErrorCode)(code->value.GetInt())) {
1276012761
case kValidateErrorType:

0 commit comments

Comments
 (0)