RInside Version 0.2.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rinsideclient.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Christian Authmann
3  */
4 
5 
6 #include "rinsideclient.h"
7 #include "common/constants.h"
8 #include <exception>
9 #include <stdexcept>
10 
11 
12 RInsideClient::RInsideClient(BinaryStream &_stream) : stream(std::move(_stream)), next_callback_id(1), had_unrecoverable_error(false), can_send_command(false) {
14  can_send_command = true;
15 }
16 
19  try {
21  }
22  catch (...) {
23  // don't ever throw in a destructor!
24  }
25  }
26 }
27 
28 
29 void RInsideClient::runScript(const std::string code, int32_t result_typeid) {
31  stream.write(code);
32  stream.write(result_typeid);
33 
34  while (true) {
35  auto reply = stream.read<char>();
36  if (reply == RIS_REPLY_CALLBACK) {
37  auto callback_id = stream.read<uint32_t>();
38 
39  auto &func = callbacks.at(callback_id);
40  try {
41  func();
42  }
44  // This is a recoverable error!
45  can_send_command = true;
46  throw std::runtime_error(e.what());
47  }
48  catch (...) {
50  throw;
51  }
52  }
53  else if (reply == RIS_REPLY_OK) {
54  if (result_typeid != 0)
55  unrecoverable_error("runScript() did not return a value when one was requested");
56  return;
57  }
58  else if (reply == RIS_REPLY_VALUE) {
59  if (result_typeid == 0)
60  unrecoverable_error("runScript() did return a value when none was requested");
61 
62  auto type = stream.read<int32_t>();
63  if (type != result_typeid)
64  unrecoverable_error("runScript() did return a value of the wrong type");
65  return;
66  }
67  }
68 }
69 
72  readReply(false, true);
73  auto result = stream.read<std::string>();
74  can_send_command = true;
75  return result;
76 }
77 
78 
79 void RInsideClient::initPlot(uint32_t width, uint32_t height) {
81  stream.write(width);
82  stream.write(height);
83  readReply(true, false);
84  can_send_command = true;
85 }
86 
87 std::string RInsideClient::getPlot() {
89  readReply(false, true);
90  auto result = stream.read<std::string>();
91  can_send_command = true;
92  return result;
93 }
94 
95 void RInsideClient::writeCommand(char command) {
97  throw std::runtime_error("RInsideClient cannot continue due to previous unrecoverable errors");
98  if (!can_send_command)
99  throw std::runtime_error("RInsideClient cannot send a command at this time");
100 
101  stream.write(command);
102  can_send_command = false;
103 }
104 
105 char RInsideClient::readReply(bool accept_ok, bool accept_value) {
106  auto reply = stream.read<char>();
107  if (reply == RIS_REPLY_ERROR) {
108  auto error = stream.read<std::string>();
109  can_send_command = true;
110  throw std::runtime_error(std::string("Error in R Server: ") + error);
111  }
112  if (reply == RIS_REPLY_OK && !accept_ok)
113  unrecoverable_error("Got unexpected reply from the R server");
114  if (reply == RIS_REPLY_VALUE && !accept_value)
115  unrecoverable_error("Got unexpected reply from the R server");
116 
117  return reply;
118 }
119 
120 void RInsideClient::unrecoverable_error(const std::string &error) {
122  throw std::runtime_error(error);
123 }
RInsideClient(BinaryStream &stream)
const char RIS_CMD_GETCONSOLE
Definition: constants.h:15
const char RIS_REPLY_OK
Definition: constants.h:21
bool had_unrecoverable_error
Definition: rinsideclient.h:99
const uint32_t RIS_MAGIC_NUMBER
Definition: constants.h:10
const char RIS_CMD_RUN
Definition: constants.h:14
void unrecoverable_error(const std::string &error)
const char RIS_CMD_INITPLOT
Definition: constants.h:16
char readReply(bool accept_ok=true, bool accept_value=false)
const char RIS_REPLY_ERROR
Definition: constants.h:24
const char RIS_CMD_GETPLOT
Definition: constants.h:17
void write(const char *buffer, size_t len)
std::string getPlot()
BinaryStream stream
Definition: rinsideclient.h:96
void initPlot(uint32_t width=800, uint32_t height=600)
const char RIS_CMD_EXIT
Definition: constants.h:18
const char RIS_REPLY_CALLBACK
Definition: constants.h:22
const char RIS_REPLY_VALUE
Definition: constants.h:23
std::map< uint32_t, std::function< void(void)> > callbacks
Definition: rinsideclient.h:98
void writeCommand(char command)
std::string getConsoleOutput()
void runScript(const std::string code, int32_t result_typeid)
size_t read(char *buffer, size_t len)