creator/engine/src/creator_scriptparser.cpp
branchRCL_3
changeset 46 fad26422216a
parent 45 b3cee849fa46
child 49 f8280f3bfeb7
equal deleted inserted replaced
45:b3cee849fa46 46:fad26422216a
     1 /*
       
     2 * Copyright (c) 2010 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: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <f32file.h>
       
    21 #include <utf.h>
       
    22 #include <xml/documentparameters.h>
       
    23 #include "creator_scriptparser.h"
       
    24 #include "creator_scriptelementfactory.h"
       
    25 #include "creator_traces.h"
       
    26 
       
    27 using namespace Xml;
       
    28 
       
    29 CCreatorScriptParser::CCreatorScriptParser() 
       
    30 : iDefaultElement(TCreatorScriptElementInfo(TCreatorScriptElementInfo::EStatusUndefined, 0))
       
    31     {        
       
    32     }
       
    33 void CCreatorScriptParser::ConstructL(CCreatorEngine* aEngine)
       
    34     {
       
    35     LOGSTRING("Creator: CCreatorScriptParser::ConstructL");
       
    36     iEngine = aEngine;
       
    37     }
       
    38 
       
    39 CCreatorScriptParser* CCreatorScriptParser::NewL(CCreatorEngine* aEngine)
       
    40     {
       
    41     LOGSTRING("Creator: CCreatorScriptParser::NewL");
       
    42     CCreatorScriptParser* self = CCreatorScriptParser::NewLC(aEngine);    
       
    43     CleanupStack::Pop();
       
    44     return self;
       
    45     }
       
    46 CCreatorScriptParser* CCreatorScriptParser::NewLC(CCreatorEngine* aEngine)
       
    47     {
       
    48     LOGSTRING("Creator: CCreatorScriptParser::NewLC");
       
    49     CCreatorScriptParser* self = new (ELeave) CCreatorScriptParser;
       
    50     CleanupStack::PushL(self);
       
    51     self->ConstructL(aEngine);
       
    52     return self;
       
    53     }
       
    54 
       
    55 CCreatorScriptParser::~CCreatorScriptParser()
       
    56     {
       
    57     delete iParser;
       
    58     if( iElementStack.Count() > 0 )
       
    59         {
       
    60         delete iElementStack[0].iElement;        
       
    61         }
       
    62     iElementStack.Reset();
       
    63     iElementStack.Close();
       
    64     }
       
    65 
       
    66 void CCreatorScriptParser::GetTextFileMode(RFile& aFile, TInt& aFileSize) 
       
    67     { 
       
    68     LOGSTRING("Creator: CCreatorScriptParser::GetTextFileMode");
       
    69     iScriptTextFormat = EFormatANSIASCII; 
       
    70 
       
    71     // if we are working with text files, check the type first   
       
    72     TBuf8<4> BOM; 
       
    73 
       
    74     // first check for UTF-16 
       
    75     if (aFileSize >= 2 && aFile.Read(0, BOM, 2) == KErrNone) 
       
    76         { 
       
    77         if (BOM.Length()==2 && BOM[0]==0xFF && BOM[1]==0xFE) 
       
    78             { 
       
    79             iScriptTextFormat = EFormatUTF16LE; 
       
    80             aFileSize -= 2; 
       
    81             return; 
       
    82             } 
       
    83         else if (BOM.Length()==2 && BOM[0]==0xFE && BOM[1]==0xFF) 
       
    84             { 
       
    85             iScriptTextFormat = EFormatUTF16BE; 
       
    86             aFileSize -= 2; 
       
    87             return;                 
       
    88             }       
       
    89         }
       
    90         // then check for UTF-8 
       
    91     if (aFileSize >= 3 && aFile.Read(0, BOM, 3) == KErrNone) 
       
    92         { 
       
    93         if (BOM.Length()==3 && BOM[0]==0xEF && BOM[1]==0xBB && BOM[2]==0xBF) 
       
    94             { 
       
    95             iScriptTextFormat = EFormatUTF8; 
       
    96             aFileSize -= 3; 
       
    97             return; 
       
    98             } 
       
    99         }
       
   100         
       
   101     // none of those, seek back to beginning 
       
   102     TInt pos(0); 
       
   103     aFile.Seek(ESeekStart, pos); 
       
   104     }    
       
   105  
       
   106 
       
   107 
       
   108 void CCreatorScriptParser::ParseL(const TDesC& aFileName)
       
   109     {
       
   110     LOGSTRING2("Creator: CCreatorScriptParser::ParseL: %S", &aFileName);
       
   111     // Create and start XML-parser
       
   112     if( iParser == 0)
       
   113         {
       
   114         _LIT8(KXmlMimeType, "text/xml");
       
   115         iParser = CParser::NewL(KXmlMimeType, *this);        
       
   116         }
       
   117 
       
   118     RFs filesession;
       
   119     CleanupClosePushL(filesession);
       
   120     User::LeaveIfError( filesession.Connect() );
       
   121     Xml::ParseL(*iParser, filesession, aFileName);
       
   122     
       
   123     CleanupStack::PopAndDestroy(&filesession); // filesession    
       
   124     }
       
   125 
       
   126 void CCreatorScriptParser::ParseL(RFile& aFile)
       
   127     {
       
   128     LOGSTRING("Creator: CCreatorScriptParser::ParseL");
       
   129     TInt filesize = 0;
       
   130     aFile.Size(filesize);
       
   131     GetTextFileMode(aFile, filesize);
       
   132     // Create and start XML-parser    
       
   133     if( iParser == 0)
       
   134         {
       
   135         _LIT8(KXmlMimeType, "text/xml");
       
   136         iParser = CParser::NewL(KXmlMimeType, *this);        
       
   137         }
       
   138     Xml::ParseL(*iParser, aFile);
       
   139     }
       
   140 
       
   141 void CCreatorScriptParser::OnStartDocumentL(const Xml::RDocumentParameters& aDocParam, TInt aErrorCode)
       
   142     {
       
   143     LOGSTRING2("Creator: CCreatorScriptParser::OnStartDocumentL (Error code: %d)", aErrorCode);
       
   144     User::LeaveIfError(aErrorCode);    
       
   145     const TDesC8& charSet = aDocParam.CharacterSetName().DesC();
       
   146     }
       
   147 
       
   148 void CCreatorScriptParser::OnEndDocumentL(TInt aErrorCode)
       
   149     {
       
   150     LOGSTRING2("Creator: CCreatorScriptParser::OnEndDocumentL (Error code: %d)", aErrorCode);
       
   151     User::LeaveIfError(aErrorCode);
       
   152     iEngine->SortCommands();
       
   153     }
       
   154 
       
   155 void CCreatorScriptParser::OnStartPrefixMappingL(   const RString& /*aPrefix*/, 
       
   156                                                     const RString& /*aUri*/, 
       
   157                                                     TInt aErrorCode)
       
   158     {
       
   159     LOGSTRING2("Creator: CCreatorScriptParser::OnStartPrefixMappingL (Error code: %d)", aErrorCode);
       
   160     User::LeaveIfError(aErrorCode);
       
   161     }
       
   162 
       
   163 void CCreatorScriptParser::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt aErrorCode)
       
   164     {
       
   165     LOGSTRING2("Creator: CCreatorScriptParser::OnEndPrefixMappingL (Error code: %d)", aErrorCode);
       
   166     User::LeaveIfError(aErrorCode);
       
   167     }
       
   168 void CCreatorScriptParser::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt aErrorCode)
       
   169     {
       
   170     LOGSTRING2("Creator: CCreatorScriptParser::OnIgnorableWhiteSpaceL (Error code: %d)", aErrorCode);
       
   171     User::LeaveIfError(aErrorCode);
       
   172     }
       
   173 void CCreatorScriptParser::OnSkippedEntityL(const RString& /*aName*/, TInt aErrorCode)
       
   174     {
       
   175     LOGSTRING2("Creator: CCreatorScriptParser::OnSkippedEntityL (Error code: %d)", aErrorCode);
       
   176     User::LeaveIfError(aErrorCode);
       
   177     }
       
   178 void CCreatorScriptParser::OnProcessingInstructionL(  const TDesC8& /*aTarget*/, 
       
   179                                     const TDesC8& /*aData*/, 
       
   180                                     TInt aErrorCode)
       
   181     {
       
   182     LOGSTRING2("Creator: CCreatorScriptParser::OnProcessingInstructionL (Error code: %d)", aErrorCode);
       
   183     User::LeaveIfError(aErrorCode);
       
   184     }
       
   185 void CCreatorScriptParser::OnError(TInt aErrorCode)
       
   186     {
       
   187     LOGSTRING2("Creator: CCreatorScriptParser::OnError: %d", aErrorCode);
       
   188     
       
   189     iLastError = aErrorCode;
       
   190     
       
   191     // Delete all elements from the stack:
       
   192     while(iElementStack.Count() > 0 )
       
   193         {
       
   194         TCreatorScriptElementInfo previousElem = LastElementInfo();    
       
   195         delete previousElem.iElement;
       
   196         previousElem.iElement = 0;
       
   197         iElementStack.Remove(iElementStack.Count()-1);
       
   198         }
       
   199     }
       
   200 TAny* CCreatorScriptParser::GetExtendedInterface(const TInt32 aUid)
       
   201     {
       
   202     LOGSTRING2("Creator: CCreatorScriptParser::GetExtendedInterface (UID: %d)", aUid);
       
   203     return this;
       
   204     }
       
   205 
       
   206 const TCreatorScriptElementInfo& CCreatorScriptParser::LastElementInfo() const
       
   207 {
       
   208     LOGSTRING("Creator: CCreatorScriptParser::LastElementInfo");
       
   209     if(iElementStack.Count() > 0)
       
   210         {
       
   211         return iElementStack[iElementStack.Count()-1];
       
   212         }
       
   213     return iDefaultElement;
       
   214 }
       
   215 
       
   216 /**
       
   217  * Create an element and add attributes to it.
       
   218  */
       
   219 void CCreatorScriptParser::OnStartElementL(  const RTagInfo& aElement,
       
   220                                             const RAttributeArray& aAttributes,
       
   221                                             TInt aErrorCode)
       
   222     {
       
   223     LOGSTRING2("Creator: CCreatorScriptParser::OnStartElementL (Error code: %d)", aErrorCode);
       
   224     User::LeaveIfError(aErrorCode);
       
   225     const TDesC8& elementName8 = aElement.LocalName().DesC();        
       
   226     HBufC* elementName16 = Convert8BitTo16BitLC(elementName8);
       
   227         
       
   228     const TCreatorScriptElementInfo& context = LastElementInfo();
       
   229     
       
   230     CCreatorScriptElement* element = 0;
       
   231     if( context.iElement )
       
   232         {
       
   233         HBufC* fullContext = HBufC::NewL(
       
   234                 context.iElement->Context().Length() + 
       
   235                 context.iElement->Name().Length() + 
       
   236                 2);        
       
   237         CleanupStack::PushL(fullContext);
       
   238         if(context.iElement->Context() != KNullDesC && 
       
   239            context.iElement->Context().Length() > 0 )
       
   240             {
       
   241             fullContext->Des().Copy(context.iElement->Context());
       
   242             _LIT(KContextSeparator, "::");
       
   243             fullContext->Des().Append(TPtrC(KContextSeparator));
       
   244             }
       
   245         const TDesC& parentName = context.iElement->Name();
       
   246         if(parentName.Length() > 0 )
       
   247             {            
       
   248             fullContext->Des().Append(parentName);
       
   249             }
       
   250         element = TCreatorScriptElementFactory::CreateElementL( iEngine,
       
   251                                                                 elementName16->Des(), 
       
   252                                                                 fullContext->Des());
       
   253         CleanupStack::PopAndDestroy(fullContext); // fullContext        
       
   254         }
       
   255     else
       
   256         {
       
   257         element = TCreatorScriptElementFactory::CreateElementL(iEngine, elementName16->Des());        
       
   258         }
       
   259         
       
   260     CleanupStack::PopAndDestroy(elementName16);
       
   261     CleanupStack::PushL(element);
       
   262     
       
   263     if( element == 0 )
       
   264         {
       
   265         // Add NULL pointer to stack. Otherwise the stack would go out of sync. in ::OnEndElement().
       
   266         TCreatorScriptElementInfo info(TCreatorScriptElementInfo::EStatusParsing, element);
       
   267         iElementStack.AppendL(info);   
       
   268         CleanupStack::Pop(element);
       
   269         return;        
       
   270         }
       
   271         
       
   272     // Add attributes to the element:
       
   273     TInt attrCount = aAttributes.Count();
       
   274     for(TInt i = 0; i < attrCount; ++i)
       
   275         {
       
   276         const RAttribute& attribute = aAttributes[i];
       
   277         const RTagInfo& nameInfo = attribute.Attribute();
       
   278         const TDesC8& attrName8 = nameInfo.LocalName().DesC();
       
   279         const TDesC8& value8 = attribute.Value().DesC();
       
   280         // Convert data to 16 bit:
       
   281         HBufC* attrName16 = Convert8BitTo16BitLC(attrName8);
       
   282         HBufC* value16 = Convert8BitTo16BitLC(value8);
       
   283         CCreatorScriptAttribute* scriptAttr = CCreatorScriptAttribute::NewLC(attrName16->Des(), value16->Des());
       
   284         element->AddAttributeL(scriptAttr);
       
   285         CleanupStack::Pop(scriptAttr);
       
   286         CleanupStack::PopAndDestroy(value16);
       
   287         CleanupStack::PopAndDestroy(attrName16);
       
   288         }
       
   289     
       
   290     // Save element to the stack:
       
   291     TCreatorScriptElementInfo info(TCreatorScriptElementInfo::EStatusParsing, element);
       
   292     iElementStack.AppendL(info);
       
   293     CleanupStack::Pop(element);
       
   294     }
       
   295 
       
   296 /**
       
   297  * Executes the command if needed. Also caches the element for future use, if needed.
       
   298  */
       
   299 void CCreatorScriptParser::OnEndElementL(const RTagInfo& /*aElement*/, TInt aErrorCode)
       
   300     {
       
   301     LOGSTRING2("Creator: CCreatorScriptParser::OnEndElementL (Error code: %d)", aErrorCode);
       
   302     User::LeaveIfError(aErrorCode);
       
   303      
       
   304     if( iElementStack.Count() == 0 )
       
   305         {
       
   306         return;
       
   307         }
       
   308     // Get element from the stack:    
       
   309     TCreatorScriptElementInfo elementInfo = LastElementInfo();
       
   310     
       
   311     if( elementInfo.iElement == 0 )
       
   312         {
       
   313         // Remove element from the stack:        
       
   314         iElementStack.Remove(iElementStack.Count()-1);
       
   315         return;
       
   316         }
       
   317         
       
   318     // Execute the command if this is a command element:
       
   319     if( elementInfo.iElement->IsCommandElement() )
       
   320         {
       
   321         elementInfo.iElement->ExecuteCommandL();
       
   322         }
       
   323     
       
   324     // Remove element from the stack:
       
   325     iElementStack.Remove(iElementStack.Count()-1);
       
   326     
       
   327     // Get the previous element from the stack:
       
   328     if( iElementStack.Count() > 0 )
       
   329         {
       
   330         TCreatorScriptElementInfo previousElem = LastElementInfo();
       
   331         
       
   332         if( previousElem.iElement->IsRoot() )
       
   333             {
       
   334             // This element is not a sub-element (except of the root element, of course).        
       
   335             if( elementInfo.iElement->IsCacheNeeded() )
       
   336                 {
       
   337                 // Add element to the cache, since it will be needed in future.            
       
   338                 elementInfo.iElement->AddToCacheL();
       
   339                 }
       
   340             //else
       
   341             //    {
       
   342                 // Not needed anymore, so element can be deleted:
       
   343                 delete elementInfo.iElement;
       
   344                 elementInfo.iElement = 0;
       
   345            //     }
       
   346             }
       
   347         else
       
   348             {
       
   349             // There is a parent element (other than root), so we add this element
       
   350             // as a sub-element fot it.
       
   351             previousElem.iElement->AddSubElementL(elementInfo.iElement);
       
   352             }
       
   353         }
       
   354     else
       
   355         {
       
   356         // Delete root element, which will delete recursively all sub-elements:
       
   357         delete elementInfo.iElement;
       
   358         elementInfo.iElement = 0;
       
   359         }
       
   360     }
       
   361 
       
   362 /**
       
   363  * Add content to element.
       
   364  */
       
   365 void CCreatorScriptParser::OnContentL(const TDesC8& aBytes, TInt aErrorCode)
       
   366     {
       
   367     LOGSTRING2("Creator: CCreatorScriptParser::OnContentL (Error code: %d)", aErrorCode);
       
   368     User::LeaveIfError(aErrorCode);
       
   369     if( iElementStack.Count() > 0 )
       
   370         {
       
   371         HBufC* contentData = Convert8BitTo16BitLC(aBytes);
       
   372         TCreatorScriptElementInfo elementInfo = iElementStack[iElementStack.Count()-1];
       
   373         if( elementInfo.iElement )
       
   374             {
       
   375             elementInfo.iElement->AppendContentL(*contentData);
       
   376             }
       
   377         CleanupStack::PopAndDestroy(contentData);
       
   378         }
       
   379     }
       
   380 
       
   381 HBufC16* CCreatorScriptParser::Convert8BitTo16BitLC(const TDesC8& aInput) 
       
   382     {     
       
   383     LOGSTRING("Creator: CCreatorScriptParser::Convert8BitTo16BitLC");
       
   384     HBufC16* output = NULL;
       
   385     
       
   386     output = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aInput);
       
   387     
       
   388     CleanupStack::PushL(output);
       
   389     return output;          
       
   390     } 
       
   391 
       
   392 TInt CCreatorScriptParser::GetError() const 
       
   393 {
       
   394     return iLastError;
       
   395 }