Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,长修远,我们不能没有钱

搞定symbian的http 和xml, xml采用sdk自带的cparser

    最近弄的东西太杂了. symbian os的sdk确实不是一般的难用, 顺便更正了以前写的symbian下的支持注释和section的ini类...
    顺便发泄下. 跟人合作做东西, 如果涉及到经济利益的话确实很麻烦. 本来这些东西都不是我来做的. 只是对方对源码遮遮掩掩的. 而且类封装的也很牵强.所以我才得做大量的工作...
    symbian阵营里面这些程序员对自己的源码还是看得很重的... 很怀念linux
   
关于xml的代码. 我记得没错的话, s60 2.3以后的sdk中才提供的cparser , 如果你要使用其代码, 请确认自己的sdk是2nd fp3 或以上, 否则, 请自行查阅mozilla的xml解析包的symbian移植版本


// --------------------------------------------------------------------------
// XmlHandler.h
//
// Copyright 2007, Antony Pranata
// http://www.antonypranata.com
//
// Example how to parse XML file using SAX on Symbian OS.
//
// There are two methods to parse XML document, i.e.;
//   - StartParsingL() -> parse XML document without active object.
//     The whole file content is read at once. It is simple, but suitable
//     for relatively small file only.
//   - StartParsingWithAoL() -> parse XML document with active object.
// --------------------------------------------------------------------------

#ifndef __XMLHANDLER_H__
#define __XMLHANDLER_H__

// INCLUDE FILES
#include <e32base.h>
#include <xml\contenthandler.h> // for MContentHandler
#include <xml\parser.h> // for CParser

// CLASS DECLARATION

using namespace Xml;

/**
 * MXmlHandlerObserver, an observer to CXmlHandler class.
 */
class MXmlHandlerObserver
{
  public:
    virtual void OnParseCompleted( TInt aError ) = 0;

};

/**
 * CXmlHandler, a class to parse XML file and then output log information
 * to a buffer.
 */
class CXmlHandler: public CActive, MContentHandler
{
    enum TState
    {
        EIdle,
        EReadingFile
    };
       
  public: // Constructors and destructor
   
    static CXmlHandler* NewL( MXmlHandlerObserver& aObserver );
   
    static CXmlHandler* NewLC( MXmlHandlerObserver& aObserver );
   
    virtual ~CXmlHandler();
   
  public: // Public methods
    void StartParsingL( const TDesC8& aBody );
    void StartParsingFL( const TDesC& aFileName );
   
    void StartParsingWithAoL( const TDesC& aFileName );
   
    TPtr8 DisplayResult() { return iDisplayResult->Des(); }

  private: // Constructors

    CXmlHandler( MXmlHandlerObserver& aObserver );
   
    void ConstructL();

  private: // from CActive
   
    void DoCancel();
   
    void RunL();
   
  private: // from MContentHandler

    void OnStartDocumentL( const RDocumentParameters &aDocParam, TInt aErrorCode );
   
    void OnEndDocumentL( TInt aErrorCode );
   
    void OnStartElementL( const RTagInfo &aElement, const RAttributeArray &aAttributes, TInt aErrorCode );
       
    void OnEndElementL( const RTagInfo &aElement, TInt aErrorCode );
   
    void OnContentL( const TDesC8 &aBytes, TInt aErrorCode );
   
    void OnStartPrefixMappingL( const RString &aPrefix, const RString &aUri, TInt aErrorCode );
       
    void OnEndPrefixMappingL( const RString &aPrefix, TInt aErrorCode );
   
    void OnIgnorableWhiteSpaceL( const TDesC8 &aBytes, TInt aErrorCode );
   
    void OnSkippedEntityL( const RString &aName, TInt aErrorCode );
   
    void OnProcessingInstructionL( const TDesC8 &aTarget, const TDesC8 &aData, TInt aErrorCode);
       
    void OnError( TInt aErrorCode );
   
    TAny *GetExtendedInterface( const TInt32 aUid );
   
  private: // Private methods

    void AppendText( const TDesC8& aText );
   
    void AppendTag( const TDesC8& aTag, TBool aIsClosingTag );

  private: // Private data

    MXmlHandlerObserver& iObserver;
    CParser*             iParser;
    HBufC8*              iBuffer;
    HBufC8*              iDisplayResult;
    TState               iState;
    RFile                iFile;

};

#endif /* __XMLHANDLER_H__ */

// End of File



// --------------------------------------------------------------------------
// XmlHandler.cpp
//
// Copyright 2007, Antony Pranata
// http://www.antonypranata.com
//
// Example how to parse XML file using SAX on Symbian OS.
//
// There are two methods to parse XML document, i.e.;
//   - StartParsingL() -> parse XML document without active object.
//     The whole file content is read at once. It is simple, but suitable
//     for relatively small file only.
//   - StartParsingWithAoL() -> parse XML document with active object.
// --------------------------------------------------------------------------

// INCLUDE FILES
#include <coemain.h>
#include <f32file.h>
#include "XmlHandler.h"

// CONSTANTS
const TInt KBufferSize     = 1024; // buffer size to store the result of
                                   // XML parsing -> the actual buffer size
                                   // can expand if needed (see AppendText())
                                  
const TInt KFileBufferSize = 1024; // buffer size for file reading

const TInt KOverheadLen    = 4; // length of (KOpeningTag + KClosingTag
                                //            + KSlash + KEndOfLine)

_LIT8(KOpeningTag, "<" );
_LIT8(KClosingTag, ">" );
_LIT8(KSlash,      "/" );
//_LIT8(KEndOfLine,  "\f" ); // CEikEdwin uses '\f' as EOF mark.

_LIT8( KXmlMimeType, "text/xml" );



// METHODS DEFINITION

// --------------------------------------------------------------------------

CXmlHandler* CXmlHandler::NewL( MXmlHandlerObserver& aObserver )
{
    CXmlHandler* self = CXmlHandler::NewLC( aObserver );
    CleanupStack::Pop();
    return self;
}

// --------------------------------------------------------------------------

CXmlHandler* CXmlHandler::NewLC( MXmlHandlerObserver& aObserver )
{
    CXmlHandler* self = new ( ELeave ) CXmlHandler( aObserver );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
}

// --------------------------------------------------------------------------

CXmlHandler::~CXmlHandler()
{
    Cancel();
    delete iParser;
    delete iDisplayResult;
    delete iBuffer;
}

// --------------------------------------------------------------------------

CXmlHandler::CXmlHandler( MXmlHandlerObserver& aObserver ):CActive( EPriorityStandard ),
    iObserver( aObserver ), iParser( 0 ), iDisplayResult( 0 ), iState( EIdle )
{
    CActiveScheduler::Add( this );
}

// --------------------------------------------------------------------------

void CXmlHandler::DoCancel()
{
    iParser->ParseEndL();
    iFile.Close();
    delete iBuffer;
    iBuffer = 0;
}

// --------------------------------------------------------------------------

void CXmlHandler::RunL()
{
    if ( KErrNone == iStatus.Int() )
    {
        // If the buffe length is zero, it means if we have reached
        // the end of the file.
        if ( iBuffer->Length() == 0)
        {
            iParser->ParseEndL();
            iFile.Close();
            delete iBuffer;
            iBuffer = 0;
        }
           
        // Otherwise, we continue reading the next chunk of the XML file.
        else
        {
            // Parse the next "part" of the XML document.
            iParser->ParseL( *iBuffer );
           
            // Read the next chunk of the file.
            TPtr8 bufferPtr( iBuffer->Des() );
            iFile.Read( bufferPtr, KFileBufferSize, iStatus );
           
            // Don't forget to call this... :)
            SetActive();
        }
    }
    else
    {
        iObserver.OnParseCompleted( iStatus.Int() );
    }
}

// --------------------------------------------------------------------------

void CXmlHandler::ConstructL()
{
    iParser = CParser::NewL( KXmlMimeType, *this );
    iDisplayResult = HBufC8::NewL( KBufferSize );
}

// --------------------------------------------------------------------------
  
  
void CXmlHandler::StartParsingL( const TDesC8& aBody )
{
    iDisplayResult->Des().Zero();
   
    delete iBuffer;
    iBuffer = 0;
    iBuffer = HBufC8::NewL( aBody.Length() );
   
    iBuffer->Des().Copy(aBody);
   
    iParser->ParseBeginL();
    iParser->ParseL( *iBuffer );
   
    iParser->ParseEndL();
}


void CXmlHandler::StartParsingFL( const TDesC& aFileName )
{
    // Read the whole content of aFileName into iBuffer.
    // IMPORTANT: This example reads the whole content within
    // one-shot for simplicity reason.
    // In reality, you have to read it chunk by chunk
    // using active object so that your application doesn't block.
    RFile file;
    User::LeaveIfError( file.Open( CCoeEnv::Static()->FsSession(), aFileName, EFileRead ) );
    CleanupClosePushL( file );
   
    iDisplayResult->Des().Zero();
    TInt size;
    User::LeaveIfError( file.Size( size ) );
    delete iBuffer;
    iBuffer = 0;
    iBuffer = HBufC8::NewL( size );
    TPtr8 bufferPtr( iBuffer->Des() );
    User::LeaveIfError( file.Read( bufferPtr ) );
   
    CleanupStack::PopAndDestroy(); // file
   
    // Now, we have the whole file content in iBuffer.
    // We are ready to parse the XML content.
    iParser->ParseBeginL();
    iParser->ParseL( *iBuffer );
   
    // Since we read the whole file contents within one-shot,
    // we can call ParseEndL() right after calling ParseL().
    iParser->ParseEndL();
}

// --------------------------------------------------------------------------
  
void CXmlHandler::StartParsingWithAoL( const TDesC& aFileName )
{
     // Remember to cancel any outstanding request first.
    if ( IsActive() )
    {
        Cancel();
    }
       
    User::LeaveIfError( iFile.Open( CCoeEnv::Static()->FsSession(), aFileName, EFileRead ) );

    // Create a buffer to store the file content.
    // Note that this method uses active object to read the file.
    // So we have to call SetActive() at the end. Then we call CParser::ParseL()
    // in RunL() method.
    iDisplayResult->Des().Zero();
    delete iBuffer;
    iBuffer = 0;
    iBuffer = HBufC8::NewL( KFileBufferSize );
    TPtr8 bufferPtr( iBuffer->Des() );
    iFile.Read( bufferPtr, KFileBufferSize, iStatus );
    SetActive();

    // Tell the parser that we are about to parse a XML document.   
    iParser->ParseBeginL();
}

// --------------------------------------------------------------------------

void CXmlHandler::OnStartDocumentL( const RDocumentParameters& /*aDocParam*/, TInt aErrorCode )
{
    _LIT8( KOnStartDocumentL, "*** OnStartDocumentL ***\f" );
    AppendText( KOnStartDocumentL );
   
    if ( KErrNone == aErrorCode )
    {
       //可以在这里解析xml头
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}



// --------------------------------------------------------------------------
   
void CXmlHandler::OnEndDocumentL( TInt aErrorCode )
{
    //_LIT8( KOnEndDocumentL, "*** OnEndDocumentL ***\f" );
    //AppendText( KOnEndDocumentL );
   
    if ( KErrNone == aErrorCode )
    {
        // Do something here if needed....
    }
       
    iObserver.OnParseCompleted( aErrorCode );
}

// --------------------------------------------------------------------------

void CXmlHandler::OnStartElementL( const RTagInfo& aElement, const RAttributeArray& aAttributes, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // If we find the start of an element, we write to the screen,
        // for example: "<tag>"
        //AppendTag( aElement.LocalName().DesC(), EFalse );
        for(TInt i = 0; i<aAttributes.Count(); i++)
        {
            RAttribute ra = aAttributes[i];
            if( ra.Attribute().LocalName().DesC() == _L8("id") 
              || ra.Attribute().LocalName().DesC() == _L8("name") )
            {
                //AppendText(ra.Attribute().LocalName().DesC());
                AppendText(aElement.LocalName().DesC());
                AppendText(_L8(" "));
                AppendText(ra.Value().DesC());
                AppendText(_L8(" "));
            }

        }
        AppendText(_L8("\r\n"));
 
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}
       
// --------------------------------------------------------------------------

void CXmlHandler::OnEndElementL( const RTagInfo& /*aElement*/, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // If we find the end of an element, we write it to the screen,
        // for example: "</tag>"
        //AppendTag( aElement.LocalName().DesC(), ETrue );
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}
   
// --------------------------------------------------------------------------

void CXmlHandler::OnContentL( const TDesC8 &aBytes, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // Display aBytes on the screen.
        // Before we can display it, we have to convert the content
        // from TDesC8 to TDesC16.
        HBufC8* buffer = HBufC8::NewLC( aBytes.Length() + 1 );
        TPtr8 bufferPtr( buffer->Des() );
        bufferPtr.Copy( aBytes );
        bufferPtr.Trim();
        AppendText( *buffer );
        CleanupStack::PopAndDestroy(); // buffer
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}
   
// --------------------------------------------------------------------------

void CXmlHandler::OnStartPrefixMappingL( const RString& /*aPrefix*/, const RString& /*aUri*/, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // Do something here...
       
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}
       
// --------------------------------------------------------------------------

void CXmlHandler::OnEndPrefixMappingL( const RString& /*aPrefix*/, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // Do something here...
        //AppendText(aPrefix.DesC());
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}
   
// --------------------------------------------------------------------------

void CXmlHandler::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // Do something here...
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}
   
// --------------------------------------------------------------------------

void CXmlHandler::OnSkippedEntityL( const RString& /*aName*/, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // Do something here...
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}

// --------------------------------------------------------------------------

void CXmlHandler::OnProcessingInstructionL( const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt aErrorCode )
{
    if ( KErrNone == aErrorCode )
    {
        // Do something here...
    }
    else
    {
        iObserver.OnParseCompleted( aErrorCode );
    }
}

// --------------------------------------------------------------------------

void CXmlHandler::OnError( TInt aErrorCode )
{
    //_LIT8( KErrorMessage, "*** OnError ***\f" );
    //AppendText( KErrorMessage );
    iObserver.OnParseCompleted( aErrorCode );
}

// --------------------------------------------------------------------------

TAny* CXmlHandler::GetExtendedInterface( const TInt32 /*aUid*/ )
{
    return 0;
}

// --------------------------------------------------------------------------

void CXmlHandler::AppendText( const TDesC8& aText )
{
    TPtr8 displayResultPtr( iDisplayResult->Des() );
    if ( displayResultPtr.Length() + aText.Length() > displayResultPtr.MaxLength() )
    {
        iDisplayResult = iDisplayResult->ReAllocL( displayResultPtr.MaxLength() + KBufferSize );
        displayResultPtr.Set( iDisplayResult->Des() );
    }   
    displayResultPtr.Append( aText );
}

// --------------------------------------------------------------------------

void CXmlHandler::AppendTag( const TDesC8& aTag, TBool aIsClosingTag )
{
    // Instantiate buffer to display tag information.
    HBufC8* buffer = HBufC8::NewLC( aTag.Length() + ( ( aIsClosingTag ) ? KOverheadLen : KOverheadLen - 1 ) );
    TPtr8 bufferPtr( buffer->Des() );
       
    // Convert tag name from TDesC8 to TDesC16.
    bufferPtr.Copy( aTag );
       
    // Add opening tag.
    if ( aIsClosingTag )
    {
        bufferPtr.Insert( 0, KSlash );
    }
    bufferPtr.Insert( 0, KOpeningTag );
       
    // Add closing tag.
    bufferPtr.Append( KClosingTag );
    //bufferPtr.Append( KEndOfLine );
       
    // Add to the result text and then destroy it.
    AppendText( *buffer );
    CleanupStack::PopAndDestroy(); // buffer
}

// End of File




//CHttpEngine.h



#ifndef _CHTTPENGINE_H_
#define _CHTTPENGINE_H_

#include <e32base.h>                // CBase
#include <MHTTPAuthenticationCallback.h>    // MHTTPAuthenticationCallback

#include <MHttpTransactionCallback.h>        // MHTTPTransactionCallback
#include <RHTTPSession.h>            // RHTTPSession
#include <RHTTPTransaction.h>            // RHTTPTransaction

#include <MHttpDataSupplier.h>

#include "NewCommon.h"

class CHTTPFormEncoder;

enum
{
    EMaxUrlLength = 128,
    EMaxNameLength = 32
};



//抽象的数据接口, 回调函数
class MHttpEngineObserver
{
  public:
    //返回链接状态
    virtual void ResponseStatusL(TInt aStatusCode, const TDesC8& aStatusText, TNewHeader& newheader) = 0;
   
    //返回数据
    virtual void ResponseReceivedL( const TDesC8& aResponseBuffer) = 0;
    //virtual void ResponseNewStatusL()=0;
};



class CHttpEngine : public CBase, MHTTPTransactionCallback, MHTTPDataSupplier
    {
    public:
      static CHttpEngine* NewL(MHttpEngineObserver& aObserver);
      static CHttpEngine* NewLC(MHttpEngineObserver& aObserver);

        ~CHttpEngine();

        void GetRequestL(const TDesC8& aUri);
        void PostRequestL(const TDesC8& aPostUri, const TDesC8& aName);

        // Cancel an outstanding transaction
        void Cancel();

    private: // from MHTTPTransactionCallback
        virtual void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
        virtual TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);

    private:
        CHttpEngine(MHttpEngineObserver& aObserver);
        void ConstructL();

        void ParseUriL(const TDesC8& aUri);
        void AddHeaderL(RHTTPHeaders aHeaders, TInt aHeaderField, const TDesC8& aHeaderValue);
        void AddHeaderExL(RHTTPHeaders aHeaders, const TDesC8 &aHeaderField, const TDesC8 &aHeaderValue);
        TInt GetHeaderL(RHTTPHeaders aHeaders, const TDesC8 &aHeaderField, THTTPHdrVal &aHeaderValue);
        void DumpRespHeadersL(RHTTPTransaction& aTrans);
    private://from MHTTPDataSupplier
          TBool GetNextDataPart(TPtrC8& aDataPart);
          void ReleaseData();
          TInt OverallDataSize();
          TInt Reset();
         
    private://data
        RHTTPSession          iSession;
        RHTTPTransaction      iTransaction;
        HBufC8*               iPostData;    // Data for HTTP POST
        HBufC8*               iResponseBuffer;

        CHTTPFormEncoder*     iFormEncoder;
       
        MHttpEngineObserver&  iObserver;
    };

#endif //_CHTTPENGINE_H_



//CHttpEngine.cpp


#include <chttpformencoder.h>    // CHTTPFormEncoder
#include <httpstringconstants.h>  // HTTP string table
#include <rhttpheaders.h>      // RHTTPHeaders
#include <mhttpdatasupplier.h>    // MHTTPDataSupplier

#include "CHttpEngine.h"



// CONSTANTS
// HTTP header values
_LIT8(KUserAgent, "NewEyes(1.0)");  // Name of this client app
_LIT8(KAccept, "*/*");        // Accept any (but only) text content
_LIT8(KPostParamName, "NAME");      // Name of the parameter sent in a POST request
_LIT8(KPostContentType, "text/plain");  // Content type sent in a POST request
_LIT8(KXHost,"X-Online-Host:");
_LIT8(KIP,"222.66.92.54");



CHttpEngine* CHttpEngine::NewL(MHttpEngineObserver& aObserver)
{
  CHttpEngine* self = CHttpEngine::NewLC(aObserver);
  CleanupStack::Pop(self);
  return self;
}



CHttpEngine* CHttpEngine::NewLC(MHttpEngineObserver& aObserver)
{
  CHttpEngine* self = new (ELeave) CHttpEngine(aObserver);
  CleanupStack::PushL(self);
  self->ConstructL();
  return self;
}



CHttpEngine::CHttpEngine(MHttpEngineObserver& aObserver): iObserver(aObserver)
{
}



CHttpEngine::~CHttpEngine()
{
  // Close session
  iSession.Close();  // Will also close any open transactions
  delete iResponseBuffer;
  delete iFormEncoder;
  //delete iUri;
}



void CHttpEngine::ConstructL()
{
    TRAPD( err, iSession.OpenL() );//创建会话并捕获异常
    if( err != KErrNone ) {
        iFormEncoder = CHTTPFormEncoder::NewL();
        User::Leave( err );
    }
}






