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-2017 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 "data.hpp"
24 #include "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  BOOST_THROW_EXCEPTION(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  m_fullName.clear();
125  m_wire = wire;
126  m_wire.parse();
127 
128  // Name
129  m_name.wireDecode(m_wire.get(tlv::Name));
130 
131  // MetaInfo
132  m_metaInfo.wireDecode(m_wire.get(tlv::MetaInfo));
133 
134  // Content
135  m_content = m_wire.get(tlv::Content);
136 
137  // SignatureInfo
138  m_signature.setInfo(m_wire.get(tlv::SignatureInfo));
139 
140  // SignatureValue
142  if (val != m_wire.elements_end()) {
143  m_signature.setValue(*val);
144  }
145 }
146 
147 const Name&
149 {
150  if (m_fullName.empty()) {
151  if (!m_wire.hasWire()) {
152  BOOST_THROW_EXCEPTION(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
153  }
154  m_fullName = m_name;
155  m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire.wire(), m_wire.size()));
156  }
157 
158  return m_fullName;
159 }
160 
161 void
163 {
164  m_wire.reset();
165  m_fullName.clear();
166 }
167 
168 Data&
170 {
171  resetWire();
172  m_name = name;
173  return *this;
174 }
175 
176 Data&
177 Data::setMetaInfo(const MetaInfo& metaInfo)
178 {
179  resetWire();
180  m_metaInfo = metaInfo;
181  return *this;
182 }
183 
184 const Block&
186 {
187  if (!m_content.hasWire()) {
188  const_cast<Block&>(m_content).encode();
189  }
190  return m_content;
191 }
192 
193 Data&
194 Data::setContent(const Block& block)
195 {
196  resetWire();
197 
198  if (block.type() == tlv::Content) {
199  m_content = block;
200  }
201  else {
202  m_content = Block(tlv::Content, block);
203  }
204 
205  return *this;
206 }
207 
208 Data&
209 Data::setContent(const uint8_t* value, size_t valueSize)
210 {
211  resetWire();
212  m_content = makeBinaryBlock(tlv::Content, value, valueSize);
213  return *this;
214 }
215 
216 Data&
218 {
219  resetWire();
220  m_content = Block(tlv::Content, value);
221  return *this;
222 }
223 
224 Data&
225 Data::setSignature(const Signature& signature)
226 {
227  resetWire();
228  m_signature = signature;
229  return *this;
230 }
231 
232 Data&
234 {
235  resetWire();
236  m_signature.setValue(value);
237  return *this;
238 }
239 
240 Data&
241 Data::setContentType(uint32_t type)
242 {
243  resetWire();
244  m_metaInfo.setType(type);
245  return *this;
246 }
247 
248 Data&
249 Data::setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
250 {
251  resetWire();
252  m_metaInfo.setFreshnessPeriod(freshnessPeriod);
253  return *this;
254 }
255 
256 Data&
258 {
259  resetWire();
260  m_metaInfo.setFinalBlockId(finalBlockId);
261  return *this;
262 }
263 
264 bool
265 operator==(const Data& lhs, const Data& rhs)
266 {
267  return lhs.getName() == rhs.getName() &&
268  lhs.getMetaInfo() == rhs.getMetaInfo() &&
269  lhs.getContent() == rhs.getContent() &&
270  lhs.getSignature() == rhs.getSignature();
271 }
272 
273 std::ostream&
274 operator<<(std::ostream& os, const Data& data)
275 {
276  os << "Name: " << data.getName() << "\n";
277  os << "MetaInfo: " << data.getMetaInfo() << "\n";
278  os << "Content: (size: " << data.getContent().value_size() << ")\n";
279  os << "Signature: (type: " << data.getSignature().getType()
280  << ", value_length: "<< data.getSignature().getValue().value_size() << ")";
281  os << std::endl;
282 
283  return os;
284 }
285 
286 } // namespace ndn
const Block & wireEncode() const
Encode to a wire format.
Definition: data.cpp:106
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:251
Data & setContentType(uint32_t type)
Definition: data.cpp:241
Copyright (c) 2011-2015 Regents of the University of California.
const Name & getName() const
Get name.
Definition: data.hpp:121
void wireDecode(const Block &wire)
Decode from the wire format.
Definition: data.cpp:122
const Block & getContent() const
Get Content.
Definition: data.cpp:185
Data & setSignature(const Signature &signature)
Set Signature.
Definition: data.cpp:225
Data & setName(const Name &name)
Set name.
Definition: data.cpp:169
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
Definition: block.cpp:318
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:274
void setInfo(const Block &info)
Decode SignatureInfo from wire format.
Definition: signature.cpp:53
element_container::const_iterator element_const_iterator
Definition: block.hpp:47
Data(const Name &name=Name())
Create a new Data with the given name and empty Content.
Definition: data.cpp:35
Data & setContent(const Block &block)
Set Content from a block.
Definition: data.cpp:194
const uint8_t * wire() const
Get pointer to encoded wire.
Definition: block.cpp:291
void parse() const
Parse TLV-VALUE into sub elements.
Definition: block.cpp:335
void resetWire()
Clear wire encoding and cached FullName.
Definition: data.cpp:162
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
MetaInfo & setFreshnessPeriod(time::milliseconds freshnessPeriod)
set FreshnessPeriod
Definition: meta-info.cpp:55
Data & setFreshnessPeriod(const time::milliseconds &freshnessPeriod)
Definition: data.cpp:249
MetaInfo & setFinalBlockId(const name::Component &finalBlockId)
Definition: meta-info.cpp:66
tlv::SignatureTypeValue getType() const
Get SignatureType.
Definition: signature.cpp:44
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:60
size_t size() const
Get size of encoded wire, including Type-Length-Value.
Definition: block.cpp:300
element_const_iterator elements_end() const
Equivalent to elements().end()
Definition: block.hpp:363
Data & setSignatureValue(const Block &value)
Set SignatureValue.
Definition: data.cpp:233
const Signature & getSignature() const
Get Signature.
Definition: data.hpp:182
MetaInfo & setType(uint32_t type)
set ContentType
Definition: meta-info.cpp:47
const Block & get(uint32_t type) const
Get the first sub element of specified TLV-TYPE.
Definition: block.cpp:417
element_const_iterator find(uint32_t type) const
Find the first sub element of specified TLV-TYPE.
Definition: block.cpp:429
void setValue(const Block &value)
Set SignatureValue.
Definition: signature.cpp:59
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
const Block & getInfo() const
Get SignatureInfo as wire format.
Definition: signature.hpp:77
const Block & getValue() const
Get SignatureValue.
Definition: signature.hpp:99
An MetaInfo holds the meta info which is signed inside the data packet.
Definition: meta-info.hpp:58
void reset()
Reset wire buffer of the element.
Definition: block.cpp:257
Represents an absolute name.
Definition: name.hpp:42
const Name & getFullName() const
Get full name including implicit digest.
Definition: data.cpp:148
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Definition: meta-info.cpp:133
Component holds a read-only name component value.
const MetaInfo & getMetaInfo() const
Get MetaInfo.
Definition: data.hpp:135
bool empty() const
Check if name is empty.
Definition: name.hpp:146
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
Definition: sha256.cpp:63
bool operator==(const Data &lhs, const Data &rhs)
Definition: data.cpp:265
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:131
Data & setMetaInfo(const MetaInfo &metaInfo)
Set MetaInfo.
Definition: data.cpp:177
Data & setFinalBlockId(const name::Component &finalBlockId)
Definition: data.cpp:257
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition: name.cpp:164
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:44
Represents a Data packet.
Definition: data.hpp:35
a concept check for TLV abstraction with .wireDecode method and constructible from Block ...
Definition: concepts.hpp:80
void clear()
Remove all components.
Definition: name.hpp:450
EncodingImpl< EncoderTag > EncodingBuffer
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:235
Name & appendImplicitSha256Digest(const ConstBufferPtr &digest)
Append an ImplicitSha256Digest component.
Definition: name.hpp:415
EncodingImpl< EstimatorTag > EncodingEstimator
Holds SignatureInfo and SignatureValue in a Data packet.
Definition: signature.hpp:37
void wireDecode(const Block &wire)
Definition: meta-info.cpp:187
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:89