blob: 5b78405c65e516c1130f1d06a53b9d07320a584b [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -08002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080020 */
21
22#ifndef NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
23#define NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
24
Alexander Afanasyev274f2b02014-01-30 20:08:45 -080025#include "../encoding/block.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070026#include "../encoding/block-helpers.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080027#include "../encoding/tlv-nfd.hpp"
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080028
29namespace ndn {
Alexander Afanasyeve289b532014-02-09 22:14:44 -080030namespace nfd {
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080031
32/**
Alexander Afanasyev4671bf72014-05-19 09:01:37 -040033 * @ingroup management
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080034 * @brief Class defining abstraction of ControlResponse for NFD Control Protocol
35 *
36 * @see http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
37 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070038class ControlResponse
39{
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080040public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070041 class Error : public Tlv::Error
42 {
43 public:
44 explicit
45 Error(const std::string& what)
46 : Tlv::Error(what)
47 {
48 }
49 };
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080050
51 ControlResponse()
52 : m_code(200)
53 {
54 }
55
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056 ControlResponse(uint32_t code, const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080057 : m_code(code)
58 , m_text(text)
59 {
60 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080061
62 ControlResponse(const Block& block)
63 {
64 wireDecode(block);
65 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070066
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080067 inline uint32_t
68 getCode() const;
69
70 inline void
71 setCode(uint32_t code);
72
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073 inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080074 getText() const;
75
76 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070077 setText(const std::string& text);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080078
79 inline const Block&
80 getBody() const;
81
82 inline void
83 setBody(const Block& body);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070084
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080085 inline const Block&
86 wireEncode() const;
87
88 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070089 wireDecode(const Block& block);
90
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080091protected:
92 uint32_t m_code;
93 std::string m_text;
94 Block m_body;
95
96 mutable Block m_wire;
97};
98
99inline uint32_t
100ControlResponse::getCode() const
101{
102 return m_code;
103}
104
105inline void
106ControlResponse::setCode(uint32_t code)
107{
108 m_code = code;
109 m_wire.reset();
110}
111
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700112inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800113ControlResponse::getText() const
114{
115 return m_text;
116}
117
118inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119ControlResponse::setText(const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800120{
121 m_text = text;
122 m_wire.reset();
123}
124
125inline const Block&
126ControlResponse::getBody() const
127{
128 return m_body;
129}
130
131inline void
132ControlResponse::setBody(const Block& body)
133{
134 m_body = body;
135 m_body.encode(); // will do nothing if already encoded
136 m_wire.reset();
137}
138
139
140inline const Block&
141ControlResponse::wireEncode() const
142{
143 if (m_wire.hasWire())
144 return m_wire;
145
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800146 m_wire = Block(tlv::nfd::ControlResponse);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800147 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800148 (nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800149
150 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800151 (dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800152
153 if (m_body.hasWire())
154 {
155 m_wire.push_back(m_body);
156 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700157
158 m_wire.encode();
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800159 return m_wire;
160}
161
162inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163ControlResponse::wireDecode(const Block& wire)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800164{
165 m_wire = wire;
166 m_wire.parse();
167
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800168 if (m_wire.type() != tlv::nfd::ControlResponse)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700169 throw Error("Requested decoding of ControlResponse, but Block is of different type");
170
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800171 Block::element_const_iterator val = m_wire.elements_begin();
172 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800173 val->type() != tlv::nfd::StatusCode)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800174 {
175 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
176 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700177
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800178 m_code = readNonNegativeInteger(*val);
179 ++val;
180
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800181 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800182 val->type() != tlv::nfd::StatusText)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800183 {
184 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
185 }
186 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
187 ++val;
188
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800189 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800190 m_body = *val;
191 else
192 m_body = Block();
193}
194
195inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700196operator << (std::ostream& os, const ControlResponse& status)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800197{
198 os << status.getCode() << " " << status.getText();
199 return os;
200}
201
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800202} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800203} // namespace ndn
204
205#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP