Scarab  v1.6.2
Project 8 C++ Utility Library
param_json.cc
Go to the documentation of this file.
1 /*
2  * param_json.cc
3  *
4  * Created on: March 27, 2015
5  * Author: nsoblath, bhlaroque
6  */
7 
8 #define SCARAB_API_EXPORTS
9 
10 #include <sstream>
11 using std::string;
12 using std::stringstream;
13 
14 #include "param_json.hh"
15 
16 #include "logger.hh"
17 
18 #include "rapidjson/document.h"
19 #include "rapidjson/filereadstream.h"
20 #include "rapidjson/filewritestream.h"
21 #include "rapidjson/stringbuffer.h"
22 
23 
24 
25 namespace scarab
26 {
27  LOGGER( dlog, "param" );
28 
29  REGISTER_PARAM_INPUT_CODEC( param_input_json, "json" );
30 
32  {
33  }
35  {
36  }
37 
38  param* param_input_json::read_file( const std::string& a_filename, const param_node* )
39  {
40  FILE* t_config_file = fopen( a_filename.c_str(), "r" );
41  if( t_config_file == NULL )
42  {
43  LERROR( dlog, "file <" << a_filename << "> did not open" );
44  return NULL;
45  }
46 
47  char t_buffer[ RAPIDJSON_FILE_BUFFER_SIZE ];
48  rapidjson::FileReadStream t_file_stream( t_config_file, t_buffer, sizeof(t_buffer) );
49 
50  rapidjson::Document t_config_doc;
51  if( t_config_doc.ParseStream<0>( t_file_stream ).HasParseError() )
52  {
53  unsigned errorPos = t_config_doc.GetErrorOffset();
54  rewind( t_config_file );
55  unsigned iChar, newlineCount = 1, lastNewlinePos = 0;
56  int thisChar;
57  for( iChar = 0; iChar != errorPos; ++iChar )
58  {
59  thisChar = fgetc( t_config_file );
60  if( thisChar == EOF )
61  {
62  break;
63  }
64  if( thisChar == '\n' || thisChar == '\r' )
65  {
66  newlineCount++;
67  lastNewlinePos = iChar + 1;
68  }
69  }
70  if( iChar == errorPos )
71  {
72  LERROR( dlog, "error parsing config file :\n" <<
73  '\t' << t_config_doc.GetParseError() << '\n' <<
74  "\tThe error was reported at line " << newlineCount << ", character " << errorPos - lastNewlinePos );
75  }
76  else
77  {
78  LERROR( dlog, "error parsing config file :\n" <<
79  '\t' << t_config_doc.GetParseError() <<
80  "\tend of file reached before error location was found" );
81  }
82  fclose( t_config_file );
83  return NULL;
84  }
85  fclose( t_config_file );
86 
87  return param_input_json::read_document( t_config_doc );
88  }
89 
90  param* param_input_json::read_string( const std::string& a_json_string, const param_node* )
91  {
92  rapidjson::Document t_config_doc;
93  if( t_config_doc.Parse<0>( a_json_string.c_str() ).HasParseError() )
94  {
95  LERROR( dlog, "error parsing string:\n" << t_config_doc.GetParseError() );
96  return NULL;
97  }
98  return param_input_json::read_document( t_config_doc );
99  }
100 
101  param_node* param_input_json::read_document( const rapidjson::Document& a_doc )
102  {
103  param_node* t_config = new param_node();
104  for( rapidjson::Value::ConstMemberIterator jsonIt = a_doc.MemberBegin();
105  jsonIt != a_doc.MemberEnd();
106  ++jsonIt)
107  {
108  t_config->replace( jsonIt->name.GetString(), param_input_json::read_value( jsonIt->value ) );
109  }
110  return t_config;
111  }
112 
113  param* param_input_json::read_value( const rapidjson::Value& a_value )
114  {
115  if( a_value.IsNull() )
116  {
117  return new param();
118  }
119  if( a_value.IsObject() )
120  {
121  param_node* t_config_object = new param_node();
122  for( rapidjson::Value::ConstMemberIterator jsonIt = a_value.MemberBegin();
123  jsonIt != a_value.MemberEnd();
124  ++jsonIt)
125  {
126  t_config_object->replace( jsonIt->name.GetString(), param_input_json::read_value( jsonIt->value ) );
127  }
128  return t_config_object;
129  }
130  if( a_value.IsArray() )
131  {
132  param_array* t_config_array = new param_array();
133  for( rapidjson::Value::ConstValueIterator jsonIt = a_value.Begin();
134  jsonIt != a_value.End();
135  ++jsonIt)
136  {
137  t_config_array->push_back( param_input_json::read_value( *jsonIt ) );
138  }
139  return t_config_array;
140  }
141  if( a_value.IsString() )
142  {
143  //LWARN( dlog, "reading string from json: " << a_value.GetString() );
144  return new param_value( a_value.GetString() );
145  }
146  if( a_value.IsBool() )
147  {
148  //LWARN( dlog, "reading bool from json: " << a_value.GetBool() );
149  return new param_value( a_value.GetBool() );
150  }
151  if( a_value.IsInt() )
152  {
153  //LWARN( dlog, "reading int from json: " << a_value.GetInt() );
154  return new param_value( a_value.GetInt() );
155  }
156  if( a_value.IsUint() )
157  {
158  //LWARN( dlog, "reading uint from json: " << a_value.GetUint() );
159  return new param_value( a_value.GetUint() );
160  }
161  if( a_value.IsInt64() )
162  {
163  //LWARN( dlog, "reading int64 from json: " << a_value.GetInt64() );
164  return new param_value( a_value.GetInt64() );
165  }
166  if( a_value.IsUint64() )
167  {
168  //LWARN( dlog, "reading uint64 from json: " << a_value.GetUint64() );
169  return new param_value( a_value.GetUint64() );
170  }
171  if( a_value.IsDouble() )
172  {
173  //LWARN( dlog, "reading double from json: " << a_value.GetDouble() );
174  return new param_value( a_value.GetDouble() );
175  }
176  LWARN( dlog, "(config_reader_json) unknown type; returning null value" );
177  return new param();
178  }
179 
180 
182 
184  {}
185 
187  {}
188 
189  bool param_output_json::write_file( const param& a_to_write, const std::string& a_filename, const param_node* a_options )
190  {
191  if( a_filename.empty() )
192  {
193  LERROR( dlog, "Filename cannot be an empty string" );
194  return false;
195  }
196 
197  FILE* file = fopen( a_filename.c_str(), "w" );
198  if( file == NULL )
199  {
200  LERROR( dlog, "Unable to open file: " << a_filename );
201  return false;
202  }
203 
204  char t_buffer[ RAPIDJSON_FILE_BUFFER_SIZE ];
205  rapidjson::FileWriteStream t_filestream( file, t_buffer, sizeof(t_buffer) );
206 
207  json_writing_style t_style = k_compact;
208  if( a_options != nullptr && a_options->has( "style" ) )
209  {
210  if( a_options->value_at( "style" )->is_uint() )
211  {
212  t_style = (json_writing_style)a_options->get_value< unsigned >( "style", k_compact );
213  }
214  else
215  {
216  string t_style_string( a_options->get_value( "style", "compact" ) );
217  if( t_style_string == string( "pretty" ) ) t_style = k_pretty;
218  }
219  }
220 
221  bool t_result = false;
222  if( t_style == k_compact )
223  {
224  rj_file_writer t_writer( t_filestream );
225  t_result = param_output_json::write_param( a_to_write, &t_writer );
226  }
227  else
228  {
229  rj_pretty_file_writer t_writer( t_filestream );
230  t_result = param_output_json::write_param( a_to_write, &t_writer );
231  }
232 
233  if (! t_result )
234  {
235  LERROR( dlog, "Error while writing file" );
236  return false;
237  }
238 
239  return true;
240  }
241 
242  bool param_output_json::write_string( const param& a_to_write, std::string& a_string, const param_node* a_options )
243  {
244  rapidjson::StringBuffer t_str_buff;
245 
246  json_writing_style t_style = k_compact;
247  if( a_options != nullptr && a_options->has( "style" ) )
248  {
249  if( a_options->value_at( "style" )->is_uint() )
250  {
251  t_style = (json_writing_style)a_options->get_value< unsigned >( "style", k_compact );
252  }
253  else
254  {
255  string t_style_string( a_options->get_value( "style", "compact" ) );
256  if( t_style_string == string( "pretty" ) ) t_style = k_pretty;
257  }
258  }
259 
260  bool t_result = false;
261  if( t_style == k_compact )
262  {
263  rj_string_writer t_writer( t_str_buff );
264  t_result = param_output_json::write_param( a_to_write, &t_writer );
265  }
266  else
267  {
268  rj_pretty_string_writer t_writer( t_str_buff );
269  t_result = param_output_json::write_param( a_to_write, &t_writer );
270  }
271 
272  if (! t_result )
273  {
274  LERROR( dlog, "Error while writing string" );
275  return false;
276  }
277 
278  a_string.assign( t_str_buff.GetString() );
279 
280  return true;
281  }
282 
283 } /* namespace scarab */
void replace(const std::string &a_name, const param &a_value)
creates a copy of a_value
Definition: param.hh:1142
REGISTER_PARAM_INPUT_CODEC(param_input_json,"json")
#define LWARN(...)
Definition: logger.hh:364
REGISTER_PARAM_OUTPUT_CODEC(param_output_json,"json")
bool write_param(const param &a_to_write, XWriter *a_writer)
Definition: param_json.hh:106
bool is_uint() const
Definition: param.hh:578
rapidjson::PrettyWriter< rapidjson::StringBuffer > rj_pretty_string_writer
Definition: param_json.hh:77
#define LERROR(...)
Definition: logger.hh:365
const param_value * value_at(const std::string &a_name) const
Definition: param.hh:1045
Contains the logger class and macros, based on Kasper&#39;s KLogger class.
rapidjson::PrettyWriter< rapidjson::FileWriteStream > rj_pretty_file_writer
Definition: param_json.hh:75
virtual bool write_file(const param &a_to_write, const std::string &a_filename, const param_node *a_options=nullptr)
Definition: param_json.cc:189
param_node * read_document(const rapidjson::Document &a_document)
Definition: param_json.cc:101
std::string get_value(const std::string &a_name) const
Definition: param.hh:1006
bool has(const std::string &a_name) const
Definition: param.hh:996
Convert Param to JSON.
Definition: param_json.hh:71
virtual param * read_string(const std::string &a_json_str, const param_node *a_options=nullptr)
Definition: param_json.cc:90
param * read_value(const rapidjson::Value &a_value)
Definition: param_json.cc:113
virtual bool write_string(const param &a_to_write, std::string &a_string, const param_node *a_options=nullptr)
Definition: param_json.cc:242
rapidjson::Writer< rapidjson::FileWriteStream > rj_file_writer
Definition: param_json.hh:74
virtual param * read_file(const std::string &a_filename, const param_node *a_options=nullptr)
Definition: param_json.cc:38
void push_back(const param &a_value)
Definition: param.hh:858
rapidjson::Writer< rapidjson::StringBuffer > rj_string_writer
Definition: param_json.hh:76
LOGGER(mtlog,"authentication")