⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psoap.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * psoap.cxx
 *
 * SOAP client / server classes.
 *
 * Portable Windows Library
 *
 * Copyright (c) 2003 Andreas Sikkema
 *
 * 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 Andreas Sikkema
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: psoap.cxx,v $
 * Revision 1.1  2006/06/29 04:18:03  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.9  2005/11/30 12:47:41  csoutheren
 * Removed tabs, reformatted some code, and changed tags for Doxygen
 *
 * Revision 1.8  2004/04/24 01:06:32  rjongbloed
 * Apploed  patch that impliments a number of checks to avoid segfaults when dealing with
 *   various clients. Thanks Ben Lear
 *
 * Revision 1.7  2004/01/17 17:45:59  csoutheren
 * Changed to use PString::MakeEmpty
 *
 * Revision 1.6  2003/10/08 21:58:13  dereksmithies
 * Add client authentication support. many thanks to Ben Lear.
 *
 * Revision 1.5  2003/04/28 00:09:14  craigs
 * Patches from Andreas Sikkema
 *
 * Revision 1.4  2003/03/31 06:20:56  craigs
 * Split the expat wrapper from the XML file handling to allow reuse of the parser
 *
 * Revision 1.3  2003/02/09 23:31:54  robertj
 * Added referention PString's for efficiency.
 *
 * Revision 1.2  2003/02/09 23:22:46  robertj
 * Fixed spelling errors, and setting return values, thanks Andreas Sikkema
 *
 * Revision 1.1  2003/02/04 22:46:48  robertj
 * Added basic SOAP support, thanks Andreas Sikkema
 *
 */

#ifdef __GNUC__
#pragma implementation "psoap.h"
#endif


#include <ptlib.h>


#if P_EXPAT

#include <ptclib/psoap.h>



/*
 SOAP message classes
 ####################
 */


PSOAPMessage::PSOAPMessage( int options ) : 
  PXML( options ),
  pSOAPBody( 0 ),
  pSOAPMethod( 0 ),
  faultCode( PSOAPMessage::NoFault )
{
}

PSOAPMessage::PSOAPMessage( const PString & method, const PString & nameSpace ) :
  PXML( PXMLParser::Indent + PXMLParser::NewLineAfterElement ),
  pSOAPBody( 0 ),
  pSOAPMethod( 0 ),
  faultCode( PSOAPMessage::NoFault )
{
    SetMethod( method, nameSpace );
}



void PSOAPMessage::SetMethod( const PString & name, const PString & nameSpace )
{
  PXMLElement* rtElement = 0;
  
  if ( pSOAPBody == 0 )
  {
    SetRootElement("SOAP-ENV:Envelope");
    
    rtElement = GetRootElement();

    rtElement->SetAttribute("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", TRUE );
    rtElement->SetAttribute("xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance", TRUE );
    rtElement->SetAttribute("xmlns:xsd", "http://www.w3.org/1999/XMLSchema", TRUE );
    rtElement->SetAttribute("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", TRUE );

    pSOAPBody = new PXMLElement( rtElement, "SOAP-ENV:Body");

    rtElement->AddChild( pSOAPBody, TRUE );
  }

  if ( pSOAPMethod == 0 )
  {
    rtElement = GetRootElement();

    pSOAPMethod = new PXMLElement( rtElement, PString( "m:") + name );
    if ( nameSpace != "" )
    {
      pSOAPMethod->SetAttribute("xmlns:m", nameSpace, TRUE );
    }
    pSOAPBody->AddChild( pSOAPMethod, TRUE );
  }

}

void PSOAPMessage::GetMethod( PString & name, PString & nameSpace )
{
  PString fullMethod = pSOAPMethod->GetName();
  PINDEX sepLocation = fullMethod.Find(':');
  if (sepLocation != P_MAX_INDEX) {
    PString methodID = fullMethod.Left(sepLocation);
    name = fullMethod.Right(fullMethod.GetSize() - 2 - sepLocation);
    nameSpace = pSOAPMethod->GetAttribute( "xmlns:" + methodID );
  }
}


void PSOAPMessage::AddParameter( PString name, PString type, PString value )
{
  if ( pSOAPMethod )
  {
    PXMLElement* rtElement = GetRootElement();
    
    PXMLElement* pParameter = new PXMLElement( rtElement, name);
    PXMLData* pParameterData = new PXMLData( pParameter, value);
    
    if ( type != "" )
    {
      pParameter->SetAttribute( "xsi:type", PString( "xsd:" ) + type );
    }
    
    pParameter->AddChild( pParameterData, TRUE );

    AddParameter( pParameter, TRUE );
  }
}

void PSOAPMessage::AddParameter( PXMLElement* parameter, BOOL dirty )
{
  if ( pSOAPMethod )
  {
    pSOAPMethod->AddChild( parameter, dirty );
  }
}

void PSOAPMessage::PrintOn(ostream & strm) const
{
  BOOL newLine = ( options & PXMLParser::NewLineAfterElement ) != 0;

  PString ver = version;
  PString enc = encoding;
  int salone = standAlone;

  if ( ver.IsEmpty() )
    ver= "1.0";
  if ( enc.IsEmpty() )
    enc = "UTF-8";
  if ( salone == -2 )
    salone = -1;

  strm << "<?xml version=\"" << ver << "\" encoding=\"" << enc << "\"";
  switch ( salone ) {
    case 0:
      strm << " standalone=\"no\"";
      break;
    case 1:
      strm << " standalone=\"yes\"";
      break;
    default:
      break;
  }

  strm << "?>";
  if ( newLine )
    strm << endl;

  if ( rootElement != NULL ) {
    rootElement->Output(strm, *(this), 2 );
  }
}

PString PSOAPMessage::AsString( void )
{
  PStringStream stringStream;
  PrintOn( stringStream );

  PString SOAPString = stringStream;

  return SOAPString;
}


PString faultCodeToString( PINDEX faultCode )
{
  PString faultCodeStr;
  switch ( faultCode )
  {
  case PSOAPMessage::VersionMismatch:
    faultCodeStr = "VersionMisMatch";
    break;
  case PSOAPMessage::MustUnderstand:
    faultCodeStr = "MustUnderstand";
    break;
  case PSOAPMessage::Client:
    faultCodeStr = "Client";
    break;
  case PSOAPMessage::Server:
    faultCodeStr = "Server";
    break;
  default:
    // Default it's the server's fault. Can't blame it on the customer, because he/she is king ;-)
    faultCodeStr = "Server";
    break;
  }

  return faultCodeStr;
}

PINDEX stringToFaultCode( PString & faultStr )
{
  if ( faultStr == "VersionMisMatch" )
    return PSOAPMessage::VersionMismatch;

  if ( faultStr == "MustUnderstand" )
    return PSOAPMessage::MustUnderstand;

  if ( faultStr == "Client" )
    return PSOAPMessage::Client;
  
  if ( faultStr == "Server" )
    return PSOAPMessage::Server;

  return PSOAPMessage::Server;
}

BOOL PSOAPMessage::GetParameter( const PString & name, PString & value )
{
  PXMLElement* pElement = GetParameter( name );
  if(pElement == NULL)
    return FALSE;


  if ( pElement->GetAttribute( "xsi:type") == "xsd:string" )
  {
    value = pElement->GetData();
    return TRUE;
  }

  value.MakeEmpty();
  return FALSE;
}

BOOL PSOAPMessage::GetParameter( const PString & name, int & value )
{
  PXMLElement* pElement = GetParameter( name );
  if(pElement == NULL)
    return FALSE;

  if ( pElement->GetAttribute( "xsi:type") == "xsd:int" )
  {
    value = pElement->GetData().AsInteger();
    return TRUE;
  }

  value = -1;
  return FALSE;
}

PXMLElement* PSOAPMessage::GetParameter( const PString & name )
{
  if ( pSOAPMethod )
  {
    return pSOAPMethod->GetElement( name, 0 );
  }
  else
  {
    return 0;
  }
}

BOOL PSOAPMessage::Load( const PString & str )
{
  if ( !PXML::Load( str ) )
    return FALSE;
 
  if ( rootElement != NULL )
  {
    PString soapEnvelopeName = rootElement->GetName();
    PString soapEnvelopeID = soapEnvelopeName.Left( soapEnvelopeName.Find(':') );
    
    pSOAPBody = rootElement->GetElement( soapEnvelopeID + ":Body", 0 );
    
    if ( pSOAPBody != NULL )
    {
      PXMLObjectArray  subObjects = pSOAPBody->GetSubObjects() ;

      PINDEX idx;
      PINDEX size = subObjects.GetSize();
      
      for ( idx = 0; idx < size; idx++ ) {
        if ( subObjects[ idx ].IsElement() ) {
          // First subobject being an element is the method
          pSOAPMethod = ( PXMLElement * ) &subObjects[ idx  ];

          PString method;
          PString nameSpace;

          GetMethod( method, nameSpace );

          // Check if method name is "Fault"
          if ( method == "Fault" )
          {
            // The SOAP server has signalled an error
            PString faultCodeData = GetParameter( "faultcode" )->GetData();
            faultCode = stringToFaultCode( faultCodeData );
            faultText = GetParameter( "faultstring" )->GetData();
          }
          else
          {
            return TRUE;
          }
        }
      }
    }
  }
  return FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -