blob: 4c098115b0550c11d9e9eed5400967a44a52f91b [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson5cae5e52013-07-10 19:41:20 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson5cae5e52013-07-10 19:41:20 -07005 * See COPYING for copyright and distribution information.
6 */
7
Jeff Thompson56ec9e22013-08-02 11:34:07 -07008#ifndef NDN_DATA_HPP
Jeff Thompsona0d18c92013-08-06 13:55:32 -07009#define NDN_DATA_HPP
Jeff Thompson5cae5e52013-07-10 19:41:20 -070010
Jeff Thompson46bd45f2013-08-08 16:46:41 -070011#include "common.hpp"
Jeff Thompson53412192013-08-06 13:35:50 -070012#include "name.hpp"
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080013#include "encoding/block.hpp"
Jeff Thompson25b4e612013-10-10 16:03:24 -070014
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080015#include "signature.hpp"
16#include "meta-info.hpp"
17#include "key-locator.hpp"
Jeff Thompson5cae5e52013-07-10 19:41:20 -070018
19namespace ndn {
Jeff Thompson5cae5e52013-07-10 19:41:20 -070020
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080021class Data : public enable_shared_from_this<Data>
22{
Jeff Thompson5cae5e52013-07-10 19:41:20 -070023public:
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080024 struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
25
Jeff Thompson20af0732013-09-12 17:01:45 -070026 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080027 * @brief Create an empty Data object
Jeff Thompson20af0732013-09-12 17:01:45 -070028 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080029 inline
30 Data();
31
Jeff Thompson20af0732013-09-12 17:01:45 -070032 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080033 * @brief Create a new Data object with the given name
Jeff Thompson20af0732013-09-12 17:01:45 -070034 * @param name A reference to the name which is copied.
35 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080036 inline
37 Data(const Name& name);
Jeff Thompson25bfdca2013-10-16 17:05:41 -070038
39 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -080040 * @brief The destructor
Jeff Thompsonc69163b2013-10-12 13:49:50 -070041 */
Alexander Afanasyev809805d2014-02-17 17:20:33 -080042 inline
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080043 ~Data();
Jeff Thompsonc69163b2013-10-12 13:49:50 -070044
45 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -080046 * @brief Fast encoding or block size estimation
Jeff Thompsonb7aefa002013-09-16 18:22:00 -070047 */
Alexander Afanasyev809805d2014-02-17 17:20:33 -080048 template<bool T>
49 inline size_t
50 wireEncode(EncodingImpl<T> &block, bool unsignedPortion = false) const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080051
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080052 /**
Alexander Afanasyev809805d2014-02-17 17:20:33 -080053 * @brief Encode to a wire format
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080054 */
Alexander Afanasyev809805d2014-02-17 17:20:33 -080055 inline const Block&
56 wireEncode() const;
57
58 /**
59 * @brief Decode from the wire format
60 */
61 inline void
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080062 wireDecode(const Block &wire);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -080063
Alexander Afanasyev809805d2014-02-17 17:20:33 -080064 ////////////////////////////////////////////////////////////////////
65
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080066 inline const Name&
67 getName() const;
Jeff Thompson5cae5e52013-07-10 19:41:20 -070068
69 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080070 * @brief Set name to a copy of the given Name.
71 *
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -070072 * @param name The Name which is copied.
Jeff Thompson6d591972013-10-17 11:16:32 -070073 * @return This Data so that you can chain calls to update values.
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -070074 */
Alexander Afanasyeva61757b2014-01-03 15:09:29 -080075 inline void
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080076 setName(const Name& name);
77
Alexander Afanasyev809805d2014-02-17 17:20:33 -080078 //
79
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080080 inline const MetaInfo&
81 getMetaInfo() const;
Jeff Thompson46bd45f2013-08-08 16:46:41 -070082
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -070083 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080084 * @brief Set metaInfo to a copy of the given MetaInfo.
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -070085 * @param metaInfo The MetaInfo which is copied.
Jeff Thompson6d591972013-10-17 11:16:32 -070086 * @return This Data so that you can chain calls to update values.
Jeff Thompson0cd8c4a2013-09-13 17:46:40 -070087 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080088 inline void
89 setMetaInfo(const MetaInfo& metaInfo);
Jeff Thompson46bd45f2013-08-08 16:46:41 -070090
Alexander Afanasyev809805d2014-02-17 17:20:33 -080091 //
92
93 ///////////////////////////////////////////////////////////////
94 ///////////////////////////////////////////////////////////////
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080095 ///////////////////////////////////////////////////////////////
96 // MetaInfo proxy methods
Alexander Afanasyev809805d2014-02-17 17:20:33 -080097
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -080098 inline uint32_t
99 getContentType() const;
100
101 inline void
102 setContentType(uint32_t type);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800103
104 //
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800105
106 inline Milliseconds
107 getFreshnessPeriod() const;
108
109 inline void
110 setFreshnessPeriod(Milliseconds freshnessPeriod);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800111
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800112 //
113
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800114 inline const name::Component&
115 getFinalBlockId() const;
116
117 inline void
118 setFinalBlockId(const name::Component& finalBlockId);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800119
120 //
121 ///////////////////////////////////////////////////////////////
122 ///////////////////////////////////////////////////////////////
123 ///////////////////////////////////////////////////////////////
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800124
125 /**
126 * @brief Get content Block
127 *
128 * To access content value, one can use value()/value_size() or
129 * value_begin()/value_end() methods of the Block class
130 */
131 inline const Block&
132 getContent() const;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800133
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700134 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800135 * @brief Set the content to a copy of the data in the vector.
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700136 * @param content A vector whose contents are copied.
Jeff Thompson6d591972013-10-17 11:16:32 -0700137 * @return This Data so that you can chain calls to update values.
Jeff Thompson0899c0f2013-09-12 12:15:31 -0700138 */
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800139 inline void
140 setContent(const uint8_t* content, size_t contentLength);
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800141
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800142 inline void
143 setContent(const Block& content);
144
145 inline void
146 setContent(const ConstBufferPtr &contentValue);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800147
148 //
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800149
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800150 inline const Signature&
151 getSignature() const;
152
153 /**
154 * @brief Set the signature to a copy of the given signature.
155 * @param signature The signature object which is cloned.
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800156 */
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800157 inline void
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800158 setSignature(const Signature& signature);
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800159
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800160 inline void
161 setSignatureValue(const Block &value);
Yingdi Yua4e57672014-02-06 11:16:17 -0800162
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800163 ///////////////////////////////////////////////////////////////
164
Yingdi Yua4e57672014-02-06 11:16:17 -0800165 inline uint64_t
166 getIncomingFaceId() const;
167
168 inline void
169 setIncomingFaceId(uint64_t incomingFaceId);
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800170
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700171private:
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700172 /**
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800173 * @brief Clear the wire encoding.
Jeff Thompsonb7aefa002013-09-16 18:22:00 -0700174 */
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800175 inline void
Jeff Thompson0050abe2013-09-17 12:50:25 -0700176 onChanged();
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800177
178private:
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800179 Name m_name;
180 MetaInfo m_metaInfo;
181 mutable Block m_content;
182 Signature m_signature;
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800183
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800184 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800185
186 uint64_t m_incomingFaceId;
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700187};
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800188
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800189inline
190Data::Data()
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800191 : m_content(Tlv::Content) // empty content
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800192{
193}
194
195inline
196Data::Data(const Name& name)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800197 : m_name(name)
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800198{
199}
200
201inline
202Data::~Data()
203{
204}
205
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800206template<bool T>
207inline size_t
208Data::wireEncode(EncodingImpl<T> &block, bool unsignedPortion/* = false*/) const
209{
210 size_t total_len = 0;
211
212 // Data ::= DATA-TLV TLV-LENGTH
213 // Name
214 // MetaInfo
215 // Content
216 // Signature
217
218 // (reverse encoding)
219
220 if (!unsignedPortion && !m_signature)
221 {
222 throw Error("Requested wire format, but data packet has not been signed yet");
223 }
224
225 if (!unsignedPortion)
226 {
227 // SignatureValue
228 total_len += prependBlock(block, m_signature.getValue());
229 }
230
231 // SignatureInfo
232 total_len += prependBlock(block, m_signature.getInfo());
233
234 // Content
235 total_len += prependBlock(block, getContent());
236
237 // MetaInfo
238 total_len += getMetaInfo().wireEncode(block);
239
240 // Name
241 total_len += getName().wireEncode(block);
242
243 if (!unsignedPortion)
244 {
245 total_len += block.prependVarNumber (total_len);
246 total_len += block.prependVarNumber (Tlv::Data);
247 }
248 return total_len;
249}
250
251inline const Block &
252Data::wireEncode() const
253{
254 if (m_wire.hasWire())
255 return m_wire;
256
257 EncodingEstimator estimator;
258 size_t estimatedSize = wireEncode(estimator);
259
260 EncodingBuffer buffer(estimatedSize, 0);
261 wireEncode(buffer);
262
263 const_cast<Data*>(this)->wireDecode(buffer.block());
264 return m_wire;
265}
266
267/**
268 * Decode the input using a particular wire format and update this Data.
269 * @param input The input byte array to be decoded.
270 */
271void
272Data::wireDecode(const Block &wire)
273{
274 m_wire = wire;
275 m_wire.parse();
276
277 // Data ::= DATA-TLV TLV-LENGTH
278 // Name
279 // MetaInfo
280 // Content
281 // Signature
282
283 // Name
284 m_name.wireDecode(m_wire.get(Tlv::Name));
285
286 // MetaInfo
287 m_metaInfo.wireDecode(m_wire.get(Tlv::MetaInfo));
288
289 // Content
290 m_content = m_wire.get(Tlv::Content);
291
292 ///////////////
293 // Signature //
294 ///////////////
295
296 // SignatureInfo
297 m_signature.setInfo(m_wire.get(Tlv::SignatureInfo));
298
299 // SignatureValue
300 Block::element_const_iterator val = m_wire.find(Tlv::SignatureValue);
301 if (val != m_wire.elements_end())
302 m_signature.setValue(*val);
303}
304
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800305inline const Name&
306Data::getName() const
307{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800308 return m_name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800309}
310
311inline void
312Data::setName(const Name& name)
313{
314 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800315 m_name = name;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800316}
317
318inline const MetaInfo&
319Data::getMetaInfo() const
320{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800321 return m_metaInfo;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800322}
323
324inline void
325Data::setMetaInfo(const MetaInfo& metaInfo)
326{
327 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800328 m_metaInfo = metaInfo;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800329}
330
331inline uint32_t
332Data::getContentType() const
333{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800334 return m_metaInfo.getType();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800335}
336
337inline void
338Data::setContentType(uint32_t type)
339{
340 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800341 m_metaInfo.setType(type);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800342}
343
344inline Milliseconds
345Data::getFreshnessPeriod() const
346{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800347 return m_metaInfo.getFreshnessPeriod();
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800348}
349
350inline void
351Data::setFreshnessPeriod(Milliseconds freshnessPeriod)
352{
353 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800354 m_metaInfo.setFreshnessPeriod(freshnessPeriod);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800355}
356
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800357inline const name::Component&
358Data::getFinalBlockId() const
359{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800360 return m_metaInfo.getFinalBlockId();
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800361}
362
363inline void
364Data::setFinalBlockId(const name::Component& finalBlockId)
365{
366 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800367 m_metaInfo.setFinalBlockId(finalBlockId);
Alexander Afanasyev95b0e342014-02-12 21:34:44 -0800368}
369
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800370inline const Block&
371Data::getContent() const
372{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800373 if (m_content.empty())
374 m_content = dataBlock(Tlv::Content, reinterpret_cast<const uint8_t*>(0), 0);
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800375
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800376 if (!m_content.hasWire())
377 m_content.encode();
378 return m_content;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800379}
380
381inline void
382Data::setContent(const uint8_t* content, size_t contentLength)
383{
384 onChanged();
385
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800386 m_content = dataBlock(Tlv::Content, content, contentLength);
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800387}
388
389inline void
390Data::setContent(const ConstBufferPtr &contentValue)
391{
392 onChanged();
393
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800394 m_content = Block(Tlv::Content, contentValue); // not real a wire encoding yet
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800395}
396
397inline void
398Data::setContent(const Block& content)
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800399{
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800400 onChanged();
401
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800402 if (content.type() == Tlv::Content)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800403 m_content = content;
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800404 else {
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800405 m_content = Block(Tlv::Content, content);
Alexander Afanasyeve0c02f52013-12-28 20:44:25 -0800406 }
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800407}
408
409inline const Signature&
410Data::getSignature() const
411{
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800412 return m_signature;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800413}
414
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800415inline void
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800416Data::setSignature(const Signature& signature)
417{
418 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800419 m_signature = signature;
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800420}
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800421
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800422inline void
423Data::setSignatureValue(const Block &value)
424{
425 onChanged();
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800426 m_signature.setValue(value);
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800427}
428
Yingdi Yua4e57672014-02-06 11:16:17 -0800429inline uint64_t
430Data::getIncomingFaceId() const
431{
432 return m_incomingFaceId;
433}
434
435inline void
436Data::setIncomingFaceId(uint64_t incomingFaceId)
437{
438 m_incomingFaceId = incomingFaceId;
439}
Alexander Afanasyevad39b182014-01-03 15:38:58 -0800440
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800441inline void
442Data::onChanged()
443{
Alexander Afanasyev2ba8f662014-01-05 22:53:18 -0800444 // The values have changed, so the wire format is invalidated
445
446 // !!!Note!!! Signature is not invalidated and it is responsibility of
447 // the application to do proper re-signing if necessary
448
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800449 m_wire.reset();
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700450}
451
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800452inline std::ostream&
453operator << (std::ostream &os, const Data &data)
454{
455 os << "Name: " << data.getName() << "\n";
456 os << "MetaInfo: " << data.getMetaInfo() << "\n";
457 os << "Content: (size: " << data.getContent().value_size() << ")\n";
458 os << "Signature: (type: " << data.getSignature().getType() <<
459 ", value_length: "<< data.getSignature().getValue().value_size() << ")";
460 os << std::endl;
461
462 return os;
463}
Alexander Afanasyev4ff3c912014-01-03 15:25:02 -0800464
Alexander Afanasyevfadc97d2014-01-03 13:22:10 -0800465} // namespace ndn
466
Jeff Thompson5cae5e52013-07-10 19:41:20 -0700467#endif