DCCL v3
field_codec_presence.h
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24 #ifndef FIELD_CODEC_PRESENCE_20190722H
25 #define FIELD_CODEC_PRESENCE_20190722H
26 
27 #include "dccl/field_codec_typed.h"
28 
29 namespace dccl
30 {
31  namespace v3
32  {
33 
44  template<typename WrappedType>
45  class PresenceBitCodec: public TypedFieldCodec<typename WrappedType::wire_type, typename WrappedType::field_type>
46  {
47 
48  public:
49 
51 
53  typedef WrappedType wrapped_type;
54 
56  typedef typename Base::wire_type wire_type;
57 
59  typedef typename Base::field_type field_type;
60 
61  protected:
62 
64  WrappedType _inner_codec;
65 
66  public:
68  _inner_codec.set_force_use_required(true);
69  }
70 
71  // required when wire_type != field_type
72  virtual wire_type pre_encode(const field_type& field_value)
73  {
74  return _inner_codec.pre_encode(field_value);
75  }
76 
77  // required when wire_type != field_type
78  virtual field_type post_decode(const wire_type& wire_value)
79  {
80  return _inner_codec.post_decode(wire_value);
81  }
82 
84  virtual void validate()
85  {
86  _inner_codec.validate();
87  }
88 
90  virtual Bitset encode()
91  {
92  return Bitset(1, 0); // presence bit == false
93  }
94 
96  virtual Bitset encode(const wire_type& value)
97  {
98  Bitset encoded = _inner_codec.encode(value);
99 
100  if (!this->use_required()) {
101  encoded.push_front(true);
102  }
103  return encoded;
104  }
105 
107  virtual wire_type decode(Bitset* bits)
108  {
109  if (!this->use_required())
110  {
111  // optional field: bits contains only the presence bit
112  bool present = bits->front();
113  if (!present)
114  {
115  throw NullValueException();
116  }
117  // the single bit was the presence bit; consume it and get the rest
118  bits->pop_front();
119  bits->get_more_bits(_inner_codec.size());
120  }
121 
122  return _inner_codec.decode(bits);
123  }
124 
126  virtual unsigned size()
127  {
128  // empty field is always 1 bit (only occurs for optional fields)
129  return 1;
130  }
131 
133  virtual unsigned size(const wire_type& wire_value)
134  {
135  int presence_bits = this->use_required() ? 0 : 1;
136  return presence_bits + _inner_codec.size(wire_value);
137  }
138 
139  virtual unsigned max_size()
140  {
141  if (this->use_required())
142  {
143  // def to "wrapped" codec
144  return _inner_codec.max_size();
145  } else
146  {
147  // optional fields have the extra presence bit
148  return _inner_codec.max_size() + 1;
149  }
150  }
151 
152  virtual unsigned min_size()
153  {
154  if (this->use_required())
155  {
156  // defer to "wrapped" codec
157  return _inner_codec.min_size();
158  } else
159  {
160  // optional fields encode as 1 bit minimum
161  return 1;
162  }
163  }
164 
165  };
166  }
167 }
168 
169 
170 
171 #endif /* FIELD_CODEC_PRESENCE_20190722H */
dccl::v3::PresenceBitCodec::max_size
virtual unsigned max_size()
Calculate maximum size of the field in bits.
Definition: field_codec_presence.h:139
dccl::v3::PresenceBitCodec::encode
virtual Bitset encode(const wire_type &value)
Encodes a non-empty field, adding a 1 bit to the front for optional fields.
Definition: field_codec_presence.h:96
dccl::Bitset::get_more_bits
void get_more_bits(size_type num_bits)
Retrieve more bits from the parent Bitset.
Definition: bitset.h:447
dccl
Dynamic Compact Control Language namespace.
Definition: gen_units_class_plugin.h:49
dccl::v3::PresenceBitCodec::size
virtual unsigned size(const wire_type &wire_value)
Size of a non-empty field; gets size from "wrapped" codec, adds 1 for optional fields.
Definition: field_codec_presence.h:133
dccl::v3::PresenceBitCodec::encode
virtual Bitset encode()
Encodes an empty field as a single 0 bit.
Definition: field_codec_presence.h:90
dccl::v3::PresenceBitCodec::decode
virtual wire_type decode(Bitset *bits)
Decodes a field, first evaluating the presence bit if necessary.
Definition: field_codec_presence.h:107
dccl::v3::PresenceBitCodec::field_type
Base::field_type field_type
The field_type of the "wrapped" codec.
Definition: field_codec_presence.h:59
dccl::v3::PresenceBitCodec::wrapped_type
WrappedType wrapped_type
The codec type of the "wrapped" codec.
Definition: field_codec_presence.h:53
dccl::NullValueException
Exception used to signal null (non-existent) value within field codecs during decode.
Definition: exception.h:40
dccl::Bitset
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy....
Definition: bitset.h:38
dccl::v3::PresenceBitCodec::validate
virtual void validate()
Calls _inner_codec.validate()
Definition: field_codec_presence.h:84
dccl::v3::PresenceBitCodec::_inner_codec
WrappedType _inner_codec
Instance of the "wrapped" codec.
Definition: field_codec_presence.h:64
dccl::TypedFieldCodec
Base class for static-typed (no boost::any) field encoders/decoders. Most single-valued user defined ...
Definition: field_codec_typed.h:82
dccl::v3::PresenceBitCodec
Encodes empty optional fields with a single "presence" bit.
Definition: field_codec_presence.h:45
dccl::FieldCodecBase::use_required
bool use_required()
Whether to use the required or optional encoding.
Definition: field_codec.h:353
dccl::v3::PresenceBitCodec::size
virtual unsigned size()
Size of an empty field (1 bit)
Definition: field_codec_presence.h:126
dccl::v3::PresenceBitCodec::min_size
virtual unsigned min_size()
Calculate minimum size of the field in bits.
Definition: field_codec_presence.h:152
dccl::v3::PresenceBitCodec::wire_type
Base::wire_type wire_type
The wire_type of the "wrapped" codec.
Definition: field_codec_presence.h:56