blob: d829ed301c28cc08b5375e5b36c620a6340423b7 [file] [log] [blame]
Alexander Afanasyev01065fb2014-10-02 13:01:46 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 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 "meta-info.hpp"
23#include "encoding/block-helpers.hpp"
24#include "encoding/encoding-buffer.hpp"
25#include "util/time.hpp"
26
27namespace ndn {
28
29MetaInfo::MetaInfo()
30 : m_type(TYPE_DEFAULT)
31 , m_freshnessPeriod(-1)
32{
33}
34
35MetaInfo::MetaInfo(const Block& block)
36{
37 wireDecode(block);
38}
39
40MetaInfo&
41MetaInfo::setType(uint32_t type)
42{
43 m_wire.reset();
44 m_type = type;
45 return *this;
46}
47
48MetaInfo&
49MetaInfo::setFreshnessPeriod(const time::milliseconds& freshnessPeriod)
50{
51 m_wire.reset();
52 m_freshnessPeriod = freshnessPeriod;
53 return *this;
54}
55
56MetaInfo&
57MetaInfo::setFinalBlockId(const name::Component& finalBlockId)
58{
59 m_wire.reset();
60 m_finalBlockId = finalBlockId;
61 return *this;
62}
63
64template<bool T>
65size_t
66MetaInfo::wireEncode(EncodingImpl<T>& blk) const
67{
68 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
69 // ContentType?
70 // FreshnessPeriod?
71 // FinalBlockId?
72
73 size_t totalLength = 0;
74
75 // FinalBlockId
76 if (!m_finalBlockId.empty())
77 {
78 totalLength += prependNestedBlock(blk, tlv::FinalBlockId, m_finalBlockId);
79 }
80
81 // FreshnessPeriod
82 if (m_freshnessPeriod >= time::milliseconds::zero())
83 {
84 totalLength += prependNonNegativeIntegerBlock(blk, tlv::FreshnessPeriod,
85 m_freshnessPeriod.count());
86 }
87
88 // ContentType
89 if (m_type != TYPE_DEFAULT)
90 {
91 totalLength += prependNonNegativeIntegerBlock(blk, tlv::ContentType, m_type);
92 }
93
94 totalLength += blk.prependVarNumber(totalLength);
95 totalLength += blk.prependVarNumber(tlv::MetaInfo);
96 return totalLength;
97}
98
99template size_t
100MetaInfo::wireEncode<true>(EncodingImpl<true>& block) const;
101
102template size_t
103MetaInfo::wireEncode<false>(EncodingImpl<false>& block) const;
104
105const Block&
106MetaInfo::wireEncode() const
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 m_wire = buffer.block();
118 return m_wire;
119}
120
121void
122MetaInfo::wireDecode(const Block& wire)
123{
124 m_wire = wire;
125 m_wire.parse();
126
127 // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
128 // ContentType?
129 // FreshnessPeriod?
130
131 // ContentType
132 Block::element_const_iterator val = m_wire.find(tlv::ContentType);
133 if (val != m_wire.elements().end())
134 {
135 m_type = readNonNegativeInteger(*val);
136 }
137 else
138 m_type = TYPE_DEFAULT;
139
140 // FreshnessPeriod
141 val = m_wire.find(tlv::FreshnessPeriod);
142 if (val != m_wire.elements().end())
143 {
144 m_freshnessPeriod = time::milliseconds(readNonNegativeInteger(*val));
145 }
146 else
147 m_freshnessPeriod = time::milliseconds::min();
148
149 // FinalBlockId
150 val = m_wire.find(tlv::FinalBlockId);
151 if (val != m_wire.elements().end())
152 {
153 m_finalBlockId = val->blockFromValue();
154 if (m_finalBlockId.type() != tlv::NameComponent)
155 {
156 /// @todo May or may not throw exception later...
157 m_finalBlockId.reset();
158 }
159 }
160 else
161 m_finalBlockId.reset();
162}
163
164std::ostream&
165operator<<(std::ostream& os, const MetaInfo& info)
166{
167 // ContentType
168 os << "ContentType: " << info.getType();
169
170 // FreshnessPeriod
171 if (info.getFreshnessPeriod() >= time::milliseconds::zero()) {
172 os << ", FreshnessPeriod: " << info.getFreshnessPeriod();
173 }
174
175 if (!info.getFinalBlockId().empty()) {
176 os << ", FinalBlockId: ";
177 info.getFinalBlockId().toUri(os);
178 }
179 return os;
180}
181
182} // namespace ndn