📄 pxmlrpc.cxx
字号:
/* * pxmlrpc.cxx * * XML/RPC support * * Portable Windows Library * * Copyright (c) 2002 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Contributor(s): ______________________________________. * * $Log: pxmlrpc.cxx,v $ * Revision 1.24 2003/04/15 03:00:41 robertj * Added array support to XML/RPC * Fixed XML/RPC parsing when lots of white space in raw XML, caused by * big fix to base XML parser not returning internal data elements. * * Revision 1.23 2003/02/21 05:07:27 robertj * Fixed GetParam() for an int type so can accept i4/int/boolean type names. * * Revision 1.22 2003/01/28 07:42:17 robertj * Improved trace output of errors. * * Revision 1.21 2002/12/16 06:53:19 robertj * Added ability to specify certain elemets (by name) that are exempt from * the indent formatting. Useful for XML/RPC where leading white space is * not ignored by all servers. * Allowed for some servers that only send "string" type for "int" etc * Fixed problem with autodetecting reply that is a single struct. * * Revision 1.20 2002/12/13 01:12:24 robertj * Added copy constructor and assignment operator to XML/RPC structs * * Revision 1.19 2002/12/10 03:51:17 robertj * Fixed member variable display in structure * * Revision 1.18 2002/12/09 04:06:44 robertj * Added macros for defining multi-argument functions * * Revision 1.17 2002/12/04 00:31:13 robertj * Fixed GNU compatibility * * Revision 1.16 2002/12/04 00:15:44 robertj * Changed usage of PHTTPClient so supports chunked transfer encoding. * Large enhancement to create automatically encoding and decoding structures * using macros to build a class. * * Revision 1.15 2002/11/06 22:47:25 robertj * Fixed header comment (copyright etc) * * Revision 1.14 2002/10/08 12:26:31 craigs * Changed struct members to always contain name/value in that order * * Revision 1.13 2002/10/08 12:09:28 craigs * More fixes for creation of struct params * * Revision 1.12 2002/10/08 11:58:01 craigs * Fixed creation of struct params * * Revision 1.11 2002/10/08 11:48:37 craigs * Added logging of incoming and outgoing XML at highest log level * * Revision 1.10 2002/10/08 11:36:56 craigs * Fixed fault parsing * * Revision 1.9 2002/10/08 08:22:18 craigs * Fixed problem with parsing struct parameters * * Revision 1.8 2002/10/02 08:54:01 craigs * Added support for XMLRPC server * * Revision 1.7 2002/08/13 03:02:07 robertj * Removed previous fix for memory leak, as object was already deleted. * * Revision 1.6 2002/08/13 01:54:47 craigs * Fixed memory leak on PXMLRPCRequest class * * Revision 1.5 2002/08/06 01:04:03 robertj * Fixed missing pragma interface/implementation * * Revision 1.4 2002/08/02 05:42:10 robertj * Fixed confusion between in and out MIME. * Improved trace logging and error reporting. * * Revision 1.3 2002/07/12 05:51:35 craigs * Added structs to XMLRPC response types * * Revision 1.2 2002/03/27 00:50:29 craigs * Fixed problems with parsing faults and creating structs * * Revision 1.1 2002/03/26 07:06:29 craigs * Initial version * */// This depends on the expat XML library by Jim Clark// See http://www.jclark.com/xml/expat.html for more information#include <ptlib.h>#ifdef __GNUC__#pragma implementation "pxmlrpc.h"#endif#include <ptclib/pxmlrpc.h>#if P_EXPAT#include <ptclib/mime.h>#include <ptclib/http.h>static const char NoIndentElements[] = "methodName name string int boolean double dateTime.iso8601";/////////////////////////////////////////////////////////////////PXMLRPCBlock::PXMLRPCBlock() : PXML(-1, NoIndentElements){ faultCode = P_MAX_INDEX; SetRootElement("methodResponse"); params = NULL;}PXMLRPCBlock::PXMLRPCBlock(const PString & method) : PXML(-1, NoIndentElements){ faultCode = P_MAX_INDEX; SetRootElement("methodCall"); rootElement->AddChild(new PXMLElement(rootElement, "methodName", method)); params = NULL;}PXMLRPCBlock::PXMLRPCBlock(const PString & method, const PXMLRPCStructBase & data) : PXML(-1, NoIndentElements){ faultCode = P_MAX_INDEX; SetRootElement("methodCall"); rootElement->AddChild(new PXMLElement(rootElement, "methodName", method)); params = NULL; for (PINDEX i = 0; i < data.GetNumVariables(); i++) { PXMLRPCVariableBase & variable = data.GetVariable(i); if (variable.IsArray()) AddParam(CreateArray(variable)); else { PXMLRPCStructBase * structVar = variable.GetStruct(0); if (structVar != NULL) AddParam(*structVar); else AddParam(CreateValueElement(new PXMLElement(NULL, variable.GetType(), variable.ToString(0)))); } }}BOOL PXMLRPCBlock::Load(const PString & str){ if (!PXML::Load(str)) return FALSE; if (rootElement != NULL) params = rootElement->GetElement("params"); return TRUE;}PXMLElement * PXMLRPCBlock::GetParams(){ if (params == NULL) params = rootElement->AddChild(new PXMLElement(rootElement, "params")); return params;}PXMLElement * PXMLRPCBlock::CreateValueElement(PXMLElement * element) { PXMLElement * value = new PXMLElement(NULL, "value"); value->AddChild(element); element->SetParent(value); return value;}PXMLElement * PXMLRPCBlock::CreateScalar(const PString & type, const PString & scalar){ return CreateValueElement(new PXMLElement(NULL, type, scalar));}PXMLElement * PXMLRPCBlock::CreateScalar(const PString & str) { return CreateScalar("string", str);}PXMLElement * PXMLRPCBlock::CreateScalar(int value) { return CreateScalar("int", PString(PString::Unsigned, value)); }PXMLElement * PXMLRPCBlock::CreateScalar(double value){ return CreateScalar("double", psprintf("%lf", value)); }PXMLElement * PXMLRPCBlock::CreateDateAndTime(const PTime & time){ return CreateScalar("dateTime.iso8601", PXMLRPC::PTimeToISO8601(time)); }PXMLElement * PXMLRPCBlock::CreateBinary(const PBYTEArray & data){ return CreateScalar("base64", PBase64::Encode(data)); }PXMLElement * PXMLRPCBlock::CreateStruct(){ PAssertAlways("Not used"); return NULL;}PXMLElement * PXMLRPCBlock::CreateStruct(const PStringToString & dict){ return CreateStruct(dict, "string");}PXMLElement * PXMLRPCBlock::CreateStruct(const PStringToString & dict, const PString & typeStr){ PXMLElement * structElement = new PXMLElement(NULL, "struct"); PXMLElement * valueElement = CreateValueElement(structElement); PINDEX i; for (i = 0; i < dict.GetSize(); i++) { PString key = dict.GetKeyAt(i); structElement->AddChild(CreateMember(key, CreateScalar(typeStr, dict[key]))); } return valueElement;}PXMLElement * PXMLRPCBlock::CreateStruct(const PXMLRPCStructBase & data){ PXMLElement * structElement = new PXMLElement(NULL, "struct"); PXMLElement * valueElement = PXMLRPCBlock::CreateValueElement(structElement); PINDEX i; for (i = 0; i < data.GetNumVariables(); i++) { PXMLElement * element; PXMLRPCVariableBase & variable = data.GetVariable(i); if (variable.IsArray()) element = CreateArray(variable); else { PXMLRPCStructBase * nested = variable.GetStruct(0); if (nested != NULL) element = CreateStruct(*nested); else element = CreateScalar(variable.GetType(), variable.ToString(0)); } structElement->AddChild(CreateMember(variable.GetName(), element)); } return valueElement;}PXMLElement * PXMLRPCBlock::CreateMember(const PString & name, PXMLElement * value){ PXMLElement * member = new PXMLElement(NULL, "member"); member->AddChild(new PXMLElement(member, "name", name)); member->AddChild(value); return member;}PXMLElement * PXMLRPCBlock::CreateArray(const PStringArray & array){ return CreateArray(array, "string");}PXMLElement * PXMLRPCBlock::CreateArray(const PStringArray & array, const PString & typeStr){ PXMLElement * arrayElement = new PXMLElement(NULL, "array"); PXMLElement * dataElement = new PXMLElement(arrayElement, "data"); arrayElement->AddChild(dataElement); PINDEX i; for (i = 0; i < array.GetSize(); i++) dataElement->AddChild(CreateScalar(typeStr, array[i])); return CreateValueElement(arrayElement);}PXMLElement * PXMLRPCBlock::CreateArray(const PStringArray & array, const PStringArray & types){ PXMLElement * arrayElement = new PXMLElement(NULL, "array"); PXMLElement * dataElement = new PXMLElement(arrayElement, "data"); arrayElement->AddChild(dataElement); PINDEX i; for (i = 0; i < array.GetSize(); i++) dataElement->AddChild(CreateScalar(types[i], array[i])); return CreateValueElement(arrayElement);}PXMLElement * PXMLRPCBlock::CreateArray(const PArray<PStringToString> & array){ PXMLElement * arrayElement = new PXMLElement(NULL, "array"); PXMLElement * dataElement = new PXMLElement(arrayElement, "data"); arrayElement->AddChild(dataElement); PINDEX i; for (i = 0; i < array.GetSize(); i++) dataElement->AddChild(CreateStruct(array[i])); return CreateValueElement(arrayElement);}PXMLElement * PXMLRPCBlock::CreateArray(const PXMLRPCVariableBase & array){ PXMLElement * arrayElement = new PXMLElement(NULL, "array"); PXMLElement * dataElement = new PXMLElement(arrayElement, "data"); arrayElement->AddChild(dataElement); PINDEX i; for (i = 0; i < array.GetSize(); i++) { PXMLElement * element; PXMLRPCStructBase * structure = array.GetStruct(i); if (structure != NULL) element = CreateStruct(*structure); else element = CreateScalar(array.GetType(), array.ToString(i)); dataElement->AddChild(element); } return CreateValueElement(arrayElement);}/////////////////////////////////////////////void PXMLRPCBlock::AddParam(PXMLElement * parm){ GetParams(); PXMLElement * child = params->AddChild(new PXMLElement(params, "param")); child->AddChild(parm); parm->SetParent(child);}void PXMLRPCBlock::AddParam(const PString & str) { AddParam(CreateScalar(str));}void PXMLRPCBlock::AddParam(int value) { AddParam(CreateScalar(value)); }void PXMLRPCBlock::AddParam(double value){ AddParam(CreateScalar(value)); }void PXMLRPCBlock::AddParam(const PTime & time){ AddParam(CreateDateAndTime(time)); }void PXMLRPCBlock::AddBinary(const PBYTEArray & data){ AddParam(CreateBinary(data)); }void PXMLRPCBlock::AddParam(const PXMLRPCStructBase & data){ AddParam(CreateStruct(data));}void PXMLRPCBlock::AddStruct(const PStringToString & dict){ AddParam(CreateStruct(dict, "string"));}void PXMLRPCBlock::AddStruct(const PStringToString & dict, const PString & typeStr){ AddParam(CreateStruct(dict, typeStr));}void PXMLRPCBlock::AddArray(const PStringArray & array){ AddParam(CreateArray(array, "string"));}void PXMLRPCBlock::AddArray(const PStringArray & array, const PString & typeStr){ AddParam(CreateArray(array, typeStr));}void PXMLRPCBlock::AddArray(const PStringArray & array, const PStringArray & types){ AddParam(CreateArray(array, types));}void PXMLRPCBlock::AddArray(const PArray<PStringToString> & array){ AddParam(CreateArray(array));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -