]> granicus.if.org Git - php/commitdiff
merged in updates from SF project. bring php repository up to date with xmlrpc-epi...
authorDan Libby <danda@php.net>
Fri, 5 Jul 2002 04:43:55 +0000 (04:43 +0000)
committerDan Libby <danda@php.net>
Fri, 5 Jul 2002 04:43:55 +0000 (04:43 +0000)
26 files changed:
ext/rpc/xmlrpc/libxmlrpc/queue.c
ext/rpc/xmlrpc/libxmlrpc/simplestring.c
ext/rpc/xmlrpc/libxmlrpc/simplestring.h
ext/rpc/xmlrpc/libxmlrpc/system_methods.c
ext/rpc/xmlrpc/libxmlrpc/xml_element.c
ext/rpc/xmlrpc/libxmlrpc/xml_to_soap.c
ext/rpc/xmlrpc/libxmlrpc/xml_to_xmlrpc.c
ext/rpc/xmlrpc/libxmlrpc/xmlrpc.c
ext/rpc/xmlrpc/libxmlrpc/xmlrpc.h
ext/rpc/xmlrpc/libxmlrpc/xmlrpc_introspection.c
ext/rpc/xmlrpc/libxmlrpc/xmlrpc_private.h
ext/rpc/xmlrpc/php_xmlrpc.h
ext/rpc/xmlrpc/xmlrpc-epi-php.c
ext/xmlrpc/libxmlrpc/queue.c
ext/xmlrpc/libxmlrpc/simplestring.c
ext/xmlrpc/libxmlrpc/simplestring.h
ext/xmlrpc/libxmlrpc/system_methods.c
ext/xmlrpc/libxmlrpc/xml_element.c
ext/xmlrpc/libxmlrpc/xml_to_soap.c
ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c
ext/xmlrpc/libxmlrpc/xmlrpc.c
ext/xmlrpc/libxmlrpc/xmlrpc.h
ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c
ext/xmlrpc/libxmlrpc/xmlrpc_private.h
ext/xmlrpc/php_xmlrpc.h
ext/xmlrpc/xmlrpc-epi-php.c

index ecef90caf6a177000103ff17e00038270af3c8c5..24187383fd13bcd2e7ba9431646763fd1182dfa7 100644 (file)
@@ -367,6 +367,7 @@ int Q_PushTail(queue *q, void *d)
 
       return True_;
    }
+   return False_;
 }
 
 
index 7ce68d34101c3525d6d16e9af2d0ed428ee98503..dd9850bb9cf98e757da84fb407268da5ca4efe73 100644 (file)
@@ -44,6 +44,13 @@ static const char rcsid[] = "#(@) $Id$";
  * CREATION DATE
  *   06/2000
  * HISTORY
+ *   $Log$
+ *   Revision 1.4  2002/02/13 20:58:50  danda
+ *   patch to make source more windows friendly, contributed by Jeff Lawson
+ *
+ *   Revision 1.3  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   10/15/2000 -- danda -- adding robodoc documentation
  * PORTABILITY
  *   Coded on RedHat Linux 6.2.  Builds on Solaris x86.  Should build on just
index a891ba6d7812d5c19d414f52310ad974a6ddae90..c5d98cf1d8e014b82a4bd192898b28fd3f01f1f6 100644 (file)
@@ -62,6 +62,7 @@ typedef struct _simplestring {
 void simplestring_init(simplestring* string);
 void simplestring_clear(simplestring* string);
 void simplestring_free(simplestring* string);
+void simplestring_add(simplestring* string, const char* add);
 void simplestring_addn(simplestring* string, const char* add, int add_len);
 
 #ifdef __cplusplus
index 742b8371438a9a2a3457dfcee7f9d359d9781f17..c47236df140e53a9162ff0335772554232f9ad30 100644 (file)
  * AUTHOR
  *   Dan Libby, aka danda  (dan@libby.com)
  * HISTORY
+ *   $Log$
+ *   Revision 1.7  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   4/28/2001 -- danda -- adding system.multicall and separating out system methods.
  * TODO
  * NOTES
index 2625e99913ff7e563799b7c7e4e580330729b15d..edbc6de346221d3965ae26c8c3547af6424740c9 100644 (file)
@@ -43,6 +43,22 @@ static const char rcsid[] = "#(@) $Id$";
  * CREATION DATE
  *   06/2000
  * HISTORY
+ *   $Log$
+ *   Revision 1.9  2002/07/03 20:54:30  danda
+ *   root element should not have a parent. patch from anon SF user
+ *
+ *   Revision 1.8  2002/05/23 17:46:51  danda
+ *   patch from mukund - fix non utf-8 encoding conversions
+ *
+ *   Revision 1.7  2002/02/13 20:58:50  danda
+ *   patch to make source more windows friendly, contributed by Jeff Lawson
+ *
+ *   Revision 1.6  2002/01/08 01:06:55  danda
+ *   enable <?xml version="1.0"?> format for parsers that are very picky.
+ *
+ *   Revision 1.5  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   10/15/2000 -- danda -- adding robodoc documentation
  * TODO
  *   Nicer external API. Get rid of macros.  Make opaque types, etc.
@@ -86,7 +102,7 @@ static const char rcsid[] = "#(@) $Id$";
 
 #define XML_DECL_START                 "<?xml"
 #define XML_DECL_START_LEN             sizeof(XML_DECL_START) - 1
-#define XML_DECL_VERSION               "version='1.0'"
+#define XML_DECL_VERSION               "version=\"1.0\""
 #define XML_DECL_VERSION_LEN           sizeof(XML_DECL_VERSION) - 1
 #define XML_DECL_ENCODING_ATTR         "encoding"
 #define XML_DECL_ENCODING_ATTR_LEN     sizeof(XML_DECL_ENCODING_ATTR) - 1
@@ -353,7 +369,6 @@ static void xml_element_serialize(xml_element *el, int (*fptr)(void *data, const
           xml_elem_writefunc(fptr, options->encoding, data, 0);
           xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN);
       }
-      xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN);
       xml_elem_writefunc(fptr, XML_DECL_END, data, XML_DECL_END_LEN);
       if(options->verbosity != xml_elem_no_white_space) {
          xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN);
@@ -591,8 +606,10 @@ static void charHandler(void *userData,
 
       /* Check if we need to decode utf-8 parser output to another encoding */
       if(mydata->needs_enc_conversion && mydata->input_options->encoding) {
-         char* add_text = utf8_decode(s, len, &len, mydata->input_options->encoding);
+         int new_len = 0;
+         char* add_text = utf8_decode(s, len, &new_len, mydata->input_options->encoding);
          if(add_text) {
+            len = new_len;
             simplestring_addn(&mydata->current->text, add_text, len);
             free(add_text);
             return;
@@ -700,6 +717,7 @@ xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTI
       }
       else {
          xReturn = (xml_element*)Q_Head(&mydata.root->children);
+         xReturn->parent = NULL;
       }
 
       XML_ParserFree(parser);
index fada389fb6ad8a96bb5bdbd42a31b987e0defb1f..a09131aad6108152038578c6dddb339f20848c7b 100644 (file)
@@ -5,7 +5,7 @@
 */
 
 
-/************************************************************************
+/*-**********************************************************************
 * TODO:                                                                 *
 *  - [SOAP-ENC:position] read sparse arrays (and write?)                *
 *  - [SOAP-ENC:offset] read partially transmitted arrays  (and write?)  *
index 8bace4dab69973a818c01e05d9a7281a5c7e89ec..c45d3ec3db31d357ff6a51783542f34f4b164ccc 100644 (file)
@@ -71,11 +71,30 @@ XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC
       current_val = XMLRPC_CreateValueEmpty();
    }
 
-   if (el->name) {
-      if (!strcmp(el->name, ELEM_DATA) /* should be ELEM_ARRAY, but there is an extra level. weird */
-          || ((!strcmp(el->name, ELEM_PARAMS)) && 
-              (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call))    /* this "PARAMS" concept is silly.  dave?! */
-          || !strcmp(el->name, ELEM_FAULT)) {  /* so is this "FAULT" nonsense. */
+       if (el->name) {
+
+      /* first, deal with the crazy/stupid fault format */
+      if (!strcmp(el->name, ELEM_FAULT)) {
+                       xml_element* fault_value = (xml_element*)Q_Head(&el->children);
+                       XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct);
+
+         if(fault_value) {
+            xml_element* fault_struct = (xml_element*)Q_Head(&fault_value->children);
+            if(fault_struct) {
+               xml_element* iter = (xml_element*)Q_Head(&fault_struct->children);
+
+               while (iter) {
+                  XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty();
+                  xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter);
+                  XMLRPC_AddValueToVector(current_val, xNextVal);
+                  iter = (xml_element*)Q_Next(&fault_struct->children);
+               }
+            }
+         }
+      }
+               else if (!strcmp(el->name, ELEM_DATA)   /* should be ELEM_ARRAY, but there is an extra level. weird */
+                        || (!strcmp(el->name, ELEM_PARAMS) && 
+                                 (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call)) ) {           /* this "PARAMS" concept is silly.  dave?! */
          xml_element* iter = (xml_element*)Q_Head(&el->children);
          XMLRPC_SetIsVector(current_val, xmlrpc_vector_array);
 
index cfac12d496011a029be0f9341d76466c34bfb116..3eca7065a809a36f6c4fe78a71ce182ff5194177 100644 (file)
@@ -42,16 +42,31 @@ static const char rcsid[] = "#(@) $Id$";
  * CREATION DATE
  *   9/1999 - 10/2000
  * HISTORY
+ *   $Log$
+ *   Revision 1.22  2002/03/09 23:15:44  danda
+ *   add fault interrogation funcs
+ *
+ *   Revision 1.21  2002/03/09 22:27:41  danda
+ *   win32 build patches contributed by Jeff Lawson
+ *
+ *   Revision 1.20  2002/02/13 20:58:50  danda
+ *   patch to make source more windows friendly, contributed by Jeff Lawson
+ *
+ *   Revision 1.19  2001/10/12 23:25:54  danda
+ *   default to writing xmlrpc
+ *
+ *   Revision 1.18  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
+ *   10/15/2000 -- danda -- adding robodoc documentation
+ *   08/2000 -- danda -- PHP C extension that uses XMLRPC                     
+ *   08/2000 -- danda -- support for two vocabularies: danda-rpc and xml-rpc
  *   09/1999 -- danda -- Initial API, before I even knew of standard XMLRPC vocab. Response only.
- *   06/2000 -- danda -- played with expat-ensor from www.ensor.org.  Cool, but some flaws.
  *   07/2000 -- danda -- wrote new implementation to be compatible with xmlrpc standard and
  *                       incorporated some ideas from ensor, most notably the separation of
  *                       xml dom from xmlrpc api.
- *   08/2000 -- danda -- support for two vocabularies: danda-rpc and xml-rpc
- *   08/2000 -- danda -- PHP C extension that uses XMLRPC                     
- *   10/15/2000 -- danda -- adding robodoc documentation
+ *   06/2000 -- danda -- played with expat-ensor from www.ensor.org.  Cool, but some flaws.
  * TODO
- *   Server method introspection. (Enumerate available methods, describe I/O)
  * PORTABILITY
  *   Coded on RedHat Linux 6.2.  Builds on Solaris x86.  Should build on just
  *   about anything with minor mods.
@@ -116,6 +131,7 @@ static const char rcsid[] = "#(@) $Id$";
 #include "xml_element.h"
 #include "xmlrpc_private.h"
 #include "xmlrpc_introspection_private.h"
+#include "system_methods_private.h"
 
 
 
@@ -127,7 +143,6 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
    struct tm tm;
    int n;
    int i;
-   time_t t;
        char buf[18];
 
        if (strchr (text, '-')) {
@@ -625,7 +640,8 @@ char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request, int* buf_len) {
                if (request->output.version == xmlrpc_version_simple) {
                        root_elem = DANDARPC_REQUEST_to_xml_element (request);
                }
-               else if (request->output.version == xmlrpc_version_1_0) {
+               else if (request->output.version == xmlrpc_version_1_0 ||
+                                       request->output.version == xmlrpc_version_none) {
                        root_elem = XMLRPC_REQUEST_to_xml_element (request);
                }
                else if (request->output.version == xmlrpc_version_soap_1_1) {
@@ -2382,7 +2398,7 @@ int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_C
 
 /*******/
 
-inline server_method* find_method(XMLRPC_SERVER server, const char* name) {
+server_method* find_method(XMLRPC_SERVER server, const char* name) {
    server_method* sm;
 
    q_iter qi = Q_Iter_Head_F(&server->methodlist);
@@ -2649,7 +2665,7 @@ XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON
 
 
 /*-******************
-* Utility API funcs *
+* Fault API funcs   *
 ********************/
 
 /****f* UTILITY/XMLRPC_UtilityCreateFault
@@ -2683,6 +2699,7 @@ XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON
  *   simplerpc serialization, meaning that there will be no "<fault>" element in that
  *   serialization. There will simply be a standard struct with 2 child elements.  
  *   imho, the "<fault>" element is unnecessary and/or out of place as part of the standard API.
+ *
  * SOURCE
  */
 XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string) {
@@ -2749,6 +2766,147 @@ XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string)
 /*******/
 
 
+/****f* FAULT/XMLRPC_ValueIsFault
+ * NAME
+ *   XMLRPC_ValueIsFault
+ * SYNOPSIS
+ *   int XMLRPC_ValueIsFault (XMLRPC_VALUE value)
+ * FUNCTION
+ *   Determines if a value encapsulates a fault "object"
+ * INPUTS
+ *   value  any XMLRPC_VALUE
+ * RESULT
+ *   1 if it is a fault, else 0
+ * SEE ALSO
+ *   XMLRPC_ResponseIsFault ()
+ * SOURCE
+ */
+int XMLRPC_ValueIsFault (XMLRPC_VALUE value) {
+   if( XMLRPC_VectorGetValueWithID(value, "faultCode") &&
+       XMLRPC_VectorGetValueWithID(value, "faultString") ) {
+      return 1;
+   }
+   return 0;
+}
+/*******/
+
+
+/****f* FAULT/XMLRPC_ResponseIsFault
+ * NAME
+ *   XMLRPC_ResponseIsFault
+ * SYNOPSIS
+ *   int XMLRPC_ResponseIsFault (XMLRPC_REQUEST response)
+ * FUNCTION
+ *   Determines if a response contains an encapsulated fault "object"
+ * INPUTS
+ *   value  any XMLRPC_REQUEST. typically of type xmlrpc_request_response
+ * RESULT
+ *   1 if it contains a fault, else 0
+ * SEE ALSO
+ *   XMLRPC_ValueIsFault ()
+ * SOURCE
+ */
+int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response) {
+   return XMLRPC_ValueIsFault( XMLRPC_RequestGetData(response) );
+}
+
+/*******/
+
+/****f* FAULT/XMLRPC_GetValueFaultCode
+ * NAME
+ *   XMLRPC_GetValueFaultCode
+ * SYNOPSIS
+ *   int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value)
+ * FUNCTION
+ *   returns fault code from a struct, if any
+ * INPUTS
+ *   value  XMLRPC_VALUE of type xmlrpc_vector_struct.
+ * RESULT
+ *   fault code, else 0.
+ * BUGS
+ *   impossible to distinguish faultCode == 0 from faultCode not present.
+ * SEE ALSO
+ *   XMLRPC_GetResponseFaultCode ()
+ * SOURCE
+ */
+int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value) {
+   return XMLRPC_VectorGetIntWithID(value, "faultCode");
+}
+
+/*******/
+
+/****f* FAULT/XMLRPC_GetResponseFaultCode
+ * NAME
+ *   XMLRPC_GetResponseFaultCode
+ * SYNOPSIS
+ *   int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response)
+ * FUNCTION
+ *   returns fault code from a response, if any
+ * INPUTS
+ *   response  XMLRPC_REQUEST. typically of type xmlrpc_request_response.
+ * RESULT
+ *   fault code, else 0.
+ * BUGS
+ *   impossible to distinguish faultCode == 0 from faultCode not present.
+ * SEE ALSO
+ *   XMLRPC_GetValueFaultCode ()
+ * SOURCE
+ */
+int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response) {
+   return XMLRPC_GetValueFaultCode( XMLRPC_RequestGetData(response) );
+}
+
+/*******/
+
+
+/****f* FAULT/XMLRPC_GetValueFaultString
+ * NAME
+ *   XMLRPC_GetValueFaultString
+ * SYNOPSIS
+ *   const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value)
+ * FUNCTION
+ *   returns fault string from a struct, if any
+ * INPUTS
+ *   value  XMLRPC_VALUE of type xmlrpc_vector_struct.
+ * RESULT
+ *   fault string, else 0.
+ * SEE ALSO
+ *   XMLRPC_GetResponseFaultString ()
+ * SOURCE
+ */
+const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value) {
+   return XMLRPC_VectorGetStringWithID(value, "faultString");
+}
+
+/*******/
+
+/****f* FAULT/XMLRPC_GetResponseFaultString
+ * NAME
+ *   XMLRPC_GetResponseFaultString
+ * SYNOPSIS
+ *   const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response)
+ * FUNCTION
+ *   returns fault string from a response, if any
+ * INPUTS
+ *   response  XMLRPC_REQUEST. typically of type xmlrpc_request_response.
+ * RESULT
+ *   fault string, else 0.
+ * SEE ALSO
+ *   XMLRPC_GetValueFaultString ()
+ * SOURCE
+ */
+const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response) {
+   return XMLRPC_GetValueFaultString( XMLRPC_RequestGetData(response) );
+}
+
+/*******/
+
+
+/*-******************
+* Utility API funcs *
+********************/
+
+
 /****f* UTILITY/XMLRPC_Free
  * NAME
  *   XMLRPC_Free
index bcfa46fadc9d73a879527d0b87c693756a29abe4..dde3d5e1224392d6b08de47e218c1a0158f43928 100644 (file)
@@ -43,11 +43,11 @@ extern "C" {
 
 /* allow version to be specified via compile line define */
 #ifndef XMLRPC_LIB_VERSION
- #define XMLRPC_LIB_VERSION "0.50"
+ #define XMLRPC_LIB_VERSION "0.51"
 #endif
 
 /* this number, representing the date, must be increased each time the API changes */
-#define XMLRPC_API_NO 20010721
+#define XMLRPC_API_NO 20020623
 
 /* this string should be changed with each packaged release */
 #define XMLRPC_VERSION_STR "xmlrpc-epi v. " XMLRPC_LIB_VERSION
@@ -191,8 +191,8 @@ typedef enum _xmlrpc_error_code {
  * SOURCE
  */
 typedef enum _xmlrpc_version {
-   xmlrpc_version_none,          /* not a recognized vocabulary    */ 
-   xmlrpc_version_1_0,           /* xmlrpc 1.0 standard vocab      */ 
+   xmlrpc_version_none = 0,      /* not a recognized vocabulary    */ 
+   xmlrpc_version_1_0 = 1,       /* xmlrpc 1.0 standard vocab      */ 
    xmlrpc_version_simple = 2,    /* alt more readable vocab        */ 
    xmlrpc_version_danda = 2,     /* same as simple. legacy         */
        xmlrpc_version_soap_1_1 = 3     /* SOAP. version 1.1              */
@@ -334,6 +334,10 @@ XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type);
 /* Cleanup values */
 void XMLRPC_CleanupValue(XMLRPC_VALUE value);
 
+/* Request error */
+XMLRPC_VALUE XMLRPC_RequestSetError (XMLRPC_REQUEST request, XMLRPC_VALUE error);
+XMLRPC_VALUE XMLRPC_RequestGetError (XMLRPC_REQUEST request);
+
 /* Copy values */
 XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value);
 XMLRPC_VALUE XMLRPC_DupValueNew(XMLRPC_VALUE xSource);
@@ -393,6 +397,15 @@ XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST reques
 
 #include "xmlrpc_introspection.h"
 
+/* Fault interrogation funcs */
+int XMLRPC_ValueIsFault (XMLRPC_VALUE value);
+int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response);
+int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value);
+int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response);
+const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value);
+const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response);
+
+
 /* Public Utility funcs */
 XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string);
 void XMLRPC_Free(void* mem);
index d9251b2709a84142930f25f7a0054ac276c58997..bc1853ea7342dfc62cdd1869a01a67d0faaf9cc1 100644 (file)
  * AUTHOR
  *   Dan Libby, aka danda  (dan@libby.com)
  * HISTORY
+ *   $Log$
+ *   Revision 1.9  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   4/10/2001 -- danda -- initial introspection support
  * TODO
  * NOTES
index afb1cd2479a795518db978e99b8e3b1bf2886a49..65c6b136a69480359e3c07c6f7b8fb0acd21038e 100644 (file)
@@ -160,7 +160,7 @@ typedef struct _server_method {
 /*----------------------------------------------------------------------------
  * Functions
  */
-extern server_method* find_method(XMLRPC_SERVER server, const char* name);
+server_method* find_method(XMLRPC_SERVER server, const char* name);
 const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype);
  
 /*----------------------------------------------------------------------------
index bdf76b0cbf3703d3fc1e53574a9df9db488b76e6..0769f0d901c6515f94842ddf686ec947d12a1a86 100644 (file)
@@ -80,6 +80,7 @@ PHP_FUNCTION(xmlrpc_decode_request);
 PHP_FUNCTION(xmlrpc_encode_request);
 PHP_FUNCTION(xmlrpc_get_type);
 PHP_FUNCTION(xmlrpc_set_type);
+PHP_FUNCTION(xmlrpc_is_fault);
 PHP_FUNCTION(xmlrpc_server_create);
 PHP_FUNCTION(xmlrpc_server_destroy);
 PHP_FUNCTION(xmlrpc_server_register_method);
index b46382af5729371d56a4fb0e62ed8bce6abb5ad3..ae172ecc5e983f7149355fb51b59c7baefc5d172 100644 (file)
@@ -68,7 +68,7 @@
 #endif
 #include "xmlrpc.h"
 
-#define PHP_EXT_VERSION "0.50"
+#define PHP_EXT_VERSION "0.51"
 
 /* You should tweak config.m4 so this symbol (or some else suitable)
        gets defined.  */
@@ -87,6 +87,7 @@ function_entry xmlrpc_functions[] = {
        PHP_FE(xmlrpc_encode_request,                                                   NULL)
        PHP_FE(xmlrpc_get_type,                                                                 NULL)
        PHP_FE(xmlrpc_set_type,                                                                 first_args_force_ref)
+       PHP_FE(xmlrpc_is_fault,                                                                 NULL)
        PHP_FE(xmlrpc_server_create,                                                    NULL)
        PHP_FE(xmlrpc_server_destroy,                                                   NULL)
        PHP_FE(xmlrpc_server_register_method,                                   NULL)
@@ -176,8 +177,13 @@ typedef struct _xmlrpc_callback_data {
 /* value types */
 #define OBJECT_TYPE_ATTR  "xmlrpc_type"
 #define OBJECT_VALUE_ATTR "scalar"
+#define OBJECT_VALUE_TS_ATTR "timestamp"
 
-
+/* faults */
+#define FAULT_CODE       "faultCode"
+#define FAULT_CODE_LEN   (sizeof(FAULT_CODE) - 1)
+#define FAULT_STRING     "faultString"
+#define FAULT_STRING_LEN (sizeof(FAULT_STRING) - 1)
 
 /***********************
 * forward declarations *
@@ -753,7 +759,7 @@ PHP_FUNCTION(xmlrpc_decode_request)
       zval* retval = decode_request_worker(xml, encoding, method);
       if(retval) {
          *return_value = *retval;
-         zval_copy_ctor(return_value);
+         FREE_ZVAL(retval);
       }
    }
 }
@@ -779,7 +785,7 @@ PHP_FUNCTION(xmlrpc_decode)
       zval* retval = decode_request_worker(arg1, arg2, NULL);
       if(retval) {
          *return_value = *retval;
-                FREE_ZVAL(retval);
+         FREE_ZVAL(retval);
       }
    }
 }
@@ -1119,14 +1125,6 @@ PHP_FUNCTION(xmlrpc_server_call_method)
                                                        out.xmlrpc_out.version = opts->version;
                                                }
                                        }
-
-                                       /* automagically determine output serialization type from request type */
-                                       if (out.b_auto_version) { 
-                                               XMLRPC_REQUEST_OUTPUT_OPTIONS opts = XMLRPC_RequestGetOutputOptions(xRequest);
-                                               if (opts) {
-                                                       out.xmlrpc_out.version = opts->version;
-                                               }
-                                       }
                  /* set some required request hoojum */
                  XMLRPC_RequestSetOutputOptions(xResponse, &out.xmlrpc_out);
                  XMLRPC_RequestSetRequestType(xResponse, xmlrpc_request_response);
@@ -1315,7 +1313,7 @@ XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str)
  * note: this only works on strings, and only for date and base64,
  *       which do not have native php types. black magic lies herein.
  */
-int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type)
+int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE newtype)
 {
    int bSuccess = FAILURE;
 
@@ -1323,8 +1321,8 @@ int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type)
     * base64 and datetime.  all other types have corresponding php types
     */
    if (Z_TYPE_P(value) == IS_STRING) {
-      if (type == xmlrpc_base64 || type == xmlrpc_datetime) {
-         const char* typestr = xmlrpc_type_as_str(type, xmlrpc_vector_none);
+      if (newtype == xmlrpc_base64 || newtype == xmlrpc_datetime) {
+         const char* typestr = xmlrpc_type_as_str(newtype, xmlrpc_vector_none);
          zval* type;
 
          MAKE_STD_ZVAL(type);
@@ -1333,8 +1331,30 @@ int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type)
          Z_STRVAL_P(type) = estrdup(typestr);
          Z_STRLEN_P(type) = strlen(typestr);
 
-         convert_to_object(value);
-         bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
+         if(newtype == xmlrpc_datetime) {
+            XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, value->value.str.val);
+            if(v) {
+               time_t timestamp = XMLRPC_GetValueDateTime(v);
+               if(time) {
+                  pval* ztimestamp;
+
+                  MAKE_STD_ZVAL(ztimestamp);
+
+                  ztimestamp->type = IS_LONG;
+                  ztimestamp->value.lval = timestamp;
+
+                  convert_to_object(value);
+                  if(SUCCESS == zend_hash_update(value->value.obj.properties, OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL)) {
+                     bSuccess = zend_hash_update(value->value.obj.properties, OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR), (void *) &ztimestamp, sizeof(zval *), NULL);
+                  }
+               }
+               XMLRPC_CleanupValue(v);
+            }
+         }
+         else {
+            convert_to_object(value);
+            bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
+         }
       }
    }
    
@@ -1457,6 +1477,37 @@ PHP_FUNCTION(xmlrpc_get_type)
    RETURN_STRING((char*) xmlrpc_type_as_str(type, vtype), 1);
 }
 
+/* {{{ proto string xmlrpc_is_fault(array)
+   Determines if an array value represents an XMLRPC fault. */
+PHP_FUNCTION(xmlrpc_is_fault)
+{
+   zval* arg, **val;
+
+   if (!(ARG_COUNT(ht) == 1) || getParameters(ht, ARG_COUNT(ht), &arg) == FAILURE) {
+      WRONG_PARAM_COUNT; /* prints/logs a warning and returns */
+   }
+
+       if (Z_TYPE_P(arg) != IS_ARRAY) {
+               php_error(E_NOTICE, "%s() expects argument to be an array", get_active_function_name(TSRMLS_CC));
+       }
+   else {
+      /* The "correct" way to do this would be to call the xmlrpc
+       * library XMLRPC_ValueIsFault() func.  However, doing that
+       * would require us to create an xmlrpc value from the php
+       * array, which is rather expensive, especially if it was
+       * a big array.  Thus, we resort to this not so clever hackery.
+       */
+      if( zend_hash_find(Z_ARRVAL_P(arg), FAULT_CODE, FAULT_CODE_LEN + 1, (void**) &val) == SUCCESS &&
+          zend_hash_find(Z_ARRVAL_P(arg), FAULT_STRING, FAULT_STRING_LEN + 1, (void**) &val) == SUCCESS)
+      {
+         RETURN_TRUE;
+      }
+   }
+
+   RETURN_FALSE;
+}
+
+
 
 /*
  * Local variables:
index ecef90caf6a177000103ff17e00038270af3c8c5..24187383fd13bcd2e7ba9431646763fd1182dfa7 100644 (file)
@@ -367,6 +367,7 @@ int Q_PushTail(queue *q, void *d)
 
       return True_;
    }
+   return False_;
 }
 
 
index 7ce68d34101c3525d6d16e9af2d0ed428ee98503..dd9850bb9cf98e757da84fb407268da5ca4efe73 100644 (file)
@@ -44,6 +44,13 @@ static const char rcsid[] = "#(@) $Id$";
  * CREATION DATE
  *   06/2000
  * HISTORY
+ *   $Log$
+ *   Revision 1.4  2002/02/13 20:58:50  danda
+ *   patch to make source more windows friendly, contributed by Jeff Lawson
+ *
+ *   Revision 1.3  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   10/15/2000 -- danda -- adding robodoc documentation
  * PORTABILITY
  *   Coded on RedHat Linux 6.2.  Builds on Solaris x86.  Should build on just
index a891ba6d7812d5c19d414f52310ad974a6ddae90..c5d98cf1d8e014b82a4bd192898b28fd3f01f1f6 100644 (file)
@@ -62,6 +62,7 @@ typedef struct _simplestring {
 void simplestring_init(simplestring* string);
 void simplestring_clear(simplestring* string);
 void simplestring_free(simplestring* string);
+void simplestring_add(simplestring* string, const char* add);
 void simplestring_addn(simplestring* string, const char* add, int add_len);
 
 #ifdef __cplusplus
index 742b8371438a9a2a3457dfcee7f9d359d9781f17..c47236df140e53a9162ff0335772554232f9ad30 100644 (file)
  * AUTHOR
  *   Dan Libby, aka danda  (dan@libby.com)
  * HISTORY
+ *   $Log$
+ *   Revision 1.7  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   4/28/2001 -- danda -- adding system.multicall and separating out system methods.
  * TODO
  * NOTES
index 2625e99913ff7e563799b7c7e4e580330729b15d..edbc6de346221d3965ae26c8c3547af6424740c9 100644 (file)
@@ -43,6 +43,22 @@ static const char rcsid[] = "#(@) $Id$";
  * CREATION DATE
  *   06/2000
  * HISTORY
+ *   $Log$
+ *   Revision 1.9  2002/07/03 20:54:30  danda
+ *   root element should not have a parent. patch from anon SF user
+ *
+ *   Revision 1.8  2002/05/23 17:46:51  danda
+ *   patch from mukund - fix non utf-8 encoding conversions
+ *
+ *   Revision 1.7  2002/02/13 20:58:50  danda
+ *   patch to make source more windows friendly, contributed by Jeff Lawson
+ *
+ *   Revision 1.6  2002/01/08 01:06:55  danda
+ *   enable <?xml version="1.0"?> format for parsers that are very picky.
+ *
+ *   Revision 1.5  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   10/15/2000 -- danda -- adding robodoc documentation
  * TODO
  *   Nicer external API. Get rid of macros.  Make opaque types, etc.
@@ -86,7 +102,7 @@ static const char rcsid[] = "#(@) $Id$";
 
 #define XML_DECL_START                 "<?xml"
 #define XML_DECL_START_LEN             sizeof(XML_DECL_START) - 1
-#define XML_DECL_VERSION               "version='1.0'"
+#define XML_DECL_VERSION               "version=\"1.0\""
 #define XML_DECL_VERSION_LEN           sizeof(XML_DECL_VERSION) - 1
 #define XML_DECL_ENCODING_ATTR         "encoding"
 #define XML_DECL_ENCODING_ATTR_LEN     sizeof(XML_DECL_ENCODING_ATTR) - 1
@@ -353,7 +369,6 @@ static void xml_element_serialize(xml_element *el, int (*fptr)(void *data, const
           xml_elem_writefunc(fptr, options->encoding, data, 0);
           xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN);
       }
-      xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN);
       xml_elem_writefunc(fptr, XML_DECL_END, data, XML_DECL_END_LEN);
       if(options->verbosity != xml_elem_no_white_space) {
          xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN);
@@ -591,8 +606,10 @@ static void charHandler(void *userData,
 
       /* Check if we need to decode utf-8 parser output to another encoding */
       if(mydata->needs_enc_conversion && mydata->input_options->encoding) {
-         char* add_text = utf8_decode(s, len, &len, mydata->input_options->encoding);
+         int new_len = 0;
+         char* add_text = utf8_decode(s, len, &new_len, mydata->input_options->encoding);
          if(add_text) {
+            len = new_len;
             simplestring_addn(&mydata->current->text, add_text, len);
             free(add_text);
             return;
@@ -700,6 +717,7 @@ xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTI
       }
       else {
          xReturn = (xml_element*)Q_Head(&mydata.root->children);
+         xReturn->parent = NULL;
       }
 
       XML_ParserFree(parser);
index fada389fb6ad8a96bb5bdbd42a31b987e0defb1f..a09131aad6108152038578c6dddb339f20848c7b 100644 (file)
@@ -5,7 +5,7 @@
 */
 
 
-/************************************************************************
+/*-**********************************************************************
 * TODO:                                                                 *
 *  - [SOAP-ENC:position] read sparse arrays (and write?)                *
 *  - [SOAP-ENC:offset] read partially transmitted arrays  (and write?)  *
index 8bace4dab69973a818c01e05d9a7281a5c7e89ec..c45d3ec3db31d357ff6a51783542f34f4b164ccc 100644 (file)
@@ -71,11 +71,30 @@ XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC
       current_val = XMLRPC_CreateValueEmpty();
    }
 
-   if (el->name) {
-      if (!strcmp(el->name, ELEM_DATA) /* should be ELEM_ARRAY, but there is an extra level. weird */
-          || ((!strcmp(el->name, ELEM_PARAMS)) && 
-              (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call))    /* this "PARAMS" concept is silly.  dave?! */
-          || !strcmp(el->name, ELEM_FAULT)) {  /* so is this "FAULT" nonsense. */
+       if (el->name) {
+
+      /* first, deal with the crazy/stupid fault format */
+      if (!strcmp(el->name, ELEM_FAULT)) {
+                       xml_element* fault_value = (xml_element*)Q_Head(&el->children);
+                       XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct);
+
+         if(fault_value) {
+            xml_element* fault_struct = (xml_element*)Q_Head(&fault_value->children);
+            if(fault_struct) {
+               xml_element* iter = (xml_element*)Q_Head(&fault_struct->children);
+
+               while (iter) {
+                  XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty();
+                  xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter);
+                  XMLRPC_AddValueToVector(current_val, xNextVal);
+                  iter = (xml_element*)Q_Next(&fault_struct->children);
+               }
+            }
+         }
+      }
+               else if (!strcmp(el->name, ELEM_DATA)   /* should be ELEM_ARRAY, but there is an extra level. weird */
+                        || (!strcmp(el->name, ELEM_PARAMS) && 
+                                 (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call)) ) {           /* this "PARAMS" concept is silly.  dave?! */
          xml_element* iter = (xml_element*)Q_Head(&el->children);
          XMLRPC_SetIsVector(current_val, xmlrpc_vector_array);
 
index cfac12d496011a029be0f9341d76466c34bfb116..3eca7065a809a36f6c4fe78a71ce182ff5194177 100644 (file)
@@ -42,16 +42,31 @@ static const char rcsid[] = "#(@) $Id$";
  * CREATION DATE
  *   9/1999 - 10/2000
  * HISTORY
+ *   $Log$
+ *   Revision 1.22  2002/03/09 23:15:44  danda
+ *   add fault interrogation funcs
+ *
+ *   Revision 1.21  2002/03/09 22:27:41  danda
+ *   win32 build patches contributed by Jeff Lawson
+ *
+ *   Revision 1.20  2002/02/13 20:58:50  danda
+ *   patch to make source more windows friendly, contributed by Jeff Lawson
+ *
+ *   Revision 1.19  2001/10/12 23:25:54  danda
+ *   default to writing xmlrpc
+ *
+ *   Revision 1.18  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
+ *   10/15/2000 -- danda -- adding robodoc documentation
+ *   08/2000 -- danda -- PHP C extension that uses XMLRPC                     
+ *   08/2000 -- danda -- support for two vocabularies: danda-rpc and xml-rpc
  *   09/1999 -- danda -- Initial API, before I even knew of standard XMLRPC vocab. Response only.
- *   06/2000 -- danda -- played with expat-ensor from www.ensor.org.  Cool, but some flaws.
  *   07/2000 -- danda -- wrote new implementation to be compatible with xmlrpc standard and
  *                       incorporated some ideas from ensor, most notably the separation of
  *                       xml dom from xmlrpc api.
- *   08/2000 -- danda -- support for two vocabularies: danda-rpc and xml-rpc
- *   08/2000 -- danda -- PHP C extension that uses XMLRPC                     
- *   10/15/2000 -- danda -- adding robodoc documentation
+ *   06/2000 -- danda -- played with expat-ensor from www.ensor.org.  Cool, but some flaws.
  * TODO
- *   Server method introspection. (Enumerate available methods, describe I/O)
  * PORTABILITY
  *   Coded on RedHat Linux 6.2.  Builds on Solaris x86.  Should build on just
  *   about anything with minor mods.
@@ -116,6 +131,7 @@ static const char rcsid[] = "#(@) $Id$";
 #include "xml_element.h"
 #include "xmlrpc_private.h"
 #include "xmlrpc_introspection_private.h"
+#include "system_methods_private.h"
 
 
 
@@ -127,7 +143,6 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
    struct tm tm;
    int n;
    int i;
-   time_t t;
        char buf[18];
 
        if (strchr (text, '-')) {
@@ -625,7 +640,8 @@ char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request, int* buf_len) {
                if (request->output.version == xmlrpc_version_simple) {
                        root_elem = DANDARPC_REQUEST_to_xml_element (request);
                }
-               else if (request->output.version == xmlrpc_version_1_0) {
+               else if (request->output.version == xmlrpc_version_1_0 ||
+                                       request->output.version == xmlrpc_version_none) {
                        root_elem = XMLRPC_REQUEST_to_xml_element (request);
                }
                else if (request->output.version == xmlrpc_version_soap_1_1) {
@@ -2382,7 +2398,7 @@ int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_C
 
 /*******/
 
-inline server_method* find_method(XMLRPC_SERVER server, const char* name) {
+server_method* find_method(XMLRPC_SERVER server, const char* name) {
    server_method* sm;
 
    q_iter qi = Q_Iter_Head_F(&server->methodlist);
@@ -2649,7 +2665,7 @@ XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON
 
 
 /*-******************
-* Utility API funcs *
+* Fault API funcs   *
 ********************/
 
 /****f* UTILITY/XMLRPC_UtilityCreateFault
@@ -2683,6 +2699,7 @@ XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON
  *   simplerpc serialization, meaning that there will be no "<fault>" element in that
  *   serialization. There will simply be a standard struct with 2 child elements.  
  *   imho, the "<fault>" element is unnecessary and/or out of place as part of the standard API.
+ *
  * SOURCE
  */
 XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string) {
@@ -2749,6 +2766,147 @@ XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string)
 /*******/
 
 
+/****f* FAULT/XMLRPC_ValueIsFault
+ * NAME
+ *   XMLRPC_ValueIsFault
+ * SYNOPSIS
+ *   int XMLRPC_ValueIsFault (XMLRPC_VALUE value)
+ * FUNCTION
+ *   Determines if a value encapsulates a fault "object"
+ * INPUTS
+ *   value  any XMLRPC_VALUE
+ * RESULT
+ *   1 if it is a fault, else 0
+ * SEE ALSO
+ *   XMLRPC_ResponseIsFault ()
+ * SOURCE
+ */
+int XMLRPC_ValueIsFault (XMLRPC_VALUE value) {
+   if( XMLRPC_VectorGetValueWithID(value, "faultCode") &&
+       XMLRPC_VectorGetValueWithID(value, "faultString") ) {
+      return 1;
+   }
+   return 0;
+}
+/*******/
+
+
+/****f* FAULT/XMLRPC_ResponseIsFault
+ * NAME
+ *   XMLRPC_ResponseIsFault
+ * SYNOPSIS
+ *   int XMLRPC_ResponseIsFault (XMLRPC_REQUEST response)
+ * FUNCTION
+ *   Determines if a response contains an encapsulated fault "object"
+ * INPUTS
+ *   value  any XMLRPC_REQUEST. typically of type xmlrpc_request_response
+ * RESULT
+ *   1 if it contains a fault, else 0
+ * SEE ALSO
+ *   XMLRPC_ValueIsFault ()
+ * SOURCE
+ */
+int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response) {
+   return XMLRPC_ValueIsFault( XMLRPC_RequestGetData(response) );
+}
+
+/*******/
+
+/****f* FAULT/XMLRPC_GetValueFaultCode
+ * NAME
+ *   XMLRPC_GetValueFaultCode
+ * SYNOPSIS
+ *   int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value)
+ * FUNCTION
+ *   returns fault code from a struct, if any
+ * INPUTS
+ *   value  XMLRPC_VALUE of type xmlrpc_vector_struct.
+ * RESULT
+ *   fault code, else 0.
+ * BUGS
+ *   impossible to distinguish faultCode == 0 from faultCode not present.
+ * SEE ALSO
+ *   XMLRPC_GetResponseFaultCode ()
+ * SOURCE
+ */
+int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value) {
+   return XMLRPC_VectorGetIntWithID(value, "faultCode");
+}
+
+/*******/
+
+/****f* FAULT/XMLRPC_GetResponseFaultCode
+ * NAME
+ *   XMLRPC_GetResponseFaultCode
+ * SYNOPSIS
+ *   int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response)
+ * FUNCTION
+ *   returns fault code from a response, if any
+ * INPUTS
+ *   response  XMLRPC_REQUEST. typically of type xmlrpc_request_response.
+ * RESULT
+ *   fault code, else 0.
+ * BUGS
+ *   impossible to distinguish faultCode == 0 from faultCode not present.
+ * SEE ALSO
+ *   XMLRPC_GetValueFaultCode ()
+ * SOURCE
+ */
+int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response) {
+   return XMLRPC_GetValueFaultCode( XMLRPC_RequestGetData(response) );
+}
+
+/*******/
+
+
+/****f* FAULT/XMLRPC_GetValueFaultString
+ * NAME
+ *   XMLRPC_GetValueFaultString
+ * SYNOPSIS
+ *   const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value)
+ * FUNCTION
+ *   returns fault string from a struct, if any
+ * INPUTS
+ *   value  XMLRPC_VALUE of type xmlrpc_vector_struct.
+ * RESULT
+ *   fault string, else 0.
+ * SEE ALSO
+ *   XMLRPC_GetResponseFaultString ()
+ * SOURCE
+ */
+const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value) {
+   return XMLRPC_VectorGetStringWithID(value, "faultString");
+}
+
+/*******/
+
+/****f* FAULT/XMLRPC_GetResponseFaultString
+ * NAME
+ *   XMLRPC_GetResponseFaultString
+ * SYNOPSIS
+ *   const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response)
+ * FUNCTION
+ *   returns fault string from a response, if any
+ * INPUTS
+ *   response  XMLRPC_REQUEST. typically of type xmlrpc_request_response.
+ * RESULT
+ *   fault string, else 0.
+ * SEE ALSO
+ *   XMLRPC_GetValueFaultString ()
+ * SOURCE
+ */
+const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response) {
+   return XMLRPC_GetValueFaultString( XMLRPC_RequestGetData(response) );
+}
+
+/*******/
+
+
+/*-******************
+* Utility API funcs *
+********************/
+
+
 /****f* UTILITY/XMLRPC_Free
  * NAME
  *   XMLRPC_Free
index bcfa46fadc9d73a879527d0b87c693756a29abe4..dde3d5e1224392d6b08de47e218c1a0158f43928 100644 (file)
@@ -43,11 +43,11 @@ extern "C" {
 
 /* allow version to be specified via compile line define */
 #ifndef XMLRPC_LIB_VERSION
- #define XMLRPC_LIB_VERSION "0.50"
+ #define XMLRPC_LIB_VERSION "0.51"
 #endif
 
 /* this number, representing the date, must be increased each time the API changes */
-#define XMLRPC_API_NO 20010721
+#define XMLRPC_API_NO 20020623
 
 /* this string should be changed with each packaged release */
 #define XMLRPC_VERSION_STR "xmlrpc-epi v. " XMLRPC_LIB_VERSION
@@ -191,8 +191,8 @@ typedef enum _xmlrpc_error_code {
  * SOURCE
  */
 typedef enum _xmlrpc_version {
-   xmlrpc_version_none,          /* not a recognized vocabulary    */ 
-   xmlrpc_version_1_0,           /* xmlrpc 1.0 standard vocab      */ 
+   xmlrpc_version_none = 0,      /* not a recognized vocabulary    */ 
+   xmlrpc_version_1_0 = 1,       /* xmlrpc 1.0 standard vocab      */ 
    xmlrpc_version_simple = 2,    /* alt more readable vocab        */ 
    xmlrpc_version_danda = 2,     /* same as simple. legacy         */
        xmlrpc_version_soap_1_1 = 3     /* SOAP. version 1.1              */
@@ -334,6 +334,10 @@ XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type);
 /* Cleanup values */
 void XMLRPC_CleanupValue(XMLRPC_VALUE value);
 
+/* Request error */
+XMLRPC_VALUE XMLRPC_RequestSetError (XMLRPC_REQUEST request, XMLRPC_VALUE error);
+XMLRPC_VALUE XMLRPC_RequestGetError (XMLRPC_REQUEST request);
+
 /* Copy values */
 XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value);
 XMLRPC_VALUE XMLRPC_DupValueNew(XMLRPC_VALUE xSource);
@@ -393,6 +397,15 @@ XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST reques
 
 #include "xmlrpc_introspection.h"
 
+/* Fault interrogation funcs */
+int XMLRPC_ValueIsFault (XMLRPC_VALUE value);
+int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response);
+int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value);
+int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response);
+const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value);
+const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response);
+
+
 /* Public Utility funcs */
 XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string);
 void XMLRPC_Free(void* mem);
index d9251b2709a84142930f25f7a0054ac276c58997..bc1853ea7342dfc62cdd1869a01a67d0faaf9cc1 100644 (file)
  * AUTHOR
  *   Dan Libby, aka danda  (dan@libby.com)
  * HISTORY
+ *   $Log$
+ *   Revision 1.9  2001/09/29 21:58:05  danda
+ *   adding cvs log to history section
+ *
  *   4/10/2001 -- danda -- initial introspection support
  * TODO
  * NOTES
index afb1cd2479a795518db978e99b8e3b1bf2886a49..65c6b136a69480359e3c07c6f7b8fb0acd21038e 100644 (file)
@@ -160,7 +160,7 @@ typedef struct _server_method {
 /*----------------------------------------------------------------------------
  * Functions
  */
-extern server_method* find_method(XMLRPC_SERVER server, const char* name);
+server_method* find_method(XMLRPC_SERVER server, const char* name);
 const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype);
  
 /*----------------------------------------------------------------------------
index bdf76b0cbf3703d3fc1e53574a9df9db488b76e6..0769f0d901c6515f94842ddf686ec947d12a1a86 100644 (file)
@@ -80,6 +80,7 @@ PHP_FUNCTION(xmlrpc_decode_request);
 PHP_FUNCTION(xmlrpc_encode_request);
 PHP_FUNCTION(xmlrpc_get_type);
 PHP_FUNCTION(xmlrpc_set_type);
+PHP_FUNCTION(xmlrpc_is_fault);
 PHP_FUNCTION(xmlrpc_server_create);
 PHP_FUNCTION(xmlrpc_server_destroy);
 PHP_FUNCTION(xmlrpc_server_register_method);
index b46382af5729371d56a4fb0e62ed8bce6abb5ad3..ae172ecc5e983f7149355fb51b59c7baefc5d172 100644 (file)
@@ -68,7 +68,7 @@
 #endif
 #include "xmlrpc.h"
 
-#define PHP_EXT_VERSION "0.50"
+#define PHP_EXT_VERSION "0.51"
 
 /* You should tweak config.m4 so this symbol (or some else suitable)
        gets defined.  */
@@ -87,6 +87,7 @@ function_entry xmlrpc_functions[] = {
        PHP_FE(xmlrpc_encode_request,                                                   NULL)
        PHP_FE(xmlrpc_get_type,                                                                 NULL)
        PHP_FE(xmlrpc_set_type,                                                                 first_args_force_ref)
+       PHP_FE(xmlrpc_is_fault,                                                                 NULL)
        PHP_FE(xmlrpc_server_create,                                                    NULL)
        PHP_FE(xmlrpc_server_destroy,                                                   NULL)
        PHP_FE(xmlrpc_server_register_method,                                   NULL)
@@ -176,8 +177,13 @@ typedef struct _xmlrpc_callback_data {
 /* value types */
 #define OBJECT_TYPE_ATTR  "xmlrpc_type"
 #define OBJECT_VALUE_ATTR "scalar"
+#define OBJECT_VALUE_TS_ATTR "timestamp"
 
-
+/* faults */
+#define FAULT_CODE       "faultCode"
+#define FAULT_CODE_LEN   (sizeof(FAULT_CODE) - 1)
+#define FAULT_STRING     "faultString"
+#define FAULT_STRING_LEN (sizeof(FAULT_STRING) - 1)
 
 /***********************
 * forward declarations *
@@ -753,7 +759,7 @@ PHP_FUNCTION(xmlrpc_decode_request)
       zval* retval = decode_request_worker(xml, encoding, method);
       if(retval) {
          *return_value = *retval;
-         zval_copy_ctor(return_value);
+         FREE_ZVAL(retval);
       }
    }
 }
@@ -779,7 +785,7 @@ PHP_FUNCTION(xmlrpc_decode)
       zval* retval = decode_request_worker(arg1, arg2, NULL);
       if(retval) {
          *return_value = *retval;
-                FREE_ZVAL(retval);
+         FREE_ZVAL(retval);
       }
    }
 }
@@ -1119,14 +1125,6 @@ PHP_FUNCTION(xmlrpc_server_call_method)
                                                        out.xmlrpc_out.version = opts->version;
                                                }
                                        }
-
-                                       /* automagically determine output serialization type from request type */
-                                       if (out.b_auto_version) { 
-                                               XMLRPC_REQUEST_OUTPUT_OPTIONS opts = XMLRPC_RequestGetOutputOptions(xRequest);
-                                               if (opts) {
-                                                       out.xmlrpc_out.version = opts->version;
-                                               }
-                                       }
                  /* set some required request hoojum */
                  XMLRPC_RequestSetOutputOptions(xResponse, &out.xmlrpc_out);
                  XMLRPC_RequestSetRequestType(xResponse, xmlrpc_request_response);
@@ -1315,7 +1313,7 @@ XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str)
  * note: this only works on strings, and only for date and base64,
  *       which do not have native php types. black magic lies herein.
  */
-int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type)
+int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE newtype)
 {
    int bSuccess = FAILURE;
 
@@ -1323,8 +1321,8 @@ int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type)
     * base64 and datetime.  all other types have corresponding php types
     */
    if (Z_TYPE_P(value) == IS_STRING) {
-      if (type == xmlrpc_base64 || type == xmlrpc_datetime) {
-         const char* typestr = xmlrpc_type_as_str(type, xmlrpc_vector_none);
+      if (newtype == xmlrpc_base64 || newtype == xmlrpc_datetime) {
+         const char* typestr = xmlrpc_type_as_str(newtype, xmlrpc_vector_none);
          zval* type;
 
          MAKE_STD_ZVAL(type);
@@ -1333,8 +1331,30 @@ int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type)
          Z_STRVAL_P(type) = estrdup(typestr);
          Z_STRLEN_P(type) = strlen(typestr);
 
-         convert_to_object(value);
-         bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
+         if(newtype == xmlrpc_datetime) {
+            XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, value->value.str.val);
+            if(v) {
+               time_t timestamp = XMLRPC_GetValueDateTime(v);
+               if(time) {
+                  pval* ztimestamp;
+
+                  MAKE_STD_ZVAL(ztimestamp);
+
+                  ztimestamp->type = IS_LONG;
+                  ztimestamp->value.lval = timestamp;
+
+                  convert_to_object(value);
+                  if(SUCCESS == zend_hash_update(value->value.obj.properties, OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL)) {
+                     bSuccess = zend_hash_update(value->value.obj.properties, OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR), (void *) &ztimestamp, sizeof(zval *), NULL);
+                  }
+               }
+               XMLRPC_CleanupValue(v);
+            }
+         }
+         else {
+            convert_to_object(value);
+            bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
+         }
       }
    }
    
@@ -1457,6 +1477,37 @@ PHP_FUNCTION(xmlrpc_get_type)
    RETURN_STRING((char*) xmlrpc_type_as_str(type, vtype), 1);
 }
 
+/* {{{ proto string xmlrpc_is_fault(array)
+   Determines if an array value represents an XMLRPC fault. */
+PHP_FUNCTION(xmlrpc_is_fault)
+{
+   zval* arg, **val;
+
+   if (!(ARG_COUNT(ht) == 1) || getParameters(ht, ARG_COUNT(ht), &arg) == FAILURE) {
+      WRONG_PARAM_COUNT; /* prints/logs a warning and returns */
+   }
+
+       if (Z_TYPE_P(arg) != IS_ARRAY) {
+               php_error(E_NOTICE, "%s() expects argument to be an array", get_active_function_name(TSRMLS_CC));
+       }
+   else {
+      /* The "correct" way to do this would be to call the xmlrpc
+       * library XMLRPC_ValueIsFault() func.  However, doing that
+       * would require us to create an xmlrpc value from the php
+       * array, which is rather expensive, especially if it was
+       * a big array.  Thus, we resort to this not so clever hackery.
+       */
+      if( zend_hash_find(Z_ARRVAL_P(arg), FAULT_CODE, FAULT_CODE_LEN + 1, (void**) &val) == SUCCESS &&
+          zend_hash_find(Z_ARRVAL_P(arg), FAULT_STRING, FAULT_STRING_LEN + 1, (void**) &val) == SUCCESS)
+      {
+         RETURN_TRUE;
+      }
+   }
+
+   RETURN_FALSE;
+}
+
+
 
 /*
  * Local variables: