additional-description.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2020 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
26 
27 namespace ndn {
28 namespace security {
29 inline namespace v2 {
30 
31 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<AdditionalDescription>));
32 BOOST_CONCEPT_ASSERT((WireEncodable<AdditionalDescription>));
34 BOOST_CONCEPT_ASSERT((WireDecodable<AdditionalDescription>));
35 static_assert(std::is_base_of<tlv::Error, AdditionalDescription::Error>::value,
36  "AdditionalDescription::Error must inherit from tlv::Error");
37 
38 static const size_t KEY_OFFSET = 0;
39 static const size_t VALUE_OFFSET = 1;
40 
42 {
43  wireDecode(block);
44 }
45 
46 const std::string&
47 AdditionalDescription::get(const std::string& key) const
48 {
49  auto it = m_info.find(key);
50  if (it == m_info.end())
51  NDN_THROW(Error("Entry does not exist for key (" + key + ")"));
52 
53  return it->second;
54 }
55 
56 void
57 AdditionalDescription::set(const std::string& key, const std::string& value)
58 {
59  m_info[key] = value;
60 }
61 
62 bool
63 AdditionalDescription::has(const std::string& key) const
64 {
65  return (m_info.find(key) != m_info.end());
66 }
67 
70 {
71  return m_info.begin();
72 }
73 
76 {
77  return m_info.end();
78 }
79 
82 {
83  return m_info.begin();
84 }
85 
88 {
89  return m_info.end();
90 }
91 
92 template<encoding::Tag TAG>
93 size_t
95 {
96  size_t totalLength = 0;
97 
98  for (auto it = m_info.rbegin(); it != m_info.rend(); it++) {
99  size_t entryLength = 0;
100  entryLength += prependStringBlock(encoder, tlv::DescriptionValue, it->second);
101  entryLength += prependStringBlock(encoder, tlv::DescriptionKey, it->first);
102  entryLength += encoder.prependVarNumber(entryLength);
103  entryLength += encoder.prependVarNumber(tlv::DescriptionEntry);
104 
105  totalLength += entryLength;
106  }
107 
108  totalLength += encoder.prependVarNumber(totalLength);
109  totalLength += encoder.prependVarNumber(tlv::AdditionalDescription);
110  return totalLength;
111 }
112 
114 
115 const Block&
117 {
118  if (m_wire.hasWire())
119  return m_wire;
120 
121  EncodingEstimator estimator;
122  size_t estimatedSize = wireEncode(estimator);
123 
124  EncodingBuffer buffer(estimatedSize, 0);
125  wireEncode(buffer);
126 
127  m_wire = buffer.block();
128  m_wire.parse();
129 
130  return m_wire;
131 }
132 
133 void
135 {
136  if (!wire.hasWire()) {
137  NDN_THROW(Error("The supplied block does not contain wire format"));
138  }
139 
140  m_wire = wire;
141  m_wire.parse();
142 
143  if (m_wire.type() != tlv::AdditionalDescription)
144  NDN_THROW(Error("AdditionalDescription", m_wire.type()));
145 
146  auto it = m_wire.elements_begin();
147  while (it != m_wire.elements_end()) {
148  const Block& entry = *it;
149  entry.parse();
150 
151  if (entry.type() != tlv::DescriptionEntry)
152  NDN_THROW(Error("DescriptionEntry", entry.type()));
153 
154  if (entry.elements_size() != 2)
155  NDN_THROW(Error("DescriptionEntry does not have two sub-TLVs"));
156 
157  if (entry.elements()[KEY_OFFSET].type() != tlv::DescriptionKey ||
158  entry.elements()[VALUE_OFFSET].type() != tlv::DescriptionValue)
159  NDN_THROW(Error("Invalid DescriptionKey or DescriptionValue field"));
160 
161  m_info[readString(entry.elements()[KEY_OFFSET])] = readString(entry.elements()[VALUE_OFFSET]);
162  it++;
163  }
164 }
165 
166 std::ostream&
167 operator<<(std::ostream& os, const AdditionalDescription& desc)
168 {
169  os << "[";
170 
171  auto join = make_ostream_joiner(os, ", ");
172  for (const auto& entry : desc) {
173  join = "(" + entry.first + ":" + entry.second + ")";
174  }
175 
176  return os << "]";
177 }
178 
179 } // inline namespace v2
180 } // namespace security
181 } // namespace ndn
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
element_const_iterator elements_begin() const noexcept
Equivalent to elements().begin().
Definition: block.hpp:435
size_t elements_size() const noexcept
Equivalent to elements().size().
Definition: block.hpp:453
const element_container & elements() const noexcept
Get container of sub-elements.
Definition: block.hpp:426
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
Definition: block.hpp:444
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:221
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:277
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:324
A concept check for TLV abstraction with a wireDecode(Block) method and constructible from Block.
Definition: concepts.hpp:81
A concept check for TLV abstraction with a wireEncode(EncodingBuffer) method.
Definition: concepts.hpp:61
A concept check for TLV abstraction with a wireEncode() method.
Definition: concepts.hpp:45
Represents an AdditionalDescription TLV element.
std::map< std::string, std::string >::const_iterator const_iterator
std::map< std::string, std::string >::iterator iterator
const Block & wireEncode() const
Encode ValidityPeriod into TLV block.
void set(const std::string &key, const std::string &value)
const std::string & get(const std::string &key) const
bool has(const std::string &key) const
void wireDecode(const Block &wire)
Decode ValidityPeriod from TLV block.
AdditionalDescription()=default
Create an empty AdditionalDescription.
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW(e)
Definition: exception.hpp:61
EncodingImpl< EstimatorTag > EncodingEstimator
size_t prependStringBlock(EncodingImpl< TAG > &encoder, uint32_t type, const std::string &value)
Prepend a TLV element containing a string.
std::string readString(const Block &block)
Read TLV-VALUE of a TLV element as a string.
EncodingImpl< EncoderTag > EncodingBuffer
std::ostream & operator<<(std::ostream &os, const AdditionalDescription &desc)
@ DescriptionValue
Definition: tlv.hpp:113
@ DescriptionKey
Definition: tlv.hpp:112
@ AdditionalDescription
Definition: tlv.hpp:110
@ DescriptionEntry
Definition: tlv.hpp:111
Definition: data.cpp:25
ostream_joiner< std::decay_t< DelimT >, CharT, Traits > make_ostream_joiner(std::basic_ostream< CharT, Traits > &os, DelimT &&delimiter)
Backport of ostream_joiner from the Library Fundamentals v2 TS.