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(void)
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
00059 CSerializableJsonFile::push_object(json_object* o)
00060 { m_stack_stream.push_back(o); json_object_get(o); }
00061 
00062 void
00063 CSerializableJsonFile::pop_object(void)
00064 { json_object_put(m_stack_stream.back()); m_stack_stream.pop_back(); }
00065 
00066 bool
00067 CSerializableJsonFile::get_object_any(
00068     json_object** dest, json_object* src, const char* key)
00069 {
00070     *dest = json_object_object_get(src, key);
00071 
00072     return !is_error(*dest);
00073 }
00074 
00075 bool
00076 CSerializableJsonFile::get_object(json_object** dest, json_object* src,
00077                                   const char* key, json_type t)
00078 {
00079     *dest = json_object_object_get(src, key);
00080 
00081     return *dest != NULL && !is_error(*dest)
00082         && json_object_is_type(*dest, t);
00083 }
00084 
00085 void
00086 CSerializableJsonFile::init(const char* fname)
00087 {
00088     if (m_filename == NULL || *m_filename == '\0') {
00089         SG_WARNING("Filename not given for opening file!\n");
00090         close(); return;
00091     }
00092 
00093     json_object* buf;
00094     switch (m_task) {
00095     case 'r':
00096         buf = json_object_from_file((char*) fname);
00097         if (is_error(buf)) {
00098             SG_WARNING("Could not open file `%s' for reading!\n",
00099                        fname);
00100             return;
00101         }
00102         push_object(buf);
00103         break;
00104     case 'w':
00105         push_object(json_object_new_object());
00106 
00107         buf = json_object_new_string(STR_FILETYPE_00);
00108         json_object_object_add(m_stack_stream.back(),
00109                                STR_KEY_FILETYPE, buf);
00110         break;
00111     default:
00112         SG_WARNING("Could not open file `%s', unknown mode!\n",
00113                    m_filename);
00114         close(); return;
00115     }
00116 }
00117 
00118 void
00119 CSerializableJsonFile::close(void)
00120 {
00121     while (m_stack_stream.get_num_elements() > 1)
00122         pop_object();
00123 
00124     if (m_stack_stream.get_num_elements() == 1) {
00125         if (m_task == 'w'
00126             && is_error(
00127                 json_object_to_file(m_filename, m_stack_stream.back())
00128                 )) {
00129             SG_WARNING("Could not close file `%s' for writing!\n",
00130                        m_filename);
00131         }
00132 
00133         pop_object();
00134     }
00135 }
00136 
00137 bool
00138 CSerializableJsonFile::is_opened(void)
00139 {
00140     return m_stack_stream.get_num_elements() > 0;
00141 }
00142 
00143 bool
00144 CSerializableJsonFile::write_scalar_wrapped(
00145     const TSGDataType* type, const void* param)
00146 {
00147     switch (type->m_ptype) {
00148     case PT_BOOL:
00149         push_object(json_object_new_boolean(*(bool*) param));
00150         break;
00151     case PT_CHAR:
00152         push_object(json_object_new_int((int) *(char*) param));
00153         break;
00154     case PT_INT8:
00155         push_object(json_object_new_int((int) *(int8_t*) param));
00156         break;
00157     case PT_UINT8:
00158         push_object(json_object_new_int((int) *(uint8_t*) param));
00159         break;
00160     case PT_INT16:
00161         push_object(json_object_new_int((int) *(int16_t*) param));
00162         break;
00163     case PT_UINT16:
00164         push_object(json_object_new_int((int) *(uint16_t*) param));
00165         break;
00166     case PT_INT32:
00167         push_object(json_object_new_int((int) *(int32_t*) param));
00168         break;
00169     case PT_UINT32:
00170         push_object(json_object_new_int((int) *(uint32_t*) param));
00171         break;
00172     case PT_INT64:
00173         push_object(json_object_new_int((int) *(int64_t*) param));
00174         break;
00175     case PT_UINT64:
00176         push_object(json_object_new_int((int) *(uint64_t*) param));
00177         break;
00178     case PT_FLOAT32:
00179         push_object(json_object_new_double(
00180                         (double) *(float32_t*) param));
00181         break;
00182     case PT_FLOAT64:
00183         push_object(json_object_new_double(
00184                         (double) *(float64_t*) param));
00185         break;
00186     case PT_FLOATMAX:
00187         push_object(json_object_new_double(
00188                         (double) *(floatmax_t*) param));
00189         break;
00190     case PT_SGOBJECT:
00191         SG_ERROR("write_scalar_wrapped(): Implementation error during"
00192                  " writing JsonFile!");
00193         return false;
00194     }
00195 
00196     if (is_error(m_stack_stream.back())) return false;
00197 
00198     return true;
00199 }
00200 
00201 bool
00202 CSerializableJsonFile::write_cont_begin_wrapped(
00203     const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00204 {
00205     push_object(json_object_new_array());
00206 
00207     for (index_t i=0; i<len_real_x && (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX); i++)
00208         json_object_array_add(m_stack_stream.back(),
00209                               json_object_new_array());
00210 
00211     return true;
00212 }
00213 
00214 bool
00215 CSerializableJsonFile::write_cont_end_wrapped(
00216     const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00217 {
00218     return true;
00219 }
00220 
00221 bool
00222 CSerializableJsonFile::write_string_begin_wrapped(
00223     const TSGDataType* type, index_t length)
00224 {
00225     push_object(json_object_new_array());
00226 
00227     return true;
00228 }
00229 
00230 bool
00231 CSerializableJsonFile::write_string_end_wrapped(
00232     const TSGDataType* type, index_t length)
00233 {
00234     return true;
00235 }
00236 
00237 bool
00238 CSerializableJsonFile::write_stringentry_begin_wrapped(
00239     const TSGDataType* type, index_t y)
00240 {
00241     return true;
00242 }
00243 
00244 bool
00245 CSerializableJsonFile::write_stringentry_end_wrapped(
00246     const TSGDataType* type, index_t y)
00247 {
00248     json_object* array = m_stack_stream.get_element(
00249         m_stack_stream.get_num_elements() - 2);
00250 
00251     if (is_error(json_object_array_put_idx(
00252                      array, y, m_stack_stream.back()))) return false;
00253 
00254     pop_object();
00255     return true;
00256 }
00257 
00258 bool
00259 CSerializableJsonFile::write_sparse_begin_wrapped(
00260     const TSGDataType* type, index_t vec_index,
00261     index_t length)
00262 {
00263     push_object(json_object_new_object());
00264 
00265     json_object* buf = json_object_new_int(vec_index);
00266     if (is_error(buf)) return false;
00267     json_object_object_add(m_stack_stream.back(),
00268                            STR_KEY_SPARSE_VECINDEX, buf);
00269 
00270     buf = json_object_new_array();
00271     if (is_error(buf)) return false;
00272     json_object_object_add(m_stack_stream.back(),
00273                            STR_KEY_SPARSE_FEATURES, buf);
00274 
00275     push_object(buf);
00276     return true;
00277 }
00278 
00279 bool
00280 CSerializableJsonFile::write_sparse_end_wrapped(
00281     const TSGDataType* type, index_t vec_index,
00282     index_t length)
00283 {
00284     pop_object();
00285     return true;
00286 }
00287 
00288 bool
00289 CSerializableJsonFile::write_sparseentry_begin_wrapped(
00290     const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00291     index_t feat_index, index_t y)
00292 {
00293     json_object* buf = json_object_new_object();
00294     if (is_error(json_object_array_put_idx(m_stack_stream.back(), y,
00295                                            buf))) return false;
00296     push_object(buf);
00297 
00298     buf = json_object_new_int(feat_index);
00299     if (is_error(buf)) return false;
00300     json_object_object_add(m_stack_stream.back(),
00301                            STR_KEY_SPARSE_FEATINDEX, buf);
00302 
00303     return true;
00304 }
00305 
00306 bool
00307 CSerializableJsonFile::write_sparseentry_end_wrapped(
00308     const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00309     index_t feat_index, index_t y)
00310 {
00311     json_object* o = m_stack_stream.get_element(
00312         m_stack_stream.get_num_elements() - 2);
00313 
00314     json_object_object_add(o, STR_KEY_SPARSE_ENTRY,
00315                            m_stack_stream.back());
00316 
00317     pop_object(); pop_object();
00318     return true;
00319 }
00320 
00321 bool
00322 CSerializableJsonFile::write_item_begin_wrapped(
00323     const TSGDataType* type, index_t y, index_t x)
00324 {
00325     return true;
00326 }
00327 
00328 bool
00329 CSerializableJsonFile::write_item_end_wrapped(
00330     const TSGDataType* type, index_t y, index_t x)
00331 {
00332     json_object* array = m_stack_stream.get_element(
00333         m_stack_stream.get_num_elements() - 2);
00334 
00335     if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
00336         array = json_object_array_get_idx(array, x);
00337 
00338     json_object_array_put_idx(array, y, m_stack_stream.back());
00339 
00340     pop_object();
00341     return true;
00342 }
00343 
00344 bool
00345 CSerializableJsonFile::write_sgserializable_begin_wrapped(
00346     const TSGDataType* type, const char* sgserializable_name,
00347     EPrimitiveType generic)
00348 {
00349     if (*sgserializable_name == '\0') {
00350         push_object(NULL); return true;
00351     }
00352 
00353     push_object(json_object_new_object());
00354 
00355     json_object* buf;
00356     buf = json_object_new_string(sgserializable_name);
00357     if (is_error(buf)) return false;
00358     json_object_object_add(m_stack_stream.back(),
00359                            STR_KEY_INSTANCE_NAME, buf);
00360 
00361     if (generic != PT_NOT_GENERIC) {
00362         string_t buf_str;
00363         TSGDataType::ptype_to_string(buf_str, generic, STRING_LEN);
00364         buf = json_object_new_string(buf_str);
00365         if (is_error(buf)) return false;
00366         json_object_object_add(m_stack_stream.back(),
00367                                STR_KEY_GENERIC_NAME, buf);
00368     }
00369 
00370     buf = json_object_new_object();
00371     if (is_error(buf)) return false;
00372     json_object_object_add(m_stack_stream.back(), STR_KEY_INSTANCE,
00373                            buf);
00374     push_object(buf);
00375 
00376     return true;
00377 }
00378 
00379 bool
00380 CSerializableJsonFile::write_sgserializable_end_wrapped(
00381     const TSGDataType* type, const char* sgserializable_name,
00382     EPrimitiveType generic)
00383 {
00384     if (*sgserializable_name == '\0') return true;
00385 
00386     pop_object();
00387     return true;
00388 }
00389 
00390 bool
00391 CSerializableJsonFile::write_type_begin_wrapped(
00392     const TSGDataType* type, const char* name, const char* prefix)
00393 {
00394     json_object* buf = json_object_new_object();
00395     if (is_error(buf)) return false;
00396 
00397     json_object_object_add(m_stack_stream.back(), name, buf);
00398     push_object(buf);
00399 
00400     string_t str_buf;
00401     type->to_string(str_buf, STRING_LEN);
00402     buf = json_object_new_string(str_buf);
00403     if (is_error(buf)) return false;
00404     json_object_object_add(m_stack_stream.back(), STR_KEY_TYPE, buf);
00405 
00406     return true;
00407 }
00408 
00409 bool
00410 CSerializableJsonFile::write_type_end_wrapped(
00411     const TSGDataType* type, const char* name, const char* prefix)
00412 {
00413     json_object_object_add(
00414         m_stack_stream.get_element(
00415             m_stack_stream.get_num_elements() - 2), STR_KEY_DATA,
00416         m_stack_stream.back());
00417     pop_object();
00418 
00419     pop_object();
00420     return true;
00421 }
00422 
00423 #endif /* HAVE_JSON  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation