From 2edc9c6fd10e34ca1da0d25d3ceb9b67a6b9c73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Fri, 7 Jul 2023 12:25:14 +0200 Subject: Add a C++ backend for LibertyXDR Also change the C backend so that it also de/serializes unions without any other fields besides the tag. --- tests/lxdrgen.c | 11 +++++ tests/lxdrgen.cpp | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/lxdrgen.lxdr | 1 + 3 files changed, 144 insertions(+) create mode 100644 tests/lxdrgen.cpp (limited to 'tests') diff --git a/tests/lxdrgen.c b/tests/lxdrgen.c index 14f40e2..78ec47b 100644 --- a/tests/lxdrgen.c +++ b/tests/lxdrgen.c @@ -53,6 +53,10 @@ test_ser_deser_free (void) u->others.bar = str_make (); for (int i = rand () % 0x30; i > 0; i--) str_append_c (&u->others.bar, 0x30 + i); + u->others.baz_len = rand () % 0x30; + u->others.baz = xcalloc (1, u->others.baz_len); + for (uint32_t i = 0; i < u->others.baz_len; i++) + u->others.baz[i] = 0x30 + i; break; case 2: u->tag = PROTO_GEN_ENUM_NOTHING; @@ -62,6 +66,8 @@ test_ser_deser_free (void) } } + a.o.tag = PROTO_GEN_ENUM_NOTHING; + struct str buf = str_make (); hard_assert (proto_gen_struct_serialize (&a, &buf)); struct msg_unpacker r = msg_unpacker_make (buf.str, buf.len); @@ -92,6 +98,9 @@ test_ser_deser_free (void) hard_assert (ua->others.bar.len == ub->others.bar.len); hard_assert (!memcmp (ua->others.bar.str, ub->others.bar.str, ua->others.bar.len)); + hard_assert (ua->others.baz_len == ub->others.baz_len); + hard_assert (!memcmp (ua->others.baz, ub->others.baz, + ua->others.baz_len)); break; case PROTO_GEN_ENUM_NOTHING: break; @@ -100,6 +109,8 @@ test_ser_deser_free (void) } } + hard_assert (a.o.tag == b.o.tag); + // Emulate partially deserialized data to test disposal of that. for (size_t i = b.u_len - CASES; i < b.u_len; i++) { diff --git a/tests/lxdrgen.cpp b/tests/lxdrgen.cpp new file mode 100644 index 0000000..1a8c726 --- /dev/null +++ b/tests/lxdrgen.cpp @@ -0,0 +1,132 @@ +/* + * tests/lxdrgen.cpp + * + * Copyright (c) 2023, Přemysl Eric Janouch + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "lxdrgen.lxdr.cpp" + +#include + +static void +hard_assert (bool condition, const char *description) +{ + if (!condition) + { + fprintf (stderr, "assertion failed: %s\n", description); + abort (); + } +} + +#define hard_assert(condition) hard_assert (condition, #condition) + +int +main (int argc, char *argv[]) +{ + hard_assert (ProtoGen::VERSION == 1); + + enum { CASES = 3 }; + + ProtoGen::Struct a = {}, b = {}; + a.u.resize (CASES + rand () % 100); + for (size_t i = 0; i < a.u.size (); i++) + { + std::unique_ptr &u = a.u[i]; + switch (i % CASES) + { + case 0: + { + auto numbers = new ProtoGen::Union_Numbers (); + numbers->a = rand () % UINT8_MAX; + numbers->b = rand () % UINT16_MAX; + numbers->c = rand () % UINT32_MAX; + numbers->d = rand () % UINT64_MAX; + numbers->e = rand () % UINT8_MAX; + numbers->f = rand () % UINT16_MAX; + numbers->g = rand () % UINT32_MAX; + numbers->h = rand () % UINT64_MAX; + u.reset (numbers); + break; + } + case 1: + { + auto others = new ProtoGen::Union_Others (); + others->foo = rand () % 2; + for (int i = rand () % 0x30; i > 0; i--) + others->bar += 0x30 + i; + for (int i = rand () % 0x30; i > 0; i--) + others->baz.push_back (0x30 + i); + u.reset (others); + break; + } + case 2: + u.reset (new ProtoGen::Union_Nothing ()); + break; + default: + hard_assert (!"unhandled case"); + } + } + + a.o.reset (new ProtoGen::Onion_Nothing ()); + + LibertyXDR::Writer buf; + hard_assert (a.serialize (buf)); + LibertyXDR::Reader r; + r.data = buf.data.data (); + r.length = buf.data.size (); + hard_assert (b.deserialize (r)); + hard_assert (!r.length); + + hard_assert (a.u.size () == b.u.size ()); + for (size_t i = 0; i < a.u.size (); i++) + { + ProtoGen::Union *ua = a.u[i].get (); + ProtoGen::Union *ub = b.u[i].get (); + hard_assert (ua->tag == ub->tag); + switch (ua->tag) + { + case ProtoGen::Enum::NUMBERS: + { + auto a = dynamic_cast (ua); + auto b = dynamic_cast (ub); + hard_assert (a->a == b->a); + hard_assert (a->b == b->b); + hard_assert (a->c == b->c); + hard_assert (a->d == b->d); + hard_assert (a->e == b->e); + hard_assert (a->f == b->f); + hard_assert (a->g == b->g); + hard_assert (a->h == b->h); + break; + } + case ProtoGen::Enum::OTHERS: + { + auto a = dynamic_cast (ua); + auto b = dynamic_cast (ub); + hard_assert (a->foo == b->foo); + hard_assert (a->bar == b->bar); + hard_assert (a->baz == b->baz); + break; + } + case ProtoGen::Enum::NOTHING: + break; + default: + hard_assert (!"unexpected case"); + } + } + + hard_assert (a.o->tag == b.o->tag); + return 0; +} diff --git a/tests/lxdrgen.lxdr b/tests/lxdrgen.lxdr index 41973f8..d332336 100644 --- a/tests/lxdrgen.lxdr +++ b/tests/lxdrgen.lxdr @@ -17,6 +17,7 @@ struct Struct { case OTHERS: bool foo; string bar; + u8 baz<>; case NOTHING: void; } u<>; -- cgit v1.2.3