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

SHOGUN Machine Learning Toolbox - Documentation