📄 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.1 2006/06/29 04:18:04 joegenbaclor
* *** empty log message ***
*
* 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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -