NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
data.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 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 
22 #include "ndn-cxx/data.hpp"
24 #include "ndn-cxx/util/sha256.hpp"
25 
26 namespace ndn {
27 
28 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Data>));
29 BOOST_CONCEPT_ASSERT((WireEncodable<Data>));
30 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Data>));
31 BOOST_CONCEPT_ASSERT((WireDecodable<Data>));
32 static_assert(std::is_base_of<tlv::Error, Data::Error>::value,
33  "Data::Error must inherit from tlv::Error");
34 
36  : m_name(name)
37  , m_content(tlv::Content)
38 {
39 }
40 
41 Data::Data(const Block& wire)
42 {
43  wireDecode(wire);
44 }
45 
46 template<encoding::Tag TAG>
47 size_t
48 Data::wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly) const
49 {
50  // Data ::= DATA-TLV TLV-LENGTH
51  // Name
52  // MetaInfo?
53  // Content?
54  // SignatureInfo
55  // SignatureValue
56 
57  size_t totalLength = 0;
58 
59  // SignatureValue
60  if (!wantUnsignedPortionOnly) {
61  if (!m_signature) {
62  NDN_THROW(Error("Requested wire format, but Data has not been signed"));
63  }
64  totalLength += encoder.prependBlock(m_signature.getValue());
65  }
66 
67  // SignatureInfo
68  totalLength += encoder.prependBlock(m_signature.getInfo());
69 
70  // Content
71  totalLength += encoder.prependBlock(getContent());
72 
73  // MetaInfo
74  totalLength += getMetaInfo().wireEncode(encoder);
75 
76  // Name
77  totalLength += getName().wireEncode(encoder);
78 
79  if (!wantUnsignedPortionOnly) {
80  totalLength += encoder.prependVarNumber(totalLength);
81  totalLength += encoder.prependVarNumber(tlv::Data);
82  }
83  return totalLength;
84 }
85 
86 template size_t
87 Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;
88 
89 template size_t
90 Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
91 
92 const Block&
93 Data::wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const
94 {
95  size_t totalLength = encoder.size();
96  totalLength += encoder.appendBlock(signatureValue);
97 
98  encoder.prependVarNumber(totalLength);
99  encoder.prependVarNumber(tlv::Data);
100 
101  const_cast<Data*>(this)->wireDecode(encoder.block());
102  return m_wire;
103 }
104 
105 const Block&
107 {
108  if (m_wire.hasWire())
109  return m_wire;
110 
111  EncodingEstimator estimator;
112  size_t estimatedSize = wireEncode(estimator);
113 
114  EncodingBuffer buffer(estimatedSize, 0);
115  wireEncode(buffer);
116 
117  const_cast<Data*>(this)->wireDecode(buffer.block());
118  return m_wire;
119 }
120 
121 void
123 {
124  // Data ::= DATA-TLV TLV-LENGTH
125  // Name
126  // MetaInfo?
127  // Content?
128  // SignatureInfo
129  // SignatureValue
130 
131  m_wire = wire;
132  m_wire.parse();
133 
134  auto element = m_wire.elements_begin();
135  if (element == m_wire.elements_end() || element->type() != tlv::Name) {
136  NDN_THROW(Error("Name element is missing or out of order"));
137  }
138  m_name.wireDecode(*element);
139  int lastElement = 1; // last recognized element index, in spec order
140 
141  m_metaInfo = MetaInfo();
142  m_content = Block(tlv::Content);
143  m_signature = Signature();
144  m_fullName.clear();
145 
146  for (++element; element != m_wire.elements_end(); ++element) {
147  switch (element->type()) {
148  case tlv::MetaInfo: {
149  if (lastElement >= 2) {
150  NDN_THROW(Error("MetaInfo element is out of order"));
151  }
152  m_metaInfo.wireDecode(*element);
153  lastElement = 2;
154  break;
155  }
156  case tlv::Content: {
157  if (lastElement >= 3) {
158  NDN_THROW(Error("Content element is out of order"));
159  }
160  m_content = *element;
161  lastElement = 3;
162  break;
163  }
164  case tlv::SignatureInfo: {
165  if (lastElement >= 4) {
166  NDN_THROW(Error("SignatureInfo element is out of order"));
167  }
168  m_signature.setInfo(*element);
169  lastElement = 4;
170  break;
171  }
172  case tlv::SignatureValue: {
173  if (lastElement >= 5) {
174  NDN_THROW(Error("SignatureValue element is out of order"));
175  }
176  m_signature.setValue(*element);
177  lastElement = 5;
178  break;
179  }
180  default: {
181  if (tlv::isCriticalType(element->type())) {
182  NDN_THROW(Error("unrecognized element of critical type " + to_string(element->type())));
183  }
184  break;
185  }
186  }
187  }
188 
189  if (!m_signature) {
190  NDN_THROW(Error("SignatureInfo element is missing"));
191  }
192 }
193 
194 const Name&
196 {
197  if (m_fullName.empty()) {
198  if (!m_wire.hasWire()) {
199  NDN_THROW(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
200  }
201  m_fullName = m_name;
202  m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire.wire(), m_wire.size()));
203  }
204 
205  return m_fullName;
206 }
207 
208 void
210 {
211  m_wire.reset();
212  m_fullName.clear();
213 }
214 
215 Data&
217 {
218  resetWire();
219  m_name = name;
220  return *this;
221 }
222 
223 Data&
224 Data::setMetaInfo(const MetaInfo& metaInfo)
225 {
226  resetWire();
227  m_metaInfo = metaInfo;
228  return *this;
229 }
230 
231 const Block&
233 {
234  if (!m_content.hasWire()) {
235  const_cast<Block&>(m_content).encode();
236  }
237  return m_content;
238 }
239 
240 Data&
241 Data::setContent(const Block& block)
242 {
243  resetWire();
244 
245  if (block.type() == tlv::Content) {
246  m_content = block;
247  }
248  else {
249  m_content = Block(tlv::Content, block);
250  }
251 
252  return *this;
253 }
254 
255 Data&
256 Data::setContent(const uint8_t* value, size_t valueSize)
257 {
258  resetWire();
259  m_content = makeBinaryBlock(tlv::Content, value, valueSize);
260  return *this;
261 }
262 
263 Data&
265 {
266  resetWire();
267  m_content = Block(tlv::Content, std::move(value));
268  return *this;
269 }
270 
271 Data&
272 Data::setSignature(const Signature& signature)
273 {
274  resetWire();
275  m_signature = signature;
276  return *this;
277 }
278 
279 Data&
281 {
282  resetWire();
283  m_signature.setValue(value);
284  return *this;
285 }
286 
287 Data&
288 Data::setContentType(uint32_t type)
289 {
290  resetWire();
291  m_metaInfo.setType(type);
292  return *this;
293 }
294 
295 Data&
296 Data::setFreshnessPeriod(time::milliseconds freshnessPeriod)
297 {
298  resetWire();
299  m_metaInfo.setFreshnessPeriod(freshnessPeriod);
300  return *this;
301 }
302 
303 Data&
304 Data::setFinalBlock(optional<name::Component> finalBlockId)
305 {
306  resetWire();
307  m_metaInfo.setFinalBlock(std::move(finalBlockId));
308  return *this;
309 }
310 
311 bool
312 operator==(const Data& lhs, const Data& rhs)
313 {
314  return lhs.getName() == rhs.getName() &&
315  lhs.getMetaInfo().wireEncode() == rhs.getMetaInfo().wireEncode() &&
316  lhs.getContent() == rhs.getContent() &&
318  lhs.getSignature().getValue() == rhs.getSignature().getValue();
319 }
320 
321 std::ostream&
322 operator<<(std::ostream& os, const Data& data)
323 {
324  os << "Name: " << data.getName() << "\n";
325  os << "MetaInfo: " << data.getMetaInfo() << "\n";
326  os << "Content: (size: " << data.getContent().value_size() << ")\n";
327  os << "Signature: (type: " << data.getSignature().getType()
328  << ", value_length: "<< data.getSignature().getValue().value_size() << ")";
329  os << std::endl;
330 
331  return os;
332 }
333 
334 } // namespace ndn
ndn::MetaInfo::setFreshnessPeriod
MetaInfo & setFreshnessPeriod(time::milliseconds freshnessPeriod)
set FreshnessPeriod
Definition: meta-info.cpp:54
ndn::Signature::getInfo
const Block & getInfo() const
Get SignatureInfo as wire format.
Definition: signature.hpp:73
ndn::Signature::getValue
const Block & getValue() const
Get SignatureValue.
Definition: signature.hpp:95
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
ndn::Block::value_size
size_t value_size() const noexcept
Return the size of TLV-VALUE, aka TLV-LENGTH.
Definition: block.cpp:308
ndn::Data::setContentType
Data & setContentType(uint32_t type)
Definition: data.cpp:288
ndn::Signature::setValue
void setValue(const Block &value)
Set SignatureValue.
Definition: signature.cpp:58
ndn::Data::setMetaInfo
Data & setMetaInfo(const MetaInfo &metaInfo)
Set MetaInfo.
Definition: data.cpp:224
ndn::Block::elements_begin
element_const_iterator elements_begin() const
Equivalent to elements().begin()
Definition: block.hpp:399
ndn::Data::resetWire
void resetWire()
Clear wire encoding and cached FullName.
Definition: data.cpp:209
ndn::MetaInfo::wireDecode
void wireDecode(const Block &wire)
Definition: meta-info.cpp:179
ndn::MetaInfo::setType
MetaInfo & setType(uint32_t type)
set ContentType
Definition: meta-info.cpp:46
ndn::Data::getContent
const Block & getContent() const
Get Content.
Definition: data.cpp:232
ndn::Name::empty
NDN_CXX_NODISCARD bool empty() const
Checks if the name is empty, i.e.
Definition: name.hpp:145
ndn::Data::setName
Data & setName(const Name &name)
Set name.
Definition: data.cpp:216
ndn::Data::getName
const Name & getName() const
Get name.
Definition: data.hpp:124
ndn::Block::reset
void reset() noexcept
Reset the Block to a default-constructed state.
Definition: block.cpp:250
ndn::MetaInfo
A MetaInfo holds the meta info which is signed inside the data packet.
Definition: meta-info.hpp:59
ndn::WireDecodable
a concept check for TLV abstraction with .wireDecode method and constructible from Block
Definition: concepts.hpp:81
ndn::tlv::SignatureValue
@ SignatureValue
Definition: tlv.hpp:81
ndn::encoding::EncodingEstimator
EncodingImpl< EstimatorTag > EncodingEstimator
Definition: encoding-buffer-fwd.hpp:39
ndn::Name
Represents an absolute name.
Definition: name.hpp:44
ndn::Name::wireDecode
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition: name.cpp:150
ndn::Signature::getSignatureInfo
const SignatureInfo & getSignatureInfo() const
Get SignatureInfo.
Definition: signature.hpp:65
ndn::Block::type
uint32_t type() const
Return the TLV-TYPE of the Block.
Definition: block.hpp:274
ndn::WireEncodable
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:45
ndn::Data::wireDecode
void wireDecode(const Block &wire)
Decode from wire in NDN Packet Format v0.2 or v0.3.
Definition: data.cpp:122
ndn::Signature::setInfo
void setInfo(const Block &info)
Decode SignatureInfo from wire format.
Definition: signature.cpp:52
ndn::Name::wireEncode
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:117
ndn::MetaInfo::setFinalBlock
MetaInfo & setFinalBlock(optional< name::Component > finalBlockId)
set FinalBlockId
Definition: meta-info.cpp:65
NDN_THROW
#define NDN_THROW(e)
Definition: exception.hpp:61
ndn::Signature
Holds SignatureInfo and SignatureValue in a Data packet.
Definition: signature.hpp:38
ndn::Data::setContent
Data & setContent(const Block &block)
Set Content from a block.
Definition: data.cpp:241
ndn::Data::setSignatureValue
Data & setSignatureValue(const Block &value)
Set SignatureValue.
Definition: data.cpp:280
ndn::Data::setFreshnessPeriod
Data & setFreshnessPeriod(time::milliseconds freshnessPeriod)
Definition: data.cpp:296
ndn::Data::Error
Definition: data.hpp:39
ndn::tlv::Name
@ Name
Definition: tlv.hpp:67
ndn::util::Sha256::computeDigest
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
Definition: sha256.cpp:63
ndn::Block::parse
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:325
ndn::Data
Represents a Data packet.
Definition: data.hpp:36
ndn::Data::setSignature
Data & setSignature(const Signature &signature)
Set Signature.
Definition: data.cpp:272
ndn::tlv::Data
@ Data
Definition: tlv.hpp:66
ndn::encoding::EncodingImpl
Definition: encoding-buffer-fwd.hpp:36
data.hpp
block-helpers.hpp
ndn::Data::setFinalBlock
Data & setFinalBlock(optional< name::Component > finalBlockId)
Definition: data.cpp:304
ndn::tlv::isCriticalType
constexpr bool isCriticalType(uint32_t type)
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
Definition: tlv.hpp:174
ndn::Block
Represents a TLV element of NDN packet format.
Definition: block.hpp:43
ndn::Block::size
size_t size() const
Return the size of the encoded wire, i.e.
Definition: block.cpp:290
ndn::to_string
std::string to_string(const T &val)
Definition: backports.hpp:102
ndn::Block::elements_end
element_const_iterator elements_end() const
Equivalent to elements().end()
Definition: block.hpp:407
ndn::operator==
bool operator==(const Data &lhs, const Data &rhs)
Definition: data.cpp:312
ndn::operator<<
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:322
ndn::name
Definition: name-component-types.hpp:33
ndn::Signature::getType
tlv::SignatureTypeValue getType() const
Get SignatureType.
Definition: signature.cpp:43
ndn::Data::wireEncode
const Block & wireEncode() const
Encode to a Block.
Definition: data.cpp:106
ndn::Name::clear
void clear()
Remove all components.
Definition: name.cpp:280
ndn::Block::hasWire
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:230
ndn::Data::getMetaInfo
const MetaInfo & getMetaInfo() const
Get MetaInfo.
Definition: data.hpp:138
ndn::Data::Data
Data(const Name &name=Name())
Construct an unsigned Data packet with given name and empty Content.
Definition: data.cpp:35
ndn::Data::getFullName
const Name & getFullName() const
Get full name including implicit digest.
Definition: data.cpp:195
ndn::Block::wire
const uint8_t * wire() const
Return a raw pointer to the beginning of the encoded wire.
Definition: block.cpp:281
ndn::tlv::MetaInfo
@ MetaInfo
Definition: tlv.hpp:78
ndn::MetaInfo::wireEncode
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Definition: meta-info.cpp:125
ndn::Name::appendImplicitSha256Digest
Name & appendImplicitSha256Digest(ConstBufferPtr digest)
Append an ImplicitSha256Digest component.
Definition: name.hpp:460
ndn::encoding::makeBinaryBlock
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
Definition: block-helpers.cpp:181
ndn::ConstBufferPtr
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:126
ndn::WireEncodableWithEncodingBuffer
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:61
ndn
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-strategy-choice-helper.hpp:34
ndn::encoding::EncodingBuffer
EncodingImpl< EncoderTag > EncodingBuffer
Definition: encoding-buffer-fwd.hpp:38
ndn::tlv::Content
@ Content
Definition: tlv.hpp:79
ndn::tlv::SignatureInfo
@ SignatureInfo
Definition: tlv.hpp:80
ndn::Data::getSignature
const Signature & getSignature() const
Get Signature.
Definition: data.hpp:185
sha256.hpp