DCCL v4
test.cpp
1 // Copyright 2019-2023:
2 // GobySoft, LLC (2013-)
3 // Community contributors (see AUTHORS file)
4 // File authors:
5 // Toby Schneider <toby@gobysoft.org>
6 //
7 //
8 // This file is part of the Dynamic Compact Control Language Library
9 // ("DCCL").
10 //
11 // DCCL is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU Lesser General Public License as published by
13 // the Free Software Foundation, either version 2.1 of the License, or
14 // (at your option) any later version.
15 //
16 // DCCL is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public License
22 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
23 // tests usage of a custom DCCL ID codec
24 
25 #include "../../codec.h"
26 #include "../../field_codec_id.h"
27 #include "test.pb.h"
28 using namespace dccl::test;
29 
30 
31 namespace dccl
32 {
33 namespace test
34 {
35 // If "user_id" is set via UserCustomIdRAII, use that, fall back to using the
36 // default ID Codec
38 {
39  private:
40  dccl::Bitset encode(const dccl::uint32& wire_value) override
41  {
42  return user_id_set ? encode() : DefaultIdentifierCodec::encode(wire_value);
43  }
44 
45  dccl::Bitset encode() override
46  {
47  return user_id_set ? dccl::Bitset() : DefaultIdentifierCodec::encode();
48  }
49 
50  unsigned size() override { return user_id_set ? 0 : DefaultIdentifierCodec::size(); }
51 
52  unsigned size(const dccl::uint32& wire_value) override
53  {
54  return user_id_set ? 0 : DefaultIdentifierCodec::size(wire_value);
55  }
56 
57  unsigned min_size() override { return user_id_set ? 0 : DefaultIdentifierCodec::min_size(); }
58 
59  unsigned max_size() override { return user_id_set ? 0 : DefaultIdentifierCodec::max_size(); }
60 
61  // pass the current ID back
62  dccl::uint32 decode(dccl::Bitset* bits) override
63  {
64  return user_id_set ? user_id : DefaultIdentifierCodec::decode(bits);
65  }
66 
67  void validate() override
68  {
69  if (!user_id_set)
71  }
72 
73  friend struct UserCustomIdRAII;
74  static dccl::uint32 user_id;
75  static bool user_id_set;
76 };
77 
78 // RAII-based tool for setting the current DCCL ID within the scope of this
79 // object's lifetime. Any actions (load, info, encode, decode, etc.) will
80 // use this DCCL ID for the duration of this lifetime.
82 {
84  {
85  UserCustomIdCodec::user_id = id;
86  UserCustomIdCodec::user_id_set = true;
87  }
89  {
90  UserCustomIdCodec::user_id = 0;
91  UserCustomIdCodec::user_id_set = false;
92  }
93 };
94 } // namespace test
95 } // namespace dccl
96 
97 bool dccl::test::UserCustomIdCodec::user_id_set = false;
98 dccl::uint32 dccl::test::UserCustomIdCodec::user_id = 0;
99 
100 int main(int /*argc*/, char* /*argv*/ [])
101 {
102  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
103 
104  {
105  dccl::Codec codec("user_id_codec", dccl::test::UserCustomIdCodec());
106 
107  // load TestMessageA as DCCL ID 1
108  {
109  dccl::test::UserCustomIdRAII scoped_user_id(1);
110  codec.load<TestMessageA>();
111  codec.info<TestMessageA>(&dccl::dlog);
112  }
113  // load TestMessageA as DCCL ID 2
114  {
115  dccl::test::UserCustomIdRAII scoped_user_id(2);
116  codec.load<TestMessageA>();
117  codec.info<TestMessageA>(&dccl::dlog);
118  }
119 
120  // load TestMessageB as DCCL ID 3
121  {
122  dccl::test::UserCustomIdRAII scoped_user_id(3);
123  codec.load<TestMessageB>();
124  codec.info<TestMessageB>(&dccl::dlog);
125  }
126 
127  // load TestMessageA using default ID codec
128  {
129  codec.load<TestMessageA>();
130  codec.info<TestMessageA>(&dccl::dlog);
131  }
132 
133  // one byte as the UserCustomIdCodec doesn't use any bytes on the wire
134  unsigned byte_size_user_specified = 1;
135  TestMessageA a1;
136  a1.set_a(10);
137 
138  TestMessageA a2;
139  a2.set_a(20);
140 
141  TestMessageB b;
142  b.set_b(30);
143 
144  // one byte for the data, one byte for the ID
145  unsigned byte_size_default = 2;
146  TestMessageA a_default;
147  a_default.set_a(40);
148 
149  // encode/decode using user-specified DCCL ID
150  {
151  dccl::test::UserCustomIdRAII scoped_user_id(1);
152  std::string bytes;
153 
154  std::cout << "A1: " << a1.ShortDebugString() << std::endl;
155  assert(codec.size(a1) == byte_size_user_specified);
156  codec.encode(&bytes, a1);
157  assert(bytes.size() == byte_size_user_specified);
158  TestMessageA a1_out;
159  codec.decode(bytes, &a1_out);
160  std::cout << "A1 decoded: " << a1_out.ShortDebugString() << std::endl;
161  assert(a1_out.SerializeAsString() == a1.SerializeAsString());
162  }
163 
164  {
165  dccl::test::UserCustomIdRAII scoped_user_id(2);
166  std::string bytes;
167  std::cout << "A2: " << a2.ShortDebugString() << std::endl;
168  assert(codec.size(a2) == byte_size_user_specified);
169  codec.encode(&bytes, a2);
170  assert(bytes.size() == byte_size_user_specified);
171  TestMessageA a2_out;
172  codec.decode(bytes, &a2_out);
173  std::cout << "A2 decoded: " << a2_out.ShortDebugString() << std::endl;
174  assert(a2_out.SerializeAsString() == a2.SerializeAsString());
175  }
176 
177  {
178  dccl::test::UserCustomIdRAII scoped_user_id(3);
179  std::string bytes;
180  std::cout << "B: " << b.ShortDebugString() << std::endl;
181  assert(codec.size(b) == byte_size_user_specified);
182  codec.encode(&bytes, b);
183  assert(bytes.size() == byte_size_user_specified);
184  TestMessageA b_out;
185  codec.decode(bytes, &b_out);
186  std::cout << "B decoded: " << b_out.ShortDebugString() << std::endl;
187  assert(b_out.SerializeAsString() == b.SerializeAsString());
188  }
189 
190  // encode/decode using default DCCL ID
191  {
192  std::string bytes;
193 
194  std::cout << "A Default: " << a_default.ShortDebugString() << std::endl;
195  assert(codec.size(a_default) == byte_size_default);
196  codec.encode(&bytes, a_default);
197  assert(bytes.size() == byte_size_default);
198  TestMessageA a_default_out;
199  codec.decode(bytes, &a_default_out);
200  std::cout << "A Default decoded: " << a_default_out.ShortDebugString() << std::endl;
201  assert(a_default_out.SerializeAsString() == a_default.SerializeAsString());
202  }
203  }
204 
205  std::cout << "all tests passed" << std::endl;
206 }
dccl::test
Unit test namespace.
Definition: test.cpp:44
dccl::DefaultIdentifierCodec::size
unsigned size() override
Calculate the size (in bits) of an empty field.
Definition: field_codec_id.cpp:68
dccl::test::UserCustomIdCodec
Definition: test.cpp:37
dccl
Dynamic Compact Control Language namespace.
Definition: any.h:46
dccl::DefaultIdentifierCodec::validate
void validate() override
Validate a field. Use require() inside your overloaded validate() to assert requirements or throw Exc...
Definition: field_codec_id.h:39
dccl::DefaultIdentifierCodec::min_size
unsigned min_size() override
Calculate minimum size of the field in bits.
Definition: field_codec_id.cpp:85
dccl::uint32
google::protobuf::uint32 uint32
an unsigned 32 bit integer
Definition: common.h:56
dccl::Codec
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:62
dccl::DefaultIdentifierCodec::max_size
unsigned max_size() override
Calculate maximum size of the field in bits.
Definition: field_codec_id.cpp:83
dccl::DefaultIdentifierCodec::decode
uint32 decode(Bitset *bits) override
Decode a field. If the field is empty (i.e. was encoded using the zero-argument encode()),...
Definition: field_codec_id.cpp:49
dccl::Logger::connect
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar)
Definition: logger.h:214
dccl::DefaultIdentifierCodec::encode
Bitset encode() override
Encode an empty field.
Definition: field_codec_id.cpp:30
dccl::Bitset
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
Definition: bitset.h:42
dccl::DefaultIdentifierCodec
Provides the default 1 byte or 2 byte DCCL ID codec.
Definition: field_codec_id.h:29
dccl::test::UserCustomIdRAII
Definition: test.cpp:81