json2matlab.c
Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <string.h>
00003 #include "../csm/csm_all.h"
00004 #include <options/options.h>
00005 
00006 #include <json-c/json.h>
00007 #include <json-c/json_object_private.h>
00008 
00009 void jo_write_as_matlab(JO jo, FILE*out);
00010 
00011 void jo_write_as_matrix(JO jo, FILE*out);
00012 void jo_write_as_column_vector(JO jo, FILE* out);
00013 
00014 void jo_write_as_cell_array(JO jo, FILE* out);
00015 int jo_is_numeric_matrix(JO jo);
00016 int jo_is_numeric_array(JO jo);
00017 void jo_write_as_matlab_object(JO jo, FILE*out);
00018 
00019 
00020 const char * banner = 
00021 "Converts JSON stream to Matlab file. \n"
00022 "There are three usages: \n"
00023 " 1) with only one parameter, \n"
00024 "    $ json2matlab dir/mydata.json \n"
00025 "    creates a Matlab function 'mydata' inside the file 'dir/mydata.m' \n"
00026 " 2) with two parameters, \n"
00027 "     $ json2matlab dir/mydata.json dir/out.m \n" 
00028 "    creates a Matlab function 'out' inside the file 'dir/out.m'. \n"
00029 " 3) otherwise, use the options switches. \n"
00030 " \n"
00031 " By default it creates a complete script of the kind:\n"
00032 " \n"
00033 "   function res = function_name()\n"
00034 "      res = \n"
00035 "               { ...}\n"
00036 " \n"
00037 " If complete_script is set to 0, it just outputs the meat: \n"
00038 " \n"
00039 "               { ...}\n"
00040 " \n";
00041 
00042 
00043 int main(int argc, const char * argv[]) {
00044         sm_set_program_name(argv[0]);
00045 
00046         const char * input_filename;
00047         const char * out_filename;
00048         const char * function;
00049         int complete_script;
00050         int debug;
00051         
00052         options_banner(banner);
00053         
00054         struct option* ops = options_allocate(8);
00055         options_string(ops, "in", &input_filename, "stdin", "input file (JSON)");
00056         options_string(ops, "out", &out_filename, "stdout", "output file (MATLAB)");
00057         options_string(ops, "function", &function, "", "Matlab function name (if empty, use basename of out)");
00058         options_int(ops, "complete_script", &complete_script, 1, "Write complete script 'function  res = ...'");
00059         options_int(ops, "debug", &debug, 1, "Shows debug information");
00060         
00061         if(argc == 2 && (argv[1][0] != '-')) { 
00062                 /* one parameter */
00063                 input_filename = argv[1]; int len = strlen(input_filename) + 4;
00064                 char base[len], no_suffix[len], out[len];
00065                 my_no_suffix(input_filename, no_suffix);
00066                 sprintf(out, "%s.m", no_suffix);
00067                 my_basename_no_suffix(input_filename, base);
00068                 out_filename = my_strdup(out);
00069                 function = my_strdup(base);
00070         } else if(argc == 3 && (argv[1][0] != '-') && (argv[2][0] != '-')) { 
00071                 input_filename = argv[1]; 
00072                 out_filename = argv[2];
00073         } else {
00074                 /* FIXME help not shown */
00075                 if(!options_parse_args(ops, argc, argv))
00076                         return -1;
00077         }
00078 
00079         sm_debug_write(debug);
00080 
00081         if(!strcmp(function,"")) {
00082                 int len = strlen(out_filename) + 4;
00083                 char base[len];
00084                 my_basename_no_suffix(out_filename, base);
00085                 function = my_strdup(base);                             
00086         }
00087         
00088         
00089         FILE * out = open_file_for_writing(out_filename);
00090         if(!out) return -2;
00091 
00092         FILE * in = open_file_for_reading(input_filename);
00093         if(!in) return -3;
00094         
00095         if(complete_script) {
00096                 fprintf(out, "function res = %s\n", function);
00097                 fprintf(out, " res = ... \n");
00098         }
00099         fprintf(out, " { ... \n\t");
00100         
00101         JO jo; 
00102         int i = 0;
00103         while((jo = json_read_stream(in))) {
00104                 if(i>0) fprintf(out, ", ...\n\t");
00105                 jo_write_as_matlab(jo, out);
00106                 jo_free(jo);
00107                 i++;
00108         }
00109 
00110         fprintf(out, "... \n }; \n");
00111         return 0;
00112 }
00113 
00114 
00115 void jo_write_as_matlab(JO jo, FILE*out) {
00116         if(!jo) { fprintf(out, "NaN"); return; } 
00117         
00118         switch(json_object_get_type(jo)) {
00119                 case json_type_null: 
00120                         fprintf(out, "NaN"); 
00121                         return;
00122                 
00123                 case json_type_boolean:
00124                         fprintf(out, json_object_get_boolean(jo) ? "true" : "false" );
00125                         return;
00126                 
00127                 case json_type_int:
00128                         fprintf(out, "%d", json_object_get_int(jo));            
00129                         return;
00130 
00131                 case json_type_double: 
00132                         fprintf(out, "%lg", json_object_get_double(jo));                
00133                         return;
00134                 
00135                 case json_type_object:
00136                         jo_write_as_matlab_object(jo, out);
00137                         return;
00138                 
00139                 case json_type_array:
00140                         if(jo_is_numeric_matrix(jo))
00141                         jo_write_as_matrix(jo, out);
00142                         else
00143                         if(jo_is_numeric_array(jo))
00144                         jo_write_as_column_vector(jo, out);
00145                         else 
00146                         jo_write_as_cell_array(jo, out);                
00147                 return;
00148                 
00149                 case json_type_string:
00150                         fprintf(out, "'");
00151                         const char* s = json_object_get_string(jo);
00152                         while(*s) {
00153                                 if(*s==39) 
00154                                 fputc('"', out);
00155                                 else 
00156                                 fputc(*s, out);
00157                                 s++;
00158                         }
00159                                 
00160                         fprintf(out, "'");
00161                         return;
00162         }
00163         
00164         
00165 }
00166 
00167 
00168 
00169 void jo_write_as_matlab_object(JO jo, FILE*out) {
00170         int i=0;
00171         struct json_object_iter iter;
00172         fprintf(out, "struct(");
00173         
00174         json_object_object_foreachC(jo, iter) {
00175                 if(i) fprintf(out, ", ... \n\t ");
00176                 fprintf(out, "'%s', ", iter.key);
00177                 
00178                 enum json_type t = json_object_get_type(iter.val);
00179                 if( (t == json_type_array) && (!jo_is_numeric_matrix(iter.val)) && (!jo_is_numeric_array(iter.val))) {
00180                         fprintf(out, "{");
00181                         jo_write_as_matlab(iter.val, out);
00182                         fprintf(out, "}");
00183                 } else if(t == json_type_object) {
00184                         fprintf(out, "{ ");
00185                         jo_write_as_matlab(iter.val, out);
00186                         fprintf(out, " }");                     
00187                 } else jo_write_as_matlab(iter.val, out);
00188 
00189                 i++;
00190         }
00191         fprintf(out, ")");
00192 }
00193 
00194 
00195 int jo_is_numeric_matrix(JO jo) {
00196         /* null is not a matrix */
00197         if(!jo) return 0;
00198         if(json_object_get_type(jo) != json_type_array) return 0;
00199         int len = json_object_array_length(jo);
00200         int ncolumns = -1;
00201         for(int i=0;i<len;i++){
00202                 JO row = json_object_array_get_idx(jo, i);
00203                 if(!jo_is_numeric_array(row)) return 0;
00204                 if(i==0) 
00205                         ncolumns = json_object_array_length(row);
00206                 else
00207                         if(ncolumns !=  json_object_array_length(row))
00208                         return 0;
00209         }
00210         if(ncolumns==0) return 0;
00211         return 1;
00212 }
00213 
00214 int jo_is_numeric_array(JO jo) {
00215         /* null is not an array */
00216         if(!jo) return 0;
00217         if(json_object_get_type(jo) != json_type_array) return 0;
00218         int len = json_object_array_length(jo);
00219         for(int i=0;i<len;i++){
00220                 JO elem = json_object_array_get_idx(jo, i);
00221 
00222                 /* I consider null elements as numeric values because they can be
00223                    converted into NaN */
00224                 if(elem==0)
00225                         continue;
00226                         
00227                 switch(json_object_get_type(elem)) {
00228                         case json_type_null: 
00229                         case json_type_boolean:
00230                         case json_type_int:
00231                         case json_type_double:
00232                         continue;
00233                         default:
00234                         return 0;
00235                 }
00236         }
00237         return 1;
00238 }
00239 
00240 void jo_write_as_matrix(JO jo, FILE*out) {
00241 //              "[ " + map{|row| row.join(", ")}.join("; ... \n") +  "]"        
00242         assert(json_object_get_type(jo) == json_type_array);
00243         fprintf(out, "[");
00244         int len = json_object_array_length(jo);
00245         for(int i=0;i<len;i++){
00246                 if(i>0) fprintf(out, ";  ");
00247                 JO row = json_object_array_get_idx(jo, i);
00248                 int n = json_object_array_length(row);
00249                 for(int j=0;j<n;j++) {
00250                         if(j>0) fprintf(out, ", ");
00251                         jo_write_as_matlab(json_object_array_get_idx(row, j), out);
00252                 }
00253         }
00254         fprintf(out, "]");              
00255 }
00256 
00257 void jo_write_as_column_vector(JO jo, FILE* out) {
00258 //      "[  "+map{|x| x.to_matlab }.join("; ")+"]"
00259         assert(json_object_get_type(jo) == json_type_array);
00260         fprintf(out, "[");
00261         int len = json_object_array_length(jo);
00262         for(int i=0;i<len;i++){
00263                 if(i>0) fprintf(out, "; ");
00264                 JO elem = json_object_array_get_idx(jo, i);
00265                 jo_write_as_matlab(elem, out);
00266         }
00267         fprintf(out, "]");
00268 }
00269 
00270 void jo_write_as_cell_array(JO jo, FILE* out) {
00271         assert(json_object_get_type(jo) == json_type_array);
00272         int len = json_object_array_length(jo);
00273         if(len==0) { 
00274                 fprintf(out, "{}"); 
00275                 return; 
00276         } else {        
00277                 fprintf(out, "{ ");
00278                 for(int i=0;i<len;i++){
00279                         if(i>0) fprintf(out, ", ");
00280                         JO elem = json_object_array_get_idx(jo, i);
00281                         jo_write_as_matlab(elem, out);
00282                 }
00283                 fprintf(out, "}");
00284         }
00285 //              "{ ... \n "+map{|x| x.to_matlab }.join(",  ... \n")+"}"
00286 }


csm
Author(s): Andrea Censi
autogenerated on Fri May 17 2019 02:28:33