URY playd
C++ minimalist audio player
response.cpp
Go to the documentation of this file.
1 // This file is part of playd.
2 // playd is licensed under the MIT licence: see LICENSE.txt.
3 
10 #include <array>
11 #include <cctype>
12 #include <sstream>
13 
14 #include "errors.hpp"
15 
16 #include "response.hpp"
17 
18 /* static */ const std::string Response::NOREQUEST = "!";
19 
20 /* static */ const std::array<std::string, Response::CODE_COUNT> Response::STRINGS {{
21  "OHAI", // Code::OHAI
22  "IAMA", // Code::IAMA
23  "FLOAD", // Code::FLOAD
24  "EJECT", // Code::EJECT
25  "POS", // Code::POS
26  "END", // Code::END
27  "PLAY", // Code::PLAY
28  "STOP", // Code::STOP
29  "ACK" // Code::ACK
30 }};
31 
32 Response::Response(const std::string &tag, Response::Code code)
33 {
34  this->string = Response::EscapeArg(tag) + " " +
35  STRINGS[static_cast<uint8_t>(code)];
36 }
37 
38 Response &Response::AddArg(const std::string &arg)
39 {
40  this->string += " " + Response::EscapeArg(arg);
41  return *this;
42 }
43 
44 std::string Response::Pack() const
45 {
46  return this->string;
47 }
48 
49 /* static */ Response Response::Success(const std::string &tag)
50 {
51  return Response(tag, Response::Code::ACK)
52  .AddArg("OK")
53  .AddArg("success");
54 }
55 
56 /* static */ Response Response::Invalid(const std::string &tag,
57  const std::string &msg)
58 {
59  return Response(tag, Response::Code::ACK).AddArg("WHAT").AddArg(msg);
60 }
61 
62 /* static */ Response Response::Failure(const std::string &tag,
63  const std::string &msg)
64 {
65  return Response(tag, Response::Code::ACK).AddArg("FAIL").AddArg(msg);
66 }
67 
68 /* static */ std::string Response::EscapeArg(const std::string &arg)
69 {
70  bool escaping = false;
71  std::string escaped;
72 
73  for (char c : arg) {
74  // These are the characters (including all whitespace, via
75  // isspace()) whose presence means we need to single-quote
76  // escape the argument.
77  bool is_escaper = c == '"' || c == '\'' || c == '\\';
78  if (isspace(c) || is_escaper) escaping = true;
79 
80  // Since we use single-quote escaping, the only thing we need
81  // to escape by itself is single quotes, which are replaced by
82  // the sequence '\'' (break out of single quotes, escape a
83  // single quote, then re-enter single quotes).
84  escaped += (c == '\'') ? R"('\'')" : std::string(1, c);
85  }
86 
87  // Only single-quote escape if necessary.
88  // Otherwise, it wastes two characters!
89  if (escaping) return "'" + escaped + "'";
90  return escaped;
91 }
92 
93 //
94 // ResponseSink
95 //
96 
97 void ResponseSink::Respond(size_t, const Response &) const
98 {
99  // By default, do nothing.
100 }
Declarations of the playd Error exception set.
A response.
Definition: response.hpp:23
std::string Pack() const
Packs the Response, converting it to a BAPS3 protocol message.
Definition: response.cpp:44
std::string string
The current packed form of the response.
Definition: response.hpp:111
static const std::array< std::string, CODE_COUNT > STRINGS
A map from Response::Code codes to their string equivalents.
Definition: response.hpp:100
virtual void Respond(size_t id, const Response &response) const
Outputs a response.
Definition: response.cpp:97
Command result.
static const std::string NOREQUEST
The tag for unsolicited messages (not from responses).
Definition: response.hpp:27
static Response Success(const std::string &tag)
Shortcut for constructing a final response to a successful request.
Definition: response.cpp:49
Response(const std::string &tag, Response::Code code)
Constructs a Response with no arguments.
Definition: response.cpp:32
static Response Failure(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a failed request.
Definition: response.cpp:62
static std::string EscapeArg(const std::string &arg)
Escapes a single response argument.
Definition: response.cpp:68
Declaration of classes pertaining to responses to the client.
Response & AddArg(const std::string &arg)
Adds an argument to this Response.
Definition: response.cpp:38
Code
Enumeration of all possible response codes.
Definition: response.hpp:35
static Response Invalid(const std::string &tag, const std::string &msg)
Shortcut for constructing a final response to a invalid request.
Definition: response.cpp:56