From: Wouter van Oortmerssen Date: Mon, 26 Aug 2019 18:54:38 +0000 (-0700) Subject: FlexBuffers: allow any values to be shared. X-Git-Tag: v1.12.0~155 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1fbb711324720ffe43f972450f16aeb9f0b27beb;p=platform%2Fupstream%2Fflatbuffers.git FlexBuffers: allow any values to be shared. (see comments in the code). Change-Id: I5603abb0db436145739653692644bbcfd3c946e3 --- diff --git a/include/flatbuffers/flexbuffers.h b/include/flatbuffers/flexbuffers.h index 3425150..35c3e0b 100644 --- a/include/flatbuffers/flexbuffers.h +++ b/include/flatbuffers/flexbuffers.h @@ -914,7 +914,9 @@ class Builder FLATBUFFERS_FINAL_CLASS { 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) { Key(key); IndirectInt(i); @@ -1194,6 +1196,26 @@ class Builder FLATBUFFERS_FINAL_CLASS { 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. void Add(int8_t i) { Int(i); } void Add(int16_t i) { Int(i); } @@ -1319,6 +1341,8 @@ class Builder FLATBUFFERS_FINAL_CLASS { : FBT_INT); } + public: + // This was really intended to be private, except for LastValue/ReuseValue. struct Value { union { int64_t i_; @@ -1388,6 +1412,7 @@ class Builder FLATBUFFERS_FINAL_CLASS { } }; + private: void WriteAny(const Value &val, uint8_t byte_width) { switch (val.type_) { case FBT_NULL: diff --git a/tests/test.cpp b/tests/test.cpp index 2efef43..a3474cb 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -2514,9 +2514,11 @@ void FlexBuffersTest() { slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100); slb += "Fred"; slb.IndirectFloat(4.0f); + auto i_f = slb.LastValue(); uint8_t blob[] = { 77 }; slb.Blob(blob, 1); slb += false; + slb.ReuseValue(i_f); }); int ints[] = { 1, 2, 3 }; slb.Vector("bar", ints, 3); @@ -2537,9 +2539,11 @@ void FlexBuffersTest() { slb3 += -100; // Equivalent to slb.Add(-100) or slb.Int(-100); slb3 += "Fred"; slb3.IndirectFloat(4.0f); + auto i_f = slb3.LastValue(); uint8_t blob[] = { 77 }; slb3.Blob(blob, 1); slb3 += false; + slb3.ReuseValue(i_f); }, slb2); int ints[] = { 1, 2, 3 }; slb2.Vector("bar", ints, 3); @@ -2563,7 +2567,7 @@ void FlexBuffersTest() { auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap(); TEST_EQ(map.size(), 7); auto vec = map["vec"].AsVector(); - TEST_EQ(vec.size(), 5); + TEST_EQ(vec.size(), 6); TEST_EQ(vec[0].AsInt64(), -100); TEST_EQ_STR(vec[1].AsString().c_str(), "Fred"); 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_STR(vec[2].AsString().c_str(), ""); // This still works though. TEST_EQ_STR(vec[2].ToString().c_str(), "4.0"); // Or have it converted. - // Few tests for templated version of As. TEST_EQ(vec[0].As(), -100); TEST_EQ_STR(vec[1].As().c_str(), "Fred"); TEST_EQ(vec[1].As(), 0); // Number parsing failed. TEST_EQ(vec[2].As(), 4.0); - // Test that the blob can be accessed. TEST_EQ(vec[3].IsBlob(), true); auto blob = vec[3].AsBlob(); @@ -2585,6 +2587,7 @@ void FlexBuffersTest() { TEST_EQ(blob.data()[0], 77); 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[5].AsDouble(), 4.0); // This is shared with vec[2] ! auto tvec = map["bar"].AsTypedVector(); TEST_EQ(tvec.size(), 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 #if !defined(_MSC_VER) || _MSC_VER >= 1700 // load FlatBuffer schema (.fbs) and JSON from disk