/**
* Override of pure virtual method in MHTTPTransactionCallback.
* Called to report progress by a currently outstanding transaction.
*
* @param aTransaction The transaction reporting progress
* @param aEvent The event being notified
*/
void CHttpEngine::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
{
  switch (aEvent.iStatus)
  {
    case THTTPEvent::EGotResponseHeaders:
    {
      // HTTP response headers have been received. Pass status information to observer.
      RHTTPResponse resp = aTransaction.Response();

      TInt statusCode = resp.StatusCode();
     
      RHTTPHeaders headers = resp.GetHeaderCollection();

      TNewHeader aNewHeader;
     
      THTTPHdrVal aHeaderValue;
      GetHeaderL(headers, _L8("Content-Length"), aHeaderValue);
      aNewHeader._data_len = aHeaderValue.Int();
     
      GetHeaderL(headers, _L8("Text-content-length"), aHeaderValue);
     
      RStringPool strP = aTransaction.Session().StringPool();
      RStringF fieldValStr = strP.StringF(aHeaderValue.StrF());
      const TDesC8& fieldValDesC = fieldValStr.DesC();

      TLex8 iLex(fieldValDesC);
      TInt iNum2;
      iLex.Val(iNum2);
     
      aNewHeader._xml_len = iNum2;
     
      fieldValStr.Close();
      //strP.Close();
     
      // Get status text
      RStringF statusStr = resp.StatusText();

      // Inform observer 调用返回链接状态的用户接口
      iObserver.ResponseStatusL(statusCode, statusStr.DesC(), aNewHeader);
      statusStr.Close();
    }
      break;


    case THTTPEvent::EGotResponseBodyData:
    {
      //dataSupplier
      // Get text of response body
      MHTTPDataSupplier* abody = aTransaction.Response().Body();
      TPtrC8 ptr;
      TBool isLast = abody->GetNextDataPart(ptr);

      // Append to iResponseBuffer
      if (!iResponseBuffer)
      {
        iResponseBuffer = ptr.Alloc();
      }
      else
      {
        iResponseBuffer = iResponseBuffer->ReAllocL(iResponseBuffer->Length() + ptr.Length());
        iResponseBuffer->Des().Append(ptr);
      }
     
      // Release the body data
      abody->ReleaseData();
    }
      break;

    case THTTPEvent::EResponseComplete:
    {
      // Pass the response buffer by reference to the observer
      iObserver.ResponseReceivedL(*iResponseBuffer);
      if(iResponseBuffer != NULL)
      {
          delete iResponseBuffer;
          iResponseBuffer = NULL;
      }
       
    }
      break;
    case THTTPEvent::ESucceeded:
    {
    }
      break;

    case THTTPEvent::EFailed:
    {
    }
      break;

    default:
    {
      TBuf8<64> text;
      if (aEvent.iStatus < 0)
      {
        _LIT8(KErrorStr, "Error: %d");
        text.Format(KErrorStr, aEvent.iStatus);
        // Just close the transaction on errors
        aTransaction.Close();
      }
      else
      {
        // Other events are not errors (e.g. permanent and temporary redirections)
        _LIT8(KUnrecognisedEvent, "Unrecognised event: %d");
        text.Format(KUnrecognisedEvent, aEvent.iStatus);
      }
      //iObserver.DataReceived(6, text);
    }
      break;
  }
}




TInt CHttpEngine::MHFRunError(TInt aError, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/)
{
  return aError;
}



void CHttpEngine::GetRequestL(const TDesC8& aUri)
{
  TUriParser8 uri;
  uri.Parse(aUri);

  // Create the transaction
  iTransaction = iSession.OpenTransactionL(uri, *this, iSession.StringPool().StringF(HTTP::EGET, RHTTPSession::GetTable()));

  // Set transaction headers
  RHTTPHeaders headers = iTransaction.Request().GetHeaderCollection();
  AddHeaderL(headers, HTTP::EUserAgent, KUserAgent);
  AddHeaderL(headers, HTTP::EAccept, KAccept);
  AddHeaderExL(headers,KXHost,KIP);
  // Submit the request
  iTransaction.SubmitL();
}



void CHttpEngine::PostRequestL(const TDesC8& aPostUri, const TDesC8& aBody)
{
  // Build form encoder
  // Start by removing any previous content
  /*
  delete iFormEncoder;
  iFormEncoder = NULL;
  iFormEncoder = CHTTPFormEncoder::NewL();
  TBuf8<EMaxNameLength> buf8;
  buf8.Copy(aName);
  iFormEncoder->AddFieldL(KPostParamName, buf8);
*/
  // Create transaction
  TUriParser8 uri;
  uri.Parse(aPostUri);

 
  delete iPostData;
  iPostData = aBody.AllocL();
 
  iTransaction = iSession.OpenTransactionL(uri, *this, iSession.StringPool().StringF(HTTP::EPOST, RHTTPSession::GetTable()));

  // Set transaction headers
  RHTTPHeaders headers = iTransaction.Request().GetHeaderCollection();
  AddHeaderL(headers, HTTP::EUserAgent, KUserAgent);
  AddHeaderL(headers, HTTP::EAccept, KAccept);
  AddHeaderL(headers, HTTP::EContentType, KPostContentType);
  AddHeaderExL(headers,KXHost,KIP);

  MHTTPDataSupplier* dataSupplier = this;
  iTransaction.Request().SetBody(*dataSupplier);
  // Set the form encoder as the data supplier
  //iTransaction.Request().SetBody(*iFormEncoder);

  // Submit the request
  iTransaction.SubmitL();
}



TBool CHttpEngine::GetNextDataPart(TPtrC8& aDataPart)
{

    if(iPostData){
        aDataPart.Set(iPostData->Des());
    }
    return ETrue;
}


void CHttpEngine::ReleaseData()
{
    // It's safe to delete iPostData now.
    delete iPostData;
    iPostData = NULL;
}


TInt CHttpEngine::OverallDataSize()
{
    if(iPostData)
        return iPostData->Length();
    else
        return KErrNotFound ;
}




TInt CHttpEngine::Reset()
{
    return KErrNone;
}


TInt CHttpEngine::GetHeaderL(RHTTPHeaders aHeaders, const TDesC8 &aHeaderField, THTTPHdrVal &aHeaderValue)
{
  RStringPool string_pool = iSession.StringPool();
  RStringF contLength = string_pool.OpenFStringL(aHeaderField);
 
  TInt err = aHeaders.GetField(contLength,0,aHeaderValue);

  contLength.Close();
  return err;
}


void CHttpEngine::AddHeaderL(RHTTPHeaders aHeaders, TInt aHeaderField, const TDesC8& aHeaderValue)
{
  RStringPool stringPool = iSession.StringPool();
  RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
  THTTPHdrVal headerVal(valStr);
  aHeaders.SetFieldL(stringPool.StringF(aHeaderField, RHTTPSession::GetTable()), headerVal);
  valStr.Close();
}


void CHttpEngine::AddHeaderExL(RHTTPHeaders aHeaders, const TDesC8 &aHeaderField, const TDesC8 &aHeaderValue)
{
    RStringPool stringPool = iSession.StringPool();
    RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
    THTTPHdrVal headerVal(valStr);
    RStringF sHeaderField = stringPool.OpenFStringL(aHeaderField);
    aHeaders.SetFieldL(sHeaderField, headerVal);
    valStr.Close();
    sHeaderField.Close();
}

/**
* Cancel any outstanding transaction
*/
void CHttpEngine::Cancel()
{
  iTransaction.Cancel();
}







void CHttpEngine::DumpRespHeadersL(RHTTPTransaction& aTrans)
{
    TBuf<64> fieldName16;
    TBuf<128> fieldVal16;
   
    RHTTPResponse resp = aTrans.Response();
    RStringPool strP = aTrans.Session().StringPool();
    RHTTPHeaders hdr = resp.GetHeaderCollection();
    // Get an iterator for the collection of response headers
    THTTPHdrFieldIter it = hdr.Fields();
    while (it.AtEnd() == EFalse)
    {
        // Get name of next header field
        RStringTokenF fieldName = it();
        RStringF fieldNameStr = strP.StringF(fieldName);
        // Get the field value
        THTTPHdrVal fieldVal;
        if (hdr.GetField(fieldNameStr,0,fieldVal) == KErrNone)
        {
            const TDesC8& fieldNameDesC = fieldNameStr.DesC();
            fieldName16.Copy(fieldNameDesC.Left(fieldNameDesC.Length()));
            switch (fieldVal.Type())
            {
                case THTTPHdrVal::KTIntVal:
                    //Printf(_L("%S: %d\n"), &fieldName16, fieldVal.Int());
                    break;
                case THTTPHdrVal::KStrFVal:
                    {
                    RStringF fieldValStr = strP.StringF(fieldVal.StrF());
                    const TDesC8& fieldValDesC = fieldValStr.DesC();
                    fieldVal16.Copy(fieldValDesC.Left(fieldValDesC.Length()));
                    //Printf(_L("%S: %S\n"), &fieldName16, &fieldVal16);
                    }
                    break;
                case THTTPHdrVal::KStrVal:
                    {
                    RString fieldValStr = strP.String(fieldVal.Str());
                    const TDesC8& fieldValDesC = fieldValStr.DesC();
                    fieldVal16.Copy(fieldValDesC.Left(fieldValDesC.Length()));
                    //Printf(_L("%S: %S\n"), &fieldName16, &fieldVal16);
                    }
                    break;
                case THTTPHdrVal::KDateVal:
                    {
                    TDateTime date = fieldVal.DateTime();
                    TBuf<40> dateTimeString;
                    TTime t(date);
                    t.FormatL(dateTimeString,_L("%H:%T:%S on %E, %F%D-%*M-%Y"));
                    //Printf(_L("%S: %S\n"), &fieldName16, &dateTimeString);
                    }
                    break;
                default:
                    //Printf(_L("%S: <unrecognised value type>\n"), &fieldName16);
                    break;
            }
           
           
           
        }
            // Advance the iterator to get the next field
        ++it;
    }
}






调用他们的程序需要实现那些虚接口.

/* ====================================================================
 * File: NewEyesAppUi.h
 * Created: 12/14/07
 * Author: Khan.Lau
 * Copyright (c): 2007, All rights reserved
 * ==================================================================== */

#ifndef __NEWEYES_APPUI_H__
#define __NEWEYES_APPUI_H__

#include <aknappui.h>

#include "CHttpEngine.h"
#include "XmlHandler.h"


// Forward reference
class CNewEyesAppView;


class CAknNavigationDecorator;
class CAknTabGroup;
class CHttpEngine;
//class CXmlHandler;

/*!
  @class CNewEyesAppUi
 
  @discussion An instance of class CNewEyesAppUi is the UserInterface part of the AVKON
  application framework for the NewEyes example application
  */
class CNewEyesAppUi : public CAknAppUi,
                      public MHttpEngineObserver,
                      public MXmlHandlerObserver
    {
public:
    void ConstructL();

    CNewEyesAppUi();



    ~CNewEyesAppUi();


public: // from CAknAppUi
    void HandleCommandL(TInt aCommand);
   
private://CEikServAppUiBase
    TKeyResponse HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);

private: // from MHttpEngineObserver
    virtual void ResponseStatusL(TInt aStatusCode, const TDesC8& aStatusText, TNewHeader& newheader);
    virtual void ResponseReceivedL(const TDesC8& aResponse);

   
private://MXmlHandlerObserver
    virtual void OnParseCompleted( TInt aError );

private:
    void InitNaviPane();
   
    void ConvUni2Gbk(TDesC& original, TDes8& res) ;

private:
    CNewEyesAppView* iAppView;
    CAknNavigationDecorator *iNaviDecorator;
    CAknTabGroup* iTabGroup;
   
   
    CXmlHandler* iXmlHandler;
   
    CHttpEngine* iEngine;
    TNewHeader iNewheader;
    TInt    iIndex;
    };


#endif // __NEWEYES_APPUI_H__



/* ====================================================================
 * File: NewEyesAppUi.cpp
 * Created: 12/14/07
 * Author: Khan.Lau
 * Copyright (c): 2007 All rights reserved
 * ==================================================================== */

#include <avkon.hrh>
#include <aknnotewrappers.h>

#include <aknnavi.h>               // for CAknNavigationControlContainer
#include <eikspane.h>              // for CEikStatusPane
#include <aknnavide.h>             // for CAknNavigationDecorator
#include <akntabgrp.h>             // CAknTabGroup
#include <akntitle.h>

#include <e32base.h>
//#include <utf.h>
#include <charconv.h>

#include "NewEyes.pan"
#include "NewEyesAppUi.h"
#include "NewEyesAppView.h"
#include "NewEyes.hrh"

#include "CFile.h"



const TInt KStatusCodeLength = 10;  // Enough room in a descriptor for code + ": "


// ConstructL is called by the application framework
void CNewEyesAppUi::ConstructL()
{
    BaseConstructL();
    iIndex = 0;
   
   
    iEngine = CHttpEngine::NewL(*this);
   
    iXmlHandler = CXmlHandler::NewL( *this );
   
    InitNaviPane();
   
    if(iAppView)
    {
        RemoveFromStack(iAppView);
        delete iAppView;
        iAppView = NULL;
    }
   

    TUid muid;
    muid.iUid = iIndex;
    iAppView = CNewEyesAppView::NewL(ClientRect(), muid);   
    AddToStackL(iAppView);
}



CNewEyesAppUi::CNewEyesAppUi()                             
{
    this->iNewheader._data_len = 0;
    this->iNewheader._xml_len = 0;
}



CNewEyesAppUi::~CNewEyesAppUi()
{
    delete iNaviDecorator;
    delete iXmlHandler;
    delete iEngine;
}

// handle any menu commands
void CNewEyesAppUi::HandleCommandL(TInt aCommand)
{
    switch(aCommand)
    {
        case EEikCmdExit:
        case EAknSoftkeyExit:
            Exit();
            break;

        case ENewEyesCommand1:
        {
             iEngine->GetRequestL(_L8("http://222.66.92.54:8080/cmcc/phone?c=as"));
        }
            break;

        default:
            Panic(ENewEyesBasicUi);
            break;
    }
}


void CNewEyesAppUi::InitNaviPane()
{
    CEikStatusPane* statusPane = StatusPane();

    CEikStatusPaneBase::TPaneCapabilities subPane = statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidNavi));


    if (subPane.IsPresent() && subPane.IsAppOwned())
    {

        CAknNavigationControlContainer* naviPane =(CAknNavigationControlContainer *) statusPane->ControlL(TUid::Uid(EEikStatusPaneUidNavi));

        delete iNaviDecorator;
        iNaviDecorator = NULL;

        iNaviDecorator = naviPane->CreateTabGroupL();

        iTabGroup = (CAknTabGroup*) iNaviDecorator->DecoratedControl();

        iTabGroup->SetTabFixedWidthL(KTabWidthWithTwoTabs);

        TInt tabId = 0;


        iTabGroup->AddTabL(tabId++, _L("aaaaaaaaa"));
        iTabGroup->AddTabL(tabId++, _L("bbbbbbbbb"));
        iTabGroup->AddTabL(tabId++, _L("ccccccccc"));
       
        iTabGroup->SetActiveTabByIndex(iIndex);
        naviPane->PushL(*iNaviDecorator);
    }
}



TKeyResponse CNewEyesAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType){
    if(iTabGroup == NULL){
        return EKeyWasNotConsumed;
    }
    //如果按下的是左方向键或右方向键
    if(aKeyEvent.iCode==EKeyLeftArrow || aKeyEvent.iCode == EKeyRightArrow){
   
        TUid muid;
        muid.iUid = iTabGroup->ActiveTabIndex();
        if(aKeyEvent.iCode==EKeyLeftArrow)
        {
            if(muid.iUid > 0)
            {
                //ActivateLocalViewL(TUid::Uid(ViewId));
                muid.iUid--;
            }
        }
        else
        {
            if(muid.iUid < iTabGroup->TabCount() - 1)
            {
                //ActivateLocalViewL(TUid::Uid(ViewId));
                muid.iUid++;
            }
        }
       
        if(    muid.iUid != iTabGroup->ActiveTabIndex())
        {
            if(iAppView)
            {
                RemoveFromStack(iAppView);
                delete iAppView;
                iAppView = NULL;
            }
            CEikStatusPane* statusPane = StatusPane();
            CAknTitlePane* aTitlePane=(CAknTitlePane*)statusPane->ControlL(TUid::Uid(EEikStatusPaneUidTitle));
           
           
            aTitlePane->SetTextL(_L("453543634") );
            iAppView = CNewEyesAppView::NewL(ClientRect(), muid);   
            AddToStackL(iAppView);
        }
       
        return iTabGroup->OfferKeyEventL(aKeyEvent, aType);
    } else {
        return EKeyWasNotConsumed;
    }
}





void CNewEyesAppUi::ResponseStatusL(TInt aStatusCode, const TDesC8& aStatusText, TNewHeader& newheader)
{
    iNewheader._data_len = newheader._data_len;
    iNewheader._xml_len = newheader._xml_len;
   
   
    HBufC* buf = HBufC::NewLC(aStatusText.Length() + KStatusCodeLength);
    buf->Des().Format(_L("%d: %S"), aStatusCode, &aStatusText);
    CAknInformationNote* note = new (ELeave) CAknInformationNote;
    note->ExecuteLD(*buf);
    CleanupStack::PopAndDestroy(buf);
}



/**
* Callback from engine invoked when the complete response has been received.
*
* @param aResponse Text of the HTTP response
*/
void CNewEyesAppUi::ResponseReceivedL(const TDesC8& aResponse)
{

  if(iNewheader._data_len > 0 && iNewheader._xml_len < iNewheader._data_len)
  {
      HBufC8* buf8 = HBufC8::NewLC(iNewheader._xml_len);
    buf8->Des().Copy(aResponse.Left( iNewheader._xml_len));

    //CFile::LogToFile(_L("c:\\debug.txt"), (TDes8&)buf8->Des());
    buf8->Des().TrimAll();
    iXmlHandler->StartParsingL(buf8->Des());
    CleanupStack::PopAndDestroy(buf8);
  }

  iNewheader._data_len = 0;
  iNewheader._xml_len = 0;
}


void CNewEyesAppUi::OnParseCompleted( TInt aError )
    {
    if ( KErrNone == aError )
        {
        TPtr8 resultPtr( iXmlHandler->DisplayResult() );
        //iXmlHandlerp->
       
        //HBufC* buffer = HBufC::NewLC(resultPtr.Length());
        //buffer->Des().Copy(resultPtr);
        //iAppView->SetTextL( buffer->Des() );
       
        //CleanupStack::PopAndDestroy(); // buffer
        CFile::LogToFile(_L("c:\\debug.txt"), resultPtr);
        }
    else
        {
        TBuf8<50> buffer;
        buffer.Append( _L("Error: " ) );
        buffer.AppendNum( aError );
        CFile::LogToFile(_L("c:\\debug.txt"), (TDes8&)buffer);
        //iAppView->SetTextL( buffer );
        }
    }


本例中是将http发过来的文档解析后. 存入log

mmp中需要引入的lib
LIBRARY     aknicon.lib
LIBRARY     fbscli.lib
LIBRARY     eikcoctl.lib
LIBRARY     http.lib
LIBRARY     InetProtUtil.lib    // TUriParser
LIBRARY     bafl.lib            // String pool APIs
LIBRARY     charconv.lib
LIBRARY     efsrv.lib           // Rfs
LIBRARY     xmlframework.lib


以上内容, 转载请注明出处. 本人保留所有权利, 如果对代码有修改, 请在版权信息中注明.

posted on 2007-12-19 14:11 Khan 阅读(6401) 评论(13)  编辑 收藏 引用 所属分类: GCC/G++

评论

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser[未登录] 2008-01-06 15:21 robin

大哥,能不能换个背景色,
看着真的很压抑  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-04-01 10:41 Khan's Notebook

@robin
嘿嘿. 个人爱好. 你帖到editplus或者vim里面看吧  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-05-10 16:56 diyer

你好,你的文章很好,但是为什么CHttpEngine文件编译不过,你的LIB文件我都已经包含了。  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-05-21 12:08 思春贴调查员

@diyer

这个...不清楚你的编程环境.... 也不清楚你的RP.... 仅仅凭借一句编译不过我很难解释的哦....
代码确定没问题的...  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-07-04 17:51 ouccomputer

where is "NewCommon.h"?  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-07-07 10:21 Khan's Notebook

@ouccomputer
NewCommon.h 里没有跟你相关的东西  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-07-08 12:59 ouccomputer

知道了,3q~  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-07-26 16:37 Airon

太强悍了。。。小弟佩服佩服。。。  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-09-14 13:09 缘分天空

使用你设计的类如果解析<a>1234</a>Xml文件,在哪个函数或方法中能取得
"1234"的值,谢谢指点,!!!!

在OnStartElementL函数中通过 aElement.LocalName().DesC()取得

tag <a> 但是怎么取得1234那???
  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-09-16 10:22 Khan's Notebook

@缘分天空
代码实在太久了. 我不太记得了. 你自己查查sdk吧.... 我已经好久不碰symbian了  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-10-22 10:31 Youngmingxin

NewCommon.h文件里是不是这样的啊
struct TNewHeader
{
TInt _data_len;
TInt _xml_len;
};
另外,要增加System includes,包含epoc32/include/http和epoc32/include/ecom
要不然编译不过去啊  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-11-24 15:58 adler0518

大哥,mobile中的ini怎么用啊,是sdk。现成的API函数都用不了,自己封装的老说是文件报错说2,系统找不到指定的文件。if( (stream = fopen( lpFileName, "r" )) != NULL ) // 根据所指定的路径和名字打开文件

mobile,vs2005中,怎么用ini呢  回复  更多评论   

# re: 搞定symbian的http 和xml, xml采用sdk自带的cparser 2008-11-27 13:55 Khan.Lau

我这段代码就是在wm5下用的
找不到指定文件就说明你路径错了  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2004年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

公告

短信大全 for android 1.5
豌豆荚一键安装

现在时刻

IM在线情况:
点击这里给我发消息

常用链接

留言簿(33)

随笔分类(218)

随笔档案(163)

相册

技术

友情链接

最新随笔

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