blob: 3c2a06dc7855343a9dc6fcfba8d839095393d3a4 [file] [log] [blame]
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
8#define NDN_MANAGEMENT_CONTROL_RESPONSE_HPP
9
Alexander Afanasyev274f2b02014-01-30 20:08:45 -080010#include "../encoding/block.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080011#include "../encoding/tlv-nfd.hpp"
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080012
13namespace ndn {
Alexander Afanasyeve289b532014-02-09 22:14:44 -080014namespace nfd {
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080015
16/**
17 * @brief Class defining abstraction of ControlResponse for NFD Control Protocol
18 *
19 * @see http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
20 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070021class ControlResponse
22{
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080023public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070024 class Error : public Tlv::Error
25 {
26 public:
27 explicit
28 Error(const std::string& what)
29 : Tlv::Error(what)
30 {
31 }
32 };
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080033
34 ControlResponse()
35 : m_code(200)
36 {
37 }
38
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070039 ControlResponse(uint32_t code, const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080040 : m_code(code)
41 , m_text(text)
42 {
43 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080044
45 ControlResponse(const Block& block)
46 {
47 wireDecode(block);
48 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070049
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080050 inline uint32_t
51 getCode() const;
52
53 inline void
54 setCode(uint32_t code);
55
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056 inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080057 getText() const;
58
59 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070060 setText(const std::string& text);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080061
62 inline const Block&
63 getBody() const;
64
65 inline void
66 setBody(const Block& body);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080068 inline const Block&
69 wireEncode() const;
70
71 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072 wireDecode(const Block& block);
73
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080074protected:
75 uint32_t m_code;
76 std::string m_text;
77 Block m_body;
78
79 mutable Block m_wire;
80};
81
82inline uint32_t
83ControlResponse::getCode() const
84{
85 return m_code;
86}
87
88inline void
89ControlResponse::setCode(uint32_t code)
90{
91 m_code = code;
92 m_wire.reset();
93}
94
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080096ControlResponse::getText() const
97{
98 return m_text;
99}
100
101inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700102ControlResponse::setText(const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800103{
104 m_text = text;
105 m_wire.reset();
106}
107
108inline const Block&
109ControlResponse::getBody() const
110{
111 return m_body;
112}
113
114inline void
115ControlResponse::setBody(const Block& body)
116{
117 m_body = body;
118 m_body.encode(); // will do nothing if already encoded
119 m_wire.reset();
120}
121
122
123inline const Block&
124ControlResponse::wireEncode() const
125{
126 if (m_wire.hasWire())
127 return m_wire;
128
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800129 m_wire = Block(tlv::nfd::ControlResponse);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800130 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800131 (nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800132
133 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800134 (dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800135
136 if (m_body.hasWire())
137 {
138 m_wire.push_back(m_body);
139 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140
141 m_wire.encode();
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800142 return m_wire;
143}
144
145inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146ControlResponse::wireDecode(const Block& wire)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800147{
148 m_wire = wire;
149 m_wire.parse();
150
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800151 if (m_wire.type() != tlv::nfd::ControlResponse)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 throw Error("Requested decoding of ControlResponse, but Block is of different type");
153
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800154 Block::element_const_iterator val = m_wire.elements_begin();
155 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800156 val->type() != tlv::nfd::StatusCode)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800157 {
158 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
159 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700160
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800161 m_code = readNonNegativeInteger(*val);
162 ++val;
163
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800164 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800165 val->type() != tlv::nfd::StatusText)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800166 {
167 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
168 }
169 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
170 ++val;
171
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800172 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800173 m_body = *val;
174 else
175 m_body = Block();
176}
177
178inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179operator << (std::ostream& os, const ControlResponse& status)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800180{
181 os << status.getCode() << " " << status.getText();
182 return os;
183}
184
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800185} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800186} // namespace ndn
187
188#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP