mmappcomponents/asxparser/src/asxparser.cpp
changeset 0 a2952bb97e68
child 2 7a9a8e73f54b
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Simple v2/v3 ASX-fileparser
       
    15 *
       
    16 */
       
    17 
       
    18 // Version : %version: 10.1.5 %
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include <e32base.h>
       
    24 #include <f32file.h>
       
    25 #include <bautils.h>
       
    26 #include <utf.h>
       
    27 #include <asxparser.h>
       
    28 
       
    29 #include <xmlengdomimplementation.h>
       
    30 #include <xmlengdomparser.h>
       
    31 #include <xmlengdocument.h>
       
    32 #include <xmlengelement.h>
       
    33 #include <xmlengnodelist.h>
       
    34 
       
    35 #include "AsxParser_debug.h"
       
    36 
       
    37 // CONSTANTS
       
    38 #define KMaxAsxFileSize 5192
       
    39 _LIT8( KNoSkip, "no" );
       
    40 
       
    41 // ============================ MEMBER FUNCTIONS ===============================
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 //   CAsxParser::NewL
       
    45 //   Two-phased constructor.
       
    46 // -----------------------------------------------------------------------------
       
    47 EXPORT_C CAsxParser* CAsxParser::NewL( const TDesC& aFileName )
       
    48 {
       
    49     ASX_DEBUG(_L("#MP# CAsxParser::NewL(%S)"), &aFileName);
       
    50 
       
    51     CAsxParser* self = new( ELeave ) CAsxParser();
       
    52 
       
    53     CleanupStack::PushL( self );
       
    54     self->ConstructL( aFileName );
       
    55     CleanupStack::Pop( self );
       
    56     return self;
       
    57 }
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 //   CAsxParser::NewL
       
    61 //   Two-phased constructor.
       
    62 // -----------------------------------------------------------------------------
       
    63 EXPORT_C CAsxParser* CAsxParser::NewL( RFile& aFile )
       
    64 {
       
    65     ASX_DEBUG(_L("#MP# CAsxParser::NewL(aFile)"));
       
    66 
       
    67     CAsxParser* self = new( ELeave ) CAsxParser();
       
    68 
       
    69     CleanupStack::PushL( self );
       
    70     self->ConstructL( aFile );
       
    71     CleanupStack::Pop( self );
       
    72     return self;
       
    73 }
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 //   CAsxParser::~CAsxParser()
       
    77 //   Destructor
       
    78 // -----------------------------------------------------------------------------
       
    79 EXPORT_C CAsxParser::~CAsxParser()
       
    80 {
       
    81     ASX_DEBUG(_L("#MP# CAsxParser::~CAsxParser()"));
       
    82 
       
    83     for ( TInt i = 0 ; i < iAsxArray.Count() ; i++ )
       
    84     {
       
    85         delete iAsxArray[i]->url;
       
    86     }
       
    87 
       
    88     iAsxArray.ResetAndDestroy();
       
    89 }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 //   CAsxParser::CAsxParser
       
    93 //   C++ default constructor can NOT contain any code, that might leave.
       
    94 // -----------------------------------------------------------------------------
       
    95 CAsxParser::CAsxParser()
       
    96 {
       
    97     ASX_DEBUG(_L("#MP# CAsxParser::CAsxParser()"));
       
    98 }
       
    99 
       
   100 // -----------------------------------------------------------------------------
       
   101 //   CAsxParser::ConstructL
       
   102 //   Symbian 2nd phase constructor can leave.
       
   103 // -----------------------------------------------------------------------------
       
   104 void CAsxParser::ConstructL( const TDesC& aFileName )
       
   105 {
       
   106     ASX_DEBUG(_L("#MP# CAsxParser::CAsxParser(%S)"), &aFileName);
       
   107 
       
   108     RFs rFs;
       
   109     RFile asxFile;
       
   110 
       
   111     User::LeaveIfError( rFs.Connect() );
       
   112     CleanupClosePushL( rFs );
       
   113 
       
   114     if ( ! BaflUtils::FileExists( rFs, aFileName ) )
       
   115     {
       
   116         ASX_DEBUG(_L("#MP# CAsxParser::ConstructL() file not found"));
       
   117         User::Leave( KErrNotFound );
       
   118     }
       
   119 
       
   120     User::LeaveIfError( asxFile.Open( rFs, aFileName, EFileShareAny ) );
       
   121     CleanupClosePushL( asxFile );
       
   122 	HandleFileParsingL( asxFile );
       
   123     CleanupStack::PopAndDestroy( 2 ); // rFs, asxFile
       
   124 
       
   125 }
       
   126 
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 //   CAsxParser::ConstructL
       
   130 //   Symbian 2nd phase constructor can leave.
       
   131 // -----------------------------------------------------------------------------
       
   132 void CAsxParser::ConstructL( RFile& aFile  )
       
   133 {
       
   134     ASX_DEBUG(_L("#MP# CAsxParser::ConstructL(aFile)"));
       
   135     RFile asxFile;
       
   136 	
       
   137     if( ! aFile.SubSessionHandle() )
       
   138     {
       
   139         ASX_DEBUG(_L("#MP# CAsxParser::ConstructL(aFile) file handle not found"));
       
   140         User::Leave( KErrNotFound );
       
   141     }
       
   142 
       
   143     User::LeaveIfError( asxFile.Duplicate( aFile ) );
       
   144     CleanupClosePushL( asxFile );
       
   145     HandleFileParsingL( asxFile );
       
   146     asxFile.Close();
       
   147     CleanupStack::PopAndDestroy( ); // asxFile
       
   148 }
       
   149 
       
   150 // -----------------------------------------------------------------------------
       
   151 //   CAsxParser::ParseAsxV2HeaderL
       
   152 // -----------------------------------------------------------------------------
       
   153 void CAsxParser::ParseAsxV2HeaderL( TPtr8 aPtr )
       
   154 {
       
   155     ASX_DEBUG(_L("#MP# CAsxParser::ParseAsxV2HeaderL()"));
       
   156 
       
   157     iVersion = 2;
       
   158     TInt location = 0;
       
   159 
       
   160     //
       
   161     //  Find all RefX= string and the URLs
       
   162     //
       
   163     //  v2 ASX file has simple Ref-strings for URLs, one URL per line
       
   164     //  File starts with [Reference]
       
   165     //  Example:
       
   166     //     [Reference]
       
   167     //        Ref1=http://server.com:8888/wm/file.wmv?MSWMExt=.asf
       
   168     //        Ref2=http://server2.com:8888/wm/file.wmv?MSWMExt=.asf
       
   169     //
       
   170     for ( TInt refNumber = 1 ; location >= 0 ; refNumber++ )
       
   171     {
       
   172         HBufC8* refString = HBufC8::NewLC(10);
       
   173         TPtr8 refPtr = refString->Des();
       
   174 
       
   175         refPtr.Append(_L("Ref"));
       
   176         refPtr.AppendNum(refNumber);
       
   177         refPtr.Append(_L("="));
       
   178 
       
   179         location = aPtr.FindF( refPtr );
       
   180 
       
   181         if ( location != KErrNotFound )
       
   182         {
       
   183             location     += refPtr.Length();
       
   184             TPtrC8 mid    = aPtr.Mid(location);
       
   185             TInt length   = mid.Locate(EKeyEnter);
       
   186            
       
   187             if ( length == KErrNotFound )
       
   188             {
       
   189                 length = mid.Length();
       
   190             }
       
   191                                
       
   192             AsxStruct* asxItem = new( ELeave ) AsxStruct ;
       
   193             CleanupStack::PushL( asxItem );
       
   194 
       
   195             // default the seek to true 
       
   196             asxItem->seek = ETrue;
       
   197             TPtrC8 urlStr    = mid.Left(length);
       
   198             asxItem->url = urlStr.AllocL();
       
   199             iAsxArray.Append(asxItem);  
       
   200             
       
   201             CleanupStack::Pop();   // pop the asxItem
       
   202         }
       
   203 
       
   204         CleanupStack::PopAndDestroy( refString );
       
   205     }
       
   206 }
       
   207 
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 //  CAsxParser::ParseAsxV3HeaderL
       
   211 // -----------------------------------------------------------------------------
       
   212 void CAsxParser::ParseAsxV3HeaderL( TPtr8 aPtr )
       
   213 {
       
   214     ASX_DEBUG(_L("#MP# CAsxParser::ParseAsxV3HeaderL()"));
       
   215 
       
   216     RXmlEngDOMImplementation DOM_impl;
       
   217     DOM_impl.OpenL();
       
   218 
       
   219     RXmlEngDOMParser parser;
       
   220     TInt error = parser.Open( DOM_impl );
       
   221     
       
   222     if (error == KErrNone)
       
   223     {
       
   224 	    RXmlEngDocument doc;
       
   225 
       
   226 	    //
       
   227 	    //  Parse the xml data stream
       
   228 	    //
       
   229 	    TRAPD( err, doc = parser.ParseL(aPtr) );
       
   230 
       
   231 	    if ( ! err )
       
   232 	    {
       
   233 	        iVersion = 3;
       
   234 	        TXmlEngElement element;
       
   235 	        TXmlEngNode node;
       
   236 	        RXmlEngNodeList<TXmlEngElement> nodelist1;
       
   237 	        RXmlEngNodeList<TXmlEngElement> nodelist2;
       
   238 	        node = doc.DocumentElement();
       
   239 	        node.AsElement().GetChildElements(nodelist1);
       
   240 
       
   241 	        CleanupClosePushL(nodelist1);
       
   242 	        CleanupClosePushL(nodelist2);
       
   243 
       
   244 	        _LIT8(KEntry,"ENTRY");
       
   245 	        _LIT8(KRef,"REF");
       
   246             _LIT8(KHRef,"HREF");
       
   247             _LIT8(KClientSkip,"CLIENTSKIP");
       
   248 
       
   249 	        while ( nodelist1.HasNext() )
       
   250 	        {
       
   251 	            element = nodelist1.Next();
       
   252 	            element.GetChildElements(nodelist2);
       
   253 
       
   254 	            //
       
   255 	            //  In v3 ASX file the streaming URLs are REF tags under
       
   256 	            //  ENTRY-element
       
   257 	            //
       
   258 	            //  Search for all ENTRYs and REFs under them
       
   259 	            //  Example
       
   260 	            //  <ENTRY>
       
   261 	            //        <REF HREF = "rtsp://ServerName/Path/FileName.wmv" />
       
   262 	            //        <BANNER HREF="http://ServerName/Path/Banner1.gif">
       
   263 	            //            <MOREINFO HREF ="http://www.microsoft.com/windows/windowsmedia" />
       
   264 	            //            <ABSTRACT>This is the description for this clip.</ABSTRACT>
       
   265 	            //        </BANNER>
       
   266 	            //  </ENTRY>
       
   267 	            //
       
   268 	            TPtrC8 name = element.Name();
       
   269 
       
   270 	            if ( ! element.Name().CompareF(KEntry) )
       
   271 	            {
       
   272                     AsxStruct* asxItem = new( ELeave ) AsxStruct;
       
   273                     CleanupStack::PushL( asxItem );
       
   274 
       
   275                     // init to True
       
   276                     asxItem->seek = ETrue;
       
   277 	                
       
   278                     TBool entryHasAttributes = element.HasAttributes();
       
   279                     if ( entryHasAttributes )
       
   280                     {
       
   281                         RXmlEngNodeList<TXmlEngAttr> attributeList;
       
   282                         element.GetAttributes(attributeList);
       
   283                         CleanupClosePushL(attributeList);
       
   284 
       
   285                         while ( attributeList.HasNext() )
       
   286                         {
       
   287                             TXmlEngAttr attr = attributeList.Next();
       
   288 
       
   289                             if ( ! attr.Name().CompareF(KClientSkip) )
       
   290                             {
       
   291                                 TPtrC8 attrData = attr.Value();
       
   292 
       
   293                                 if ( ! attrData.CompareF(KNoSkip) )
       
   294                                 {
       
   295                                     asxItem->seek = EFalse; 
       
   296                                 }
       
   297                             }
       
   298                         }
       
   299                         CleanupStack::PopAndDestroy(); //attributeList
       
   300                     }
       
   301 	            
       
   302 	                while( nodelist2.HasNext() )
       
   303 	                {
       
   304 	                    element = nodelist2.Next();
       
   305 
       
   306 	                    if ( ! element.IsNull() )
       
   307 	                    {
       
   308 	                        TPtrC8 name = element.Name();
       
   309 
       
   310 	                        if ( ! element.Name().CompareF(KRef) )
       
   311 	                        {
       
   312 	                            TBool hasAttributes = element.HasAttributes();
       
   313 
       
   314 	                            RXmlEngNodeList<TXmlEngAttr> attributeList;
       
   315 
       
   316 	                            element.GetAttributes(attributeList);
       
   317 
       
   318 	                            CleanupClosePushL(attributeList);
       
   319 
       
   320 	                            while ( attributeList.HasNext() )
       
   321 	                            {
       
   322 	                                TXmlEngAttr attr = attributeList.Next();
       
   323 
       
   324 	                                if ( ! attr.Name().CompareF(KHRef) )
       
   325 	                                {
       
   326 	                                    TPtrC8 attrData = attr.Value();
       
   327 	                                    asxItem->url = attrData.AllocL();
       
   328 	                                    iAsxArray.Append(asxItem);
       
   329 	                                }
       
   330 	                            }
       
   331 
       
   332 	                            CleanupStack::PopAndDestroy(); //attributeList
       
   333 	                        }
       
   334 	                    }
       
   335 	                }
       
   336                     CleanupStack::Pop();   // pop the asxItem                    
       
   337 	            }
       
   338 	        }
       
   339 
       
   340 	        CleanupStack::PopAndDestroy(); //nodelist2
       
   341 	        CleanupStack::PopAndDestroy(); //nodelist1
       
   342 	    }
       
   343 
       
   344 	    doc.Close();
       
   345 	    parser.Close();
       
   346 	    DOM_impl.Close();
       
   347     
       
   348     }
       
   349 }
       
   350 
       
   351 // -----------------------------------------------------------------------------
       
   352 //  CAsxParser::GetUrl
       
   353 //  First URL at position 1
       
   354 // -----------------------------------------------------------------------------
       
   355 EXPORT_C TInt CAsxParser::GetUrl( const TUint aUrlIndex, TPtrC8& aUrl )
       
   356 {
       
   357     ASX_DEBUG(_L("#MP# CAsxParser::GetUrl(%d)"), aUrlIndex);
       
   358 
       
   359     TInt retVal = KErrNone;
       
   360 
       
   361     if ( aUrlIndex - 1 > iAsxArray.Count() || iAsxArray.Count() == 0 )
       
   362     {
       
   363         ASX_DEBUG(_L("#MP# CAsxParser::GetUrl() Bad index"));
       
   364         retVal = KErrArgument;
       
   365     }
       
   366     else
       
   367     {
       
   368         aUrl.Set( (iAsxArray[aUrlIndex - 1]->url)->Des() );
       
   369     }
       
   370 
       
   371     return retVal;
       
   372 }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 //  CAsxParser::GetUrl
       
   376 //  First URL at position 1
       
   377 // -----------------------------------------------------------------------------
       
   378 EXPORT_C AsxStruct* CAsxParser::GetUrl( const TUint aUrlIndex )
       
   379 {
       
   380     ASX_DEBUG(_L("#MP# CAsxParser::GetUrl(%d)"), aUrlIndex);
       
   381 
       
   382     AsxStruct* retVal = NULL;
       
   383 
       
   384     if ( aUrlIndex  <= iAsxArray.Count() )
       
   385     {
       
   386         retVal = iAsxArray[aUrlIndex - 1];
       
   387     }
       
   388 
       
   389     return retVal;
       
   390 }
       
   391 
       
   392 
       
   393 // -----------------------------------------------------------------------------
       
   394 //  CAsxParser::GetUrlCount
       
   395 // -----------------------------------------------------------------------------
       
   396 EXPORT_C void CAsxParser::GetUrlCount( TUint &aHowManyUrls )
       
   397 {
       
   398     aHowManyUrls = iAsxArray.Count();
       
   399 
       
   400     ASX_DEBUG(_L("#MP# CAsxParser::GetUrlCount(%d)"), aHowManyUrls);
       
   401 }
       
   402 
       
   403 // -----------------------------------------------------------------------------
       
   404 //  CAsxParser::IsValid
       
   405 // -----------------------------------------------------------------------------
       
   406 EXPORT_C TInt CAsxParser::FileVersion()
       
   407 {
       
   408     ASX_DEBUG(_L("#MP# CAsxParser::FileVersion(%d)"), iVersion);
       
   409 
       
   410     return iVersion;
       
   411 }
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 // CAsxParser::HandleFileParsingL
       
   415 // -----------------------------------------------------------------------------
       
   416 //
       
   417 void CAsxParser::HandleFileParsingL( RFile& aFile )
       
   418 {
       
   419     iVersion = KErrNotFound;
       
   420 
       
   421     TInt size;
       
   422     User::LeaveIfError( aFile.Size( size ) );
       
   423 
       
   424     if ( size > KMaxAsxFileSize )
       
   425     {
       
   426         ASX_DEBUG(_L("#MP# CAsxParser::HandleFileParsingL() file size > max size"));
       
   427         User::Leave( KErrNotSupported );
       
   428     }
       
   429 
       
   430     HBufC8* urlBuf = HBufC8::NewLC( size );
       
   431     TPtr8 ptr = urlBuf->Des();
       
   432 
       
   433     //
       
   434     //  Read ASX-file to urlBuf
       
   435     //
       
   436     User::LeaveIfError( aFile.Read( ptr ) );
       
   437 
       
   438     //
       
   439     //  V2 file will start with [Reference]
       
   440     //
       
   441     _LIT8(KAsxV2Start,"[Reference]");
       
   442     TInt location = ptr.FindF( KAsxV2Start );
       
   443 
       
   444     if ( location == 0 )
       
   445     {
       
   446         //
       
   447         //  Found V2 ASX file header
       
   448         //
       
   449         ParseAsxV2HeaderL( ptr );
       
   450     }
       
   451     else
       
   452     {
       
   453         //
       
   454         //  Did not find V2 ASX file, V3 will start with <ASX
       
   455         //
       
   456         _LIT8(KAsxV3Start,"<ASX");
       
   457         TInt location = ptr.FindF( KAsxV3Start );
       
   458 
       
   459         if ( location == 0 )
       
   460         {
       
   461             ParseAsxV3HeaderL( ptr );
       
   462         }
       
   463         else
       
   464         {
       
   465             ASX_DEBUG(_L("#MP# CAsxParser::HandleFileParsingL() ASX file not V2 or V3"));
       
   466             User::Leave( KErrNotSupported );
       
   467         }
       
   468     }
       
   469     
       
   470     CleanupStack::PopAndDestroy(); // urlBuf   
       
   471 }
       
   472 
       
   473 // -----------------------------------------------------------------------------
       
   474 //  CAsxParser::PrintUrl
       
   475 //  First URL at position 1
       
   476 // -----------------------------------------------------------------------------
       
   477 EXPORT_C void CAsxParser::PrintUrl( TPtrC8& aUrl8, TPtr& aUrl )
       
   478 {
       
   479     ASX_DEBUG(_L("#MP# CAsxParser::PrintUrl()"));
       
   480 
       
   481 	if ( aUrl8.Length() )
       
   482 	{
       
   483 		CnvUtfConverter::ConvertToUnicodeFromUtf8(aUrl, aUrl8);	
       
   484 	    ASX_DEBUG(_L("#MP# CAsxParser::PrintUrl(%S)"), &aUrl);
       
   485 	}
       
   486 }
       
   487 //  EOF