28#include "../../codec.h"
31#include "../../binary.h"
34using dccl::operator<<;
45 unsigned size()
override {
return (
part() == dccl::HEAD) ? 0 : A_SIZE + B_SIZE; }
50 if (
part() == dccl::HEAD)
56 Bitset a(A_SIZE,
static_cast<unsigned long>(msg.a()));
57 Bitset b(B_SIZE,
static_cast<unsigned long>(msg.b()));
59 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"a: " << a << std::endl;
60 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"b: " << b << std::endl;
67 CustomMsg decode(
Bitset* bits)
override
69 if (
part() == dccl::HEAD)
105 REPEAT_STORAGE_BITS = 4
109 MAX_REPEAT_SIZE = 1 << REPEAT_STORAGE_BITS
116 Bitset encode_repeated(
const std::vector<dccl::int32>& wire_values)
override
120 static_cast<int>(wire_values.size()) > max_repeat() ? max_repeat() : wire_values.size();
122 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"repeat size is " << repeat_size << std::endl;
124 for (
int i = 0, n = repeat_size; i < n; ++i)
128 value_bits.
append(
Bitset(singular_size(),
static_cast<unsigned long>(wire_value)));
131 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog << value_bits << std::endl;
132 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
Bitset(REPEAT_STORAGE_BITS, repeat_size) << std::endl;
133 Bitset out(REPEAT_STORAGE_BITS, repeat_size);
138 std::vector<dccl::int32> decode_repeated(
Bitset* bits)
override
141 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"repeat size is " << repeat_size << std::endl;
145 Bitset value_bits = *bits;
146 value_bits >>= REPEAT_STORAGE_BITS;
148 std::vector<dccl::int32> out;
149 for (
int i = 0; i < repeat_size; ++i)
153 out.push_back(value);
154 value_bits >>= singular_size();
159 unsigned size_repeated(
const std::vector<dccl::int32>& field_values)
override
161 return REPEAT_STORAGE_BITS + field_values.size() * singular_size();
164 unsigned singular_size() {
return dccl::ceil_log2((max() - min()) + 1); }
168 return REPEAT_STORAGE_BITS + max_repeat() * singular_size();
176 "missing (dccl.field).min");
178 "missing (dccl.field).max");
181 "(dccl.field).max_repeat must be less than " +
182 std::to_string(
static_cast<int>(MAX_REPEAT_SIZE)));
189int main(
int argc,
char* argv[])
191 bool verbose =
false;
192 for (
int i = 1; i < argc; ++i)
194 if (argv[i] && argv[i][0] ==
'-' && argv[i][1] ==
'v' && argv[i][2] ==
'\0')
198 dccl::dlog.connect(verbose ? dccl::logger::ALL : dccl::logger::WARN_PLUS, &std::cerr);
204 codec.set_crypto_passphrase(
"my_passphrase!");
211 if (dccl::dlog.is(dccl::logger::INFO))
212 codec.
info(msg_in1.GetDescriptor(), &dccl::dlog);
215 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"Message in:\n" << msg_in1.DebugString() << std::endl;
216 codec.load(msg_in1.GetDescriptor());
217 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"Try encode..." << std::endl;
219 codec.encode(&bytes1, msg_in1);
220 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"... got bytes (hex): " <<
dccl::hex_encode(bytes1) << std::endl;
221 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"Try decode..." << std::endl;
222 std::shared_ptr<google::protobuf::Message> msg_out1 =
223 codec.decode<std::shared_ptr<google::protobuf::Message>>(bytes1);
224 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"... got Message out:\n" << msg_out1->DebugString() << std::endl;
225 assert(msg_in1.SerializeAsString() == msg_out1->SerializeAsString());
227 CustomMsg2 msg_in2, msg_out2;
229 msg_in2.mutable_msg()->CopyFrom(msg_in1);
233 if (dccl::dlog.is(dccl::logger::INFO))
235 codec.info(msg_in2.GetDescriptor(), &dccl::dlog);
237 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"Message in:\n" << msg_in2.DebugString() << std::endl;
238 codec.load(msg_in2.GetDescriptor());
239 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"Try encode..." << std::endl;
241 codec.encode(&bytes2, msg_in2);
242 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"... got bytes (hex): " <<
dccl::hex_encode(bytes2) << std::endl;
243 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"Try decode..." << std::endl;
244 codec.decode(bytes2, &msg_out2);
245 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"... got Message out:\n" << msg_out2.DebugString() << std::endl;
246 assert(msg_in2.SerializeAsString() == msg_out2.SerializeAsString());
248 dccl::dlog.is(dccl::logger::INFO) && dccl::dlog <<
"all tests passed" << std::endl;
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
void get_more_bits(size_type num_bits)
Retrieve more bits from the parent Bitset.
Bitset & append(const Bitset &bits)
Adds the bitset to the big end.
unsigned long to_ulong() const
Returns the value of the Bitset as an unsigned long integer. Equivalent to to<unsigned long>().
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
virtual std::string info()
Write field specific information (in addition to general information such as sizes that are automatic...
MessagePart part()
the part of the message currently being encoded (head or body)
void require(bool b, const std::string &description)
Essentially an assertion to be used in the validate() virtual method.
virtual void validate()
Validate a field. Use require() inside your overloaded validate() to assert requirements or throw Exc...
dccl::DCCLFieldOptions dccl_field_options() const
Get the DCCL field option extension value for the current field.
std::enable_if< std::is_base_of< google::protobuf::Message, typenameCodec::wire_type >::value &&!std::is_same< google::protobuf::Message, typenameCodec::wire_type >::value, void >::type add(const std::string &name)
Add a new field codec (used for codecs operating on statically generated Protobuf messages,...
Exception used to signal null (non-existent) value within field codecs during decode.
Base class for "repeated" (multiple value) static-typed (no dccl::any) field encoders/decoders....
unsigned max_size_repeated() override=0
unsigned min_size_repeated() override=0
virtual Bitset encode()=0
Base class for static-typed field encoders/decoders that use a fixed number of bits on the wire regar...
unsigned size() override=0
Dynamic Compact Control Language namespace.
google::protobuf::int32 int32
a signed 32 bit integer
void hex_encode(CharIterator begin, CharIterator end, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of begin is written to index...
unsigned ceil_log2(dccl::uint64 v)