static void test_value_array_nil(void) { xmlrpc_value * arrayP; xmlrpc_env env; xmlrpc_int32 i1, i2; xmlrpc_value * itemP; size_t len; xmlrpc_env_init(&env); arrayP = xmlrpc_build_value(&env, "(nini)", (xmlrpc_int32) 10, (xmlrpc_int32) 20); TEST_NO_FAULT(&env); TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); len = xmlrpc_array_size(&env, arrayP); TEST_NO_FAULT(&env); TEST(len == 4); itemP = xmlrpc_array_get_item(&env, arrayP, 0); TEST_NO_FAULT(&env); xmlrpc_decompose_value(&env, itemP, "n"); TEST_NO_FAULT(&env); itemP = xmlrpc_array_get_item(&env, arrayP, 1); TEST_NO_FAULT(&env); { int i; xmlrpc_decompose_value(&env, itemP, "i", &i); TEST_NO_FAULT(&env); TEST(i == 10); } xmlrpc_decompose_value(&env, arrayP, "(nini)", &i1, &i2); TEST_NO_FAULT(&env); TEST(i1 == 10 && i2 == 20); /* Test bounds check on xmlrpc_array_get_item. */ xmlrpc_array_read_item(&env, arrayP, 4, &itemP); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_env_clean(&env); xmlrpc_env_init(&env); xmlrpc_array_get_item(&env, arrayP, 4); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_env_clean(&env); xmlrpc_env_init(&env); xmlrpc_DECREF(arrayP); xmlrpc_env_clean(&env); }
bool ArchiveDataClient::getNames(int key, const stdString &pattern, stdVector<NameInfo> &names) { xmlrpc_value *result, *element; const char *name; xmlrpc_int32 start_sec, start_nano, end_sec, end_nano; size_t count, i, len; NameInfo info; result = xmlrpc_client_call(&env, (char *)URL, "archiver.names", "(is)", (xmlrpc_int32) key, pattern.c_str()); if (log_fault()) return false; count = xmlrpc_array_size(&env, result); names.reserve(count); for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, result, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "{s:s#,s:i,s:i,s:i,s:i,*}", "name", &name, &len, "start_sec", &start_sec, "start_nano", &start_nano, "end_sec", &end_sec, "end_nano", &end_nano); if (log_fault()) return false; info.name.assign(name, len); pieces2epicsTime(start_sec, start_nano, info.start); pieces2epicsTime(end_sec, end_nano, info.end); names.push_back(info); } xmlrpc_DECREF(result); return true; }
bool ArchiveDataClient::getArchives(stdVector<ArchiveInfo> &archives) { xmlrpc_value *result, *element; xmlrpc_int32 key; const char *name, *path; size_t count, i, n_len, p_len; ArchiveInfo info; result = xmlrpc_client_call(&env, (char *)URL, "archiver.archives", "()"); if (log_fault()) return false; count = xmlrpc_array_size(&env, result); archives.reserve(count); for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, result, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "{s:i,s:s#,s:s#,*}", "key", &key, "name", &name, &n_len, "path", &path, &p_len); if (log_fault()) return false; info.key = key; info.name.assign(name, n_len); info.path.assign(path, p_len); archives.push_back(info); } xmlrpc_DECREF(result); return true; }
const char* extract_result (xmlrpc_env *env , xmlrpc_value *temp) { xmlrpc_value * arrayP; xmlrpc_decompose_value(env, temp, "(A)", &arrayP); size_t size = xmlrpc_array_size(env, arrayP); xmlrpc_value * strctP; strctP = xmlrpc_array_get_item(env, arrayP, 0); const char *primeResult = (const char *)malloc (256); size_t str1_len; xmlrpc_read_string_lp(env, strctP, &str1_len, &primeResult); return primeResult; }
static xmlrpc_value * system_multicall(xmlrpc_env * const envP, xmlrpc_value * const paramArrayP, void * const serverInfo, void * const callInfo) { xmlrpc_registry * registryP; xmlrpc_value * resultsP; xmlrpc_value * methlistP; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT_ARRAY_OK(paramArrayP); XMLRPC_ASSERT_PTR_OK(serverInfo); resultsP = NULL; /* defeat compiler warning */ /* Turn our arguments into something more useful. */ registryP = (xmlrpc_registry*) serverInfo; getMethListFromMulticallPlist(envP, paramArrayP, &methlistP); if (!envP->fault_occurred) { /* Create an initially empty result list. */ resultsP = xmlrpc_array_new(envP); if (!envP->fault_occurred) { /* Loop over our input list, calling each method in turn. */ unsigned int const methodCount = xmlrpc_array_size(envP, methlistP); unsigned int i; for (i = 0; i < methodCount && !envP->fault_occurred; ++i) { xmlrpc_value * const methinfoP = xmlrpc_array_get_item(envP, methlistP, i); xmlrpc_value * resultP; XMLRPC_ASSERT_ENV_OK(envP); callOneMethod(envP, registryP, methinfoP, callInfo, &resultP); if (!envP->fault_occurred) { /* Append this method result to our master array. */ xmlrpc_array_append_item(envP, resultsP, resultP); xmlrpc_DECREF(resultP); } } if (envP->fault_occurred) xmlrpc_DECREF(resultsP); xmlrpc_DECREF(methlistP); } } return resultsP; }
bool ArchiveDataClient::getValues(int key, stdVector<stdString> &names, const epicsTime &start, const epicsTime &end, int count, int how, value_callback callback, void *callback_arg) { xmlrpc_value *name_array, *result, *element; size_t n; name_array = xmlrpc_build_value(&env, "()"); if (log_fault()) return false; for (n=0; n<names.size(); ++n) { element = xmlrpc_build_value(&env, "s", names[n].c_str()); if (log_fault()) return false; xmlrpc_array_append_item(&env, name_array, element); if (log_fault()) return false; xmlrpc_DECREF(element); } xmlrpc_int32 start_sec, start_nano, end_sec, end_nano; epicsTime2pieces(start, start_sec, start_nano); epicsTime2pieces(end, end_sec, end_nano); result = xmlrpc_client_call(&env, (char *)URL, "archiver.values", "(iViiiiii)", (xmlrpc_int32)key, name_array, start_sec, start_nano, end_sec, end_nano, (xmlrpc_int32)count, (xmlrpc_int32)how); if (log_fault()) return false; xmlrpc_DECREF(name_array); size_t channel_count = xmlrpc_array_size(&env, result); xmlrpc_value *channel_result; for (n=0; n<channel_count; ++n) { channel_result = xmlrpc_array_get_item(&env, result, n); if (log_fault()) return false; if (!decode_channel(channel_result, n, callback, callback_arg)) return false; } xmlrpc_DECREF(result); return true; }
// very_complex_array = archiver.values(key, names[], start, end, ...) xmlrpc_value *get_values(xmlrpc_env *env, xmlrpc_value *args, void *user) { #ifdef LOGFILE LOG_MSG("archiver.get_values\n"); #endif xmlrpc_value *names; xmlrpc_int32 key, start_sec, start_nano, end_sec, end_nano, count, how; xmlrpc_int32 actual_count; // Extract arguments xmlrpc_parse_value(env, args, "(iAiiiiii)", &key, &names, &start_sec, &start_nano, &end_sec, &end_nano, &count, &how); if (env->fault_occurred) return 0; #ifdef LOGFILE LOG_MSG("how=%d, count=%d\n", (int) how, (int) count); #endif if (count <= 1) count = 1; actual_count = count; if (count > 10000) // Upper limit to avoid outrageous requests. actual_count = 10000; // Build start/end epicsTime start, end; pieces2epicsTime(start_sec, start_nano, start); pieces2epicsTime(end_sec, end_nano, end); // Pull names into vector for SpreadsheetReader and just because. xmlrpc_value *name_val; char *name; int i; xmlrpc_int32 name_count = xmlrpc_array_size(env, names); stdVector<stdString> name_vector; name_vector.reserve(name_count); for (i=0; i<name_count; ++i) { // no new ref! name_val = xmlrpc_array_get_item(env, names, i); if (env->fault_occurred) return 0; xmlrpc_parse_value(env, name_val, "s", &name); if (env->fault_occurred) return 0; name_vector.push_back(stdString(name)); } // Build results switch (how) { case HOW_RAW: return get_channel_data(env, key, name_vector, start, end, actual_count, ReaderFactory::Raw, 0.0); case HOW_SHEET: return get_sheet_data(env, key, name_vector, start, end, actual_count, ReaderFactory::Raw, 0.0); case HOW_AVERAGE: return get_sheet_data(env, key, name_vector, start, end, actual_count, ReaderFactory::Average, (end-start)/count); case HOW_PLOTBIN: // 'count' = # of bins, resulting in up to 4*count samples return get_channel_data(env, key, name_vector, start, end, actual_count*4, ReaderFactory::Plotbin, (end-start)/count); case HOW_LINEAR: return get_sheet_data(env, key, name_vector, start, end, actual_count, ReaderFactory::Linear, (end-start)/count); } xmlrpc_env_set_fault_formatted(env, ARCH_DAT_ARG_ERROR, "Invalid how=%d", how); return 0; }
bool ArchiveDataClient::decode_data(const char *name, xmlrpc_int32 type, xmlrpc_int32 count, xmlrpc_value *data_array, CtrlInfo &ctrlinfo, size_t n, value_callback callback, void *callback_arg) { size_t i, num, v, v_num; xmlrpc_int32 stat, sevr, secs, nano; xmlrpc_value *data, *value_array, *value; epicsTime stamp; DbrType dbr_type; RawValue::Data *raw_value; switch (type) { case XML_STRING: dbr_type = DBR_TIME_STRING; break; case XML_ENUM: dbr_type = DBR_TIME_ENUM; break; case XML_INT: dbr_type = DBR_TIME_LONG; break; case XML_DOUBLE: dbr_type = DBR_TIME_DOUBLE; break; default: LOG_MSG("Cannot decode data type %d\n", type); return false; } raw_value = RawValue::allocate(dbr_type, count, 1); num = xmlrpc_array_size(&env, data_array); if (log_fault()) return false; for (i=0; i<num; ++i) { data = xmlrpc_array_get_item(&env, data_array, i); xmlrpc_parse_value(&env, data, "{s:i,s:i,s:i,s:i,s:A,*}", "stat", &stat, "sevr", &sevr, "secs", &secs, "nano", &nano, "value", &value_array); if (log_fault()) return false; pieces2epicsTime(secs, nano, stamp); RawValue::setStatus(raw_value, stat, sevr); RawValue::setTime(raw_value, stamp); v_num = xmlrpc_array_size(&env, value_array); if (log_fault()) return false; if (v_num != (size_t)count) { LOG_MSG("value size discrepancy, %zu != %zu\n", v_num, (size_t)count); return false; } for (v=0; v<v_num; ++v) { value = xmlrpc_array_get_item(&env, value_array, v); if (log_fault()) return false; switch (dbr_type) { case DBR_TIME_STRING: { if (v > 0) break; const char *txt; size_t len; xmlrpc_parse_value(&env, value, "s#", &txt, &len); if (len >= MAX_STRING_SIZE) len = MAX_STRING_SIZE-1; memcpy(((dbr_time_string *)raw_value)->value, txt, len); ((dbr_time_string *)raw_value)->value[len] = '\0'; } break; case DBR_TIME_ENUM: { dbr_enum_t *val = &((dbr_time_enum *)raw_value)->value; xmlrpc_int32 ival; xmlrpc_parse_value(&env, value, "i", &ival); val[v] = ival; if (log_fault()) return false; } break; case DBR_TIME_LONG: { dbr_long_t *val = &((dbr_time_long *)raw_value)->value; xmlrpc_int32 ival; xmlrpc_parse_value(&env, value, "i", &ival); val[v] = ival; if (log_fault()) return false; } break; case DBR_TIME_DOUBLE: { double *val = &((dbr_time_double *)raw_value)->value; xmlrpc_parse_value(&env, value, "d", &val[v]); if (log_fault()) return false; } break; } } if (!callback(callback_arg, name, n, i, ctrlinfo, dbr_type, count, raw_value)) break; } RawValue::free(raw_value); return true; }
bool ArchiveDataClient::getInfo(int &version, stdString &description, stdVector<stdString> &how_strings, stdVector<stdString> &stat_strings, stdVector<SeverityInfo> &sevr_infos) { xmlrpc_value *result, *hows, *stats, *sevrs, *element; xmlrpc_int32 num; xmlrpc_bool has_value, txt_stat; const char *str; size_t count, len, i; result = xmlrpc_client_call(&env, (char *)URL, "archiver.info", "()"); if (log_fault()) return false; xmlrpc_parse_value(&env, result, "{s:i,s:s#,s:A,s:A,s:A,*}", "ver", &num, "desc", &str, &len, "how", &hows, "stat", &stats, "sevr", &sevrs); if (log_fault()) return false; version = num; description.assign(str, len); // 'how' array count = xmlrpc_array_size(&env, hows); how_strings.reserve(count); for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, hows, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "s", &str); if (log_fault()) return false; how_strings.push_back(stdString(str)); } // 'stat' array count = xmlrpc_array_size(&env, stats); stat_strings.reserve(count); for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, stats, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "s", &str); if (log_fault()) return false; stat_strings.push_back(stdString(str)); } // 'sevr' array count = xmlrpc_array_size(&env, sevrs); stat_strings.reserve(count); SeverityInfo info; for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, sevrs, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "{s:i,s:s#,s:b,s:b,*}", "num", &num, "sevr", &str, &len, "has_value", &has_value, "txt_stat", &txt_stat); if (log_fault()) return false; info.num = num; info.text.assign(str, len); info.has_value = has_value; info.txt_stat = txt_stat; sevr_infos.push_back(info); } xmlrpc_DECREF(result); return true; }
// Dump 'meta' part of returned value bool ArchiveDataClient::decode_meta(xmlrpc_value *meta, CtrlInfo &ctrlinfo) { xmlrpc_int32 type; xmlrpc_parse_value(&env, meta, "{s:i,*}", "type", &type); if (log_fault()) return false; if (type == 0) { xmlrpc_value *element, *states; xmlrpc_parse_value(&env, meta, "{s:A,*}", "states", &states); if (log_fault()) return false; size_t i, total, len, count = xmlrpc_array_size(&env, states); const char *str; total = 0; for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, states, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "s#", &str, &len); if (log_fault()) return false; total += len+1; } ctrlinfo.allocEnumerated(count, total); for (i=0; i<count; ++i) { element = xmlrpc_array_get_item(&env, states, i); if (log_fault()) return false; xmlrpc_parse_value(&env, element, "s", &str); if (log_fault()) return false; ctrlinfo.setEnumeratedString(i, str); } } else if (type == 1) { double disp_high, disp_low, alarm_high, alarm_low, warn_high, warn_low; xmlrpc_int32 prec; char *units; xmlrpc_parse_value(&env, meta, "{s:d,s:d,s:d,s:d,s:d,s:d,s:i,s:s,*}", "disp_high", &disp_high, "disp_low", &disp_low, "alarm_high", &alarm_high, "alarm_low", &alarm_low, "warn_high", &warn_high, "warn_low", &warn_low, "prec", &prec, "units", &units); if (log_fault()) return false; ctrlinfo.setNumeric(prec, units, disp_low, disp_high, alarm_low, warn_low, warn_high, alarm_high); } else { LOG_MSG("unknown meta type %d\n", type); return false; } return true; }
static void test_value_array2(void) { xmlrpc_value * arrayP; xmlrpc_env env; xmlrpc_int32 i, i1, i2, i3, i4, i5; xmlrpc_value * itemP; xmlrpc_value * subarrayP; size_t len; /* A more complex array. */ xmlrpc_env_init(&env); arrayP = xmlrpc_build_value(&env, "(i(ii)i)", (xmlrpc_int32) 10, (xmlrpc_int32) 20, (xmlrpc_int32) 30, (xmlrpc_int32) 40); TEST_NO_FAULT(&env); TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP)); len = xmlrpc_array_size(&env, arrayP); TEST_NO_FAULT(&env); TEST(len == 3); xmlrpc_array_read_item(&env, arrayP, 1, &subarrayP); TEST_NO_FAULT(&env); len = xmlrpc_array_size(&env, subarrayP); TEST_NO_FAULT(&env); TEST(len == 2); xmlrpc_array_read_item(&env, subarrayP, 0, &itemP); TEST_NO_FAULT(&env); xmlrpc_decompose_value(&env, itemP, "i", &i); xmlrpc_DECREF(itemP); TEST_NO_FAULT(&env); TEST(i == 20); xmlrpc_DECREF(subarrayP); itemP = xmlrpc_array_get_item(&env, arrayP, 0); TEST_NO_FAULT(&env); xmlrpc_decompose_value(&env, itemP, "i", &i); TEST_NO_FAULT(&env); TEST(i == 10); xmlrpc_decompose_value(&env, arrayP, "(i(ii)i)", &i1, &i2, &i3, &i4); TEST_NO_FAULT(&env); TEST(i1 == 10 && i2 == 20 && i3 == 30 && i4 == 40); xmlrpc_decompose_value(&env, arrayP, "(i(i*)i)", &i1, &i2, &i3); TEST_NO_FAULT(&env); TEST(i1 == 10 && i2 == 20 && i3 == 40); xmlrpc_decompose_value(&env, arrayP, "(i(ii*)i)", &i1, &i2, &i3, &i4); TEST_NO_FAULT(&env); xmlrpc_decompose_value(&env, arrayP, "(i(iii)i)", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_decompose_value(&env, arrayP, "(i(i)i)", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_decompose_value(&env, arrayP, "(i(ii)i*i)", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_decompose_value(&env, arrayP, "(i(iiQ)i*i)", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_decompose_value(&env, arrayP, "(", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_decompose_value(&env, arrayP, "(i", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); xmlrpc_decompose_value(&env, arrayP, "(i*", &i1, &i2, &i3, &i4, &i5); TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR); /* Test bounds check on xmlrpc_array_get_item. */ xmlrpc_array_read_item(&env, arrayP, 3, &itemP); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_array_get_item(&env, arrayP, 3); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_array_get_item(&env, arrayP, -1); TEST_FAULT(&env, XMLRPC_INDEX_ERROR); xmlrpc_DECREF(arrayP); xmlrpc_env_clean(&env); }
struct mi_root * xr_parse_tree( xmlrpc_env * env, xmlrpc_value * paramArray ) { struct mi_root * mi_root; int size, i; size_t length; xmlrpc_int32 intValue; xmlrpc_bool boolValue; #ifdef XMLRPC_OLD_VERSION double doubleValue; char * contents; #else xmlrpc_double doubleValue; #endif char * stringValue = 0; char * byteStringValue =0; xmlrpc_value * item; mi_root = init_mi_tree(0, 0, 0); if ( !mi_root ) { LM_ERR("the MI tree cannot be initialized!\n"); goto error; } size = xmlrpc_array_size(env, paramArray); for (i=0 ; i< size ; i++) { item = xmlrpc_array_get_item(env, paramArray, i); if ( env->fault_occurred ) { LM_ERR("failed to get array item: %s\n", env->fault_string); goto error; } switch ( xmlrpc_value_type(item) ) { case (XMLRPC_TYPE_INT): #ifdef XMLRPC_OLD_VERSION intValue = item->_value.i; #else xmlrpc_read_int(env,item,&intValue); #endif if (addf_mi_node_child(&mi_root->node,0,0,0,"%d",intValue)==NULL) { LM_ERR("failed to add node to the MI tree.\n"); goto error; } break; case (XMLRPC_TYPE_BOOL): #ifdef XMLRPC_OLD_VERSION boolValue = item->_value.b; #else xmlrpc_read_bool(env,item,&boolValue); #endif if (addf_mi_node_child(&mi_root->node,0,0,0,"%u",boolValue)==NULL){ LM_ERR("failed to add node to the MI tree.\n"); goto error; } break; case (XMLRPC_TYPE_DOUBLE): #ifdef XMLRPC_OLD_VERSION doubleValue = item->_value.d; #else xmlrpc_read_double(env,item,&doubleValue); #endif if ( addf_mi_node_child(&mi_root->node, 0, 0, 0, "%lf", doubleValue) == NULL ) { LM_ERR("failed to add node to the MI tree.\n"); goto error; } break; case (XMLRPC_TYPE_STRING): #if HAVE_UNICODE_WCHAR #ifdef XMLRPC_OLD_VERSION xmlrpc_read_string_w(env, item, &stringValue); #else xmlrpc_read_string_w(env, item , (const char **)&stringValue); #endif #else #ifdef XMLRPC_OLD_VERSION xmlrpc_read_string(env, item, &stringValue); #else xmlrpc_read_string(env, item, (const char **)&stringValue); #endif #endif if ( env->fault_occurred ) { LM_ERR("failed to read stringValue: %s!\n", env->fault_string); goto error; } if ( add_mi_node_child(&mi_root->node, 0, 0, 0, stringValue, lflf_to_crlf_hack(stringValue)) == NULL ) { LM_ERR("failed to add node to the MI tree.\n"); goto error; } break; case (XMLRPC_TYPE_BASE64): #ifdef XMLRPC_OLD_VERSION length = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &item->_block); contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &item->_block); byteStringValue = pkg_malloc(length); if ( !byteStringValue ){ xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, "Unable to allocate %u bytes for byte string.", length); LM_ERR("pkg_malloc cannot allocate any more memory!\n"); goto error; } else memcpy(byteStringValue, contents, length); if ( add_mi_node_child(&mi_root->node, 0, 0, 0, byteStringValue, length) == NULL ) { LM_ERR("failed to add node to the MI tree.\n"); goto error; } #else xmlrpc_read_base64(env, item, &length, (const unsigned char **)(void*)&byteStringValue); if ( env->fault_occurred ) { LM_ERR("failed to read byteStringValue: %s!\n", env->fault_string); goto error; } if ( add_mi_node_child(&mi_root->node, MI_DUP_VALUE, 0, 0, byteStringValue, length) == NULL ) { LM_ERR("failed to add node to the MI tree.\n"); goto error; } free(byteStringValue); #endif break; default : LM_ERR("unsupported node type %d\n", xmlrpc_value_type(item) ); xmlrpc_env_set_fault_formatted( env, XMLRPC_TYPE_ERROR, "Unsupported value of type %d supplied", xmlrpc_value_type(item)); goto error; } } return mi_root; error: if ( mi_root ) free_mi_tree(mi_root); if ( byteStringValue ) pkg_free(byteStringValue); return 0; }
static xmlrpc_value * calculate_modexp(xmlrpc_env * const env, xmlrpc_value * const param_array, void * const serverInfo, void * const channelInfo) { int i = 0; Task temp; xmlrpc_value * retval; xmlrpc_value * arrayP; xmlrpc_decompose_value(env, param_array, "(A)", &arrayP); size_t size = xmlrpc_array_size(env, arrayP); if (env->fault_occurred) retval = NULL; else { for (i = 0; i < size && !env->fault_occurred; ++i) { xmlrpc_value * strctP; strctP = xmlrpc_array_get_item(env, arrayP, i); if (!env->fault_occurred) { if(i == 0) { const char * str1; size_t str1_len; xmlrpc_read_string_lp(env, strctP, &str1_len, &str1); //xmlrpc_int32 curly; //xmlrpc_decompose_value(env, strctP, "(s)",&ip[0]); strcpy(temp._clientid, str1); } else { const char * str1; size_t str1_len; xmlrpc_read_string_lp(env, strctP, &str1_len, &str1); if(i == 1) strcpy(temp.p,str1); else if(i == 2) strcpy(temp.m,str1); } } } } xmlrpc_DECREF(arrayP); if (env->fault_occurred) return NULL; printf("Received: %s %s %s\n",temp._clientid,temp.p,temp.m); /* Add our two numbers. */ // z = x + y; /* Sometimes, make it look hard (so client can see what it's like to do an RPC that takes a while). */ compute_mod(&temp); xmlrpc_value *arr = xmlrpc_array_new(env); xmlrpc_value *v1 = xmlrpc_build_value(env, "s", temp.response); xmlrpc_array_append_item (env,arr,v1); /* Return our result. */ return xmlrpc_build_value(env,"(A)", arr); }
static xmlrpc_value * you_search (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { RCWorld *world = (RCWorld *) user_data; xmlrpc_value *value = NULL; int size = 0; RCDQueryPart *parts = NULL; int i; RCYouPatchSList *rc_you_patches = NULL; xmlrpc_value *xmlrpc_patches = NULL; xmlrpc_parse_value (env, param_array, "(V)", &value); XMLRPC_FAIL_IF_FAULT (env); size = xmlrpc_array_size (env, value); XMLRPC_FAIL_IF_FAULT (env); parts = g_new0 (RCDQueryPart, size + 1); for (i = 0; i < size; i++) { xmlrpc_value *v; v = xmlrpc_array_get_item (env, value, i); XMLRPC_FAIL_IF_FAULT (env); parts[i] = rcd_xmlrpc_tuple_to_query_part (v, env); XMLRPC_FAIL_IF_FAULT (env); if (parts[i].type == RCD_QUERY_INVALID) { xmlrpc_env_set_fault (env, RCD_RPC_FAULT_INVALID_SEARCH_TYPE, "Invalid search type"); goto cleanup; } } parts[i].type = RCD_QUERY_LAST; rc_you_query_patches (world, parts, add_patch_cb, &rc_you_patches); xmlrpc_patches = rc_you_patch_slist_to_xmlrpc_array (rc_you_patches, env); cleanup: if (parts) { for (i = 0; i < size; i++) { g_free (parts[i].key); g_free (parts[i].query_str); } g_free (parts); } if (rc_you_patches) { rc_you_patch_slist_unref (rc_you_patches); g_slist_free (rc_you_patches); } if (env->fault_occurred) return NULL; return xmlrpc_patches; } /* you_search */