Pakman
deserialisation.cc
1 #include <stdexcept>
2 #include <sstream>
3 
4 #include "deserialisation.h"
5 
6 void read_key(const LineString& key, std::istream& in)
7 {
8  // Read until ':'
9  std::string read_key;
10  std::getline(in, read_key, ':');
11 
12  // Check input stream
13  if (!in)
14  {
15  std::string error_msg("deserialisation failed, ");
16  error_msg += "could not read key";
17  std::runtime_error e(error_msg);
18  throw e;
19  }
20 
21  // Check key
22  if (read_key != key.str())
23  {
24  std::string error_msg("deserialisation failed, read key ('");
25  error_msg += read_key;
26  error_msg += "') did not match queried key ('";
27  error_msg += key.str();
28  error_msg += "')";
29  std::runtime_error e(error_msg);
30  throw e;
31  }
32 }
33 
34 std::string read_value(std::istream& in)
35 {
36  // Read until newline
37  std::string read_value;
38  std::getline(in, read_value);
39 
40  // Check input stream
41  if (!in)
42  {
43  std::string error_msg("deserialisation failed, ");
44  error_msg += "could not read value";
45  std::runtime_error e(error_msg);
46  throw e;
47  }
48 
49  return read_value;
50 }
51 
52 template <>
53 bool deserialise_scalar_value(const LineString& key, std::istream& in)
54 {
55  // Read key
56  read_key(key, in);
57 
58  // Read value
59  auto value_string = read_value(in);
60 
61  // Deserialise value
62  bool val;
63  std::istringstream isstr(value_string);
64  isstr >> std::boolalpha >> val;
65 
66  // Check input stream
67  if (!isstr)
68  {
69  std::string error_msg("deserialisation failed, ");
70  error_msg += "could not extract value";
71  std::runtime_error e(error_msg);
72  throw e;
73  }
74 
75  return val;
76 }
77 
78 template <>
79 std::string deserialise_scalar_value(const LineString& key, std::istream& in)
80 {
81  // Read key
82  read_key(key, in);
83 
84  // Read string size
85  std::string string_size_string;
86  std::getline(in, string_size_string, ':');
87 
88  // Check input stream
89  if (!in)
90  {
91  std::string error_msg("deserialisation failed, ");
92  error_msg += "could not read string size";
93  std::runtime_error e(error_msg);
94  throw e;
95  }
96 
97  // Extract string size
98  unsigned string_size;
99  std::istringstream isstr(string_size_string);
100  isstr >> string_size;
101 
102  // Check input stream
103  if (!isstr)
104  {
105  std::string error_msg("deserialisation failed, ");
106  error_msg += "could not extract string size";
107  std::runtime_error e(error_msg);
108  throw e;
109  }
110 
111  // Extract string, including trailing new newline character
112  char buf[string_size + 1];
113  in.read(buf, string_size + 1);
114  buf[string_size] = '\0';
115 
116  if (!in)
117  {
118  std::string error_msg("deserialisation failed, ");
119  error_msg += "could not extract string";
120  std::runtime_error e(error_msg);
121  throw e;
122  }
123 
124  std::string val(buf);
125  return val;
126 }
127 
128 template <>
129 Command deserialise_scalar_value(const LineString& key, std::istream& in)
130 {
131  // Read string
132  auto raw_command_string = deserialise_scalar_value<std::string>(key, in);
133 
134  // Construct and return command
135  return static_cast<Command>(raw_command_string);
136 }
137 
138 template <>
139 TaskHandler deserialise_scalar_value(const LineString& key, std::istream& in)
140 {
141  read_key(key, in);
142  auto input_string = deserialise_scalar_value<std::string>("m_input_string",
143  in);
144 
145  read_key(key, in);
146  auto output_string = deserialise_scalar_value<std::string>(
147  "m_output_string", in);
148 
149  read_key(key, in);
150  auto error_code = deserialise_scalar_value<int>("m_error_code", in);
151 
152  TaskHandler task(input_string);
153 
154  // If pending task, return without recording output string and error code
155  if (output_string.empty() && (error_code == -1))
156  {
157  return task;
158  }
159 
160  // If finished task, return after recording output string and error code
161  task.recordOutputAndErrorCode(output_string, error_code);
162 
163  return task;
164 }
165 
166 std::istream& operator>>(std::istream& in, LineString& line_string)
167 {
168  // Extract to string
169  std::string str;
170  in >> str;
171 
172  // Assign LineString
173  line_string = LineString(str);
174 
175  return in;
176 }
const std::string & str() const
Definition: LineString.cc:45
value_type deserialise_scalar_value(const LineString &key, std::istream &in)
void read_key(const LineString &key, std::istream &in)
std::istream & operator>>(std::istream &in, LineString &line_string)
std::string read_value(std::istream &in)