SHOGUN  4.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SerializableJsonFile.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010 Soeren Sonnenburg
8  * Copyright (C) 2010 Berlin Institute of Technology
9  */
10 
11 #include <shogun/lib/config.h>
12 #ifdef HAVE_JSON
13 
16 
17 #define STR_KEY_FILETYPE "filetype"
18 #define STR_FILETYPE_00 \
19  "_SHOGUN_SERIALIZABLE_JSON_FILE_V_00_"
20 
21 using namespace shogun;
22 
23 CSerializableJsonFile::CSerializableJsonFile()
24  :CSerializableFile() { init(""); }
25 
26 CSerializableJsonFile::CSerializableJsonFile(const char* fname, char rw)
28 {
29  CSerializableFile::init(NULL, rw, fname);
30  init(fname);
31 }
32 
33 CSerializableJsonFile::~CSerializableJsonFile()
34 {
35  close();
36 }
37 
39 CSerializableJsonFile::new_reader(char* dest_version, size_t n)
40 {
41  const char* ftype;
42  json_object* buf;
43 
44  bool success = json_object_object_get_ex(
45  m_stack_stream.back(), STR_KEY_FILETYPE, &buf);
46 
47  if (!success || buf == NULL
48  || is_error(buf)
49  || (ftype = json_object_get_string(buf)) == NULL)
50  return NULL;
51 
52  strncpy(dest_version, ftype, n);
53 
54  if (strcmp(STR_FILETYPE_00, dest_version) == 0)
55  return new SerializableJsonReader00(this);
56 
57  return NULL;
58 }
59 
60 void CSerializableJsonFile::push_object(json_object* o)
61 {
62  m_stack_stream.push_back(o);
63  json_object_get(o);
64 }
65 
66 void CSerializableJsonFile::pop_object()
67 {
68  json_object_put(m_stack_stream.back());
69  m_stack_stream.pop_back();
70 }
71 
72 bool
73 CSerializableJsonFile::get_object_any(
74  json_object** dest, json_object* src, const char* key)
75 {
76  return json_object_object_get_ex(src, key, & *dest);
77 }
78 
79 bool
80 CSerializableJsonFile::get_object(json_object** dest, json_object* src,
81  const char* key, json_type t)
82 {
83  bool success = true ;
84  success = json_object_object_get_ex(src, key, & *dest);
85 
86  return success && *dest != NULL && !is_error(*dest)
87  && json_object_is_type(*dest, t);
88 }
89 
90 void
91 CSerializableJsonFile::init(const char* fname)
92 {
93  if (m_filename == NULL || *m_filename == '\0') {
94  SG_WARNING("Filename not given for opening file!\n")
95  close();
96  return;
97  }
98 
99  json_object* buf;
100  switch (m_task) {
101  case 'r':
102  buf = json_object_from_file((char*) fname);
103  if (is_error(buf)) {
104  SG_ERROR("Could not open file `%s' for reading!\n",
105  fname);
106  return;
107  }
108  m_stack_stream.push_back(buf);
109  break;
110  case 'w':
111  m_stack_stream.push_back(json_object_new_object());
112  buf = json_object_new_string(STR_FILETYPE_00);
113  json_object_object_add(m_stack_stream.back(),
114  STR_KEY_FILETYPE, buf);
115  break;
116  default:
117  SG_WARNING("Could not open file `%s', unknown mode!\n",
118  m_filename);
119  close();
120  return;
121  }
122 }
123 
124 void
125 CSerializableJsonFile::close()
126 {
127  while (m_stack_stream.get_num_elements() > 1)
128  pop_object();
129 
130  if (m_stack_stream.get_num_elements() == 1) {
131  if (m_task == 'w'
132  && json_object_to_file(m_filename, m_stack_stream.back()))
133  {
134  SG_WARNING("Could not close file `%s' for writing!\n",
135  m_filename);
136  }
137 
138  pop_object();
139  }
140 }
141 
142 bool
143 CSerializableJsonFile::is_opened()
144 {
145  return m_stack_stream.get_num_elements() > 0;
146 }
147 
148 bool
149 CSerializableJsonFile::write_scalar_wrapped(
150  const TSGDataType* type, const void* param)
151 {
152  switch (type->m_ptype) {
153  case PT_BOOL:
154  push_object(json_object_new_boolean(*(bool*) param));
155  break;
156  case PT_CHAR:
157  push_object(json_object_new_int((int) *(char*) param));
158  break;
159  case PT_INT8:
160  push_object(json_object_new_int((int) *(int8_t*) param));
161  break;
162  case PT_UINT8:
163  push_object(json_object_new_int((int) *(uint8_t*) param));
164  break;
165  case PT_INT16:
166  push_object(json_object_new_int((int) *(int16_t*) param));
167  break;
168  case PT_UINT16:
169  push_object(json_object_new_int((int) *(uint16_t*) param));
170  break;
171  case PT_INT32:
172  push_object(json_object_new_int((int) *(int32_t*) param));
173  break;
174  case PT_UINT32:
175  push_object(json_object_new_int((int) *(uint32_t*) param));
176  break;
177  case PT_INT64:
178  push_object(json_object_new_int((int) *(int64_t*) param));
179  break;
180  case PT_UINT64:
181  push_object(json_object_new_int((int) *(uint64_t*) param));
182  break;
183  case PT_FLOAT32:
184 #if JSON_C_MINOR_VERSION >= 12
185  push_object(json_object_new_double_s(
186  (double) *(float32_t*) param,
187  std::to_string((double) *(float32_t*) param).c_str()
188  ));
189 #else
190  push_object(json_object_new_double((double) *(float32_t*) param));
191 #endif
192  break;
193  case PT_FLOAT64:
194 #if JSON_C_MINOR_VERSION >= 12
195  push_object(json_object_new_double_s(
196  (double) *(float64_t*) param,
197  std::to_string((double) *(float64_t*) param).c_str()
198  ));
199 #else
200  push_object(json_object_new_double((double) *(float64_t*) param));
201 #endif
202  break;
203  case PT_FLOATMAX:
204 #if JSON_C_MINOR_VERSION >= 12
205  push_object(json_object_new_double_s(
206  (double) *(floatmax_t*) param,
207  std::to_string((double) *(floatmax_t*) param).c_str()
208  ));
209 #else
210  push_object(json_object_new_double((double) *(floatmax_t*) param));
211 #endif
212  break;
213  case PT_COMPLEX128:
214  SG_ERROR("Not supported for complex128_t for writing into JsonFile!");
215  break;
216  case PT_SGOBJECT:
217  SG_ERROR("Implementation error during writing JsonFile!");
218  return false;
219  case PT_UNDEFINED: default:
220  SG_ERROR("Implementation error: undefined primitive type\n");
221  return false;
222  break;
223  }
224 
225  if (is_error(m_stack_stream.back()))
226  return false;
227 
228  return true;
229 }
230 
231 bool
232 CSerializableJsonFile::write_cont_begin_wrapped(
233  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
234 {
235  push_object(json_object_new_array());
236 
237  for (index_t i=0; i<len_real_x && (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX); i++)
238  json_object_array_add(m_stack_stream.back(),
239  json_object_new_array());
240 
241  return true;
242 }
243 
244 bool
245 CSerializableJsonFile::write_cont_end_wrapped(
246  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
247 {
248  return true;
249 }
250 
251 bool
252 CSerializableJsonFile::write_string_begin_wrapped(
253  const TSGDataType* type, index_t length)
254 {
255  push_object(json_object_new_array());
256 
257  return true;
258 }
259 
260 bool
261 CSerializableJsonFile::write_string_end_wrapped(
262  const TSGDataType* type, index_t length)
263 {
264  return true;
265 }
266 
267 bool
268 CSerializableJsonFile::write_stringentry_begin_wrapped(
269  const TSGDataType* type, index_t y)
270 {
271  return true;
272 }
273 
274 bool
275 CSerializableJsonFile::write_stringentry_end_wrapped(
276  const TSGDataType* type, index_t y)
277 {
278  json_object* array = m_stack_stream.get_element(
279  m_stack_stream.get_num_elements() - 2);
280 
281  if (json_object_array_put_idx( array, y, m_stack_stream.back()))
282  return false;
283 
284  pop_object();
285  return true;
286 }
287 
288 bool
289 CSerializableJsonFile::write_sparse_begin_wrapped(
290  const TSGDataType* type, index_t length)
291 {
292  push_object(json_object_new_object());
293 
294  json_object* buf = json_object_new_array();
295  if (is_error(buf))
296  return false;
297 
298  json_object_object_add(m_stack_stream.back(),
299  STR_KEY_SPARSE_FEATURES, buf);
300 
301  push_object(buf);
302  return true;
303 }
304 
305 bool
306 CSerializableJsonFile::write_sparse_end_wrapped(
307  const TSGDataType* type, index_t length)
308 {
309  pop_object();
310  return true;
311 }
312 
313 bool
314 CSerializableJsonFile::write_sparseentry_begin_wrapped(
315  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
316  index_t feat_index, index_t y)
317 {
318  json_object* buf = json_object_new_object();
319  if (json_object_array_put_idx(m_stack_stream.back(), y, buf))
320  return false;
321 
322  push_object(buf);
323 
324  buf = json_object_new_int(feat_index);
325  if (is_error(buf))
326  return false;
327 
328  json_object_object_add(m_stack_stream.back(),
329  STR_KEY_SPARSE_FEATINDEX, buf);
330 
331  return true;
332 }
333 
334 bool
335 CSerializableJsonFile::write_sparseentry_end_wrapped(
336  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
337  index_t feat_index, index_t y)
338 {
339  json_object* o = m_stack_stream.get_element(
340  m_stack_stream.get_num_elements() - 2);
341 
342  json_object_object_add(o, STR_KEY_SPARSE_ENTRY,
343  m_stack_stream.back());
344 
345  pop_object(); pop_object();
346  return true;
347 }
348 
349 bool
350 CSerializableJsonFile::write_item_begin_wrapped(
351  const TSGDataType* type, index_t y, index_t x)
352 {
353  return true;
354 }
355 
356 bool
357 CSerializableJsonFile::write_item_end_wrapped(
358  const TSGDataType* type, index_t y, index_t x)
359 {
360  json_object* array = m_stack_stream.get_element(
361  m_stack_stream.get_num_elements() - 2);
362 
363  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
364  array = json_object_array_get_idx(array, x);
365 
366  json_object_array_put_idx(array, y, m_stack_stream.back());
367 
368  pop_object();
369  return true;
370 }
371 
372 bool
373 CSerializableJsonFile::write_sgserializable_begin_wrapped(
374  const TSGDataType* type, const char* sgserializable_name,
375  EPrimitiveType generic)
376 {
377  if (*sgserializable_name == '\0') {
378  push_object(NULL);
379  return true;
380  }
381 
382  push_object(json_object_new_object());
383 
384  json_object* buf;
385  buf = json_object_new_string(sgserializable_name);
386  if (is_error(buf))
387  return false;
388 
389  json_object_object_add(m_stack_stream.back(),
390  STR_KEY_INSTANCE_NAME, buf);
391 
392  if (generic != PT_NOT_GENERIC) {
393  string_t buf_str;
394  TSGDataType::ptype_to_string(buf_str, generic, STRING_LEN);
395  buf = json_object_new_string(buf_str);
396  if (is_error(buf))
397  return false;
398 
399  json_object_object_add(m_stack_stream.back(),
400  STR_KEY_GENERIC_NAME, buf);
401  }
402 
403  buf = json_object_new_object();
404  if (is_error(buf))
405  return false;
406  json_object_object_add(m_stack_stream.back(), STR_KEY_INSTANCE,
407  buf);
408  push_object(buf);
409 
410  return true;
411 }
412 
413 bool
414 CSerializableJsonFile::write_sgserializable_end_wrapped(
415  const TSGDataType* type, const char* sgserializable_name,
416  EPrimitiveType generic)
417 {
418  if (*sgserializable_name == '\0') return true;
419 
420  pop_object();
421  return true;
422 }
423 
424 bool
425 CSerializableJsonFile::write_type_begin_wrapped(
426  const TSGDataType* type, const char* name, const char* prefix)
427 {
428  json_object* buf = json_object_new_object();
429  if (is_error(buf))
430  return false;
431 
432  json_object_object_add(m_stack_stream.back(), name, buf);
433  push_object(buf);
434 
435  string_t str_buf;
436  type->to_string(str_buf, STRING_LEN);
437  buf = json_object_new_string(str_buf);
438  if (is_error(buf))
439  return false;
440 
441  json_object_object_add(m_stack_stream.back(), STR_KEY_TYPE, buf);
442 
443  return true;
444 }
445 
446 bool
447 CSerializableJsonFile::write_type_end_wrapped(
448  const TSGDataType* type, const char* name, const char* prefix)
449 {
450  json_object_object_add(
451  m_stack_stream.get_element(
452  m_stack_stream.get_num_elements() - 2), STR_KEY_DATA,
453  m_stack_stream.back());
454  pop_object();
455 
456  pop_object();
457  return true;
458 }
459 
460 #endif /* HAVE_JSON */
int32_t index_t
Definition: common.h:62
#define SG_ERROR(...)
Definition: SGIO.h:129
static void ptype_to_string(char *dest, EPrimitiveType ptype, size_t n)
Definition: DataType.cpp:365
Datatypes that shogun supports.
Definition: DataType.h:68
double float64_t
Definition: common.h:50
long double floatmax_t
Definition: common.h:51
#define STRING_LEN
Definition: common.h:55
float float32_t
Definition: common.h:49
void to_string(char *dest, size_t n) const
Definition: DataType.cpp:145
EContainerType m_ctype
Definition: DataType.h:71
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
template class SGSparseVectorEntry
Definition: File.h:23
#define PT_NOT_GENERIC
Definition: DataType.h:21
char string_t[STRING_LEN]
Definition: common.h:57
EPrimitiveType m_ptype
Definition: DataType.h:75
#define SG_WARNING(...)
Definition: SGIO.h:128
void init(FILE *fstream, char task, const char *filename)

SHOGUN Machine Learning Toolbox - Documentation