00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "TXmlRpc.h"
00020
00021
00022 #include "TClSession.h"
00023 #include "TError.h"
00024
00025
00026
00027
00028 namespace {
00029
00030 void print_values(int level, xmlrpc_env *env, xmlrpc_value *in);
00031
00032 Bool_t report_error(xmlrpc_env *env, const char *what)
00033 {
00034 if (env->fault_occurred) {
00035 printf("Error decoding %s: %s (%d)", what, env->fault_string,
00036 env->fault_code);
00037 }
00038 return env->fault_occurred;
00039 }
00040
00041
00042 int get_int(xmlrpc_env *env, xmlrpc_value *in)
00043 {
00044 int i = 0;
00045 xmlrpc_parse_value(env, in, "i", &i);
00046 report_error(env,"int");
00047 return(i);
00048 }
00049
00050
00051 int get_boolean(xmlrpc_env *env, xmlrpc_value *in)
00052 {
00053 int i = 0;
00054 xmlrpc_parse_value(env, in, "b", &i);
00055 report_error(env,"bool");
00056 return(i);
00057 }
00058
00059
00060 double get_double(xmlrpc_env *env, xmlrpc_value *in)
00061 {
00062 double d = 0;
00063 xmlrpc_parse_value(env, in, "d", &d);
00064 report_error(env,"double");
00065 return(d);
00066 }
00067
00068
00069 char* get_timestamp(xmlrpc_env *env, xmlrpc_value *in)
00070 {
00071 char *s = 0;
00072
00073 xmlrpc_parse_value(env, in, "8", &s);
00074 report_error(env,"timestamp");
00075 return(s);
00076 }
00077
00078
00079 char* get_string(xmlrpc_env *env, xmlrpc_value *in){
00080 char* s = 0;
00081
00082 xmlrpc_parse_value(env, in, "s", &s);
00083 report_error(env,"string");
00084 return(s);
00085 }
00086
00087
00088 char* get_base64(xmlrpc_env *env, xmlrpc_value *in)
00089 {
00090 char *s = 0;
00091
00092 xmlrpc_parse_value(env, in, "6", &s);
00093 report_error(env,"base64");
00094 return(s);
00095 }
00096
00097
00098 void get_struct(int level, xmlrpc_env *env, xmlrpc_value *in){
00099 int i, size = 0;
00100 xmlrpc_value *key, *value;
00101 TString space(' ', level * 3);
00102
00103 size = xmlrpc_struct_size(env, in);
00104 if (report_error(env,"struct")) return;
00105
00106 for(i=0; i < size; i++){
00107 xmlrpc_struct_get_key_and_value(env, in, i, &key, &value);
00108 if (report_error(env,"struct member")) return;
00109
00110 char *keystr = get_string(env, key);
00111 if (env->fault_occurred) return;
00112
00113 printf("%s%s:\n", space.Data(), keystr);
00114 print_values(level+1, env, value);
00115 if (env->fault_occurred) return;
00116 }
00117 }
00118
00119
00120 void get_array(int level, xmlrpc_env *env, xmlrpc_value *in)
00121 {
00122 int i, size = 0;
00123 xmlrpc_value *el;
00124
00125 size = xmlrpc_array_size(env, in);
00126 if (report_error(env,"array")) return;
00127
00128 for(i=0; i < size; i++){
00129 el = xmlrpc_array_get_item( env, in, i);
00130 if (report_error(env,"array element")) return;
00131
00132 print_values(level, env, el);
00133 if (env->fault_occurred) return;
00134 }
00135 }
00136
00137
00138 void print_values(int level, xmlrpc_env *env, xmlrpc_value *in)
00139 {
00140 TString space(' ', level * 3);
00141
00142 printf("%s", space.Data());
00143
00144
00145 switch (xmlrpc_value_type(in)) {
00146 case (XMLRPC_TYPE_INT):
00147 printf("int %d\n", get_int(env, in));
00148 break;
00149 case (XMLRPC_TYPE_BOOL):
00150 printf("bool %s\n", get_boolean(env, in) ? "true" : "false" );
00151 break;
00152 case (XMLRPC_TYPE_DOUBLE):
00153 printf("double %g\n", get_double(env, in));
00154 break;
00155 case (XMLRPC_TYPE_DATETIME):
00156 printf("timestamp %s\n",
00157 get_timestamp(env, in));
00158 break;
00159 case (XMLRPC_TYPE_STRING):
00160 printf("string '%s'\n", get_string(env, in));
00161 break;
00162 case (XMLRPC_TYPE_BASE64):
00163 printf("base64 %s\n",
00164 get_base64(env, in));
00165 break;
00166 case (XMLRPC_TYPE_ARRAY):
00167 printf("(\n");
00168 get_array(level+1, env, in);
00169 printf("%s)\n", space.Data());
00170 break;
00171 case (XMLRPC_TYPE_STRUCT):
00172 printf("{\n");
00173 get_struct(level+1, env, in);
00174 printf("%s}\n", space.Data());
00175 break;
00176 case (XMLRPC_TYPE_C_PTR):
00177 printf("Got a C pointer?!\n");
00178 break;
00179 case (XMLRPC_TYPE_DEAD):
00180 printf("Got a 0xDEADr?!\n");
00181 break;
00182 default:
00183 printf("UNKNOWN XML-RPC DATATYPE\n");
00184 }
00185 }
00186
00187
00188 };
00189
00190
00191 ClassImp(TXmlRpc)
00192
00193
00194 TXmlRpc::TXmlRpc(TClSession *session)
00195 : fSession(session)
00196 {
00197 fEnv = new xmlrpc_env;
00198 xmlrpc_env_init(fEnv);
00199 }
00200
00201
00202
00203 TXmlRpc::~TXmlRpc()
00204 {
00205 delete fEnv;
00206 }
00207
00208
00209
00210 xmlrpc_value *TXmlRpc::Call(const Char_t *method, xmlrpc_value *arg)
00211 {
00212
00213
00214 TString m = fService + "." + method;
00215
00216 xmlrpc_value *retval = xmlrpc_client_call_server( fEnv,
00217 fSession->GetServerInfo(), (char *) m.Data(),
00218 (char *) (arg == 0 ? "()" : "V"), arg);
00219
00220 if (gDebug > 1) {
00221 if (retval != 0) {
00222 Info("Call", "%s: returns:", m.Data());
00223 PrintValue(retval);
00224 } else {
00225 Info("Call", "%s: no return value", m.Data());
00226 }
00227 }
00228
00229 return retval;
00230 }
00231
00232
00233
00234 Bool_t TXmlRpc::RpcFailed(const Char_t *where, const Char_t *what)
00235 {
00236
00237
00238 if (fEnv->fault_occurred) {
00239 ::Error(where, "%s: %s (%d)", what,
00240 fEnv->fault_string, fEnv->fault_code);
00241 return kTRUE;
00242 }
00243
00244 return kFALSE;
00245 }
00246
00247
00248
00249 void TXmlRpc::PrintValue(xmlrpc_value *val)
00250 {
00251
00252
00253 xmlrpc_env *env = new xmlrpc_env; xmlrpc_env_init(env);
00254
00255 print_values(0, env, val);
00256
00257 xmlrpc_env_clean(env);
00258 }
00259
00260