📄 pxmlrpc.cxx
字号:
AddParam(CreateArray(array));
}
/////////////////////////////////////////////
BOOL PXMLRPCBlock::ValidateResponse()
{
// ensure root element exists and has correct name
if ((rootElement == NULL) ||
(rootElement->GetName() != "methodResponse")) {
SetFault(PXMLRPC::ResponseRootNotMethodResponse, "Response root not methodResponse");
PTRACE(2, "XMLRPC\t" << GetFaultText());
return FALSE;
}
// determine if response returned
if (params == NULL)
params = rootElement->GetElement("params");
if (params == NULL)
return TRUE;
// determine if fault
if (params->GetName() == "fault") {
// assume fault is a simple struct
PStringToString faultInfo;
PXMLElement * value = params->GetElement("value");
if (value == NULL) {
PStringStream txt;
txt << "Fault does not contain value\n" << *this;
SetFault(PXMLRPC::FaultyFault, txt);
} else if (!ParseStruct(value->GetElement("struct"), faultInfo) ||
(faultInfo.GetSize() != 2) ||
(!faultInfo.Contains("faultCode")) ||
(!faultInfo.Contains("faultString"))
) {
PStringStream txt;
txt << "Fault return is faulty:\n" << *this;
SetFault(PXMLRPC::FaultyFault, txt);
PTRACE(2, "XMLRPC\t" << GetFaultText());
return FALSE;
}
// get fault code and string
SetFault(faultInfo["faultCode"].AsInteger(), faultInfo["faultString"]);
return FALSE;
}
// must be params
else if (params->GetName() != "params") {
SetFault(PXMLRPC::ResponseUnknownFormat, PString("Response contains unknown element") & params->GetName());
PTRACE(2, "XMLRPC\t" << GetFaultText());
return FALSE;
}
return TRUE;
}
BOOL PXMLRPCBlock::ParseScalar(PXMLElement * valueElement,
PString & type,
PString & value)
{
if (valueElement == NULL)
return FALSE;
if (!valueElement->IsElement())
return FALSE;
if (valueElement->GetName() != "value") {
SetFault(PXMLRPC::ParamNotValue, "Scalar value does not contain value element");
PTRACE(2, "RPCXML\t" << GetFaultText());
return FALSE;
}
for (PINDEX i = 0; i < valueElement->GetSize(); i++) {
PXMLElement * element = (PXMLElement *)valueElement->GetElement(i);
if (element != NULL && element->IsElement()) {
type = element->GetName();
value = element->GetData();
return TRUE;
}
}
SetFault(PXMLRPC::ScalarWithoutElement, "Scalar without sub-element");
PTRACE(2, "XMLRPC\t" << GetFaultText());
return FALSE;
}
static BOOL ParseStructBase(PXMLRPCBlock & block, PXMLElement * & element)
{
if (element == NULL)
return FALSE;
if (!element->IsElement())
return FALSE;
if (element->GetName() == "struct")
return TRUE;
if (element->GetName() != "value")
block.SetFault(PXMLRPC::ParamNotStruct, "Param is not struct");
else {
element = element->GetElement("struct");
if (element != NULL)
return TRUE;
block.SetFault(PXMLRPC::ParamNotStruct, "nested structure not present");
}
PTRACE(2, "XMLRPC\t" << block.GetFaultText());
return FALSE;
}
static PXMLElement * ParseStructElement(PXMLRPCBlock & block,
PXMLElement * structElement,
PINDEX idx,
PString & name)
{
if (structElement == NULL)
return NULL;
PXMLElement * member = (PXMLElement *)structElement->GetElement(idx);
if (member == NULL)
return NULL;
if (!member->IsElement())
return NULL;
if (member->GetName() != "member") {
PStringStream txt;
txt << "Member " << idx << " missing";
block.SetFault(PXMLRPC::MemberIncomplete, txt);
PTRACE(2, "XMLRPC\t" << block.GetFaultText());
return NULL;
}
PXMLElement * nameElement = member->GetElement("name");
PXMLElement * valueElement = member->GetElement("value");
if ((nameElement == NULL) || (valueElement == NULL)) {
PStringStream txt;
txt << "Member " << idx << " incomplete";
block.SetFault(PXMLRPC::MemberIncomplete, txt);
PTRACE(2, "XMLRPC\t" << block.GetFaultText());
return NULL;
}
if (nameElement->GetName() != "name") {
PStringStream txt;
txt << "Member " << idx << " unnamed";
block.SetFault(PXMLRPC::MemberUnnamed, txt);
PTRACE(2, "XMLRPC\t" << block.GetFaultText());
return NULL;
}
name = nameElement->GetData();
return valueElement;
}
BOOL PXMLRPCBlock::ParseStruct(PXMLElement * structElement,
PStringToString & structDict)
{
if (!ParseStructBase(*this, structElement))
return FALSE;
for (PINDEX i = 0; i < structElement->GetSize(); i++) {
PString name;
PXMLElement * element = ParseStructElement(*this, structElement, i, name);
if (element != NULL) {
PString value;
PString type;
if (ParseScalar(element, type, value))
structDict.SetAt(name, value);
}
}
return TRUE;
}
BOOL PXMLRPCBlock::ParseStruct(PXMLElement * structElement, PXMLRPCStructBase & data)
{
if (!ParseStructBase(*this, structElement))
return FALSE;
for (PINDEX i = 0; i < structElement->GetSize(); i++) {
PString name;
PXMLElement * element = ParseStructElement(*this, structElement, i, name);
if (element != NULL) {
PXMLRPCVariableBase * variable = data.GetVariable(name);
if (variable != NULL) {
if (variable->IsArray()) {
if (!ParseArray(element, *variable))
return FALSE;
}
else {
PXMLRPCStructBase * nested = variable->GetStruct(0);
if (nested != NULL) {
if (!ParseStruct(element, *nested))
return FALSE;
}
else {
PString value;
PCaselessString type;
if (!ParseScalar(element, type, value))
return FALSE;
if (type != "string" && type != variable->GetType()) {
PTRACE(2, "RPCXML\tMember " << i << " is not of expected type: " << variable->GetType());
return FALSE;
}
variable->FromString(0, value);
}
}
}
}
}
return TRUE;
}
static PXMLElement * ParseArrayBase(PXMLRPCBlock & block, PXMLElement * element)
{
if (element == NULL)
return NULL;
if (!element->IsElement())
return NULL;
if (element->GetName() == "value")
element = element->GetElement("array");
if (element == NULL)
block.SetFault(PXMLRPC::ParamNotArray, "array not present");
else {
if (element->GetName() != "array")
block.SetFault(PXMLRPC::ParamNotArray, "Param is not array");
else {
element = element->GetElement("data");
if (element != NULL)
return element;
block.SetFault(PXMLRPC::ParamNotArray, "Array param has no data");
}
}
PTRACE(2, "XMLRPC\t" << block.GetFaultText());
return NULL;
}
BOOL PXMLRPCBlock::ParseArray(PXMLElement * arrayElement, PStringArray & array)
{
PXMLElement * dataElement = ParseArrayBase(*this, arrayElement);
if (dataElement == NULL)
return FALSE;
array.SetSize(dataElement->GetSize());
PINDEX count = 0;
for (PINDEX i = 0; i < dataElement->GetSize(); i++) {
PString value;
PString type;
if (ParseScalar((PXMLElement *)dataElement->GetElement(i), type, value))
array[count++] = value;
}
array.SetSize(count);
return TRUE;
}
BOOL PXMLRPCBlock::ParseArray(PXMLElement * arrayElement, PArray<PStringToString> & array)
{
PXMLElement * dataElement = ParseArrayBase(*this, arrayElement);
if (dataElement == NULL)
return FALSE;
array.SetSize(dataElement->GetSize());
PINDEX count = 0;
for (PINDEX i = 0; i < dataElement->GetSize(); i++) {
PStringToString values;
if (!ParseStruct((PXMLElement *)dataElement->GetElement(i), values))
return FALSE;
array[count++] = values;
}
array.SetSize(count);
return TRUE;
}
BOOL PXMLRPCBlock::ParseArray(PXMLElement * arrayElement, PXMLRPCVariableBase & array)
{
PXMLElement * dataElement = ParseArrayBase(*this, arrayElement);
if (dataElement == NULL)
return FALSE;
array.SetSize(dataElement->GetSize());
PINDEX count = 0;
for (PINDEX i = 0; i < dataElement->GetSize(); i++) {
PXMLElement * element = (PXMLElement *)dataElement->GetElement(i);
PXMLRPCStructBase * structure = array.GetStruct(i);
if (structure != NULL) {
if (ParseStruct(element, *structure))
count++;
}
else {
PString value;
PCaselessString type;
if (ParseScalar(element, type, value)) {
if (type != "string" && type != array.GetType())
PTRACE(2, "RPCXML\tArray entry " << i << " is not of expected type: " << array.GetType());
else
array.FromString(count++, value);
}
}
}
array.SetSize(count);
return TRUE;
}
PINDEX PXMLRPCBlock::GetParamCount() const
{
if (params == NULL)
return 0;
PINDEX count = 0;
for (PINDEX i = 0; i < params->GetSize(); i++) {
PXMLElement * element = (PXMLElement *)params->GetElement(i);
if (element != NULL && element->IsElement() && element->GetName() == "param")
count++;
}
return count;
}
PXMLElement * PXMLRPCBlock::GetParam(PINDEX idx) const
{
if (params == NULL)
return NULL;
PXMLElement * param = NULL;
PINDEX i;
for (i = 0; i < params->GetSize(); i++) {
PXMLElement * element = (PXMLElement *)params->GetElement(i);
if (element != NULL && element->IsElement() && element->GetName() == "param") {
if (idx <= 0) {
param = element;
break;
}
idx--;
}
}
if (param == NULL)
return FALSE;
for (i = 0; i < param->GetSize(); i++) {
PXMLObject * parm = param->GetElement(i);
if (parm != NULL && parm->IsElement())
return (PXMLElement *)parm;
}
return NULL;
}
BOOL PXMLRPCBlock::GetParams(PXMLRPCStructBase & data)
{
if (params == NULL)
return FALSE;
// Special case to allow for server implementations that always return
// values as a struct rather than multiple parameters.
if (GetParamCount() == 1 &&
(data.GetNumVariables() > 1 || data.GetVariable(0).GetStruct(0) == NULL)) {
PString type, value;
if (ParseScalar(GetParam(0), type, value) && type == "struct")
return GetParam(0, data);
}
for (PINDEX i = 0; i < data.GetNumVariables(); i++) {
PXMLRPCVariableBase & variable = data.GetVariable(i);
if (variable.IsArray()) {
if (!ParseArray(GetParam(i), variable))
return FALSE;
}
else {
PXMLRPCStructBase * structure = variable.GetStruct(0);
if (structure != NULL) {
if (!GetParam(i, *structure))
return FALSE;
}
else {
PString value;
if (!GetExpectedParam(i, variable.GetType(), value))
return FALSE;
variable.FromString(0, value);
}
}
}
return TRUE;
}
BOOL PXMLRPCBlock::GetParam(PINDEX idx, PString & type, PString & value)
{
// get the parameter
if (!ParseScalar(GetParam(idx), type, value)) {
PTRACE(3, "XMLRPC\tCannot get scalar parm " << idx);
return FALSE;
}
return TRUE;
}
BOOL PXMLRPCBlock::GetExpectedParam(PINDEX idx, const PString & expectedType, PString & value)
{
PString type;
// get parameter
if (!GetParam(idx, type, value))
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -