blob: 0a975045ea48009176f00a58ae433f88a0bcbe51 [file] [log] [blame]
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080011 */
12
13#ifndef NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
14#define NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
15
Alexander Afanasyev274f2b02014-01-30 20:08:45 -080016#include "../encoding/block.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080017#include "../encoding/tlv-nfd.hpp"
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080018
19namespace ndn {
Alexander Afanasyeve289b532014-02-09 22:14:44 -080020namespace nfd {
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080021
22/**
23 * @brief Class defining abstraction of ControlResponse for NFD Control Protocol
24 *
25 * @see http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
26 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070027class ControlResponse
28{
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080029public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070030 class Error : public Tlv::Error
31 {
32 public:
33 explicit
34 Error(const std::string& what)
35 : Tlv::Error(what)
36 {
37 }
38 };
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080039
40 ControlResponse()
41 : m_code(200)
42 {
43 }
44
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070045 ControlResponse(uint32_t code, const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080046 : m_code(code)
47 , m_text(text)
48 {
49 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080050
51 ControlResponse(const Block& block)
52 {
53 wireDecode(block);
54 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070055
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080056 inline uint32_t
57 getCode() const;
58
59 inline void
60 setCode(uint32_t code);
61
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070062 inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080063 getText() const;
64
65 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070066 setText(const std::string& text);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080067
68 inline const Block&
69 getBody() const;
70
71 inline void
72 setBody(const Block& body);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080074 inline const Block&
75 wireEncode() const;
76
77 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070078 wireDecode(const Block& block);
79
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080080protected:
81 uint32_t m_code;
82 std::string m_text;
83 Block m_body;
84
85 mutable Block m_wire;
86};
87
88inline uint32_t
89ControlResponse::getCode() const
90{
91 return m_code;
92}
93
94inline void
95ControlResponse::setCode(uint32_t code)
96{
97 m_code = code;
98 m_wire.reset();
99}
100
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800102ControlResponse::getText() const
103{
104 return m_text;
105}
106
107inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108ControlResponse::setText(const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800109{
110 m_text = text;
111 m_wire.reset();
112}
113
114inline const Block&
115ControlResponse::getBody() const
116{
117 return m_body;
118}
119
120inline void
121ControlResponse::setBody(const Block& body)
122{
123 m_body = body;
124 m_body.encode(); // will do nothing if already encoded
125 m_wire.reset();
126}
127
128
129inline const Block&
130ControlResponse::wireEncode() const
131{
132 if (m_wire.hasWire())
133 return m_wire;
134
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800135 m_wire = Block(tlv::nfd::ControlResponse);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800136 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800137 (nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800138
139 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800140 (dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800141
142 if (m_body.hasWire())
143 {
144 m_wire.push_back(m_body);
145 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146
147 m_wire.encode();
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800148 return m_wire;
149}
150
151inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152ControlResponse::wireDecode(const Block& wire)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800153{
154 m_wire = wire;
155 m_wire.parse();
156
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800157 if (m_wire.type() != tlv::nfd::ControlResponse)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158 throw Error("Requested decoding of ControlResponse, but Block is of different type");
159
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800160 Block::element_const_iterator val = m_wire.elements_begin();
161 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800162 val->type() != tlv::nfd::StatusCode)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800163 {
164 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
165 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700166
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800167 m_code = readNonNegativeInteger(*val);
168 ++val;
169
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800170 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800171 val->type() != tlv::nfd::StatusText)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800172 {
173 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
174 }
175 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
176 ++val;
177
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800178 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800179 m_body = *val;
180 else
181 m_body = Block();
182}
183
184inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185operator << (std::ostream& os, const ControlResponse& status)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800186{
187 os << status.getCode() << " " << status.getText();
188 return os;
189}
190
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800191} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800192} // namespace ndn
193
194#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP