DCCL v4
field_codec_hash.h
1 // Copyright 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 #ifndef DCCLV4FIELDCODECHASHH
24 #define DCCLV4FIELDCODECHASHH
25 
26 #include "field_codec_default.h"
27 
28 namespace dccl
29 {
30 namespace v4
31 {
32 
34 {
35  public:
36  HashCodec() { this->set_force_use_required(); }
37 
38  private:
39  Bitset encode() override
40  {
41  return this->v4::DefaultNumericFieldCodec<uint32>::encode(masked_hash());
42  }
43 
44  uint32 pre_encode(const uint32& field_value) override { return masked_hash(); }
45  uint32 post_decode(const uint32& wire_value) override
46  {
47  uint32 expected = masked_hash();
48  uint32 received = wire_value;
49 
50  if (expected != received)
51  {
52  std::stringstream ss;
53  ss << "Hash value mismatch. Expected: " << expected << ", received: " << received
54  << ". Ensure both sender and receiver are using identical DCCL definitions";
55 
56  throw(Exception(ss.str(), this->root_descriptor()));
57  }
58  return wire_value;
59  }
60 
61  void validate() override
62  {
63  FieldCodecBase::require(this->min() == 0, "(dccl.field).min must equal 0");
64 
65  uint32 max = static_cast<uint32>(this->max());
66  uint32 max_should_be = (1ull << (ceil_log2(this->max()))) - 1;
67  FieldCodecBase::require(max == max_should_be,
68  "(dccl.field).max must equal be a power of 2 minus 1 "
69  "(e.g. 255, 4294967295, etc.)");
70  FieldCodecBase::require(this->max() <=
71  static_cast<double>(std::numeric_limits<uint32>::max()),
72  "(dccl.field).max must fit in unsigned 32 bits.");
73  }
74 
75  uint32 masked_hash()
76  {
77  std::size_t hash = this->manager().hash(this->root_descriptor());
78  uint32 mask = static_cast<uint32>(this->max());
79  return mask & hash;
80  }
81 };
82 
83 } // namespace v4
84 } // namespace dccl
85 
86 #endif
dccl::v2::DefaultNumericFieldCodec::encode
Bitset encode() override
Encode an empty field.
Definition: field_codec_default.h:163
dccl
Dynamic Compact Control Language namespace.
Definition: any.h:46
dccl::Exception
Exception class for DCCL.
Definition: exception.h:46
dccl::uint32
google::protobuf::uint32 uint32
an unsigned 32 bit integer
Definition: common.h:56
dccl::FieldCodecBase::require
void require(bool b, const std::string &description)
Essentially an assertion to be used in the validate() virtual method.
Definition: field_codec.h:348
dccl::FieldCodecBase::set_force_use_required
void set_force_use_required(bool force_required=true)
Force the codec to always use the "required" field encoding, regardless of the FieldDescriptor settin...
Definition: field_codec.h:122
dccl::ceil_log2
unsigned ceil_log2(dccl::uint64 v)
Definition: binary.h:178
dccl::Bitset
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
Definition: bitset.h:42
dccl::v4::HashCodec
Definition: field_codec_hash.h:33
dccl::v2::DefaultNumericFieldCodec
Provides a basic bounded arbitrary length numeric (double, float, uint32, uint64, int32,...
Definition: field_codec_default.h:51
dccl::FieldCodecBase::hash
virtual std::size_t hash()
Generate a field specific hash to be combined with the descriptor hash.
Definition: field_codec.h:459