/* this complies with system.methodSignature as defined at * http://xmlrpc.usefulinc.com/doc/sysmethodsig.html */ static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); XMLRPC_VALUE xResponse = NULL; /* lazy loading of introspection data */ check_docs_loaded(server, userData); if(method) { server_method* sm = find_method(server, method); if(sm && sm->desc) { XMLRPC_VALUE xTypesArray = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); XMLRPC_VALUE xIter, xParams, xSig, xSigIter; const char* type; /* array of possible signatures. */ xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); /* find first signature */ xSig = XMLRPC_VectorGetValueWithID(sm->desc, xi_token_signatures); xSigIter = XMLRPC_VectorRewind( xSig ); /* iterate through sigs */ while(xSigIter) { /* first type is the return value */ type = XMLRPC_VectorGetStringWithID(XMLRPC_VectorRewind( XMLRPC_VectorGetValueWithID(xSigIter, xi_token_returns)), xi_token_type); XMLRPC_AddValueToVector(xTypesArray, XMLRPC_CreateValueString(NULL, type ? type : type_to_str(xmlrpc_none, 0), 0)); /* the rest are parameters */ xParams = XMLRPC_VectorGetValueWithID(xSigIter, xi_token_params); xIter = XMLRPC_VectorRewind(xParams); /* iter through params, adding to types array */ while(xIter) { XMLRPC_AddValueToVector(xTypesArray, XMLRPC_CreateValueString(NULL, XMLRPC_VectorGetStringWithID(xIter, xi_token_type), 0)); xIter = XMLRPC_VectorNext(xParams); } /* add types for this signature */ XMLRPC_AddValueToVector(xResponse, xTypesArray); xSigIter = XMLRPC_VectorNext( xSig ); } } } return xResponse; }
/* returns a new XMLRPC_VALUE representing a soap fault, comprised of a struct with four keys. */ static XMLRPC_VALUE gen_soap_fault(const char* fault_code, const char* fault_string, const char* actor, const char* details) { XMLRPC_VALUE xReturn = XMLRPC_CreateVector(TOKEN_FAULT, xmlrpc_vector_struct); XMLRPC_AddValuesToVector(xReturn, XMLRPC_CreateValueString(TOKEN_SOAP_FAULTCODE, fault_code, 0), XMLRPC_CreateValueString(TOKEN_SOAP_FAULTSTRING, fault_string, 0), XMLRPC_CreateValueString(TOKEN_SOAP_FAULTACTOR, actor, 0), XMLRPC_CreateValueString(TOKEN_SOAP_FAULTDETAILS, details, 0), NULL); return xReturn; }
/* * This handler takes a single parameter, which is an array containing * between 100 and 200 elements. Each of the items is a string, your handler * must return a string containing the concatenated text of the first and * last elements. */ XMLRPC_VALUE validator1_moderateSizeArrayCheck (XMLRPC_SERVER server, XMLRPC_REQUEST xRequest, void* userData) { XMLRPC_VALUE xReturn = NULL; simplestring buf; simplestring_init(&buf); if(xRequest) { XMLRPC_VALUE xArray = XMLRPC_VectorRewind(XMLRPC_RequestGetData(xRequest)); if(xArray) { XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xArray), xPrev = 0; simplestring_add(&buf, XMLRPC_GetValueString(xIter)); /* TODO: Should add XMLRPC_VectorLast() call. Much more efficient */ while(xIter) { xPrev = xIter; xIter = XMLRPC_VectorNext(xArray); } simplestring_add(&buf, XMLRPC_GetValueString(xPrev)); } } xReturn = XMLRPC_CreateValueString(0, buf.str, buf.len); return xReturn; }
bool XMLRPC::stringToBytes(const std::string* _source) { XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueString(NULL, _source->c_str(), _source->size()) ); return true; }
/* typically, most developer time will be spent writing these types of functions. */ XMLRPC_VALUE hello_callback(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { char buf[1024]; #ifdef VERBOSE XMLRPC_VALUE xParams = XMLRPC_RequestGetData(request); // obtain method params from request XMLRPC_VALUE xFirstParam = XMLRPC_VectorRewind(xParams); // obtain first parameter const char * name = XMLRPC_GetValueString(xFirstParam); // get string value #else const char* name = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request))); #endif snprintf(buf, sizeof(buf), "hello %s", name ? name : "stranger"); return XMLRPC_CreateValueString(NULL, buf, 0); }
/* this complies with system.methodHelp as defined at * http://xmlrpc.usefulinc.com/doc/sysmethhelp.html */ static XMLRPC_VALUE xi_system_method_help_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); XMLRPC_VALUE xResponse = NULL; /* lazy loading of introspection data */ check_docs_loaded(server, userData); if(method) { server_method* sm = find_method(server, method); if(sm && sm->desc) { const char* help = XMLRPC_VectorGetStringWithID(sm->desc, xi_token_purpose); /* returns a documentation string, or empty string */ xResponse = XMLRPC_CreateValueString(NULL, help ? help : xi_token_empty, 0); } } return xResponse; }
void LLXMLRPCValue::appendString(const std::string& v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueString(NULL, v.c_str(), 0)); }
/* convert an xml tree conforming to spec <url tbd> to XMLRPC_VALUE * suitable for use with XMLRPC_ServerAddIntrospectionData */ XMLRPC_VALUE xml_element_to_method_description(xml_element* el, XMLRPC_ERROR err) { XMLRPC_VALUE xReturn = NULL; if(el->name) { const char* name = NULL; const char* type = NULL; const char* basetype = NULL; const char* desc = NULL; const char* def = NULL; int optional = 0; xml_element_attr* attr_iter = Q_Head(&el->attrs); /* grab element attributes up front to save redundant while loops */ while(attr_iter) { if(!strcmp(attr_iter->key, "name")) { name = attr_iter->val; } else if(!strcmp(attr_iter->key, "type")) { type = attr_iter->val; } else if(!strcmp(attr_iter->key, "basetype")) { basetype = attr_iter->val; } else if(!strcmp(attr_iter->key, "desc")) { desc = attr_iter->val; } else if(!strcmp(attr_iter->key, "optional")) { if(attr_iter->val && !strcmp(attr_iter->val, "yes")) { optional = 1; } } else if(!strcmp(attr_iter->key, "default")) { def = attr_iter->val; } attr_iter = Q_Next(&el->attrs); } /* value and typeDescription behave about the same */ if(!strcmp(el->name, "value") || !strcmp(el->name, "typeDescription")) { XMLRPC_VALUE xSubList = NULL; const char* ptype = !strcmp(el->name, "value") ? type : basetype; if(ptype) { if(Q_Size(&el->children) && (!strcmp(ptype, "array") || !strcmp(ptype, "struct") || !strcmp(ptype, "mixed"))) { xSubList = XMLRPC_CreateVector("member", xmlrpc_vector_array); if(xSubList) { xml_element* elem_iter = Q_Head(&el->children); while(elem_iter) { XMLRPC_AddValueToVector(xSubList, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } } xReturn = describeValue_worker(ptype, name, (desc ? desc : (xSubList ? NULL : el->text.str)), optional, def, xSubList); } } /* these three kids are about equivalent */ else if(!strcmp(el->name, "params") || !strcmp(el->name, "returns") || !strcmp(el->name, "signature")) { if(Q_Size(&el->children)) { xml_element* elem_iter = Q_Head(&el->children); xReturn = XMLRPC_CreateVector(!strcmp(el->name, "signature") ? NULL : el->name, xmlrpc_vector_struct); while(elem_iter) { XMLRPC_AddValueToVector(xReturn, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } } else if(!strcmp(el->name, "methodDescription")) { xml_element* elem_iter = Q_Head(&el->children); xReturn = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(xReturn, xi_token_name, name, 0); while(elem_iter) { XMLRPC_AddValueToVector(xReturn, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } /* items are slightly special */ else if(!strcmp(el->name, "item")) { xReturn = XMLRPC_CreateValueString(name, el->text.str, el->text.len); } /* sure. we'll let any ol element with children through */ else if(Q_Size(&el->children)) { xml_element* elem_iter = Q_Head(&el->children); xReturn = XMLRPC_CreateVector(el->name, xmlrpc_vector_mixed); while(elem_iter) { XMLRPC_AddValueToVector(xReturn, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } /* or anything at all really, so long as its got some text. * no reason being all snotty about a spec, right? */ else if(el->name && el->text.len) { xReturn = XMLRPC_CreateValueString(el->name, el->text.str, el->text.len); } } return xReturn; }