SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  if ((buf = json_object_object_get(
45  m_stack_stream.back(), STR_KEY_FILETYPE)) == NULL
46  || is_error(buf)
47  || (ftype = json_object_get_string(buf)) == NULL)
48  return NULL;
49 
50  strncpy(dest_version, ftype, n);
51 
52  if (strcmp(STR_FILETYPE_00, dest_version) == 0)
53  return new SerializableJsonReader00(this);
54 
55  return NULL;
56 }
57 
58 void CSerializableJsonFile::push_object(json_object* o)
59 {
60  m_stack_stream.push_back(o);
61  json_object_get(o);
62 }
63 
64 void CSerializableJsonFile::pop_object()
65 {
66  json_object_put(m_stack_stream.back());
67  m_stack_stream.pop_back();
68 }
69 
70 bool
71 CSerializableJsonFile::get_object_any(
72  json_object** dest, json_object* src, const char* key)
73 {
74  *dest = json_object_object_get(src, key);
75 
76  return !is_error(*dest);
77 }
78 
79 bool
80 CSerializableJsonFile::get_object(json_object** dest, json_object* src,
81  const char* key, json_type t)
82 {
83  *dest = json_object_object_get(src, key);
84 
85  return *dest != NULL && !is_error(*dest)
86  && json_object_is_type(*dest, t);
87 }
88 
89 void
90 CSerializableJsonFile::init(const char* fname)
91 {
92  if (m_filename == NULL || *m_filename == '\0') {
93  SG_WARNING("Filename not given for opening file!\n")
94  close();
95  return;
96  }
97 
98  json_object* buf;
99  switch (m_task) {
100  case 'r':
101  buf = json_object_from_file((char*) fname);
102  if (is_error(buf)) {
103  SG_ERROR("Could not open file `%s' for reading!\n",
104  fname);
105  return;
106  }
107  m_stack_stream.push_back(buf);
108  break;
109  case 'w':
110  m_stack_stream.push_back(json_object_new_object());
111  buf = json_object_new_string(STR_FILETYPE_00);
112  json_object_object_add(m_stack_stream.back(),
113  STR_KEY_FILETYPE, buf);
114  break;
115  default:
116  SG_WARNING("Could not open file `%s', unknown mode!\n",
117  m_filename);
118  close();
119  return;
120  }
121 }
122 
123 void
124 CSerializableJsonFile::close()
125 {
126  while (m_stack_stream.get_num_elements() > 1)
127  pop_object();
128 
129  if (m_stack_stream.get_num_elements() == 1) {
130  if (m_task == 'w'
131  && json_object_to_file(m_filename, m_stack_stream.back()))
132  {
133  SG_WARNING("Could not close file `%s' for writing!\n",
134  m_filename);
135  }
136 
137  pop_object();
138  }
139 }
140 
141 bool
142 CSerializableJsonFile::is_opened()
143 {
144  return m_stack_stream.get_num_elements() > 0;
145 }
146 
147 bool
148 CSerializableJsonFile::write_scalar_wrapped(
149  const TSGDataType* type, const void* param)
150 {
151  switch (type->m_ptype) {
152  case PT_BOOL:
153  push_object(json_object_new_boolean(*(bool*) param));
154  break;
155  case PT_CHAR:
156  push_object(json_object_new_int((int) *(char*) param));
157  break;
158  case PT_INT8:
159  push_object(json_object_new_int((int) *(int8_t*) param));
160  break;
161  case PT_UINT8:
162  push_object(json_object_new_int((int) *(uint8_t*) param));
163  break;
164  case PT_INT16:
165  push_object(json_object_new_int((int) *(int16_t*) param));
166  break;
167  case PT_UINT16:
168  push_object(json_object_new_int((int) *(uint16_t*) param));
169  break;
170  case PT_INT32:
171  push_object(json_object_new_int((int) *(int32_t*) param));
172  break;
173  case PT_UINT32:
174  push_object(json_object_new_int((int) *(uint32_t*) param));
175  break;
176  case PT_INT64:
177  push_object(json_object_new_int((int) *(int64_t*) param));
178  break;
179  case PT_UINT64:
180  push_object(json_object_new_int((int) *(uint64_t*) param));
181  break;
182  case PT_FLOAT32:
183  push_object(json_object_new_double(
184  (double) *(float32_t*) param));
185  break;
186  case PT_FLOAT64:
187  push_object(json_object_new_double(
188  (double) *(float64_t*) param));
189  break;
190  case PT_FLOATMAX:
191  push_object(json_object_new_double(
192  (double) *(floatmax_t*) param));
193  break;
194  case PT_COMPLEX128:
195  SG_ERROR("Not supported for complex128_t for writing into JsonFile!");
196  break;
197  case PT_SGOBJECT:
198  SG_ERROR("Implementation error during writing JsonFile!");
199  return false;
200  case PT_UNDEFINED: default:
201  SG_ERROR("Implementation error: undefined primitive type\n");
202  return false;
203  break;
204  }
205 
206  if (is_error(m_stack_stream.back()))
207  return false;
208 
209  return true;
210 }
211 
212 bool
213 CSerializableJsonFile::write_cont_begin_wrapped(
214  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
215 {
216  push_object(json_object_new_array());
217 
218  for (index_t i=0; i<len_real_x && (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX); i++)
219  json_object_array_add(m_stack_stream.back(),
220  json_object_new_array());
221 
222  return true;
223 }
224 
225 bool
226 CSerializableJsonFile::write_cont_end_wrapped(
227  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
228 {
229  return true;
230 }
231 
232 bool
233 CSerializableJsonFile::write_string_begin_wrapped(
234  const TSGDataType* type, index_t length)
235 {
236  push_object(json_object_new_array());
237 
238  return true;
239 }
240 
241 bool
242 CSerializableJsonFile::write_string_end_wrapped(
243  const TSGDataType* type, index_t length)
244 {
245  return true;
246 }
247 
248 bool
249 CSerializableJsonFile::write_stringentry_begin_wrapped(
250  const TSGDataType* type, index_t y)
251 {
252  return true;
253 }
254 
255 bool
256 CSerializableJsonFile::write_stringentry_end_wrapped(
257  const TSGDataType* type, index_t y)
258 {
259  json_object* array = m_stack_stream.get_element(
260  m_stack_stream.get_num_elements() - 2);
261 
262  if (json_object_array_put_idx( array, y, m_stack_stream.back()))
263  return false;
264 
265  pop_object();
266  return true;
267 }
268 
269 bool
270 CSerializableJsonFile::write_sparse_begin_wrapped(
271  const TSGDataType* type, index_t length)
272 {
273  push_object(json_object_new_object());
274 
275  json_object* buf = json_object_new_array();
276  if (is_error(buf))
277  return false;
278 
279  json_object_object_add(m_stack_stream.back(),
280  STR_KEY_SPARSE_FEATURES, buf);
281 
282  push_object(buf);
283  return true;
284 }
285 
286 bool
287 CSerializableJsonFile::write_sparse_end_wrapped(
288  const TSGDataType* type, index_t length)
289 {
290  pop_object();
291  return true;
292 }
293 
294 bool
295 CSerializableJsonFile::write_sparseentry_begin_wrapped(
296  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
297  index_t feat_index, index_t y)
298 {
299  json_object* buf = json_object_new_object();
300  if (json_object_array_put_idx(m_stack_stream.back(), y, buf))
301  return false;
302 
303  push_object(buf);
304 
305  buf = json_object_new_int(feat_index);
306  if (is_error(buf))
307  return false;
308 
309  json_object_object_add(m_stack_stream.back(),
310  STR_KEY_SPARSE_FEATINDEX, buf);
311 
312  return true;
313 }
314 
315 bool
316 CSerializableJsonFile::write_sparseentry_end_wrapped(
317  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
318  index_t feat_index, index_t y)
319 {
320  json_object* o = m_stack_stream.get_element(
321  m_stack_stream.get_num_elements() - 2);
322 
323  json_object_object_add(o, STR_KEY_SPARSE_ENTRY,
324  m_stack_stream.back());
325 
326  pop_object(); pop_object();
327  return true;
328 }
329 
330 bool
331 CSerializableJsonFile::write_item_begin_wrapped(
332  const TSGDataType* type, index_t y, index_t x)
333 {
334  return true;
335 }
336 
337 bool
338 CSerializableJsonFile::write_item_end_wrapped(
339  const TSGDataType* type, index_t y, index_t x)
340 {
341  json_object* array = m_stack_stream.get_element(
342  m_stack_stream.get_num_elements() - 2);
343 
344  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
345  array = json_object_array_get_idx(array, x);
346 
347  json_object_array_put_idx(array, y, m_stack_stream.back());
348 
349  pop_object();
350  return true;
351 }
352 
353 bool
354 CSerializableJsonFile::write_sgserializable_begin_wrapped(
355  const TSGDataType* type, const char* sgserializable_name,
356  EPrimitiveType generic)
357 {
358  if (*sgserializable_name == '\0') {
359  push_object(NULL);
360  return true;
361  }
362 
363  push_object(json_object_new_object());
364 
365  json_object* buf;
366  buf = json_object_new_string(sgserializable_name);
367  if (is_error(buf))
368  return false;
369 
370  json_object_object_add(m_stack_stream.back(),
371  STR_KEY_INSTANCE_NAME, buf);
372 
373  if (generic != PT_NOT_GENERIC) {
374  string_t buf_str;
375  TSGDataType::ptype_to_string(buf_str, generic, STRING_LEN);
376  buf = json_object_new_string(buf_str);
377  if (is_error(buf))
378  return false;
379 
380  json_object_object_add(m_stack_stream.back(),
381  STR_KEY_GENERIC_NAME, buf);
382  }
383 
384  buf = json_object_new_object();
385  if (is_error(buf))
386  return false;
387  json_object_object_add(m_stack_stream.back(), STR_KEY_INSTANCE,
388  buf);
389  push_object(buf);
390 
391  return true;
392 }
393 
394 bool
395 CSerializableJsonFile::write_sgserializable_end_wrapped(
396  const TSGDataType* type, const char* sgserializable_name,
397  EPrimitiveType generic)
398 {
399  if (*sgserializable_name == '\0') return true;
400 
401  pop_object();
402  return true;
403 }
404 
405 bool
406 CSerializableJsonFile::write_type_begin_wrapped(
407  const TSGDataType* type, const char* name, const char* prefix)
408 {
409  json_object* buf = json_object_new_object();
410  if (is_error(buf))
411  return false;
412 
413  json_object_object_add(m_stack_stream.back(), name, buf);
414  push_object(buf);
415 
416  string_t str_buf;
417  type->to_string(str_buf, STRING_LEN);
418  buf = json_object_new_string(str_buf);
419  if (is_error(buf))
420  return false;
421 
422  json_object_object_add(m_stack_stream.back(), STR_KEY_TYPE, buf);
423 
424  return true;
425 }
426 
427 bool
428 CSerializableJsonFile::write_type_end_wrapped(
429  const TSGDataType* type, const char* name, const char* prefix)
430 {
431  json_object_object_add(
432  m_stack_stream.get_element(
433  m_stack_stream.get_num_elements() - 2), STR_KEY_DATA,
434  m_stack_stream.back());
435  pop_object();
436 
437  pop_object();
438  return true;
439 }
440 
441 #endif /* HAVE_JSON */

SHOGUN Machine Learning Toolbox - Documentation