blob: a4a5ae39f5a6e836b4286a90c4762d797bf3742d [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 */
21class ControlResponse {
22public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070023 class Error : public Tlv::Error
24 {
25 public:
26 explicit
27 Error(const std::string& what)
28 : Tlv::Error(what)
29 {
30 }
31 };
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080032
33 ControlResponse()
34 : m_code(200)
35 {
36 }
37
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038 ControlResponse(uint32_t code, const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080039 : m_code(code)
40 , m_text(text)
41 {
42 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080043
44 ControlResponse(const Block& block)
45 {
46 wireDecode(block);
47 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070048
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080049 inline uint32_t
50 getCode() const;
51
52 inline void
53 setCode(uint32_t code);
54
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070055 inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080056 getText() const;
57
58 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059 setText(const std::string& text);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080060
61 inline const Block&
62 getBody() const;
63
64 inline void
65 setBody(const Block& body);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070066
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080067 inline const Block&
68 wireEncode() const;
69
70 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070071 wireDecode(const Block& block);
72
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080073protected:
74 uint32_t m_code;
75 std::string m_text;
76 Block m_body;
77
78 mutable Block m_wire;
79};
80
81inline uint32_t
82ControlResponse::getCode() const
83{
84 return m_code;
85}
86
87inline void
88ControlResponse::setCode(uint32_t code)
89{
90 m_code = code;
91 m_wire.reset();
92}
93
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070094inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080095ControlResponse::getText() const
96{
97 return m_text;
98}
99
100inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101ControlResponse::setText(const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800102{
103 m_text = text;
104 m_wire.reset();
105}
106
107inline const Block&
108ControlResponse::getBody() const
109{
110 return m_body;
111}
112
113inline void
114ControlResponse::setBody(const Block& body)
115{
116 m_body = body;
117 m_body.encode(); // will do nothing if already encoded
118 m_wire.reset();
119}
120
121
122inline const Block&
123ControlResponse::wireEncode() const
124{
125 if (m_wire.hasWire())
126 return m_wire;
127
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800128 m_wire = Block(tlv::nfd::ControlResponse);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800129 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800130 (nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800131
132 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800133 (dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800134
135 if (m_body.hasWire())
136 {
137 m_wire.push_back(m_body);
138 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700139
140 m_wire.encode();
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800141 return m_wire;
142}
143
144inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700145ControlResponse::wireDecode(const Block& wire)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800146{
147 m_wire = wire;
148 m_wire.parse();
149
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800150 if (m_wire.type() != tlv::nfd::ControlResponse)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700151 throw Error("Requested decoding of ControlResponse, but Block is of different type");
152
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800153 Block::element_const_iterator val = m_wire.elements_begin();
154 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800155 val->type() != tlv::nfd::StatusCode)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800156 {
157 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
158 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700159
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800160 m_code = readNonNegativeInteger(*val);
161 ++val;
162
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800163 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800164 val->type() != tlv::nfd::StatusText)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800165 {
166 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
167 }
168 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
169 ++val;
170
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800171 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800172 m_body = *val;
173 else
174 m_body = Block();
175}
176
177inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700178operator << (std::ostream& os, const ControlResponse& status)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800179{
180 os << status.getCode() << " " << status.getText();
181 return os;
182}
183
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800184} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800185} // namespace ndn
186
187#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP