SHOGUN  4.1.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  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  push_object(json_object_new_double(
185  (double) *(float32_t*) param));
186  break;
187  case PT_FLOAT64:
188  push_object(json_object_new_double(
189  (double) *(float64_t*) param));
190  break;
191  case PT_FLOATMAX:
192  push_object(json_object_new_double(
193  (double) *(floatmax_t*) param));
194  break;
195  case PT_COMPLEX128:
196  SG_ERROR("Not supported for complex128_t for writing into JsonFile!");
197  break;
198  case PT_SGOBJECT:
199  SG_ERROR("Implementation error during writing JsonFile!");
200  return false;
201  case PT_UNDEFINED: default:
202  SG_ERROR("Implementation error: undefined primitive type\n");
203  return false;
204  break;
205  }
206 
207  if (is_error(m_stack_stream.back()))
208  return false;
209 
210  return true;
211 }
212 
213 bool
214 CSerializableJsonFile::write_cont_begin_wrapped(
215  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
216 {
217  push_object(json_object_new_array());
218 
219  for (index_t i=0; i<len_real_x && (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX); i++)
220  json_object_array_add(m_stack_stream.back(),
221  json_object_new_array());
222 
223  return true;
224 }
225 
226 bool
227 CSerializableJsonFile::write_cont_end_wrapped(
228  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
229 {
230  return true;
231 }
232 
233 bool
234 CSerializableJsonFile::write_string_begin_wrapped(
235  const TSGDataType* type, index_t length)
236 {
237  push_object(json_object_new_array());
238 
239  return true;
240 }
241 
242 bool
243 CSerializableJsonFile::write_string_end_wrapped(
244  const TSGDataType* type, index_t length)
245 {
246  return true;
247 }
248 
249 bool
250 CSerializableJsonFile::write_stringentry_begin_wrapped(
251  const TSGDataType* type, index_t y)
252 {
253  return true;
254 }
255 
256 bool
257 CSerializableJsonFile::write_stringentry_end_wrapped(
258  const TSGDataType* type, index_t y)
259 {
260  json_object* array = m_stack_stream.get_element(
261  m_stack_stream.get_num_elements() - 2);
262 
263  if (json_object_array_put_idx( array, y, m_stack_stream.back()))
264  return false;
265 
266  pop_object();
267  return true;
268 }
269 
270 bool
271 CSerializableJsonFile::write_sparse_begin_wrapped(
272  const TSGDataType* type, index_t length)
273 {
274  push_object(json_object_new_object());
275 
276  json_object* buf = json_object_new_array();
277  if (is_error(buf))
278  return false;
279 
280  json_object_object_add(m_stack_stream.back(),
281  STR_KEY_SPARSE_FEATURES, buf);
282 
283  push_object(buf);
284  return true;
285 }
286 
287 bool
288 CSerializableJsonFile::write_sparse_end_wrapped(
289  const TSGDataType* type, index_t length)
290 {
291  pop_object();
292  return true;
293 }
294 
295 bool
296 CSerializableJsonFile::write_sparseentry_begin_wrapped(
297  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
298  index_t feat_index, index_t y)
299 {
300  json_object* buf = json_object_new_object();
301  if (json_object_array_put_idx(m_stack_stream.back(), y, buf))
302  return false;
303 
304  push_object(buf);
305 
306  buf = json_object_new_int(feat_index);
307  if (is_error(buf))
308  return false;
309 
310  json_object_object_add(m_stack_stream.back(),
311  STR_KEY_SPARSE_FEATINDEX, buf);
312 
313  return true;
314 }
315 
316 bool
317 CSerializableJsonFile::write_sparseentry_end_wrapped(
318  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
319  index_t feat_index, index_t y)
320 {
321  json_object* o = m_stack_stream.get_element(
322  m_stack_stream.get_num_elements() - 2);
323 
324  json_object_object_add(o, STR_KEY_SPARSE_ENTRY,
325  m_stack_stream.back());
326 
327  pop_object(); pop_object();
328  return true;
329 }
330 
331 bool
332 CSerializableJsonFile::write_item_begin_wrapped(
333  const TSGDataType* type, index_t y, index_t x)
334 {
335  return true;
336 }
337 
338 bool
339 CSerializableJsonFile::write_item_end_wrapped(
340  const TSGDataType* type, index_t y, index_t x)
341 {
342  json_object* array = m_stack_stream.get_element(
343  m_stack_stream.get_num_elements() - 2);
344 
345  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
346  array = json_object_array_get_idx(array, x);
347 
348  json_object_array_put_idx(array, y, m_stack_stream.back());
349 
350  pop_object();
351  return true;
352 }
353 
354 bool
355 CSerializableJsonFile::write_sgserializable_begin_wrapped(
356  const TSGDataType* type, const char* sgserializable_name,
357  EPrimitiveType generic)
358 {
359  if (*sgserializable_name == '\0') {
360  push_object(NULL);
361  return true;
362  }
363 
364  push_object(json_object_new_object());
365 
366  json_object* buf;
367  buf = json_object_new_string(sgserializable_name);
368  if (is_error(buf))
369  return false;
370 
371  json_object_object_add(m_stack_stream.back(),
372  STR_KEY_INSTANCE_NAME, buf);
373 
374  if (generic != PT_NOT_GENERIC) {
375  string_t buf_str;
376  TSGDataType::ptype_to_string(buf_str, generic, STRING_LEN);
377  buf = json_object_new_string(buf_str);
378  if (is_error(buf))
379  return false;
380 
381  json_object_object_add(m_stack_stream.back(),
382  STR_KEY_GENERIC_NAME, buf);
383  }
384 
385  buf = json_object_new_object();
386  if (is_error(buf))
387  return false;
388  json_object_object_add(m_stack_stream.back(), STR_KEY_INSTANCE,
389  buf);
390  push_object(buf);
391 
392  return true;
393 }
394 
395 bool
396 CSerializableJsonFile::write_sgserializable_end_wrapped(
397  const TSGDataType* type, const char* sgserializable_name,
398  EPrimitiveType generic)
399 {
400  if (*sgserializable_name == '\0') return true;
401 
402  pop_object();
403  return true;
404 }
405 
406 bool
407 CSerializableJsonFile::write_type_begin_wrapped(
408  const TSGDataType* type, const char* name, const char* prefix)
409 {
410  json_object* buf = json_object_new_object();
411  if (is_error(buf))
412  return false;
413 
414  json_object_object_add(m_stack_stream.back(), name, buf);
415  push_object(buf);
416 
417  string_t str_buf;
418  type->to_string(str_buf, STRING_LEN);
419  buf = json_object_new_string(str_buf);
420  if (is_error(buf))
421  return false;
422 
423  json_object_object_add(m_stack_stream.back(), STR_KEY_TYPE, buf);
424 
425  return true;
426 }
427 
428 bool
429 CSerializableJsonFile::write_type_end_wrapped(
430  const TSGDataType* type, const char* name, const char* prefix)
431 {
432  json_object_object_add(
433  m_stack_stream.get_element(
434  m_stack_stream.get_num_elements() - 2), STR_KEY_DATA,
435  m_stack_stream.back());
436  pop_object();
437 
438  pop_object();
439  return true;
440 }
441 
442 #endif /* HAVE_JSON */

SHOGUN Machine Learning Toolbox - Documentation