upnpavcontroller/upnpxmlparser/src/upnpxmlparserlite.cpp
changeset 0 7f85d04be362
equal deleted inserted replaced
-1:000000000000 0:7f85d04be362
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:      XML SAX Parser for UPnP.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDE FILES
       
    24 // xml parser
       
    25 #include <xml/parser.h>
       
    26 #include <xml/parserfeature.h>
       
    27 #include <xml/matchdata.h>
       
    28 
       
    29 // upnp stack api
       
    30 #include <upnpstring.h>
       
    31 
       
    32 // upnpframework / xmlparser api
       
    33 #include "upnpxmlparserlite.h"
       
    34 #include "upnpobjectlite.h"
       
    35 
       
    36 // xmlparser internal
       
    37 #include "upnpobjectstacklite.h"
       
    38 
       
    39 
       
    40 _LIT( KComponentLogfile, "upnpxmlparser.txt");
       
    41 #include "upnplog.h"
       
    42 
       
    43 _LIT8( KXmlMimeType,    "text/xml"     );
       
    44 _LIT8( KLIB2XML,        "libxml2" );
       
    45 
       
    46 _LIT8( KContainer,      "container"    );
       
    47 _LIT8( KItem,           "item"         );
       
    48 _LIT8( KTitle,          "title"        );
       
    49 _LIT8( KClass,          "class"        );
       
    50 _LIT8( KId,             "id"           );
       
    51 //_LIT8( KComma,          ":"            );
       
    52 _LIT8( KDIDL,           "DIDL-Lite"    );
       
    53 _LIT8( KDesc,           "desc"         );
       
    54 _LIT8( KDlnaDoc,        "X_DLNADOC"    );
       
    55 
       
    56 _LIT( KIndexContainer,  "1" );
       
    57 _LIT( KIndexAudio,      "2" );
       
    58 _LIT( KIndexVideo,      "3" );
       
    59 _LIT( KIndexImage,      "4" );
       
    60 _LIT( KIndexOther,      "5" );
       
    61 
       
    62 // --------------------------------------------------------------------------
       
    63 // CUPnPXMLParserLite::CUPnPXMLParserLite()
       
    64 // See upnpxmlparser.h
       
    65 // --------------------------------------------------------------------------
       
    66 CUPnPXMLParserLite::CUPnPXMLParserLite()
       
    67     {
       
    68     }
       
    69 
       
    70 // --------------------------------------------------------------------------
       
    71 // CUPnPXMLParserLite::ConstructL
       
    72 // See upnpxmlparser.h
       
    73 // --------------------------------------------------------------------------
       
    74 void CUPnPXMLParserLite::ConstructL()
       
    75     {
       
    76     __LOG( "CUPnPXMLParserLite::CostructL" );
       
    77     iStack = CUPnPObjectStackLite::NewL();
       
    78     }
       
    79 
       
    80 // --------------------------------------------------------------------------
       
    81 // CUPnPXMLParserLite::NewL
       
    82 // See upnpxmlparser.h
       
    83 // --------------------------------------------------------------------------
       
    84 EXPORT_C CUPnPXMLParserLite* CUPnPXMLParserLite::NewL()
       
    85     {
       
    86     CUPnPXMLParserLite* self = CUPnPXMLParserLite::NewLC();
       
    87     CleanupStack::Pop( self );    
       
    88     return self;
       
    89     }
       
    90 
       
    91 
       
    92 // --------------------------------------------------------------------------
       
    93 // CUPnPXMLParserLite::NewLC
       
    94 // See upnpxmlparser.h
       
    95 // --------------------------------------------------------------------------
       
    96 EXPORT_C CUPnPXMLParserLite* CUPnPXMLParserLite::NewLC()
       
    97     {   
       
    98     CUPnPXMLParserLite* self = new( ELeave ) CUPnPXMLParserLite();
       
    99     CleanupStack::PushL( self );
       
   100     self->ConstructL();
       
   101     return self;
       
   102     }
       
   103     
       
   104 // --------------------------------------------------------------------------
       
   105 // CUPnPXMLParserLite::~CUPnPXMLParserLite
       
   106 // See upnpxmlparser.h
       
   107 // --------------------------------------------------------------------------
       
   108 CUPnPXMLParserLite::~CUPnPXMLParserLite()
       
   109     {
       
   110     __LOG( "CUPnPXMLParserLite::~CUPnPXMLParserLite" );
       
   111     if ( iStack )
       
   112         {
       
   113         iStack->ResetAndDestroy();
       
   114         delete iStack;
       
   115         }
       
   116     
       
   117     delete iElementValue;
       
   118     delete iFormatString;
       
   119     delete iTitleBuf;
       
   120     }
       
   121 
       
   122 // --------------------------------------------------------------------------
       
   123 // CUPnPXMLParserLite::ParseResultDataL
       
   124 // See upnpxmlparser.h
       
   125 // --------------------------------------------------------------------------
       
   126 EXPORT_C void CUPnPXMLParserLite::ParseResultDataL(
       
   127     RPointerArray<CUpnpObjectLite>& aResultArray, const TDesC8& aData,
       
   128     const TDesC& aFormatString )
       
   129     {
       
   130     __LOG( "CUPnPXMLParserLite::ParseResultDataL, begin" );
       
   131     
       
   132     delete iFormatString; iFormatString = NULL;
       
   133     if( aFormatString != KNullDesC )
       
   134         {
       
   135         iFormatString = aFormatString.AllocL();
       
   136         }
       
   137     
       
   138     if ( !aData.Length() )
       
   139         {
       
   140         User::Leave( KErrArgument );
       
   141         }
       
   142         
       
   143     iResultRoot = &aResultArray;
       
   144 
       
   145     // Create parser 
       
   146     CMatchData* matchData = CMatchData::NewLC();
       
   147     matchData->SetMimeTypeL( KXmlMimeType ); 
       
   148     matchData->SetVariantL( KLIB2XML ); 
       
   149     CParser* parser = CParser::NewLC( *matchData, *this ); 
       
   150     parser->EnableFeature( Xml::EReportNamespaceMapping );
       
   151     
       
   152     Xml::ParseL( *parser, aData );    
       
   153     
       
   154     CleanupStack::PopAndDestroy( parser );
       
   155     CleanupStack::PopAndDestroy( matchData );
       
   156     
       
   157     iResultRoot = NULL;           
       
   158     __LOG( "CUPnPXMLParserLite::ParseResultDataL, end" );
       
   159     }
       
   160 
       
   161 // --------------------------------------------------------------------------
       
   162 // CUPnPXMLParserLite::OnStartDocumentL
       
   163 // See upnpxmlparser.h
       
   164 // --------------------------------------------------------------------------
       
   165 void CUPnPXMLParserLite::OnStartDocumentL( 
       
   166                                 const RDocumentParameters& /*aDocParam*/, 
       
   167                                 TInt /*aErrorCode*/ )
       
   168     {
       
   169     // No implementation needed
       
   170     }
       
   171 
       
   172 // --------------------------------------------------------------------------
       
   173 // CUPnPXMLParserLite::OnEndDocumentL
       
   174 // See upnpxmlparser.h
       
   175 // --------------------------------------------------------------------------
       
   176 void CUPnPXMLParserLite::OnEndDocumentL( TInt /*aErrorCode*/ )
       
   177     {
       
   178     // No implementation needed
       
   179     }
       
   180 
       
   181 // --------------------------------------------------------------------------
       
   182 // CUPnPXMLParserLite::OnStartElementL
       
   183 // See upnpxmlparser.h
       
   184 // --------------------------------------------------------------------------
       
   185 void CUPnPXMLParserLite::OnStartElementL( const RTagInfo& aElement, 
       
   186                                       const RAttributeArray& aAttributes,
       
   187                                       TInt aErrorCode )
       
   188     {
       
   189     __LOG1( "CUPnPXMLParserLite::OnStartElementL, error code: %d", aErrorCode );
       
   190     if ( aErrorCode != KErrNone )
       
   191         {
       
   192         return;
       
   193         }
       
   194     const TDesC8& desName = aElement.LocalName().DesC();
       
   195     const TDesC8& prefix = aElement.Prefix().DesC();
       
   196     
       
   197     // Delete content, since there may be some stuff between the elements
       
   198     // (comments, whitespace etc.)
       
   199     delete iElementValue; iElementValue = NULL;    
       
   200       
       
   201     if ( !desName.CompareF( KContainer ) ) // Container element
       
   202         {
       
   203         CUpnpObjectLite* tmpContainer = CUpnpObjectLite::NewL();
       
   204         CleanupStack::PushL( tmpContainer );
       
   205 
       
   206         SetAttributesL( *tmpContainer, aAttributes );
       
   207         //push into the stack, ownership is transferred                      
       
   208         iStack->PushL( tmpContainer ); 
       
   209         
       
   210         CleanupStack::Pop( tmpContainer );
       
   211         }
       
   212     else if ( !desName.CompareF( KItem ) ) // Item element
       
   213         {
       
   214         CUpnpObjectLite* tmpItem = CUpnpObjectLite::NewL();
       
   215         CleanupStack::PushL( tmpItem );
       
   216 
       
   217         SetAttributesL( *tmpItem, aAttributes );                      
       
   218         //push into the stack, ownership is transferred                      
       
   219         iStack->PushL( tmpItem );
       
   220         
       
   221         CleanupStack::Pop( tmpItem );
       
   222         }
       
   223     else if( !desName.CompareF( KTitle ) ) // Title element
       
   224         {
       
   225         // check that we have item or container. cause leave if not
       
   226         if ( iStack->Count() == 0)
       
   227             {
       
   228             User::Leave( KErrArgument );
       
   229             }
       
   230         // We should have an item or a container already!
       
   231         //__ASSERTD( iStack->Top(), __FILE__, __LINE__ );
       
   232         iTitle = ETrue;
       
   233         }
       
   234     else if( !desName.CompareF( KClass ) ) // Object class element
       
   235         {
       
   236         // check that we have item or container. cause leave if not
       
   237         if ( iStack->Count() == 0)
       
   238             {
       
   239             User::Leave( KErrArgument );
       
   240             }
       
   241         // We should have an item or a container already!
       
   242         //__ASSERTD( iStack->Top(), __FILE__, __LINE__ );
       
   243         iObjectClass = ETrue;
       
   244         }
       
   245     // Ignore DIDL-Lite, desc and X_DLNADOC -elements (DLNA req)
       
   246     else if( desName.Compare( KDIDL ) == KErrNone ||
       
   247              desName.Compare( KDesc ) == KErrNone ||
       
   248              desName.Compare( KDlnaDoc ) == KErrNone    
       
   249            )
       
   250         {
       
   251         // Ignore
       
   252         }
       
   253     else 
       
   254         {
       
   255         // check that we have item or container. cause leave if not
       
   256         if ( iStack->Count() == 0)
       
   257             {
       
   258             User::Leave( KErrArgument );
       
   259             }
       
   260         // Ignore rest of the elements
       
   261                 }
       
   262     __LOG( "CUPnPXMLParserLite::OnStartElementL, end" );
       
   263     }
       
   264 
       
   265 // --------------------------------------------------------------------------
       
   266 // CUPnPXMLParserLite::OnEndElementL
       
   267 // See upnpxmlparser.h
       
   268 // --------------------------------------------------------------------------
       
   269 void CUPnPXMLParserLite::OnEndElementL( const RTagInfo& aElement, 
       
   270                                     TInt aErrorCode )
       
   271     {
       
   272     __LOG( "CUPnPXMLParserLite::OnEndElementL(), begin" );
       
   273     if ( aErrorCode != KErrNone )
       
   274         {
       
   275         return;
       
   276         }
       
   277         
       
   278     const TDesC8& desName = aElement.LocalName().DesC();    
       
   279     if ( !desName.CompareF( KContainer ) || !desName.CompareF( KItem ) )
       
   280         {
       
   281         if( iTitleBuf )
       
   282             {
       
   283             CUpnpObjectLite* obj = iStack->Top();
       
   284             __ASSERTD( obj, __FILE__, __LINE__ );
       
   285 
       
   286             if( iFormatString )
       
   287                 {
       
   288                 HBufC* tempBuf = UpnpString::ToUnicodeL( *iTitleBuf );
       
   289                 CleanupStack::PushL( tempBuf );
       
   290                 HBufC* buf = HBufC::NewL( iFormatString->Length() +
       
   291                     tempBuf->Length() );
       
   292                 buf->Des().Format( *iFormatString, tempBuf );
       
   293                 CleanupStack::PopAndDestroy( tempBuf );
       
   294                 obj->SetTitleL( buf );
       
   295                 }
       
   296             else
       
   297                 {
       
   298                 HBufC* buf = HBufC::NewL( iTitleBuf->Length() );
       
   299                 buf->Des().Copy( *iTitleBuf );
       
   300                 obj->SetTitleL( buf );
       
   301                 }
       
   302             delete iTitleBuf; iTitleBuf = NULL;
       
   303             }
       
   304                
       
   305         iResultRoot->AppendL( iStack->Top() );
       
   306         iStack->Pop(); // Remove object from stack.
       
   307         }
       
   308     else if( KErrNone != desName.CompareF( KDIDL ))
       
   309         {        
       
   310         CUpnpObjectLite* obj = iStack->Top();
       
   311         __ASSERTD( obj, __FILE__, __LINE__ );
       
   312              
       
   313         if ( iElementValue )
       
   314             {
       
   315             if( !desName.CompareF( KTitle ) )
       
   316                 {
       
   317                 delete iTitleBuf; iTitleBuf = NULL;
       
   318                 iTitleBuf = iElementValue;
       
   319                 iElementValue = NULL;
       
   320                 }
       
   321             else if( !desName.CompareF( KClass ) )
       
   322                 {
       
   323                 obj->SetObjectClass( *iElementValue );                
       
   324                 iObjectClass = EFalse;
       
   325                 if( iFormatString )
       
   326                     {
       
   327                     SetIconIndex( *obj );
       
   328                     }                
       
   329                 }
       
   330             else
       
   331                 {               
       
   332                 }          
       
   333             }
       
   334         else
       
   335             {
       
   336             }    
       
   337         
       
   338         delete iElementValue; iElementValue = NULL;    
       
   339         }    
       
   340     __LOG( "CUPnPXMLParserLite::OnEndElementL(), end" );
       
   341     }
       
   342 
       
   343 // --------------------------------------------------------------------------
       
   344 // CUPnPXMLParserLite::OnContentL
       
   345 // See upnpxmlparser.h
       
   346 // --------------------------------------------------------------------------
       
   347 void CUPnPXMLParserLite::OnContentL( const TDesC8& aBytes, TInt aErrorCode )
       
   348     {
       
   349     __LOG( "CUPnPXMLParserLite::OnContentL(), begin" );
       
   350     if ( !iStack->Count() || aErrorCode != KErrNone )
       
   351         {
       
   352         return;
       
   353         }
       
   354     
       
   355     if( iTitle || iObjectClass ) // We are only interested in title or
       
   356                                  // object class!
       
   357         {
       
   358         if( !iElementValue ) //if 1st time
       
   359             {
       
   360             iElementValue = HBufC8::NewL(aBytes.Length());
       
   361             iElementValue->Des().Copy(aBytes); 
       
   362             }
       
   363         else
       
   364             {
       
   365             HBufC8* previousValue = iElementValue;
       
   366             iElementValue = HBufC8::NewL( previousValue->Des().Length() +
       
   367                                           aBytes.Length() );
       
   368             iElementValue->Des().Append( *previousValue );
       
   369             iElementValue->Des().Append( aBytes );
       
   370             delete previousValue;
       
   371             }         
       
   372         }
       
   373     
       
   374     __LOG( "CUPnPXMLParserLite::OnContentL(), end" );
       
   375     }
       
   376 
       
   377 // --------------------------------------------------------------------------
       
   378 // CUPnPXMLParserLite::OnStartPrefixMappingL
       
   379 // See upnpxmlparser.h
       
   380 // --------------------------------------------------------------------------
       
   381 void CUPnPXMLParserLite::OnStartPrefixMappingL( const RString& /*aPrefix*/, 
       
   382                                                const RString& /*aUri*/, 
       
   383                                                TInt /*aErrorCode*/ )
       
   384     {
       
   385     // No implementation needed
       
   386     }
       
   387 
       
   388 // --------------------------------------------------------------------------
       
   389 // CUPnPXMLParserLite::OnEndPrefixMappingL
       
   390 // See upnpxmlparser.h
       
   391 // --------------------------------------------------------------------------
       
   392 void CUPnPXMLParserLite::OnEndPrefixMappingL( const RString& /*aPrefix*/, 
       
   393                                              TInt /*aErrorCode*/ )
       
   394     {
       
   395     // No implementation needed
       
   396     }
       
   397 
       
   398 // --------------------------------------------------------------------------
       
   399 // CUPnPXMLParserLite::OnIgnorableWhiteSpaceL
       
   400 // See upnpxmlparser.h
       
   401 // --------------------------------------------------------------------------
       
   402 void CUPnPXMLParserLite::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/, 
       
   403                                                 TInt /*aErrorCode*/ )
       
   404     {
       
   405     // No implementation needed
       
   406     }
       
   407 
       
   408 // --------------------------------------------------------------------------
       
   409 // CUPnPXMLParserLite::OnSkippedEntityL
       
   410 // See upnpxmlparser.h
       
   411 // --------------------------------------------------------------------------
       
   412 void CUPnPXMLParserLite::OnSkippedEntityL( const RString& /*aName*/, 
       
   413                                           TInt /*aErrorCode*/ )
       
   414     {
       
   415     // No implementation needed
       
   416     }
       
   417 
       
   418 // --------------------------------------------------------------------------
       
   419 // CUPnPXMLParserLite::OnProcessingInstructionL
       
   420 // See upnpxmlparser.h
       
   421 // --------------------------------------------------------------------------
       
   422 void CUPnPXMLParserLite::OnProcessingInstructionL( const TDesC8& /*aTarget*/, 
       
   423                                                   const TDesC8& /*aData*/, 
       
   424                                                   TInt /*aErrorCode*/ )
       
   425     {
       
   426     // No implementation needed
       
   427     }
       
   428 
       
   429 // --------------------------------------------------------------------------
       
   430 // CUPnPXMLParserLite::OnError
       
   431 // See upnpxmlparser.h
       
   432 // --------------------------------------------------------------------------
       
   433 void CUPnPXMLParserLite::OnError( TInt /*aErrorCode*/ )
       
   434     {
       
   435     // No implementation needed
       
   436     }
       
   437 
       
   438 // --------------------------------------------------------------------------
       
   439 // CUPnPXMLParserLite::GetExtendedInterface
       
   440 // See upnpxmlparser.h
       
   441 // --------------------------------------------------------------------------
       
   442 TAny* CUPnPXMLParserLite::GetExtendedInterface( const TInt32 /*aUid*/ )
       
   443     {    
       
   444     // No implementation needed
       
   445     return NULL;
       
   446     }
       
   447 
       
   448 // --------------------------------------------------------------------------
       
   449 // CUPnPXMLParserLite::SetAttributesL
       
   450 // See upnpxmlparser.h
       
   451 // --------------------------------------------------------------------------
       
   452 void CUPnPXMLParserLite::SetAttributesL( CUpnpObjectLite& aObject, 
       
   453     const RAttributeArray& aAttributes )
       
   454     {
       
   455     __LOG( "CUPnPXMLParserLite::SetAttributesL" );
       
   456     
       
   457     if ( iStack->Count() )
       
   458         {
       
   459         // Object has a parent.
       
   460         // Should not really happen
       
   461         __LOG( "Object has a parent!" );
       
   462         __PANICD(__FILE__, __LINE__);      
       
   463         }
       
   464         
       
   465     RAttribute attribute;
       
   466     TInt count = aAttributes.Count();
       
   467     for ( TInt i = 0 ; i < count; i++ ) // Read attributes.
       
   468         {
       
   469         attribute = aAttributes[ i ];
       
   470         const TDesC8& name = attribute.Attribute().LocalName().DesC();
       
   471         
       
   472         if( !name.CompareF( KId ) )
       
   473             {
       
   474             aObject.SetObjectIdL( attribute.Value().DesC() );
       
   475             }
       
   476         }
       
   477     __LOG( "CUPnPXMLParserLite::SetAttributesL - End" );
       
   478     }
       
   479 
       
   480 void CUPnPXMLParserLite::SetIconIndex( const CUpnpObjectLite& aObject )
       
   481     {
       
   482     if( aObject.IsTypeOf( CUpnpObjectLite::EContainer ) )
       
   483         {
       
   484         iFormatString->Des().Replace( 0, 1, KIndexContainer );
       
   485         }
       
   486     else if( aObject.IsTypeOf( CUpnpObjectLite::EMusicItem ) )
       
   487         {
       
   488         iFormatString->Des().Replace( 0, 1, KIndexAudio );
       
   489         }
       
   490     else if( aObject.IsTypeOf( CUpnpObjectLite::EImageItem ) )
       
   491         {
       
   492         iFormatString->Des().Replace( 0, 1, KIndexImage );
       
   493         }
       
   494     else if( aObject.IsTypeOf( CUpnpObjectLite::EVideoItem ) )
       
   495         {
       
   496         iFormatString->Des().Replace( 0, 1, KIndexVideo );
       
   497         }
       
   498     else
       
   499         {
       
   500         // Other
       
   501         iFormatString->Des().Replace( 0, 1, KIndexOther );
       
   502         }    
       
   503     }
       
   504         
       
   505 // end of file
       
   506 
       
   507