📄 cxmlrpc.c
字号:
/*************************************************************************** CXmlRpc.c XML-RPC client (c) 2004 Daniel Campos Fernández <danielcampos@netcourrier.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __CXMLRPC_C#include <stdio.h>#include <libxml/xmlreader.h>#include <libxml/xmlwriter.h>#include "main.h"#include "string.h"#include "CXmlRpc.h"BEGIN_METHOD_VOID(CXMLRPC_Free) if (THIS->parameters) GB.Free((void**)&THIS->parameters);END_METHODBEGIN_METHOD(CXMLRPC_New,GB_INTEGER RpcType;GB_STRING MethodName;GB_OBJECT Parameters;GB_INTEGER ReturnType;) int myloop; int nmax; int rtype; if ( (VARG(RpcType)<0) || (VARG(RpcType)>2) ) { GB.Error("Invalid RPC Type"); return; } //TODO if (VARG(RpcType)!=0) { GB.Error("Unimplemented RPC Type, this is alpha software, sorry"); return; } // THIS->type=VARG(RpcType); nmax=GB.Array.Count(VARG(Parameters)); if (MISSING(ReturnType)) { THIS->returntype=-1; } else { if ( (VARG(ReturnType)<0) || (VARG(ReturnType)>7) ) { GB.Error("Invalid return type"); return; } THIS->returntype=VARG(ReturnType); } if (LENGTH(MethodName)) { if (nmax) { for (myloop=0;myloop<nmax;myloop++) { rtype=*((int*)GB.Array.Get(VARG(Parameters),myloop)); if (rtype<0 || rtype>7) { GB.Error("Unknown RPC data type"); return; } } THIS->nparams=nmax; GB.Alloc ((void**)&THIS->parameters,sizeof(int)*nmax); for (myloop=0;myloop<nmax;myloop++) THIS->parameters[myloop]=*((int*)GB.Array.Get(VARG(Parameters),myloop)); } THIS->name=GB.ToZeroString(ARG(MethodName)); return; } GB.Error("Invalid RPC method name"); END_METHODBEGIN_METHOD(CXMLRPC_Call,GB_VALUE param[0];) double value; char *cname; char *buf; int bucle; long len; int myok=1; GB_VALUE *args=ARG(param[0]); xmlTextWriterPtr writer; xmlBufferPtr buffer; if (THIS->nparams != GB.NParam()) { GB.Error ("Wrong RPC parameters number"); return; } for(bucle=0;bucle<THIS->nparams;bucle++) { switch(THIS->parameters[bucle]) { case 0: if ( args[bucle].type != GB_T_BOOLEAN) myok=0; break; case 1: if ( args[bucle].type != GB_T_INTEGER) myok=0; break; case 2: if ( args[bucle].type != GB_T_FLOAT) myok=0; break; case 3: if ( args[bucle].type != GB_T_STRING) myok=0; break; case 4: if ( args[bucle].type != GB_T_DATE) myok=0; break; case 5: if ( args[bucle].type != GB_T_STRING) myok=0; break; case 6: break;// TODO: array case 7: break;// TODO: struct } if (!myok) break; } if (!myok) { GB.Error("Wrong Parameter Type"); return; } buffer=xmlBufferCreate(); writer=xmlNewTextWriterMemory(buffer, 0); xmlTextWriterSetIndent(writer,1); xmlTextWriterStartDocument(writer, NULL,"UTF-8", NULL); xmlTextWriterStartElement (writer,"methodCall"); xmlTextWriterWriteElement (writer,"methodName",THIS->name); xmlTextWriterStartElement (writer,"params"); for(bucle=0;bucle<THIS->nparams;bucle++) { xmlTextWriterStartElement (writer,"param"); xmlTextWriterStartElement (writer,"value"); switch(THIS->parameters[bucle]) { case 0: // Boolean if (((GB_BOOLEAN*)args)[bucle].value) xmlTextWriterWriteElement(writer,"boolean","1"); else xmlTextWriterWriteElement(writer,"boolean","0"); break; case 1: value=((GB_INTEGER*)args)[bucle].value; GB.NumberToString (0,value,NULL,&buf,&len); xmlTextWriterWriteElement(writer,"i4",buf); break; case 2: value=((GB_FLOAT*)args)[bucle].value; GB.NumberToString (0,value,NULL,&buf,&len); xmlTextWriterWriteElement(writer,"double",buf); break; case 3: //buf=GB.ToZeroString( ); xmlTextWriterWriteElement(writer,"string",((GB_STRING*)args)[bucle].value.addr); break; case 4:break; case 5:break; case 6: break;//TODO Array case 7: break;//TODO STRUCT } xmlTextWriterEndElement (writer); xmlTextWriterEndElement (writer); } xmlTextWriterEndDocument(writer); xmlFreeTextWriter(writer); if (THIS->type == 0) { GB.ReturnNewString(buffer->content,0); return; } xmlBufferFree(buffer); END_METHODBEGIN_METHOD(CXMLRPC_SetReply,GB_STRING Reply;) THIS->reply=GB.ToZeroString(ARG(Reply));END_METHOD /*int rpc_search(xmlTextReaderPtr reader,char *name,char *name2){ int depth; int ndepth; int retval; if (xmlTextReaderRead(reader)!=1) return -1; depth=xmlTextReaderDepth(reader); ndepth=depth; do { if (xmlTextReaderNodeType(reader)==XML_READER_TYPE_ELEMENT) { ndepth++; if (!name) return 1; if ( strcmp(xmlTextReaderName(reader),name)==0) if (ndepth==(depth+1)) return 1; if (name2) { if ( strcmp(xmlTextReaderName(reader),name2)==0) if (ndepth==(depth+1)) return 1; } } if (xmlTextReaderNodeType(reader)==XML_READER_TYPE_END_ELEMENT) { ndepth--; if (ndepth<depth) return 0; } retval=xmlTextReaderRead(reader); } while (retval==1); return 0; }void rpc_fault(xmlTextReaderPtr reader){ xmlNodePtr node; int fc=0,fd=0; char *content; if (rpc_search(reader,"value",NULL)!=1) { GB.Error("Unable to parse XML reply"); return; } if (rpc_search(reader,"struct",NULL)!=1) { GB.Error("Unable to parse XML reply"); return; } node=xmlTextReaderExpand(reader); content=xmlNodeGetContent(node); if (!content) { GB.Error("Unable to parse XML reply"); return; } GB.Error(content); free(content); return;}int rpc_eval_return_type(xmlTextReaderPtr reader){ int rtype=-1; do { switch(xmlTextReaderRead(reader)) { case 1: switch(xmlTextReaderNodeType(reader)) default: return -1; } } while (1) if ( xmlTextReaderNodeType(reader)==XML_READER_TYPE_ELEMENT) { if (strcmp(xmlTextReaderName(reader),"boolean")==0) rtype=0; if (strcmp(xmlTextReaderName(reader),"i4")==0) rtype=1; if (strcmp(xmlTextReaderName(reader),"int")==0) rtype=1; if (strcmp(xmlTextReaderName(reader),"double")==0) rtype=2; if (strcmp(xmlTextReaderName(reader),"string")==0) rtype=3; if (strcmp(xmlTextReaderName(reader),"dateTime.iso8601")==0) rtype=4; if (strcmp(xmlTextReaderName(reader),"base64")==0) rtype=5; if (strcmp(xmlTextReaderName(reader),"struct")==0) rtype=6; if (strcmp(xmlTextReaderName(reader),"array")==0) rtype=7; } else { rtype=0; } return rtype;}BEGIN_METHOD_VOID(CXMLRPC_GetReturn) xmlTextReaderPtr reader=NULL; int retval=1; int rtype=-1; if (THIS->reply) reader=xmlReaderForMemory(THIS->reply,strlen(THIS->reply),"",NULL,0); if (!reader) { GB.Error("Unable to parse XML reply"); return; } if (rpc_search(reader,"methodResponse",NULL)!=1) { GB.Error("Unable to parse XML reply"); return; } retval=rpc_search(reader,"params","fault"); switch (retval) { case 0: return; case 1: if ( strcmp(xmlTextReaderName(reader),"fault")==0) { rpc_fault(reader); return; } if (rpc_search(reader,"param",NULL)!=1) { GB.Error("Unable to parse XML reply"); return; } if (rpc_search(reader,"value",NULL)!=1) { GB.Error("Unable to parse XML reply"); return; } break; default: GB.Error("Unable to parse XML reply"); return; } END_METHOD*/GB_DESC CXmlRpcTypeDesc[] ={ GB_DECLARE("RpcType",0), GB_NOT_CREATABLE(), GB_CONSTANT("RpcAsyncHttp","i",2), GB_CONSTANT("RpcSyncHttp","i",1), GB_CONSTANT("RpcString","i",0), GB_CONSTANT("Boolean","i",0), GB_CONSTANT("Integer","i",1), GB_CONSTANT("Double","i",2), GB_CONSTANT("String","i",3), GB_CONSTANT("Date","i",4), GB_CONSTANT("Base64","i",5), GB_CONSTANT("Array","i",6), GB_CONSTANT("Struct","i",7), GB_END_DECLARE};GB_DESC CXmlRpcDesc[] ={ GB_DECLARE("XmlRpc", sizeof(CXMLRPC)), GB_METHOD("_new",NULL,CXMLRPC_New,"(RpcType)i(MethodName)s(Parameters)Integer[];[(ReturnType)i]"), GB_METHOD("_free",NULL,CXMLRPC_Free,NULL), GB_METHOD( "_call" ,"v", CXMLRPC_Call ,"."), //GB_METHOD("SetReply",NULL,CXMLRPC_SetReply,"(ServerReply)s"), //GB_METHOD("GetReturnValue","v",CXMLRPC_GetReturn,NULL), GB_END_DECLARE};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -