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