blob: c239804e8d7f5cf45e824c27c662720dcff3bddd [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/**
24 * @brief Class defining abstraction of ControlResponse for NFD Control Protocol
25 *
26 * @see http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
27 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070028class ControlResponse
29{
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080030public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070031 class Error : public Tlv::Error
32 {
33 public:
34 explicit
35 Error(const std::string& what)
36 : Tlv::Error(what)
37 {
38 }
39 };
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080040
41 ControlResponse()
42 : m_code(200)
43 {
44 }
45
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070046 ControlResponse(uint32_t code, const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080047 : m_code(code)
48 , m_text(text)
49 {
50 }
Alexander Afanasyeve289b532014-02-09 22:14:44 -080051
52 ControlResponse(const Block& block)
53 {
54 wireDecode(block);
55 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080057 inline uint32_t
58 getCode() const;
59
60 inline void
61 setCode(uint32_t code);
62
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070063 inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080064 getText() const;
65
66 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067 setText(const std::string& text);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080068
69 inline const Block&
70 getBody() const;
71
72 inline void
73 setBody(const Block& body);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070074
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080075 inline const Block&
76 wireEncode() const;
77
78 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 wireDecode(const Block& block);
80
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -080081protected:
82 uint32_t m_code;
83 std::string m_text;
84 Block m_body;
85
86 mutable Block m_wire;
87};
88
89inline uint32_t
90ControlResponse::getCode() const
91{
92 return m_code;
93}
94
95inline void
96ControlResponse::setCode(uint32_t code)
97{
98 m_code = code;
99 m_wire.reset();
100}
101
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700102inline const std::string&
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800103ControlResponse::getText() const
104{
105 return m_text;
106}
107
108inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700109ControlResponse::setText(const std::string& text)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800110{
111 m_text = text;
112 m_wire.reset();
113}
114
115inline const Block&
116ControlResponse::getBody() const
117{
118 return m_body;
119}
120
121inline void
122ControlResponse::setBody(const Block& body)
123{
124 m_body = body;
125 m_body.encode(); // will do nothing if already encoded
126 m_wire.reset();
127}
128
129
130inline const Block&
131ControlResponse::wireEncode() const
132{
133 if (m_wire.hasWire())
134 return m_wire;
135
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800136 m_wire = Block(tlv::nfd::ControlResponse);
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800137 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800138 (nonNegativeIntegerBlock(tlv::nfd::StatusCode, m_code));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800139
140 m_wire.push_back
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800141 (dataBlock(tlv::nfd::StatusText, m_text.c_str(), m_text.size()));
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800142
143 if (m_body.hasWire())
144 {
145 m_wire.push_back(m_body);
146 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147
148 m_wire.encode();
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800149 return m_wire;
150}
151
152inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700153ControlResponse::wireDecode(const Block& wire)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800154{
155 m_wire = wire;
156 m_wire.parse();
157
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800158 if (m_wire.type() != tlv::nfd::ControlResponse)
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700159 throw Error("Requested decoding of ControlResponse, but Block is of different type");
160
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800161 Block::element_const_iterator val = m_wire.elements_begin();
162 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800163 val->type() != tlv::nfd::StatusCode)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800164 {
165 throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
166 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700167
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800168 m_code = readNonNegativeInteger(*val);
169 ++val;
170
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800171 if (val == m_wire.elements_end() ||
Alexander Afanasyev6d48bc12014-02-18 00:10:51 -0800172 val->type() != tlv::nfd::StatusText)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800173 {
174 throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
175 }
176 m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
177 ++val;
178
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800179 if (val != m_wire.elements_end())
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800180 m_body = *val;
181 else
182 m_body = Block();
183}
184
185inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700186operator << (std::ostream& os, const ControlResponse& status)
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800187{
188 os << status.getCode() << " " << status.getText();
189 return os;
190}
191
Alexander Afanasyeve289b532014-02-09 22:14:44 -0800192} // namespace nfd
Alexander Afanasyeveaf105c2014-01-30 17:40:24 -0800193} // namespace ndn
194
195#endif // NDN_MANAGEMENT_CONTROL_RESPONSE_HPP