diff -r 48060abbbeaf -r b3cee849fa46 creator/engine/src/creator_scriptparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/creator/engine/src/creator_scriptparser.cpp Tue Aug 31 15:15:20 2010 +0300 @@ -0,0 +1,395 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include +#include "creator_scriptparser.h" +#include "creator_scriptelementfactory.h" +#include "creator_traces.h" + +using namespace Xml; + +CCreatorScriptParser::CCreatorScriptParser() +: iDefaultElement(TCreatorScriptElementInfo(TCreatorScriptElementInfo::EStatusUndefined, 0)) + { + } +void CCreatorScriptParser::ConstructL(CCreatorEngine* aEngine) + { + LOGSTRING("Creator: CCreatorScriptParser::ConstructL"); + iEngine = aEngine; + } + +CCreatorScriptParser* CCreatorScriptParser::NewL(CCreatorEngine* aEngine) + { + LOGSTRING("Creator: CCreatorScriptParser::NewL"); + CCreatorScriptParser* self = CCreatorScriptParser::NewLC(aEngine); + CleanupStack::Pop(); + return self; + } +CCreatorScriptParser* CCreatorScriptParser::NewLC(CCreatorEngine* aEngine) + { + LOGSTRING("Creator: CCreatorScriptParser::NewLC"); + CCreatorScriptParser* self = new (ELeave) CCreatorScriptParser; + CleanupStack::PushL(self); + self->ConstructL(aEngine); + return self; + } + +CCreatorScriptParser::~CCreatorScriptParser() + { + delete iParser; + if( iElementStack.Count() > 0 ) + { + delete iElementStack[0].iElement; + } + iElementStack.Reset(); + iElementStack.Close(); + } + +void CCreatorScriptParser::GetTextFileMode(RFile& aFile, TInt& aFileSize) + { + LOGSTRING("Creator: CCreatorScriptParser::GetTextFileMode"); + iScriptTextFormat = EFormatANSIASCII; + + // if we are working with text files, check the type first + TBuf8<4> BOM; + + // first check for UTF-16 + if (aFileSize >= 2 && aFile.Read(0, BOM, 2) == KErrNone) + { + if (BOM.Length()==2 && BOM[0]==0xFF && BOM[1]==0xFE) + { + iScriptTextFormat = EFormatUTF16LE; + aFileSize -= 2; + return; + } + else if (BOM.Length()==2 && BOM[0]==0xFE && BOM[1]==0xFF) + { + iScriptTextFormat = EFormatUTF16BE; + aFileSize -= 2; + return; + } + } + // then check for UTF-8 + if (aFileSize >= 3 && aFile.Read(0, BOM, 3) == KErrNone) + { + if (BOM.Length()==3 && BOM[0]==0xEF && BOM[1]==0xBB && BOM[2]==0xBF) + { + iScriptTextFormat = EFormatUTF8; + aFileSize -= 3; + return; + } + } + + // none of those, seek back to beginning + TInt pos(0); + aFile.Seek(ESeekStart, pos); + } + + + +void CCreatorScriptParser::ParseL(const TDesC& aFileName) + { + LOGSTRING2("Creator: CCreatorScriptParser::ParseL: %S", &aFileName); + // Create and start XML-parser + if( iParser == 0) + { + _LIT8(KXmlMimeType, "text/xml"); + iParser = CParser::NewL(KXmlMimeType, *this); + } + + RFs filesession; + CleanupClosePushL(filesession); + User::LeaveIfError( filesession.Connect() ); + Xml::ParseL(*iParser, filesession, aFileName); + + CleanupStack::PopAndDestroy(&filesession); // filesession + } + +void CCreatorScriptParser::ParseL(RFile& aFile) + { + LOGSTRING("Creator: CCreatorScriptParser::ParseL"); + TInt filesize = 0; + aFile.Size(filesize); + GetTextFileMode(aFile, filesize); + // Create and start XML-parser + if( iParser == 0) + { + _LIT8(KXmlMimeType, "text/xml"); + iParser = CParser::NewL(KXmlMimeType, *this); + } + Xml::ParseL(*iParser, aFile); + } + +void CCreatorScriptParser::OnStartDocumentL(const Xml::RDocumentParameters& aDocParam, TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnStartDocumentL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + const TDesC8& charSet = aDocParam.CharacterSetName().DesC(); + } + +void CCreatorScriptParser::OnEndDocumentL(TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnEndDocumentL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + iEngine->SortCommands(); + } + +void CCreatorScriptParser::OnStartPrefixMappingL( const RString& /*aPrefix*/, + const RString& /*aUri*/, + TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnStartPrefixMappingL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + } + +void CCreatorScriptParser::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnEndPrefixMappingL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + } +void CCreatorScriptParser::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnIgnorableWhiteSpaceL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + } +void CCreatorScriptParser::OnSkippedEntityL(const RString& /*aName*/, TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnSkippedEntityL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + } +void CCreatorScriptParser::OnProcessingInstructionL( const TDesC8& /*aTarget*/, + const TDesC8& /*aData*/, + TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnProcessingInstructionL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + } +void CCreatorScriptParser::OnError(TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnError: %d", aErrorCode); + + iLastError = aErrorCode; + + // Delete all elements from the stack: + while(iElementStack.Count() > 0 ) + { + TCreatorScriptElementInfo previousElem = LastElementInfo(); + delete previousElem.iElement; + previousElem.iElement = 0; + iElementStack.Remove(iElementStack.Count()-1); + } + } +TAny* CCreatorScriptParser::GetExtendedInterface(const TInt32 aUid) + { + LOGSTRING2("Creator: CCreatorScriptParser::GetExtendedInterface (UID: %d)", aUid); + return this; + } + +const TCreatorScriptElementInfo& CCreatorScriptParser::LastElementInfo() const +{ + LOGSTRING("Creator: CCreatorScriptParser::LastElementInfo"); + if(iElementStack.Count() > 0) + { + return iElementStack[iElementStack.Count()-1]; + } + return iDefaultElement; +} + +/** + * Create an element and add attributes to it. + */ +void CCreatorScriptParser::OnStartElementL( const RTagInfo& aElement, + const RAttributeArray& aAttributes, + TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnStartElementL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + const TDesC8& elementName8 = aElement.LocalName().DesC(); + HBufC* elementName16 = Convert8BitTo16BitLC(elementName8); + + const TCreatorScriptElementInfo& context = LastElementInfo(); + + CCreatorScriptElement* element = 0; + if( context.iElement ) + { + HBufC* fullContext = HBufC::NewL( + context.iElement->Context().Length() + + context.iElement->Name().Length() + + 2); + CleanupStack::PushL(fullContext); + if(context.iElement->Context() != KNullDesC && + context.iElement->Context().Length() > 0 ) + { + fullContext->Des().Copy(context.iElement->Context()); + _LIT(KContextSeparator, "::"); + fullContext->Des().Append(TPtrC(KContextSeparator)); + } + const TDesC& parentName = context.iElement->Name(); + if(parentName.Length() > 0 ) + { + fullContext->Des().Append(parentName); + } + element = TCreatorScriptElementFactory::CreateElementL( iEngine, + elementName16->Des(), + fullContext->Des()); + CleanupStack::PopAndDestroy(fullContext); // fullContext + } + else + { + element = TCreatorScriptElementFactory::CreateElementL(iEngine, elementName16->Des()); + } + + CleanupStack::PopAndDestroy(elementName16); + CleanupStack::PushL(element); + + if( element == 0 ) + { + // Add NULL pointer to stack. Otherwise the stack would go out of sync. in ::OnEndElement(). + TCreatorScriptElementInfo info(TCreatorScriptElementInfo::EStatusParsing, element); + iElementStack.AppendL(info); + CleanupStack::Pop(element); + return; + } + + // Add attributes to the element: + TInt attrCount = aAttributes.Count(); + for(TInt i = 0; i < attrCount; ++i) + { + const RAttribute& attribute = aAttributes[i]; + const RTagInfo& nameInfo = attribute.Attribute(); + const TDesC8& attrName8 = nameInfo.LocalName().DesC(); + const TDesC8& value8 = attribute.Value().DesC(); + // Convert data to 16 bit: + HBufC* attrName16 = Convert8BitTo16BitLC(attrName8); + HBufC* value16 = Convert8BitTo16BitLC(value8); + CCreatorScriptAttribute* scriptAttr = CCreatorScriptAttribute::NewLC(attrName16->Des(), value16->Des()); + element->AddAttributeL(scriptAttr); + CleanupStack::Pop(scriptAttr); + CleanupStack::PopAndDestroy(value16); + CleanupStack::PopAndDestroy(attrName16); + } + + // Save element to the stack: + TCreatorScriptElementInfo info(TCreatorScriptElementInfo::EStatusParsing, element); + iElementStack.AppendL(info); + CleanupStack::Pop(element); + } + +/** + * Executes the command if needed. Also caches the element for future use, if needed. + */ +void CCreatorScriptParser::OnEndElementL(const RTagInfo& /*aElement*/, TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnEndElementL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + + if( iElementStack.Count() == 0 ) + { + return; + } + // Get element from the stack: + TCreatorScriptElementInfo elementInfo = LastElementInfo(); + + if( elementInfo.iElement == 0 ) + { + // Remove element from the stack: + iElementStack.Remove(iElementStack.Count()-1); + return; + } + + // Execute the command if this is a command element: + if( elementInfo.iElement->IsCommandElement() ) + { + elementInfo.iElement->ExecuteCommandL(); + } + + // Remove element from the stack: + iElementStack.Remove(iElementStack.Count()-1); + + // Get the previous element from the stack: + if( iElementStack.Count() > 0 ) + { + TCreatorScriptElementInfo previousElem = LastElementInfo(); + + if( previousElem.iElement->IsRoot() ) + { + // This element is not a sub-element (except of the root element, of course). + if( elementInfo.iElement->IsCacheNeeded() ) + { + // Add element to the cache, since it will be needed in future. + elementInfo.iElement->AddToCacheL(); + } + //else + // { + // Not needed anymore, so element can be deleted: + delete elementInfo.iElement; + elementInfo.iElement = 0; + // } + } + else + { + // There is a parent element (other than root), so we add this element + // as a sub-element fot it. + previousElem.iElement->AddSubElementL(elementInfo.iElement); + } + } + else + { + // Delete root element, which will delete recursively all sub-elements: + delete elementInfo.iElement; + elementInfo.iElement = 0; + } + } + +/** + * Add content to element. + */ +void CCreatorScriptParser::OnContentL(const TDesC8& aBytes, TInt aErrorCode) + { + LOGSTRING2("Creator: CCreatorScriptParser::OnContentL (Error code: %d)", aErrorCode); + User::LeaveIfError(aErrorCode); + if( iElementStack.Count() > 0 ) + { + HBufC* contentData = Convert8BitTo16BitLC(aBytes); + TCreatorScriptElementInfo elementInfo = iElementStack[iElementStack.Count()-1]; + if( elementInfo.iElement ) + { + elementInfo.iElement->AppendContentL(*contentData); + } + CleanupStack::PopAndDestroy(contentData); + } + } + +HBufC16* CCreatorScriptParser::Convert8BitTo16BitLC(const TDesC8& aInput) + { + LOGSTRING("Creator: CCreatorScriptParser::Convert8BitTo16BitLC"); + HBufC16* output = NULL; + + output = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aInput); + + CleanupStack::PushL(output); + return output; + } + +TInt CCreatorScriptParser::GetError() const +{ + return iLastError; +}