DCCL v3
field_codec_var_bytes.cpp
1 #include "field_codec_var_bytes.h"
2 #include "dccl/field_codec_manager.h"
3 #include "dccl/codecs3/field_codec_default.h"
4 
5 
6 using namespace dccl::logger;
7 
8 
9 dccl::Bitset dccl::v3::VarBytesCodec::encode()
10 {
11  return dccl::Bitset(min_size());
12 }
13 
14 dccl::Bitset dccl::v3::VarBytesCodec::encode(const std::string& wire_value)
15 {
16  std::string s = wire_value;
17  if(s.size() > dccl_field_options().max_length())
18  {
19  if(this->strict())
20  throw(dccl::OutOfRangeException(std::string("Bytes too long for field: ") + FieldCodecBase::this_field()->DebugString(), this->this_field()));
21 
22  dccl::dlog.is(DEBUG2) && dccl::dlog << "Bytes " << s << " exceeds `dccl.max_length`, truncating" << std::endl;
23  s.resize(dccl_field_options().max_length());
24  }
25 
26  dccl::Bitset value_bits;
27  value_bits.from_byte_string(s);
28 
29  dccl::Bitset length_bits(presence_size() + prefix_size(), s.length());
30 
31  if(!use_required()) // set the presence bit
32  {
33  length_bits <<= 1;
34  length_bits.set(0);
35  }
36 
37  dccl::dlog.is(DEBUG2) && dccl::dlog << "dccl::v3::VarBytesCodec value_bits: " << value_bits << std::endl;
38 
39 
40  dccl::dlog.is(DEBUG2) && dccl::dlog << "dccl::v3::VarBytesCodec length_bits: " << length_bits << std::endl;
41 
42  // adds to MSBs
43  for(int i = 0, n = value_bits.size(); i < n; ++i)
44  length_bits.push_back(value_bits[i]);
45 
46  dccl::dlog.is(DEBUG2) && dccl::dlog << "dccl::v3::VarBytesCodec created: " << length_bits << std::endl;
47 
48  return length_bits;
49 }
50 
51 std::string dccl::v3::VarBytesCodec::decode(dccl::Bitset* bits)
52 {
53  if(!use_required())
54  {
55  if(bits->to_ulong() == 0)
56  {
58  }
59  else
60  {
61  bits->get_more_bits(prefix_size());
62  (*bits) >>= 1;
63  }
64  }
65 
66 
67  unsigned value_length = bits->to_ulong();
68  unsigned header_length = presence_size() + prefix_size();
69 
70  dccl::dlog.is(DEBUG2) && dccl::dlog << "Length of string is = " << value_length << std::endl;
71 
72  dccl::dlog.is(DEBUG2) && dccl::dlog << "bits before get_more_bits " << *bits << std::endl;
73 
74  // grabs more bits to add to the MSBs of `bits`
75  bits->get_more_bits(value_length*dccl::BITS_IN_BYTE);
76 
77  dccl::dlog.is(DEBUG2) && dccl::dlog << "bits after get_more_bits " << *bits << std::endl;
78  dccl::Bitset string_body_bits = *bits;
79  string_body_bits >>= header_length;
80  string_body_bits.resize(bits->size() - header_length);
81 
82  dccl::dlog.is(DEBUG2) && dccl::dlog << "string_body_bits " << string_body_bits << std::endl;
83 
84 
85  return string_body_bits.to_byte_string();
86 }
87 
88 unsigned dccl::v3::VarBytesCodec::size()
89 {
90  return min_size();
91 }
92 
93 unsigned dccl::v3::VarBytesCodec::size(const std::string& wire_value)
94 {
95  return std::min(presence_size() + prefix_size() + static_cast<unsigned>(wire_value.length()*dccl::BITS_IN_BYTE), max_size());
96 }
97 
98 
99 unsigned dccl::v3::VarBytesCodec::max_size()
100 {
101  return presence_size() + prefix_size() + dccl_field_options().max_length() * dccl::BITS_IN_BYTE;
102 }
103 
104 unsigned dccl::v3::VarBytesCodec::min_size()
105 {
106  if(use_required())
107  return prefix_size();
108  else
109  return presence_size();
110 }
111 
112 
113 void dccl::v3::VarBytesCodec::validate()
114 {
115  require(dccl_field_options().has_max_length(), "missing (dccl.field).max_length");
116 }
unsigned long to_ulong() const
Returns the value of the Bitset as an unsigned long integer. Equivalent to to<unsigned long>()...
Definition: bitset.h:284
Exception used to signal null (non-existent) value within field codecs during decode.
Definition: exception.h:40
Bitset & set(size_type n, bool val=true)
Set a bit to a given value.
Definition: bitset.h:176
const google::protobuf::FieldDescriptor * this_field() const
Returns the FieldDescriptor (field schema meta-data) for this field.
Definition: field_codec.h:75
void get_more_bits(size_type num_bits)
Retrieve more bits from the parent Bitset.
Definition: bitset.h:447
bool is(logger::Verbosity verbosity, logger::Group group=logger::GENERAL)
Indicates the verbosity of the Logger until the next std::flush or std::endl. The boolean return is u...
Definition: logger.h:145
void from_byte_string(const std::string &s)
Sets the value of the Bitset to the contents of a byte string, where each character represents 8 bits...
Definition: bitset.h:348
std::string to_byte_string()
Returns the value of the Bitset to a byte string, where each character represents 8 bits of the Bitse...
Definition: bitset.h:310
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy...
Definition: bitset.h:38