SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SerializableJsonFile.cpp
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2010 Soeren Sonnenburg
00008  * Copyright (C) 2010 Berlin Institute of Technology
00009  */
00010 
00011 #include <shogun/lib/config.h>
00012 #ifdef HAVE_JSON
00013 
00014 #include <shogun/io/SerializableJsonFile.h>
00015 #include <shogun/io/SerializableJsonReader00.h>
00016 
00017 #define STR_KEY_FILETYPE           "filetype"
00018 #define STR_FILETYPE_00 \
00019     "_SHOGUN_SERIALIZABLE_JSON_FILE_V_00_"
00020 
00021 using namespace shogun;
00022 
00023 CSerializableJsonFile::CSerializableJsonFile()
00024     :CSerializableFile() { init(""); }
00025 
00026 CSerializableJsonFile::CSerializableJsonFile(const char* fname, char rw)
00027     :CSerializableFile()
00028 {
00029     CSerializableFile::init(NULL, rw, fname);
00030     init(fname);
00031 }
00032 
00033 CSerializableJsonFile::~CSerializableJsonFile()
00034 {
00035     close();
00036 }
00037 
00038 CSerializableFile::TSerializableReader*
00039 CSerializableJsonFile::new_reader(char* dest_version, size_t n)
00040 {
00041     const char* ftype;
00042     json_object* buf;
00043 
00044     if ((buf = json_object_object_get(
00045              m_stack_stream.back(), STR_KEY_FILETYPE)) == NULL
00046         || is_error(buf)
00047         || (ftype = json_object_get_string(buf)) == NULL)
00048         return NULL;
00049 
00050     strncpy(dest_version, ftype, n);
00051 
00052     if (strcmp(STR_FILETYPE_00, dest_version) == 0)
00053         return new SerializableJsonReader00(this);
00054 
00055     return NULL;
00056 }
00057 
00058 void CSerializableJsonFile::push_object(json_object* o)
00059 {
00060     m_stack_stream.push_back(o);
00061     json_object_get(o);
00062 }
00063 
00064 void CSerializableJsonFile::pop_object()
00065 {
00066     json_object_put(m_stack_stream.back());
00067     m_stack_stream.pop_back();
00068 }
00069 
00070 bool
00071 CSerializableJsonFile::get_object_any(
00072     json_object** dest, json_object* src, const char* key)
00073 {
00074     *dest = json_object_object_get(src, key);
00075 
00076     return !is_error(*dest);
00077 }
00078 
00079 bool
00080 CSerializableJsonFile::get_object(json_object** dest, json_object* src,
00081                                   const char* key, json_type t)
00082 {
00083     *dest = json_object_object_get(src, key);
00084 
00085     return *dest != NULL && !is_error(*dest)
00086         && json_object_is_type(*dest, t);
00087 }
00088 
00089 void
00090 CSerializableJsonFile::init(const char* fname)
00091 {
00092     if (m_filename == NULL || *m_filename == '\0') {
00093         SG_WARNING("Filename not given for opening file!\n")
00094         close();
00095         return;
00096     }
00097 
00098     json_object* buf;
00099     switch (m_task) {
00100     case 'r':
00101         buf = json_object_from_file((char*) fname);
00102         if (is_error(buf)) {
00103             SG_ERROR("Could not open file `%s' for reading!\n",
00104                        fname);
00105             return;
00106         }
00107         m_stack_stream.push_back(buf);
00108         break;
00109     case 'w':
00110         m_stack_stream.push_back(json_object_new_object());
00111         buf = json_object_new_string(STR_FILETYPE_00);
00112         json_object_object_add(m_stack_stream.back(),
00113                                STR_KEY_FILETYPE, buf);
00114         break;
00115     default:
00116         SG_WARNING("Could not open file `%s', unknown mode!\n",
00117                    m_filename);
00118         close();
00119         return;
00120     }
00121 }
00122 
00123 void
00124 CSerializableJsonFile::close()
00125 {
00126     while (m_stack_stream.get_num_elements() > 1)
00127         pop_object();
00128 
00129     if (m_stack_stream.get_num_elements() == 1) {
00130         if (m_task == 'w'
00131             && json_object_to_file(m_filename, m_stack_stream.back()))
00132         {
00133             SG_WARNING("Could not close file `%s' for writing!\n",
00134                        m_filename);
00135         }
00136 
00137         pop_object();
00138     }
00139 }
00140 
00141 bool
00142 CSerializableJsonFile::is_opened()
00143 {
00144     return m_stack_stream.get_num_elements() > 0;
00145 }
00146 
00147 bool
00148 CSerializableJsonFile::write_scalar_wrapped(
00149     const TSGDataType* type, const void* param)
00150 {
00151     switch (type->m_ptype) {
00152     case PT_BOOL:
00153         push_object(json_object_new_boolean(*(bool*) param));
00154         break;
00155     case PT_CHAR:
00156         push_object(json_object_new_int((int) *(char*) param));
00157         break;
00158     case PT_INT8:
00159         push_object(json_object_new_int((int) *(int8_t*) param));
00160         break;
00161     case PT_UINT8:
00162         push_object(json_object_new_int((int) *(uint8_t*) param));
00163         break;
00164     case PT_INT16:
00165         push_object(json_object_new_int((int) *(int16_t*) param));
00166         break;
00167     case PT_UINT16:
00168         push_object(json_object_new_int((int) *(uint16_t*) param));
00169         break;
00170     case PT_INT32:
00171         push_object(json_object_new_int((int) *(int32_t*) param));
00172         break;
00173     case PT_UINT32:
00174         push_object(json_object_new_int((int) *(uint32_t*) param));
00175         break;
00176     case PT_INT64:
00177         push_object(json_object_new_int((int) *(int64_t*) param));
00178         break;
00179     case PT_UINT64:
00180         push_object(json_object_new_int((int) *(uint64_t*) param));
00181         break;
00182     case PT_FLOAT32:
00183         push_object(json_object_new_double(
00184                         (double) *(float32_t*) param));
00185         break;
00186     case PT_FLOAT64:
00187         push_object(json_object_new_double(
00188                         (double) *(float64_t*) param));
00189         break;
00190     case PT_FLOATMAX:
00191         push_object(json_object_new_double(
00192                         (double) *(floatmax_t*) param));
00193         break;
00194     case PT_COMPLEX128:
00195         SG_ERROR("Not supported for complex128_t for writing into JsonFile!");
00196         break;
00197     case PT_SGOBJECT:
00198         SG_ERROR("Implementation error during writing JsonFile!");
00199         return false;
00200     case PT_UNDEFINED: default:
00201         SG_ERROR("Implementation error: undefined primitive type\n");
00202         return false;
00203         break;
00204     }
00205 
00206     if (is_error(m_stack_stream.back()))
00207         return false;
00208 
00209     return true;
00210 }
00211 
00212 bool
00213 CSerializableJsonFile::write_cont_begin_wrapped(
00214     const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00215 {
00216     push_object(json_object_new_array());
00217 
00218     for (index_t i=0; i<len_real_x && (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX); i++)
00219         json_object_array_add(m_stack_stream.back(),
00220                               json_object_new_array());
00221 
00222     return true;
00223 }
00224 
00225 bool
00226 CSerializableJsonFile::write_cont_end_wrapped(
00227     const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00228 {
00229     return true;
00230 }
00231 
00232 bool
00233 CSerializableJsonFile::write_string_begin_wrapped(
00234     const TSGDataType* type, index_t length)
00235 {
00236     push_object(json_object_new_array());
00237 
00238     return true;
00239 }
00240 
00241 bool
00242 CSerializableJsonFile::write_string_end_wrapped(
00243     const TSGDataType* type, index_t length)
00244 {
00245     return true;
00246 }
00247 
00248 bool
00249 CSerializableJsonFile::write_stringentry_begin_wrapped(
00250     const TSGDataType* type, index_t y)
00251 {
00252     return true;
00253 }
00254 
00255 bool
00256 CSerializableJsonFile::write_stringentry_end_wrapped(
00257     const TSGDataType* type, index_t y)
00258 {
00259     json_object* array = m_stack_stream.get_element(
00260         m_stack_stream.get_num_elements() - 2);
00261 
00262     if (json_object_array_put_idx( array, y, m_stack_stream.back()))
00263         return false;
00264 
00265     pop_object();
00266     return true;
00267 }
00268 
00269 bool
00270 CSerializableJsonFile::write_sparse_begin_wrapped(
00271     const TSGDataType* type, index_t length)
00272 {
00273     push_object(json_object_new_object());
00274 
00275     json_object* buf = json_object_new_array();
00276     if (is_error(buf))
00277         return false;
00278 
00279     json_object_object_add(m_stack_stream.back(),
00280             STR_KEY_SPARSE_FEATURES, buf);
00281 
00282     push_object(buf);
00283     return true;
00284 }
00285 
00286 bool
00287 CSerializableJsonFile::write_sparse_end_wrapped(
00288     const TSGDataType* type, index_t length)
00289 {
00290     pop_object();
00291     return true;
00292 }
00293 
00294 bool
00295 CSerializableJsonFile::write_sparseentry_begin_wrapped(
00296     const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00297     index_t feat_index, index_t y)
00298 {
00299     json_object* buf = json_object_new_object();
00300     if (json_object_array_put_idx(m_stack_stream.back(), y, buf))
00301         return false;
00302 
00303     push_object(buf);
00304 
00305     buf = json_object_new_int(feat_index);
00306     if (is_error(buf))
00307         return false;
00308 
00309     json_object_object_add(m_stack_stream.back(),
00310                            STR_KEY_SPARSE_FEATINDEX, buf);
00311 
00312     return true;
00313 }
00314 
00315 bool
00316 CSerializableJsonFile::write_sparseentry_end_wrapped(
00317     const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00318     index_t feat_index, index_t y)
00319 {
00320     json_object* o = m_stack_stream.get_element(
00321         m_stack_stream.get_num_elements() - 2);
00322 
00323     json_object_object_add(o, STR_KEY_SPARSE_ENTRY,
00324                            m_stack_stream.back());
00325 
00326     pop_object(); pop_object();
00327     return true;
00328 }
00329 
00330 bool
00331 CSerializableJsonFile::write_item_begin_wrapped(
00332     const TSGDataType* type, index_t y, index_t x)
00333 {
00334     return true;
00335 }
00336 
00337 bool
00338 CSerializableJsonFile::write_item_end_wrapped(
00339     const TSGDataType* type, index_t y, index_t x)
00340 {
00341     json_object* array = m_stack_stream.get_element(
00342         m_stack_stream.get_num_elements() - 2);
00343 
00344     if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
00345         array = json_object_array_get_idx(array, x);
00346 
00347     json_object_array_put_idx(array, y, m_stack_stream.back());
00348 
00349     pop_object();
00350     return true;
00351 }
00352 
00353 bool
00354 CSerializableJsonFile::write_sgserializable_begin_wrapped(
00355     const TSGDataType* type, const char* sgserializable_name,
00356     EPrimitiveType generic)
00357 {
00358     if (*sgserializable_name == '\0') {
00359         push_object(NULL);
00360         return true;
00361     }
00362 
00363     push_object(json_object_new_object());
00364 
00365     json_object* buf;
00366     buf = json_object_new_string(sgserializable_name);
00367     if (is_error(buf))
00368         return false;
00369 
00370     json_object_object_add(m_stack_stream.back(),
00371                            STR_KEY_INSTANCE_NAME, buf);
00372 
00373     if (generic != PT_NOT_GENERIC) {
00374         string_t buf_str;
00375         TSGDataType::ptype_to_string(buf_str, generic, STRING_LEN);
00376         buf = json_object_new_string(buf_str);
00377         if (is_error(buf))
00378             return false;
00379 
00380         json_object_object_add(m_stack_stream.back(),
00381                                STR_KEY_GENERIC_NAME, buf);
00382     }
00383 
00384     buf = json_object_new_object();
00385     if (is_error(buf))
00386         return false;
00387     json_object_object_add(m_stack_stream.back(), STR_KEY_INSTANCE,
00388                            buf);
00389     push_object(buf);
00390 
00391     return true;
00392 }
00393 
00394 bool
00395 CSerializableJsonFile::write_sgserializable_end_wrapped(
00396     const TSGDataType* type, const char* sgserializable_name,
00397     EPrimitiveType generic)
00398 {
00399     if (*sgserializable_name == '\0') return true;
00400 
00401     pop_object();
00402     return true;
00403 }
00404 
00405 bool
00406 CSerializableJsonFile::write_type_begin_wrapped(
00407     const TSGDataType* type, const char* name, const char* prefix)
00408 {
00409     json_object* buf = json_object_new_object();
00410     if (is_error(buf))
00411         return false;
00412 
00413     json_object_object_add(m_stack_stream.back(), name, buf);
00414     push_object(buf);
00415 
00416     string_t str_buf;
00417     type->to_string(str_buf, STRING_LEN);
00418     buf = json_object_new_string(str_buf);
00419     if (is_error(buf))
00420         return false;
00421 
00422     json_object_object_add(m_stack_stream.back(), STR_KEY_TYPE, buf);
00423 
00424     return true;
00425 }
00426 
00427 bool
00428 CSerializableJsonFile::write_type_end_wrapped(
00429     const TSGDataType* type, const char* name, const char* prefix)
00430 {
00431     json_object_object_add(
00432         m_stack_stream.get_element(
00433             m_stack_stream.get_num_elements() - 2), STR_KEY_DATA,
00434         m_stack_stream.back());
00435     pop_object();
00436 
00437     pop_object();
00438     return true;
00439 }
00440 
00441 #endif /* HAVE_JSON  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation