blob: 6e637fa565cd5979303a8e86ce72d36e631ae352 [file] [log] [blame]
Junxiao Shic2b8d242014-11-04 08:35:29 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev74633892015-02-08 18:08:46 -08003 * Copyright (c) 2013-2015 Regents of the University of California.
Junxiao Shic2b8d242014-11-04 08:35:29 -07004 *
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"
Junxiao Shic2b8d242014-11-04 08:35:29 -070025
26namespace ndn {
27
28BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Selectors>));
29BOOST_CONCEPT_ASSERT((WireEncodable<Selectors>));
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070030BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Selectors>));
Junxiao Shic2b8d242014-11-04 08:35:29 -070031BOOST_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
Junxiao Shic2b8d242014-11-04 08:35:29 -070043Selectors::Selectors(const Block& wire)
44{
45 wireDecode(wire);
46}
47
48bool
49Selectors::empty() const
50{
51 return m_minSuffixComponents < 0 &&
52 m_maxSuffixComponents < 0 &&
53 m_publisherPublicKeyLocator.empty() &&
54 m_exclude.empty() &&
55 m_childSelector < 0 &&
56 !m_mustBeFresh;
57}
58
Alexander Afanasyev74633892015-02-08 18:08:46 -080059template<encoding::Tag TAG>
Junxiao Shic2b8d242014-11-04 08:35:29 -070060size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070061Selectors::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shic2b8d242014-11-04 08:35:29 -070062{
63 size_t totalLength = 0;
64
65 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
66 // MinSuffixComponents?
67 // MaxSuffixComponents?
68 // PublisherPublicKeyLocator?
69 // Exclude?
70 // ChildSelector?
71 // MustBeFresh?
72
73 // (reverse encoding)
74
75 // MustBeFresh
76 if (getMustBeFresh()) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070077 totalLength += prependEmptyBlock(encoder, tlv::MustBeFresh);
Junxiao Shic2b8d242014-11-04 08:35:29 -070078 }
79
80 // ChildSelector
81 if (getChildSelector() >= 0) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070082 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::ChildSelector, getChildSelector());
Junxiao Shic2b8d242014-11-04 08:35:29 -070083 }
84
85 // Exclude
86 if (!getExclude().empty()) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070087 totalLength += getExclude().wireEncode(encoder);
Junxiao Shic2b8d242014-11-04 08:35:29 -070088 }
89
90 // PublisherPublicKeyLocator
91 if (!getPublisherPublicKeyLocator().empty()) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070092 totalLength += getPublisherPublicKeyLocator().wireEncode(encoder);
Junxiao Shic2b8d242014-11-04 08:35:29 -070093 }
94
95 // MaxSuffixComponents
96 if (getMaxSuffixComponents() >= 0) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070097 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::MaxSuffixComponents,
Junxiao Shic2b8d242014-11-04 08:35:29 -070098 getMaxSuffixComponents());
99 }
100
101 // MinSuffixComponents
102 if (getMinSuffixComponents() >= 0) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700103 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::MinSuffixComponents,
Junxiao Shic2b8d242014-11-04 08:35:29 -0700104 getMinSuffixComponents());
105 }
106
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700107 totalLength += encoder.prependVarNumber(totalLength);
108 totalLength += encoder.prependVarNumber(tlv::Selectors);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700109 return totalLength;
110}
111
112template size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700113Selectors::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;
Junxiao Shic2b8d242014-11-04 08:35:29 -0700114
115template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800116Selectors::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;
Junxiao Shic2b8d242014-11-04 08:35:29 -0700117
118const Block&
119Selectors::wireEncode() const
120{
121 if (m_wire.hasWire())
122 return m_wire;
123
124 EncodingEstimator estimator;
125 size_t estimatedSize = wireEncode(estimator);
126
127 EncodingBuffer buffer(estimatedSize, 0);
128 wireEncode(buffer);
129
130 m_wire = buffer.block();
131 return m_wire;
132}
133
134void
135Selectors::wireDecode(const Block& wire)
136{
137 if (wire.type() != tlv::Selectors)
138 throw tlv::Error("Unexpected TLV type when decoding Selectors");
139
140 *this = Selectors();
141
142 m_wire = wire;
143 m_wire.parse();
144
145 // MinSuffixComponents
146 Block::element_const_iterator val = m_wire.find(tlv::MinSuffixComponents);
147 if (val != m_wire.elements_end()) {
148 m_minSuffixComponents = readNonNegativeInteger(*val);
149 }
150
151 // MaxSuffixComponents
152 val = m_wire.find(tlv::MaxSuffixComponents);
153 if (val != m_wire.elements_end()) {
154 m_maxSuffixComponents = readNonNegativeInteger(*val);
155 }
156
157 // PublisherPublicKeyLocator
158 val = m_wire.find(tlv::KeyLocator);
159 if (val != m_wire.elements_end()) {
160 m_publisherPublicKeyLocator.wireDecode(*val);
161 }
162
163 // Exclude
164 val = m_wire.find(tlv::Exclude);
165 if (val != m_wire.elements_end()) {
166 m_exclude.wireDecode(*val);
167 }
168
169 // ChildSelector
170 val = m_wire.find(tlv::ChildSelector);
171 if (val != m_wire.elements_end()) {
172 m_childSelector = readNonNegativeInteger(*val);
173 }
174
175 // MustBeFresh
176 val = m_wire.find(tlv::MustBeFresh);
177 if (val != m_wire.elements_end()) {
178 m_mustBeFresh = true;
179 }
180}
181
182Selectors&
183Selectors::setMinSuffixComponents(int minSuffixComponents)
184{
185 m_minSuffixComponents = minSuffixComponents;
186 m_wire.reset();
187 return *this;
188}
189
190Selectors&
191Selectors::setMaxSuffixComponents(int maxSuffixComponents)
192{
193 m_maxSuffixComponents = maxSuffixComponents;
194 m_wire.reset();
195 return *this;
196}
197
198Selectors&
199Selectors::setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
200{
201 m_publisherPublicKeyLocator = keyLocator;
202 m_wire.reset();
203 return *this;
204}
205
206Selectors&
207Selectors::setExclude(const Exclude& exclude)
208{
209 m_exclude = exclude;
210 m_wire.reset();
211 return *this;
212}
213
214Selectors&
215Selectors::setChildSelector(int childSelector)
216{
217 m_childSelector = childSelector;
218 m_wire.reset();
219 return *this;
220}
221
222Selectors&
223Selectors::setMustBeFresh(bool mustBeFresh)
224{
225 m_mustBeFresh = mustBeFresh;
226 m_wire.reset();
227 return *this;
228}
229
230bool
231Selectors::operator==(const Selectors& other) const
232{
233 return wireEncode() == other.wireEncode();
234}
235
236} // namespace ndn