mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-29 15:02:01 +00:00
FlexBuffers: allow any values to be shared.
(see comments in the code). Change-Id: I5603abb0db436145739653692644bbcfd3c946e3
This commit is contained in:
@@ -914,7 +914,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
Bool(b);
|
Bool(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); }
|
void IndirectInt(int64_t i) {
|
||||||
|
PushIndirect(i, FBT_INDIRECT_INT, WidthI(i));
|
||||||
|
}
|
||||||
void IndirectInt(const char *key, int64_t i) {
|
void IndirectInt(const char *key, int64_t i) {
|
||||||
Key(key);
|
Key(key);
|
||||||
IndirectInt(i);
|
IndirectInt(i);
|
||||||
@@ -1194,6 +1196,26 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
EndMap(start);
|
EndMap(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If you wish to share a value explicitly (a value not shared automatically
|
||||||
|
// through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these
|
||||||
|
// functions. Or if you wish to turn those flags off for performance reasons
|
||||||
|
// and still do some explicit sharing. For example:
|
||||||
|
// builder.IndirectDouble(M_PI);
|
||||||
|
// auto id = builder.LastValue(); // Remember where we stored it.
|
||||||
|
// .. more code goes here ..
|
||||||
|
// builder.ReuseValue(id); // Refers to same double by offset.
|
||||||
|
// LastValue works regardless of wether the value has a key or not.
|
||||||
|
// Works on any data type.
|
||||||
|
struct Value;
|
||||||
|
Value LastValue() { return stack_.back(); }
|
||||||
|
void ReuseValue(Value v) {
|
||||||
|
stack_.push_back(v);
|
||||||
|
}
|
||||||
|
void ReuseValue(const char *key, Value v) {
|
||||||
|
Key(key);
|
||||||
|
ReuseValue(v);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloaded Add that tries to call the correct function above.
|
// Overloaded Add that tries to call the correct function above.
|
||||||
void Add(int8_t i) { Int(i); }
|
void Add(int8_t i) { Int(i); }
|
||||||
void Add(int16_t i) { Int(i); }
|
void Add(int16_t i) { Int(i); }
|
||||||
@@ -1319,6 +1341,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
: FBT_INT);
|
: FBT_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// This was really intended to be private, except for LastValue/ReuseValue.
|
||||||
struct Value {
|
struct Value {
|
||||||
union {
|
union {
|
||||||
int64_t i_;
|
int64_t i_;
|
||||||
@@ -1388,6 +1412,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
void WriteAny(const Value &val, uint8_t byte_width) {
|
void WriteAny(const Value &val, uint8_t byte_width) {
|
||||||
switch (val.type_) {
|
switch (val.type_) {
|
||||||
case FBT_NULL:
|
case FBT_NULL:
|
||||||
|
|||||||
@@ -2514,9 +2514,11 @@ void FlexBuffersTest() {
|
|||||||
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
||||||
slb += "Fred";
|
slb += "Fred";
|
||||||
slb.IndirectFloat(4.0f);
|
slb.IndirectFloat(4.0f);
|
||||||
|
auto i_f = slb.LastValue();
|
||||||
uint8_t blob[] = { 77 };
|
uint8_t blob[] = { 77 };
|
||||||
slb.Blob(blob, 1);
|
slb.Blob(blob, 1);
|
||||||
slb += false;
|
slb += false;
|
||||||
|
slb.ReuseValue(i_f);
|
||||||
});
|
});
|
||||||
int ints[] = { 1, 2, 3 };
|
int ints[] = { 1, 2, 3 };
|
||||||
slb.Vector("bar", ints, 3);
|
slb.Vector("bar", ints, 3);
|
||||||
@@ -2537,9 +2539,11 @@ void FlexBuffersTest() {
|
|||||||
slb3 += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
slb3 += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
||||||
slb3 += "Fred";
|
slb3 += "Fred";
|
||||||
slb3.IndirectFloat(4.0f);
|
slb3.IndirectFloat(4.0f);
|
||||||
|
auto i_f = slb3.LastValue();
|
||||||
uint8_t blob[] = { 77 };
|
uint8_t blob[] = { 77 };
|
||||||
slb3.Blob(blob, 1);
|
slb3.Blob(blob, 1);
|
||||||
slb3 += false;
|
slb3 += false;
|
||||||
|
slb3.ReuseValue(i_f);
|
||||||
}, slb2);
|
}, slb2);
|
||||||
int ints[] = { 1, 2, 3 };
|
int ints[] = { 1, 2, 3 };
|
||||||
slb2.Vector("bar", ints, 3);
|
slb2.Vector("bar", ints, 3);
|
||||||
@@ -2563,7 +2567,7 @@ void FlexBuffersTest() {
|
|||||||
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
||||||
TEST_EQ(map.size(), 7);
|
TEST_EQ(map.size(), 7);
|
||||||
auto vec = map["vec"].AsVector();
|
auto vec = map["vec"].AsVector();
|
||||||
TEST_EQ(vec.size(), 5);
|
TEST_EQ(vec.size(), 6);
|
||||||
TEST_EQ(vec[0].AsInt64(), -100);
|
TEST_EQ(vec[0].AsInt64(), -100);
|
||||||
TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
|
TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
|
||||||
TEST_EQ(vec[1].AsInt64(), 0); // Number parsing failed.
|
TEST_EQ(vec[1].AsInt64(), 0); // Number parsing failed.
|
||||||
@@ -2571,13 +2575,11 @@ void FlexBuffersTest() {
|
|||||||
TEST_EQ(vec[2].AsString().IsTheEmptyString(), true); // Wrong Type.
|
TEST_EQ(vec[2].AsString().IsTheEmptyString(), true); // Wrong Type.
|
||||||
TEST_EQ_STR(vec[2].AsString().c_str(), ""); // This still works though.
|
TEST_EQ_STR(vec[2].AsString().c_str(), ""); // This still works though.
|
||||||
TEST_EQ_STR(vec[2].ToString().c_str(), "4.0"); // Or have it converted.
|
TEST_EQ_STR(vec[2].ToString().c_str(), "4.0"); // Or have it converted.
|
||||||
|
|
||||||
// Few tests for templated version of As.
|
// Few tests for templated version of As.
|
||||||
TEST_EQ(vec[0].As<int64_t>(), -100);
|
TEST_EQ(vec[0].As<int64_t>(), -100);
|
||||||
TEST_EQ_STR(vec[1].As<std::string>().c_str(), "Fred");
|
TEST_EQ_STR(vec[1].As<std::string>().c_str(), "Fred");
|
||||||
TEST_EQ(vec[1].As<int64_t>(), 0); // Number parsing failed.
|
TEST_EQ(vec[1].As<int64_t>(), 0); // Number parsing failed.
|
||||||
TEST_EQ(vec[2].As<double>(), 4.0);
|
TEST_EQ(vec[2].As<double>(), 4.0);
|
||||||
|
|
||||||
// Test that the blob can be accessed.
|
// Test that the blob can be accessed.
|
||||||
TEST_EQ(vec[3].IsBlob(), true);
|
TEST_EQ(vec[3].IsBlob(), true);
|
||||||
auto blob = vec[3].AsBlob();
|
auto blob = vec[3].AsBlob();
|
||||||
@@ -2585,6 +2587,7 @@ void FlexBuffersTest() {
|
|||||||
TEST_EQ(blob.data()[0], 77);
|
TEST_EQ(blob.data()[0], 77);
|
||||||
TEST_EQ(vec[4].IsBool(), true); // Check if type is a bool
|
TEST_EQ(vec[4].IsBool(), true); // Check if type is a bool
|
||||||
TEST_EQ(vec[4].AsBool(), false); // Check if value is false
|
TEST_EQ(vec[4].AsBool(), false); // Check if value is false
|
||||||
|
TEST_EQ(vec[5].AsDouble(), 4.0); // This is shared with vec[2] !
|
||||||
auto tvec = map["bar"].AsTypedVector();
|
auto tvec = map["bar"].AsTypedVector();
|
||||||
TEST_EQ(tvec.size(), 3);
|
TEST_EQ(tvec.size(), 3);
|
||||||
TEST_EQ(tvec[2].AsInt8(), 3);
|
TEST_EQ(tvec[2].AsInt8(), 3);
|
||||||
@@ -2913,7 +2916,7 @@ void NativeTypeTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedLengthArrayJsonTest(bool binary) {
|
void FixedLengthArrayJsonTest(bool binary) {
|
||||||
// VS10 does not support typed enums, exclude from tests
|
// VS10 does not support typed enums, exclude from tests
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
|
|||||||
Reference in New Issue
Block a user