blob: adf29c29dc864088a948d7588ecda48d4199983b [file] [log] [blame]
Junxiao Shi13e637f2014-07-16 19:20:40 -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 "nfd-face-status.hpp"
23
24namespace ndn {
25namespace nfd {
26
27FaceStatus::FaceStatus()
28 : m_faceId(0)
29 , m_hasExpirationPeriod(false)
30 , m_flags(0)
31 , m_nInInterests(0)
32 , m_nInDatas(0)
33 , m_nOutInterests(0)
34 , m_nOutDatas(0)
35 , m_nInBytes(0)
36 , m_nOutBytes(0)
37{
38}
39
40template<bool T>
41size_t
42FaceStatus::wireEncode(EncodingImpl<T>& encoder) const
43{
44 size_t totalLength = 0;
45
46 totalLength += prependNonNegativeIntegerBlock(encoder,
47 tlv::nfd::NOutBytes, m_nOutBytes);
48 totalLength += prependNonNegativeIntegerBlock(encoder,
49 tlv::nfd::NInBytes, m_nInBytes);
50 totalLength += prependNonNegativeIntegerBlock(encoder,
51 tlv::nfd::NOutDatas, m_nOutDatas);
52 totalLength += prependNonNegativeIntegerBlock(encoder,
53 tlv::nfd::NOutInterests, m_nOutInterests);
54 totalLength += prependNonNegativeIntegerBlock(encoder,
55 tlv::nfd::NInDatas, m_nInDatas);
56 totalLength += prependNonNegativeIntegerBlock(encoder,
57 tlv::nfd::NInInterests, m_nInInterests);
58 totalLength += prependNonNegativeIntegerBlock(encoder,
59 tlv::nfd::FaceFlags, m_flags);
60 if (m_hasExpirationPeriod) {
61 totalLength += prependNonNegativeIntegerBlock(encoder,
62 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
63 }
64 totalLength += prependByteArrayBlock(encoder, tlv::nfd::LocalUri,
65 reinterpret_cast<const uint8_t*>(m_localUri.c_str()), m_localUri.size());
66 totalLength += prependByteArrayBlock(encoder, tlv::nfd::Uri,
67 reinterpret_cast<const uint8_t*>(m_remoteUri.c_str()), m_remoteUri.size());
68 totalLength += prependNonNegativeIntegerBlock(encoder,
69 tlv::nfd::FaceId, m_faceId);
70
71 totalLength += encoder.prependVarNumber(totalLength);
72 totalLength += encoder.prependVarNumber(tlv::nfd::FaceStatus);
73 return totalLength;
74}
75
76template size_t
77FaceStatus::wireEncode<true>(EncodingImpl<true>& block) const;
78
79template size_t
80FaceStatus::wireEncode<false>(EncodingImpl<false>& block) const;
81
82const Block&
83FaceStatus::wireEncode() const
84{
85 if (m_wire.hasWire())
86 return m_wire;
87
88 EncodingEstimator estimator;
89 size_t estimatedSize = wireEncode(estimator);
90
91 EncodingBuffer buffer(estimatedSize, 0);
92 wireEncode(buffer);
93
94 m_wire = buffer.block();
95 return m_wire;
96}
97
98void
99FaceStatus::wireDecode(const Block& block)
100{
101 if (block.type() != tlv::nfd::FaceStatus) {
102 throw Error("expecting FaceStatus block");
103 }
104 m_wire = block;
105 m_wire.parse();
106 Block::element_const_iterator val = m_wire.elements_begin();
107
108 if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
109 m_faceId = readNonNegativeInteger(*val);
110 ++val;
111 }
112 else {
113 throw Error("missing required FaceId field");
114 }
115
116 if (val != m_wire.elements_end() && val->type() == tlv::nfd::Uri) {
117 m_remoteUri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
118 ++val;
119 }
120 else {
121 throw Error("missing required Uri field");
122 }
123
124 if (val != m_wire.elements_end() && val->type() == tlv::nfd::LocalUri) {
125 m_localUri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
126 ++val;
127 }
128 else {
129 throw Error("missing required LocalUri field");
130 }
131
132 if (val != m_wire.elements_end() && val->type() == tlv::nfd::ExpirationPeriod) {
133 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
134 m_hasExpirationPeriod = true;
135 ++val;
136 }
137 else {
138 m_hasExpirationPeriod = false;
139 // ExpirationPeriod is optional
140 }
141
142 if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceFlags) {
143 m_flags = readNonNegativeInteger(*val);
144 ++val;
145 }
146 else {
147 throw Error("missing required FaceFlags field");
148 }
149
150 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInInterests) {
151 m_nInInterests = readNonNegativeInteger(*val);
152 ++val;
153 }
154 else {
155 throw Error("missing required NInInterests field");
156 }
157
158 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInDatas) {
159 m_nInDatas = readNonNegativeInteger(*val);
160 ++val;
161 }
162 else {
163 throw Error("missing required NInDatas field");
164 }
165
166 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
167 m_nOutInterests = readNonNegativeInteger(*val);
168 ++val;
169 }
170 else {
171 throw Error("missing required NOutInterests field");
172 }
173
174 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutDatas) {
175 m_nOutDatas = readNonNegativeInteger(*val);
176 ++val;
177 }
178 else {
179 throw Error("missing required NOutDatas field");
180 }
181
182 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInBytes) {
183 m_nInBytes = readNonNegativeInteger(*val);
184 ++val;
185 }
186 else {
187 throw Error("missing required NInBytes field");
188 }
189
190 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutBytes) {
191 m_nOutBytes = readNonNegativeInteger(*val);
192 ++val;
193 }
194 else {
195 throw Error("missing required NOutBytes field");
196 }
197}
198
199std::ostream&
200operator<<(std::ostream& os, const FaceStatus& status)
201{
202 os << "FaceStatus("
203 << "FaceID: " << status.getFaceId() << ",\n"
204 << "RemoteUri: " << status.getRemoteUri() << ",\n"
205 << "LocalUri: " << status.getLocalUri() << ",\n";
206
207 if (status.hasExpirationPeriod()) {
208 os << "ExpirationPeriod: " << status.getExpirationPeriod() << ",\n";
209 }
210 else {
211 os << "ExpirationPeriod: infinite,\n";
212 }
213
214 os << "Flags: " << status.getFlags() << ",\n"
215 << "Counters: { Interests: {in: " << status.getNInInterests() << ", "
216 << "out: " << status.getNOutInterests() << "},\n"
217 << " Data: {in: " << status.getNInDatas() << ", "
218 << "out: " << status.getNOutDatas() << "},\n"
219 << " bytes: {in: " << status.getNInBytes() << ", "
220 << "out: " << status.getNOutBytes() << "} }\n"
221 << ")";
222 return os;
223}
224
225} // namespace nfd
226} // namespace ndn
227