/* 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;
}
示例#2
0
/* 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;
}
示例#3
0
/*
 * 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;
}
示例#4
0
         bool XMLRPC::stringToBytes(const std::string* _source)
         {
            XMLRPC_AddValueToVector(
                                    XMLRPC_RequestGetData(xmlrpc_request),
                                    XMLRPC_CreateValueString(NULL, _source->c_str(), _source->size())
                                    );

            return true;
         }
示例#5
0
/* 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;
}