Scarab  v3.9.1
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_ptr_t 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_ptr_t 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_ptr_t param_input_json::read_document( const rapidjson::Document& a_doc )
102  {
103  return read_value( a_doc );
104  }
105 
106  param_ptr_t param_input_json::read_value( const rapidjson::Value& a_value )
107  {
108  if( a_value.IsNull() )
109  {
110  return std::unique_ptr< param >( new param() );
111  }
112  if( a_value.IsObject() )
113  {
114  std::unique_ptr< param_node > t_obj_as_param( new param_node() );
115  for( rapidjson::Value::ConstMemberIterator jsonIt = a_value.MemberBegin();
116  jsonIt != a_value.MemberEnd();
117  ++jsonIt)
118  {
119  t_obj_as_param->replace( jsonIt->name.GetString(), param_input_json::read_value( jsonIt->value ) );
120  }
121  return t_obj_as_param;
122  }
123  if( a_value.IsArray() )
124  {
125  std::unique_ptr< param_array > t_array_as_param( new param_array() );
126  for( rapidjson::Value::ConstValueIterator jsonIt = a_value.Begin();
127  jsonIt != a_value.End();
128  ++jsonIt)
129  {
130  t_array_as_param->push_back( std::move(*param_input_json::read_value( *jsonIt )) );
131  }
132  return t_array_as_param;
133  }
134  if( a_value.IsString() )
135  {
136  //LWARN( dlog, "reading string from json: " << a_value.GetString() );
137  return std::unique_ptr< param_value >( new param_value( a_value.GetString() ) );
138  }
139  if( a_value.IsBool() )
140  {
141  //LWARN( dlog, "reading bool from json: " << a_value.GetBool() );
142  return std::unique_ptr< param_value >( new param_value( a_value.GetBool() ) );
143  }
144  if( a_value.IsInt() )
145  {
146  //LWARN( dlog, "reading int from json: " << a_value.GetInt() );
147  return std::unique_ptr< param_value >( new param_value( a_value.GetInt() ) ) ;
148  }
149  if( a_value.IsUint() )
150  {
151  //LWARN( dlog, "reading uint from json: " << a_value.GetUint() );
152  return std::unique_ptr< param_value >( new param_value( a_value.GetUint() ) );
153  }
154  if( a_value.IsInt64() )
155  {
156  //LWARN( dlog, "reading int64 from json: " << a_value.GetInt64() );
157  return std::unique_ptr< param_value >( new param_value( a_value.GetInt64() ) );
158  }
159  if( a_value.IsUint64() )
160  {
161  //LWARN( dlog, "reading uint64 from json: " << a_value.GetUint64() );
162  return std::unique_ptr< param_value >( new param_value( a_value.GetUint64() ) );
163  }
164  if( a_value.IsDouble() )
165  {
166  //LWARN( dlog, "reading double from json: " << a_value.GetDouble() );
167  return std::unique_ptr< param_value >( new param_value( a_value.GetDouble() ) );
168  }
169  LWARN( dlog, "(config_reader_json) unknown type; returning null value" );
170  return std::unique_ptr< param >( new param() );
171  }
172 
173 
175 
177  {}
178 
180  {}
181 
182  bool param_output_json::write_file( const param& a_to_write, const std::string& a_filename, const param_node& a_options )
183  {
184  if( a_filename.empty() )
185  {
186  LERROR( dlog, "Filename cannot be an empty string" );
187  return false;
188  }
189 
190  FILE* file = fopen( a_filename.c_str(), "w" );
191  if( file == NULL )
192  {
193  LERROR( dlog, "Unable to open file: " << a_filename );
194  return false;
195  }
196 
197  char t_buffer[ RAPIDJSON_FILE_BUFFER_SIZE ];
198  rapidjson::FileWriteStream t_filestream( file, t_buffer, sizeof(t_buffer) );
199 
200  json_writing_style t_style = k_compact;
201  if( a_options.has( "style" ) )
202  {
203  if( a_options["style"]().is_uint() )
204  {
205  t_style = (json_writing_style)a_options.get_value< unsigned >( "style", k_compact );
206  }
207  else
208  {
209  string t_style_string( a_options.get_value( "style", "compact" ) );
210  if( t_style_string == string( "pretty" ) ) t_style = k_pretty;
211  }
212  }
213 
214  bool t_result = false;
215  if( t_style == k_compact )
216  {
217  rj_file_writer t_writer( t_filestream );
218  t_result = param_output_json::write_param( a_to_write, &t_writer );
219  }
220  else
221  {
222  rj_pretty_file_writer t_writer( t_filestream );
223  t_result = param_output_json::write_param( a_to_write, &t_writer );
224  }
225 
226  if (! t_result )
227  {
228  LERROR( dlog, "Error while writing file" );
229  return false;
230  }
231 
232  return true;
233  }
234 
235  bool param_output_json::write_string( const param& a_to_write, std::string& a_string, const param_node& a_options )
236  {
237  rapidjson::StringBuffer t_str_buff;
238 
239  json_writing_style t_style = k_compact;
240  if( a_options.has( "style" ) )
241  {
242  if( a_options["style"]().is_uint() )
243  {
244  t_style = (json_writing_style)a_options.get_value< unsigned >( "style", k_compact );
245  }
246  else
247  {
248  string t_style_string( a_options.get_value( "style", "compact" ) );
249  if( t_style_string == string( "pretty" ) ) t_style = k_pretty;
250  }
251  }
252 
253  bool t_result = false;
254  if( t_style == k_compact )
255  {
256  rj_string_writer t_writer( t_str_buff );
257  t_result = param_output_json::write_param( a_to_write, &t_writer );
258  }
259  else
260  {
261  rj_pretty_string_writer t_writer( t_str_buff );
262  t_result = param_output_json::write_param( a_to_write, &t_writer );
263  }
264 
265  if (! t_result )
266  {
267  LERROR( dlog, "Error while writing string" );
268  return false;
269  }
270 
271  a_string.assign( t_str_buff.GetString() );
272 
273  return true;
274  }
275 
276 } /* namespace scarab */
param_ptr_t read_value(const rapidjson::Value &a_value)
Definition: param_json.cc:106
#define LWARN(...)
Definition: logger.hh:393
virtual param_ptr_t read_string(const std::string &a_json_str, const param_node &a_options=param_node())
Definition: param_json.cc:90
bool write_param(const param &a_to_write, XWriter *a_writer)
Definition: param_json.hh:106
LOGGER(mtlog, "authentication")
rapidjson::PrettyWriter< rapidjson::StringBuffer > rj_pretty_string_writer
Definition: param_json.hh:77
#define LERROR(...)
Definition: logger.hh:394
virtual param_ptr_t read_file(const std::string &a_filename, const param_node &a_options=param_node())
Definition: param_json.cc:38
std::string get_value(const std::string &a_name, const std::string &a_default) const
Definition: param_node.hh:208
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
param_ptr_t read_document(const rapidjson::Document &a_document)
Definition: param_json.cc:101
virtual bool write_string(const param &a_to_write, std::string &a_string, const param_node &a_options=param_node())
Definition: param_json.cc:235
REGISTER_PARAM_INPUT_CODEC(param_input_json, "json")
Convert Param to JSON.
Definition: param_json.hh:71
std::unique_ptr< param > param_ptr_t
Definition: param_base.hh:23
REGISTER_PARAM_OUTPUT_CODEC(param_output_json, "json")
rapidjson::Writer< rapidjson::FileWriteStream > rj_file_writer
Definition: param_json.hh:74
virtual bool write_file(const param &a_to_write, const std::string &a_filename, const param_node &a_options=param_node())
Definition: param_json.cc:182
bool has(const std::string &a_name) const
Definition: param_node.hh:198
rapidjson::Writer< rapidjson::StringBuffer > rj_string_writer
Definition: param_json.hh:76