Skip to content
/ bond Public
forked from microsoft/bond

Commit

Permalink
EXAMPLE: Buggy behavior when deserializing something with a base and …
Browse files Browse the repository at this point in the history
…encountering BT_STOP during the base instead of BT_STOP_BASE
  • Loading branch information
chwarr committed Dec 5, 2017
1 parent 48c4d43 commit a14486f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 100 deletions.
28 changes: 3 additions & 25 deletions examples/cpp/core/polymorphic_container/polymorphic_container.bond
Original file line number Diff line number Diff line change
@@ -1,34 +1,12 @@
namespace examples.polymorphic_containers

enum StructKind
{
StructKind_Unknown;
StructKind_Struct1;
StructKind_Struct2;
}

struct Base
{
0: StructKind kind = StructKind_Unknown;
}


struct Struct1 : Base
{
0: string str;
1: uint16 n;
0: int32 f;
}


struct Struct2 : Base
{
1: bool b;
2: int32 n;
3: string str;
}


struct Polymorphic
struct Derived : Base
{
0: list<bonded<Base>> items;
0: int32 df;
}
101 changes: 26 additions & 75 deletions examples/cpp/core/polymorphic_container/polymorphic_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,91 +18,42 @@ bond::bonded<T> Serialize(const T& obj)
return bond::bonded<T>(reader);
}


Struct1 DeserializeStruct1(const bond::bonded<Base>& base)
{
// Explicit down-casting from bonded<Base> to bonded<Struct1>
bond::bonded<Struct1> bonded(base);
Struct1 obj;
bonded.Deserialize(obj);
return obj;
}


Struct2 DeserializeStruct2(const bond::bonded<Base>& base)
{
// Explicit down-casting from bonded<Base> to bonded<Struct2>
bond::bonded<Struct2> bonded(base);
Struct2 obj;
bonded.Deserialize(obj);
return obj;
}


int main()
{
bond::bonded<Polymorphic> bonded;
bond::bonded<bond::Box<std::vector<bond::bonded<Base>>>> bonded;

{
Struct1 obj1;
obj1.kind = StructKind_Struct1;
obj1.n = 1;
obj1.str = "1";

Struct2 obj2;
obj2.kind = StructKind_Struct2;
obj2.n = 2;
obj2.str = "2";
bond::Box<std::vector<bond::bonded<Base>>> box;

Polymorphic polymorphic;
{
Base b1, b2;
b1.f = 1;
b2.f = 2;

// Implicit up-casting from bonded<Struct1/2> to bonded<Base>
polymorphic.items.push_back(Serialize(obj1));
polymorphic.items.push_back(Serialize(obj2));
box.value.emplace_back(Serialize(b1));
box.value.emplace_back(Serialize(b2));
}

bonded = Serialize(polymorphic);
bonded = Serialize(box);
}

// At this point bonded represents serialized data for a struct which has
// a polymorpic list field delcared as list<bonded<Base>>. Application can
// deserialize the Base part of each element and based of the contained type
// metadata, deserialize the full element to an appropriate struct.

Polymorphic polymorphic;

bonded.Deserialize(polymorphic);

for (
std::list<bond::bonded<Base> >::const_iterator it = polymorphic.items.begin();
it != polymorphic.items.end();
++it)
{
Base base;
it->Deserialize(base);

switch (base.kind)
{
case StructKind_Struct1:
{
Struct1 obj1 = DeserializeStruct1(*it);
assert(obj1.str == "1");
assert(obj1.n == 1);
}
break;

case StructKind_Struct2:
{
Struct2 obj2 = DeserializeStruct2(*it);
assert(obj2.b == false);
assert(obj2.n == 2);
assert(obj2.str == "2");
}
break;

default:
assert(false);
break;
}
bond::Box<std::vector<bond::bonded<Base>>> obj1;
bonded.Deserialize(obj1);

assert(obj1.value.size() == 2);

bond::bonded<Derived> bondedD(obj1.value[0]);
Derived d;
bondedD.Deserialize(d);

assert(d.f == 1);
// the default value for df is 0, so we sort of "expect" that.
// Really, though, I think that deserialization should fail at
// runtime. There could be an argument made for deserialization
// working if there are no required fields in any of the child
// parts...
assert(d.df == 0);
}

return 0;
Expand Down

0 comments on commit a14486f

Please sign in to comment.