blob: 307200f575f25c6b5f773df2eaca9da682bf0506 [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 Afanasyev258ec2b2014-05-14 16:15:37 -070017#include "../encoding/block-helpers.hpp"
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -080018#include "../encoding/tlv-nfd.hpp"
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080019
20namespace ndn {
Alexander Afanasyeve289b532014-02-09 22:14:44 -080021namespace nfd {
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080022
23/**
Alexander Afanasyev4671bf72014-05-19 09:01:37 -040024 * @ingroup management
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080025 * @brief Class defining abstraction of ControlResponse for NFD Control Protocol
26 *
27 * @see http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
28 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070029class ControlResponse
30{
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080031public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070032 class Error : public Tlv::Error
33 {
34 public:
35 explicit
36 Error(const std::string& what)
37 : Tlv::Error(what)
38 {
39 }
40 };
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080041
42 ControlResponse()
43 : m_code(200)
44 {
45 }
46
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047 ControlResponse(uint32_t code, const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080048 : m_code(code)
49 , m_text(text)
50 {
51 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080052
53 ControlResponse(const Block& block)
54 {
55 wireDecode(block);
56 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080058 inline uint32_t
59 getCode() const;
60
61 inline void
62 setCode(uint32_t code);
63
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070064 inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080065 getText() const;
66
67 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070068 setText(const std::string& text);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080069
70 inline const Block&
71 getBody() const;
72
73 inline void
74 setBody(const Block& body);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070075
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080076 inline const Block&
77 wireEncode() const;
78
79 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070080 wireDecode(const Block& block);
81
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080082protected:
83 uint32_t m_code;
84 std::string m_text;
85 Block m_body;
86
87 mutable Block m_wire;
88};
89
90inline uint32_t
91ControlResponse::getCode() const
92{
93 return m_code;
94}
95
96inline void
97ControlResponse::setCode(uint32_t code)
98{
99 m_code = code;
100 m_wire.reset();
101}
102
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700103inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800104ControlResponse::getText() const
105{
106 return m_text;
107}
108
109inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110ControlResponse::setText(const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800111{
112 m_text = text;
113 m_wire.reset();
114}
115
116inline const Block&
117ControlResponse::getBody() const
118{
119 return m_body;
120}
121
122inline void
123ControlResponse::setBody(const Block& body)
124{
125 m_body = body;
126 m_body.encode(); // will do nothing if already encoded
127 m_wire.reset();
128}
129
130
131inline const Block&
132ControlResponse::wireEncode() const
133{
134 if (m_wire.hasWire())
135 return m_wire;
136
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800137 m_wire = Block(tlv::nfd::ControlResponse);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800138 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800139 (nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800140
141 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800142 (dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800143
144 if (m_body.hasWire())
145 {
146 m_wire.push_back(m_body);
147 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700148
149 m_wire.encode();
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800150 return m_wire;
151}
152
153inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700154ControlResponse::wireDecode(const Block& wire)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800155{
156 m_wire = wire;
157 m_wire.parse();
158
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800159 if (m_wire.type() != tlv::nfd::ControlResponse)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700160 throw Error("Requested decoding of ControlResponse, but Block is of different type");
161
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800162 Block::element_const_iterator val = m_wire.elements_begin();
163 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800164 val->type() != tlv::nfd::StatusCode)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800165 {
166 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
167 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700168
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800169 m_code = readNonNegativeInteger(*val);
170 ++val;
171
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800172 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800173 val->type() != tlv::nfd::StatusText)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800174 {
175 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
176 }
177 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
178 ++val;
179
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800180 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800181 m_body = *val;
182 else
183 m_body = Block();
184}
185
186inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700187operator << (std::ostream& os, const ControlResponse& status)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800188{
189 os << status.getCode() << " " << status.getText();
190 return os;
191}
192
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800193} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800194} // namespace ndn
195
196#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP