/* This file is part of libXMLRPC - a C library for xml-encoded function calls Copyright (C) 2000 Dan Libby, Epinions.com, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA The LGPL is also available online at http://www.gnu.org/copyleft/lgpl.html The author may be contacted at dan@libby.com. Epinions.com may be contacted at feedback@epinions-inc.com */ /* This is a simple demonstration of how to use xmlrpc. This program * acts as both client and server. It instanstiates an xmlrpc * server, registers methods, creates an xmlrpc request, and processes * the request. It can optionally print out the request, the response, * or both. There are also several options for output format and * which method to call. It also acts as a test-case for each of * the xmlrpc data types, as each is implemented in a method. * * For usage, see below or execute ./sample --help * * See also ./client and ./server, which are stand-alone versions * of this program. */ #include #include #include "xmlrpc.h" /* This example shows how to use the introspection API */ void describe_TestStruct(XMLRPC_SERVER server) { STRUCT_XMLRPC_ERROR err = {0}; XMLRPC_VALUE xDesc; const char* desc = "\n" "" "" " " "" "street address" "Apartment number" "city " "state or province " "zip or postal code" "country " "" " " "" "first name" "last name" "email address" "phone number" "email address" "" "" "" "" "" "Dan Libby" "a silly method to test that structs work" "" "" "" "" "a struct representing a person's contact information" "" "" "contact info that was passed in, or John Doe's info" "" "" "" "" "system.listMethods" "" "" "" "this is a lame example" "example of multiple notes" "" "" "" "" "" ""; xDesc = XMLRPC_IntrospectionCreateDescription(desc, &err); if(xDesc) { XMLRPC_ServerAddIntrospectionData(server, xDesc); XMLRPC_CleanupValue(xDesc); // server does not keep track of this. } else { if(err.xml_elem_error.parser_code) { printf("parse error, line: %i, column: %i, message: %s\n", err.xml_elem_error.line, err.xml_elem_error.column, err.xml_elem_error.parser_error); } } } XMLRPC_VALUE method_TestStruct(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { XMLRPC_VALUE xe_struct = XMLRPC_VectorRewind(XMLRPC_RequestGetData(request)); /* should do better type checking to make sure it is a contact, but we are lazy */ if(XMLRPC_VectorGetValueWithID(xe_struct, "firstName")) { return xe_struct; } else { xe_struct = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(xe_struct, "firstName", "John", 0); XMLRPC_VectorAppendString(xe_struct, "lastName", "Doe", 0); XMLRPC_VectorAppendString(xe_struct, "email", "john@doe.com", 0); XMLRPC_VectorAppendString(xe_struct, "phone", "555-555-5555", 0); } return xe_struct; } XMLRPC_VALUE method_TestArray(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { const char *string; char *testing[3] = { "One", "Two", "Three and four", }; int i; XMLRPC_VALUE output; XMLRPC_VALUE xIter; char* outBuf; output = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); xIter = XMLRPC_VectorRewind(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request))); while(xIter) { string = XMLRPC_GetValueString(xIter); if(string) { XMLRPC_VectorAppendString(output, NULL, string, 0); } xIter = XMLRPC_VectorNext(XMLRPC_RequestGetData(request)); } for(i = 0; i < 3; i++) { XMLRPC_VectorAppendString(output, NULL, testing[i], 0); } return output; } XMLRPC_VALUE method_TestBoolean(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { int iVal = 1; XMLRPC_VALUE xVal = XMLRPC_VectorGetValueWithID(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request)), "boolean"); if(xVal && XMLRPC_GetValueType(xVal) == xmlrpc_boolean) { iVal = XMLRPC_GetValueBoolean(xVal); } return XMLRPC_CreateValueBoolean(NULL, iVal); } XMLRPC_VALUE method_TestInt(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { int iVal = 25; XMLRPC_VALUE xParams = XMLRPC_RequestGetData(request); XMLRPC_VALUE xArg1Struct = XMLRPC_VectorRewind(xParams); XMLRPC_VALUE xVal = XMLRPC_VectorGetValueWithID(xArg1Struct, "int"); if(xVal && XMLRPC_GetValueType(xVal) == xmlrpc_int) { iVal = XMLRPC_GetValueInt(xVal); } return XMLRPC_CreateValueInt(NULL, iVal); } XMLRPC_VALUE method_TestString(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { const char* pVal = "Hello World"; XMLRPC_VALUE xVal = XMLRPC_VectorGetValueWithID(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request)), "string"); if(xVal && XMLRPC_GetValueType(xVal) == xmlrpc_string) { pVal = XMLRPC_GetValueString(xVal); } return XMLRPC_CreateValueString(NULL, pVal, 0); } XMLRPC_VALUE method_TestDouble(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { double dVal = 25; XMLRPC_VALUE xVal = XMLRPC_VectorGetValueWithID(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request)), "double"); if(xVal && XMLRPC_GetValueType(xVal) == xmlrpc_double) { dVal = XMLRPC_GetValueDouble(xVal); } return XMLRPC_CreateValueDouble(NULL, dVal); } XMLRPC_VALUE method_TestBase64(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { const char* pVal = "U29tZUJhc2U2NFN0cmluZw=="; XMLRPC_VALUE xVal = XMLRPC_VectorGetValueWithID(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request)), "base64"); int buf_len = 0; if(xVal && XMLRPC_GetValueType(xVal) == xmlrpc_base64) { pVal = XMLRPC_GetValueBase64(xVal); buf_len = XMLRPC_GetValueStringLen(xVal); } return XMLRPC_CreateValueBase64(NULL, pVal, buf_len); } XMLRPC_VALUE method_TestDateTime(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { const char* pVal = "19980717T14:08:55"; XMLRPC_VALUE xVal = XMLRPC_VectorGetValueWithID(XMLRPC_VectorRewind(XMLRPC_RequestGetData(request)), "datetime"); if(xVal && XMLRPC_GetValueType(xVal) == xmlrpc_datetime) { pVal = XMLRPC_GetValueDateTime_ISO8601(xVal); } return XMLRPC_CreateValueDateTime_ISO8601(NULL, pVal); } XMLRPC_VALUE method_TestNormal(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { XMLRPC_VALUE xOutput; xOutput = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); XMLRPC_AddValuesToVector(xOutput, method_TestStruct(server, request, userData), method_TestArray(server, request, userData), method_TestBoolean(server, request, userData), method_TestInt(server, request, userData), method_TestString(server, request, userData), method_TestDouble(server, request, userData), method_TestDateTime(server, request, userData), method_TestBase64(server, request, userData), NULL); return xOutput; } XMLRPC_VALUE method_TestFault(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { return XMLRPC_UtilityCreateFault(404, "Page Not Found"); } void print_help() { printf("Usage: sample [OPTION VALUE]\n\n"); printf("\t-help this help message\n"); printf("\t-encoding (any standard character encoding)\n"); printf("\t-escaping (may repeat)\n"); printf("\t-method \n"); printf("\t-output \n"); printf("\t-verbosity \n"); printf("\t-version \n"); printf("\n\tavailable methods:\n" "\t\tmethod_TestNormal\n" "\t\tmethod_TestFault\n" "\t\tmethod_TestStruct\n" "\t\tmethod_TestArray\n" "\t\tmethod_TestBoolean\n" "\t\tmethod_TestInt\n" "\t\tmethod_TestString\n" "\t\tmethod_TestDouble\n" "\t\tmethod_TestBase64\n" "\t\tmethod_TestDateTime\n"); } int main(int argc, char **argv) { int number; int i; XMLRPC_SERVER server; XMLRPC_REQUEST request, response; XMLRPC_VALUE param1; STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS call_options; /* args */ int verbosity = 0; int version = 0; int output = 0; char *methodName = "method_TestNormal"; char *encoding = 0; int escaping = xml_elem_no_escaping; /* for every argument (after the program name) */ for(i=1; i