blob: 1e6ec24574b271a0e787f6881b2cb91af6a61147 [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"
11#include "../encoding/tlv-nfd-control.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:
23 struct Error : public Tlv::Error { Error(const std::string &what) : Tlv::Error(what) {} };
24
25 ControlResponse()
26 : m_code(200)
27 {
28 }
29
30 ControlResponse(uint32_t code, const std::string &text)
31 : m_code(code)
32 , m_text(text)
33 {
34 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080035
36 ControlResponse(const Block& block)
37 {
38 wireDecode(block);
39 }
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080040
41 inline uint32_t
42 getCode() const;
43
44 inline void
45 setCode(uint32_t code);
46
47 inline const std::string &
48 getText() const;
49
50 inline void
51 setText(const std::string &text);
52
53 inline const Block&
54 getBody() const;
55
56 inline void
57 setBody(const Block& body);
58
59 inline const Block&
60 wireEncode() const;
61
62 inline void
63 wireDecode(const Block &block);
64
65protected:
66 uint32_t m_code;
67 std::string m_text;
68 Block m_body;
69
70 mutable Block m_wire;
71};
72
73inline uint32_t
74ControlResponse::getCode() const
75{
76 return m_code;
77}
78
79inline void
80ControlResponse::setCode(uint32_t code)
81{
82 m_code = code;
83 m_wire.reset();
84}
85
86inline const std::string &
87ControlResponse::getText() const
88{
89 return m_text;
90}
91
92inline void
93ControlResponse::setText(const std::string &text)
94{
95 m_text = text;
96 m_wire.reset();
97}
98
99inline const Block&
100ControlResponse::getBody() const
101{
102 return m_body;
103}
104
105inline void
106ControlResponse::setBody(const Block& body)
107{
108 m_body = body;
109 m_body.encode(); // will do nothing if already encoded
110 m_wire.reset();
111}
112
113
114inline const Block&
115ControlResponse::wireEncode() const
116{
117 if (m_wire.hasWire())
118 return m_wire;
119
120 m_wire = Block(tlv::nfd_control::ControlResponse);
121 m_wire.push_back
122 (nonNegativeIntegerBlock(tlv::nfd_control::StatusCode, m_code));
123
124 m_wire.push_back
125 (dataBlock(tlv::nfd_control::StatusText, m_text.c_str(), m_text.size()));
126
127 if (m_body.hasWire())
128 {
129 m_wire.push_back(m_body);
130 }
131
132 m_wire.encode();
133 return m_wire;
134}
135
136inline void
137ControlResponse::wireDecode(const Block &wire)
138{
139 m_wire = wire;
140 m_wire.parse();
141
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800142 if (m_wire.type() != tlv::nfd_control::ControlResponse)
143 throw Error("Requested decoding of ControlResponse, but Block is of different type");
144
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800145 Block::element_const_iterator val = m_wire.elements_begin();
146 if (val == m_wire.elements_end() ||
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800147 val->type() != tlv::nfd_control::StatusCode)
148 {
149 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
150 }
151
152 m_code = readNonNegativeInteger(*val);
153 ++val;
154
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800155 if (val == m_wire.elements_end() ||
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800156 val->type() != tlv::nfd_control::StatusText)
157 {
158 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
159 }
160 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
161 ++val;
162
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800163 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800164 m_body = *val;
165 else
166 m_body = Block();
167}
168
169inline std::ostream&
170operator << (std::ostream &os, const ControlResponse &status)
171{
172 os << status.getCode() << " " << status.getText();
173 return os;
174}
175
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800176} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800177} // namespace ndn
178
179#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP