-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[c++] Add support for boolean types in flexbuffers #4386
Changes from 7 commits
27a6802
1b2e6f0
1fdc564
9f61984
ae18682
5754ff0
5a1f6dd
561a334
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,9 +76,10 @@ enum Type { | |
TYPE_VECTOR_UINT4 = 23, | ||
TYPE_VECTOR_FLOAT4 = 24, | ||
TYPE_BLOB = 25, | ||
TYPE_BOOL = 26, | ||
}; | ||
|
||
inline bool IsInline(Type t) { return t <= TYPE_FLOAT; } | ||
inline bool IsInline(Type t) { return t <= TYPE_FLOAT || t == TYPE_BOOL; } | ||
|
||
inline bool IsTypedVectorElementType(Type t) { | ||
return t >= TYPE_INT && t <= TYPE_STRING; | ||
|
@@ -349,6 +350,7 @@ class Reference { | |
Type GetType() const { return type_; } | ||
|
||
bool IsNull() const { return type_ == TYPE_NULL; } | ||
bool IsBool() const { return type_ == TYPE_BOOL; } | ||
bool IsInt() const { return type_ == TYPE_INT || | ||
type_ == TYPE_INDIRECT_INT; } | ||
bool IsUInt() const { return type_ == TYPE_UINT|| | ||
|
@@ -363,6 +365,13 @@ class Reference { | |
bool IsMap() const { return type_ == TYPE_MAP; } | ||
bool IsBlob() const { return type_ == TYPE_BLOB; } | ||
|
||
bool AsBool() const { | ||
if (type_ == TYPE_BOOL) { | ||
return ReadUInt64(data_, parent_width_) != 0; | ||
} | ||
return AsUInt64() != 0; | ||
} | ||
|
||
// Reads any type as a int64_t. Never fails, does most sensible conversion. | ||
// Truncates floats, strings are attempted to be parsed for a number, | ||
// vectors/maps return their size. Returns 0 if all else fails. | ||
|
@@ -381,6 +390,7 @@ class Reference { | |
case TYPE_NULL: return 0; | ||
case TYPE_STRING: return flatbuffers::StringToInt(AsString().c_str()); | ||
case TYPE_VECTOR: return static_cast<int64_t>(AsVector().size()); | ||
case TYPE_BOOL: return ReadInt64(data_, parent_width_); | ||
default: | ||
// Convert other things to int. | ||
return 0; | ||
|
@@ -408,6 +418,7 @@ class Reference { | |
case TYPE_NULL: return 0; | ||
case TYPE_STRING: return flatbuffers::StringToUInt(AsString().c_str()); | ||
case TYPE_VECTOR: return static_cast<uint64_t>(AsVector().size()); | ||
case TYPE_BOOL: return ReadUInt64(data_, parent_width_); | ||
default: | ||
// Convert other things to uint. | ||
return 0; | ||
|
@@ -435,6 +446,8 @@ class Reference { | |
case TYPE_NULL: return 0.0; | ||
case TYPE_STRING: return strtod(AsString().c_str(), nullptr); | ||
case TYPE_VECTOR: return static_cast<double>(AsVector().size()); | ||
case TYPE_BOOL: return static_cast<double>( | ||
ReadUInt64(data_, parent_width_)); | ||
default: | ||
// Convert strings and other things to float. | ||
return 0; | ||
|
@@ -494,6 +507,8 @@ class Reference { | |
s += flatbuffers::NumToString(AsDouble()); | ||
} else if (IsNull()) { | ||
s += "null"; | ||
} else if (IsBool()) { | ||
s += AsBool() ? "true" : "false"; | ||
} else if (IsMap()) { | ||
s += "{ "; | ||
auto m = AsMap(); | ||
|
@@ -588,6 +603,13 @@ class Reference { | |
} | ||
} | ||
|
||
bool MutateBool(bool b) { | ||
if (type_ == TYPE_BOOL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return Mutate(data_, b, parent_width_, BIT_WIDTH_8); | ||
} | ||
return false; | ||
} | ||
|
||
bool MutateUInt(uint64_t u) { | ||
if (type_ == TYPE_UINT) { | ||
return Mutate(data_, u, parent_width_, WidthU(u)); | ||
|
@@ -816,7 +838,7 @@ class Builder FLATBUFFERS_FINAL_CLASS { | |
void Double(double f) { stack_.push_back(Value(f)); } | ||
void Double(const char *key, double d) { Key(key); Double(d); } | ||
|
||
void Bool(bool b) { Int(static_cast<int64_t>(b)); } | ||
void Bool(bool b) { stack_.push_back(Value(b)); } | ||
void Bool(const char *key, bool b) { Key(key); Bool(b); } | ||
|
||
void IndirectInt(int64_t i) { | ||
|
@@ -1236,6 +1258,8 @@ class Builder FLATBUFFERS_FINAL_CLASS { | |
|
||
Value() : i_(0), type_(TYPE_NULL), min_bit_width_(BIT_WIDTH_8) {} | ||
|
||
Value(bool b) : u_(static_cast<uint64_t>(b)), type_(TYPE_BOOL), min_bit_width_(BIT_WIDTH_8) {} | ||
|
||
Value(int64_t i, Type t, BitWidth bw) | ||
: i_(i), type_(t), min_bit_width_(bw) {} | ||
Value(uint64_t u, Type t, BitWidth bw) | ||
|
@@ -1294,6 +1318,7 @@ class Builder FLATBUFFERS_FINAL_CLASS { | |
case TYPE_INT: | ||
Write(val.i_, byte_width); | ||
break; | ||
case TYPE_BOOL: | ||
case TYPE_UINT: | ||
Write(val.u_, byte_width); | ||
break; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -185,7 +185,8 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name, | |
TD(Attribute, 270, "attribute") \ | ||
TD(Null, 271, "null") \ | ||
TD(Service, 272, "rpc_service") \ | ||
TD(NativeInclude, 273, "native_include") | ||
TD(NativeInclude, 273, "native_include") \ | ||
TD(BooleanConstant, 274, "boolean constant") | ||
#ifdef __GNUC__ | ||
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic. | ||
#endif | ||
|
@@ -391,7 +392,7 @@ CheckedError Parser::Next() { | |
// which simplifies our logic downstream. | ||
if (attribute_ == "true" || attribute_ == "false") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed above, lets not do this. |
||
attribute_ = NumToString(attribute_ == "true"); | ||
token_ = kTokenIntegerConstant; | ||
token_ = kTokenBooleanConstant; | ||
return NoError(); | ||
} | ||
// Check for declaration keywords: | ||
|
@@ -1338,6 +1339,11 @@ CheckedError Parser::ParseSingleValue(Value &e) { | |
e, | ||
BASE_TYPE_INT, | ||
&match)); | ||
ECHECK(TryTypedValue(kTokenBooleanConstant, | ||
IsBool(e.type.base_type), | ||
e, | ||
BASE_TYPE_BOOL, | ||
&match)); | ||
ECHECK(TryTypedValue(kTokenFloatConstant, | ||
IsFloat(e.type.base_type), | ||
e, | ||
|
@@ -2007,6 +2013,9 @@ CheckedError Parser::SkipAnyJsonValue() { | |
case kTokenFloatConstant: | ||
EXPECT(kTokenFloatConstant); | ||
break; | ||
case kTokenBooleanConstant: | ||
EXPECT(kTokenBooleanConstant); | ||
break; | ||
default: | ||
return TokenError(); | ||
} | ||
|
@@ -2064,6 +2073,10 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) { | |
builder->Int(StringToInt(attribute_.c_str())); | ||
EXPECT(kTokenIntegerConstant); | ||
break; | ||
case kTokenBooleanConstant: | ||
builder->Bool(StringToInt(attribute_.c_str()) != 0); | ||
EXPECT(kTokenBooleanConstant); | ||
break; | ||
case kTokenFloatConstant: | ||
builder->Double(strtod(attribute_.c_str(), nullptr)); | ||
EXPECT(kTokenFloatConstant); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return (type_ == TYPE_BOOL ? .. : ..) != 0