blob: bfb4df46f752e36287b3cf7b264018a20599dbaf [file] [log] [blame]
Junxiao Shic2b8d242014-11-04 08:35:29 -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 "selectors.hpp"
23#include "encoding/encoding-buffer.hpp"
24#include "encoding/block-helpers.hpp"
25#include "util/concepts.hpp"
26
27namespace ndn {
28
29BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Selectors>));
30BOOST_CONCEPT_ASSERT((WireEncodable<Selectors>));
31BOOST_CONCEPT_ASSERT((WireDecodable<Selectors>));
32static_assert(std::is_base_of<tlv::Error, Selectors::Error>::value,
33 "Selectors::Error must inherit from tlv::Error");
34
35Selectors::Selectors()
36 : m_minSuffixComponents(-1)
37 , m_maxSuffixComponents(-1)
38 , m_childSelector(-1)
39 , m_mustBeFresh(false)
40{
41}
42
43Selectors::Selectors(int minSuffixComponents, int maxSuffixComponents,
44 const Exclude& exclude,
45 int childSelector,
46 bool mustBeFresh)
47 : m_minSuffixComponents(minSuffixComponents)
48 , m_maxSuffixComponents(maxSuffixComponents)
49 , m_exclude(exclude)
50 , m_childSelector(childSelector)
51 , m_mustBeFresh(mustBeFresh)
52{
53}
54
55Selectors::Selectors(const Block& wire)
56{
57 wireDecode(wire);
58}
59
60bool
61Selectors::empty() const
62{
63 return m_minSuffixComponents < 0 &&
64 m_maxSuffixComponents < 0 &&
65 m_publisherPublicKeyLocator.empty() &&
66 m_exclude.empty() &&
67 m_childSelector < 0 &&
68 !m_mustBeFresh;
69}
70
71template<bool T>
72size_t
73Selectors::wireEncode(EncodingImpl<T>& block) const
74{
75 size_t totalLength = 0;
76
77 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
78 // MinSuffixComponents?
79 // MaxSuffixComponents?
80 // PublisherPublicKeyLocator?
81 // Exclude?
82 // ChildSelector?
83 // MustBeFresh?
84
85 // (reverse encoding)
86
87 // MustBeFresh
88 if (getMustBeFresh()) {
89 totalLength += prependBooleanBlock(block, tlv::MustBeFresh);
90 }
91
92 // ChildSelector
93 if (getChildSelector() >= 0) {
94 totalLength += prependNonNegativeIntegerBlock(block, tlv::ChildSelector, getChildSelector());
95 }
96
97 // Exclude
98 if (!getExclude().empty()) {
99 totalLength += getExclude().wireEncode(block);
100 }
101
102 // PublisherPublicKeyLocator
103 if (!getPublisherPublicKeyLocator().empty()) {
104 totalLength += getPublisherPublicKeyLocator().wireEncode(block);
105 }
106
107 // MaxSuffixComponents
108 if (getMaxSuffixComponents() >= 0) {
109 totalLength += prependNonNegativeIntegerBlock(block, tlv::MaxSuffixComponents,
110 getMaxSuffixComponents());
111 }
112
113 // MinSuffixComponents
114 if (getMinSuffixComponents() >= 0) {
115 totalLength += prependNonNegativeIntegerBlock(block, tlv::MinSuffixComponents,
116 getMinSuffixComponents());
117 }
118
119 totalLength += block.prependVarNumber(totalLength);
120 totalLength += block.prependVarNumber(tlv::Selectors);
121 return totalLength;
122}
123
124template size_t
125Selectors::wireEncode<true>(EncodingImpl<true>& estimator) const;
126
127template size_t
128Selectors::wireEncode<false>(EncodingImpl<false>& encoder) const;
129
130const Block&
131Selectors::wireEncode() const
132{
133 if (m_wire.hasWire())
134 return m_wire;
135
136 EncodingEstimator estimator;
137 size_t estimatedSize = wireEncode(estimator);
138
139 EncodingBuffer buffer(estimatedSize, 0);
140 wireEncode(buffer);
141
142 m_wire = buffer.block();
143 return m_wire;
144}
145
146void
147Selectors::wireDecode(const Block& wire)
148{
149 if (wire.type() != tlv::Selectors)
150 throw tlv::Error("Unexpected TLV type when decoding Selectors");
151
152 *this = Selectors();
153
154 m_wire = wire;
155 m_wire.parse();
156
157 // MinSuffixComponents
158 Block::element_const_iterator val = m_wire.find(tlv::MinSuffixComponents);
159 if (val != m_wire.elements_end()) {
160 m_minSuffixComponents = readNonNegativeInteger(*val);
161 }
162
163 // MaxSuffixComponents
164 val = m_wire.find(tlv::MaxSuffixComponents);
165 if (val != m_wire.elements_end()) {
166 m_maxSuffixComponents = readNonNegativeInteger(*val);
167 }
168
169 // PublisherPublicKeyLocator
170 val = m_wire.find(tlv::KeyLocator);
171 if (val != m_wire.elements_end()) {
172 m_publisherPublicKeyLocator.wireDecode(*val);
173 }
174
175 // Exclude
176 val = m_wire.find(tlv::Exclude);
177 if (val != m_wire.elements_end()) {
178 m_exclude.wireDecode(*val);
179 }
180
181 // ChildSelector
182 val = m_wire.find(tlv::ChildSelector);
183 if (val != m_wire.elements_end()) {
184 m_childSelector = readNonNegativeInteger(*val);
185 }
186
187 // MustBeFresh
188 val = m_wire.find(tlv::MustBeFresh);
189 if (val != m_wire.elements_end()) {
190 m_mustBeFresh = true;
191 }
192}
193
194Selectors&
195Selectors::setMinSuffixComponents(int minSuffixComponents)
196{
197 m_minSuffixComponents = minSuffixComponents;
198 m_wire.reset();
199 return *this;
200}
201
202Selectors&
203Selectors::setMaxSuffixComponents(int maxSuffixComponents)
204{
205 m_maxSuffixComponents = maxSuffixComponents;
206 m_wire.reset();
207 return *this;
208}
209
210Selectors&
211Selectors::setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
212{
213 m_publisherPublicKeyLocator = keyLocator;
214 m_wire.reset();
215 return *this;
216}
217
218Selectors&
219Selectors::setExclude(const Exclude& exclude)
220{
221 m_exclude = exclude;
222 m_wire.reset();
223 return *this;
224}
225
226Selectors&
227Selectors::setChildSelector(int childSelector)
228{
229 m_childSelector = childSelector;
230 m_wire.reset();
231 return *this;
232}
233
234Selectors&
235Selectors::setMustBeFresh(bool mustBeFresh)
236{
237 m_mustBeFresh = mustBeFresh;
238 m_wire.reset();
239 return *this;
240}
241
242bool
243Selectors::operator==(const Selectors& other) const
244{
245 return wireEncode() == other.wireEncode();
246}
247
248} // namespace ndn