SHOGUN
v2.0.0
|
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 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() 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() 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() 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 length) 00261 { 00262 push_object(json_object_new_object()); 00263 00264 json_object* buf = json_object_new_array(); 00265 if (is_error(buf)) return false; 00266 json_object_object_add(m_stack_stream.back(), 00267 STR_KEY_SPARSE_FEATURES, buf); 00268 00269 push_object(buf); 00270 return true; 00271 } 00272 00273 bool 00274 CSerializableJsonFile::write_sparse_end_wrapped( 00275 const TSGDataType* type, index_t length) 00276 { 00277 pop_object(); 00278 return true; 00279 } 00280 00281 bool 00282 CSerializableJsonFile::write_sparseentry_begin_wrapped( 00283 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry, 00284 index_t feat_index, index_t y) 00285 { 00286 json_object* buf = json_object_new_object(); 00287 if (is_error(json_object_array_put_idx(m_stack_stream.back(), y, 00288 buf))) return false; 00289 push_object(buf); 00290 00291 buf = json_object_new_int(feat_index); 00292 if (is_error(buf)) return false; 00293 json_object_object_add(m_stack_stream.back(), 00294 STR_KEY_SPARSE_FEATINDEX, buf); 00295 00296 return true; 00297 } 00298 00299 bool 00300 CSerializableJsonFile::write_sparseentry_end_wrapped( 00301 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry, 00302 index_t feat_index, index_t y) 00303 { 00304 json_object* o = m_stack_stream.get_element( 00305 m_stack_stream.get_num_elements() - 2); 00306 00307 json_object_object_add(o, STR_KEY_SPARSE_ENTRY, 00308 m_stack_stream.back()); 00309 00310 pop_object(); pop_object(); 00311 return true; 00312 } 00313 00314 bool 00315 CSerializableJsonFile::write_item_begin_wrapped( 00316 const TSGDataType* type, index_t y, index_t x) 00317 { 00318 return true; 00319 } 00320 00321 bool 00322 CSerializableJsonFile::write_item_end_wrapped( 00323 const TSGDataType* type, index_t y, index_t x) 00324 { 00325 json_object* array = m_stack_stream.get_element( 00326 m_stack_stream.get_num_elements() - 2); 00327 00328 if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX) 00329 array = json_object_array_get_idx(array, x); 00330 00331 json_object_array_put_idx(array, y, m_stack_stream.back()); 00332 00333 pop_object(); 00334 return true; 00335 } 00336 00337 bool 00338 CSerializableJsonFile::write_sgserializable_begin_wrapped( 00339 const TSGDataType* type, const char* sgserializable_name, 00340 EPrimitiveType generic) 00341 { 00342 if (*sgserializable_name == '\0') { 00343 push_object(NULL); return true; 00344 } 00345 00346 push_object(json_object_new_object()); 00347 00348 json_object* buf; 00349 buf = json_object_new_string(sgserializable_name); 00350 if (is_error(buf)) return false; 00351 json_object_object_add(m_stack_stream.back(), 00352 STR_KEY_INSTANCE_NAME, buf); 00353 00354 if (generic != PT_NOT_GENERIC) { 00355 string_t buf_str; 00356 TSGDataType::ptype_to_string(buf_str, generic, STRING_LEN); 00357 buf = json_object_new_string(buf_str); 00358 if (is_error(buf)) return false; 00359 json_object_object_add(m_stack_stream.back(), 00360 STR_KEY_GENERIC_NAME, buf); 00361 } 00362 00363 buf = json_object_new_object(); 00364 if (is_error(buf)) return false; 00365 json_object_object_add(m_stack_stream.back(), STR_KEY_INSTANCE, 00366 buf); 00367 push_object(buf); 00368 00369 return true; 00370 } 00371 00372 bool 00373 CSerializableJsonFile::write_sgserializable_end_wrapped( 00374 const TSGDataType* type, const char* sgserializable_name, 00375 EPrimitiveType generic) 00376 { 00377 if (*sgserializable_name == '\0') return true; 00378 00379 pop_object(); 00380 return true; 00381 } 00382 00383 bool 00384 CSerializableJsonFile::write_type_begin_wrapped( 00385 const TSGDataType* type, const char* name, const char* prefix) 00386 { 00387 json_object* buf = json_object_new_object(); 00388 if (is_error(buf)) return false; 00389 00390 json_object_object_add(m_stack_stream.back(), name, buf); 00391 push_object(buf); 00392 00393 string_t str_buf; 00394 type->to_string(str_buf, STRING_LEN); 00395 buf = json_object_new_string(str_buf); 00396 if (is_error(buf)) return false; 00397 json_object_object_add(m_stack_stream.back(), STR_KEY_TYPE, buf); 00398 00399 return true; 00400 } 00401 00402 bool 00403 CSerializableJsonFile::write_type_end_wrapped( 00404 const TSGDataType* type, const char* name, const char* prefix) 00405 { 00406 json_object_object_add( 00407 m_stack_stream.get_element( 00408 m_stack_stream.get_num_elements() - 2), STR_KEY_DATA, 00409 m_stack_stream.back()); 00410 pop_object(); 00411 00412 pop_object(); 00413 return true; 00414 } 00415 00416 #endif /* HAVE_JSON */