diff -r 417699dc19c9 -r c7e9f1c97567 xml/legacyminidomparser/XMLParser/test/t_Smildtd.cpp --- a/xml/legacyminidomparser/XMLParser/test/t_Smildtd.cpp Thu Jul 01 15:13:40 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,549 +0,0 @@ -// Copyright (c) 2003-2009 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: -// CSMILDTD.cpp -// @file -// This file contains the definition of the SMILDTD class -// which describes the SMIL DTD and is responsible for validation -// of SMIL documents -// -// -#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS -#include "t_smildtdenum.h" -#endif -#include "t_SmilDtd.h" -#include "t_SmilData.h" -#include -#include "smilelements.h" -#include "smilattributes.h" -#include "smilgenericelements.h" -#include - -// -// Global functions // -// - - -EXPORT_C CSMILDtd* CSMILDtd::NewL() -// -// Two phase static factory function constructor -// @return Created CSMILDtd -// @leave can Leave due to OOM -// - { - CSMILDtd* self = NewLC(); - CleanupStack::Pop(); - return self; - } - -EXPORT_C CSMILDtd* CSMILDtd::NewLC() -// -// Two phase static factory function constructor -// @return Created CSMILDtd -// @leave can Leave due to OOM -// - { - CSMILDtd* self = new (ELeave) CSMILDtd(); - CleanupStack::PushL(self); - self->ConstructL(); - return self; - } - -void CSMILDtd::ConstructL() -// -// Second stage constructor -// @leave can Leave due to OOM -// - { - // nothing to do - } - - -CSMILDtd::CSMILDtd() - { - } - - -EXPORT_C CSMILDtd::~CSMILDtd() - { - } - -TBool CSMILDtd::IsValidElementL(const TDesC& aElement) const - { -// -// Checks to see if the element name passed in has been specified in the string table -// @param aElementName the element name to be checked -// @return ETrue if defined in the string table else EFalse -// @leave Leave due to OOM -// - - // Use the string table SMILElements to validate the element name - TBool validElement = EFalse; - - RStringPool pool; - CleanupClosePushL(pool); - pool.OpenL(SMILElements::Table); - - int numTableEntries = SMILElements::Table.iCount; - if(numTableEntries != 0) - { - // Using a binary search since the table is always sorted alphabetically by element. - - // Set us search indices to outer bounds of array - TInt left = 0; - TInt right = numTableEntries - 1; - TInt compareResult = 0; - TInt pos; - while (right >= left) - { - pos = (left + right) / 2; - - RStringF tableEntry = pool.StringF(pos, SMILElements::Table); - HBufC* buf = HBufC::NewLC(tableEntry.DesC().Length()); - buf->Des().Copy(tableEntry.DesC()); - - TLex string(*buf); - - TPtrC token = string.NextToken(); - compareResult = aElement.Compare(token); - if(compareResult == 0) - validElement = ETrue; - - CleanupStack::PopAndDestroy(buf); - - - if(compareResult == 0) - break; - else if (compareResult > 0) - left = pos + 1; - else - right = pos - 1; - } - - } - CleanupStack::PopAndDestroy(); // close pool - return validElement; - - } - -TInt CSMILDtd::IsValidAttributeForElementL(const TDesC& aElement, const TDesC& aAttribute, const TDesC& aAttributeValue) const - { -// -// Checks that both the Attribute Name & Attribute Value are valid using string tables stored in the document -// @param aAttributeName - name of attribute to be checked -// @param aAttributeValue - value of attribute to be checked -// @return KErrNone if attribute & value are valid, otherwise KErrXMLBadAttributeName or KErrXMLBadAttributeValue -// @leave Leave due to OOM -// - - - // To reduce the size of the element/attribute/value generic element names are used - // So for example 'img' and 'video' are both represented by the genericelement 'media' - // A table exists (SMILGenericElements) detailing these relationships - - // So first we see if there is a generic element name for this element - // If not then genericElementName will just be the element name passed in - HBufC* genericElementName = NULL; - - - RStringPool pool; - CleanupClosePushL(pool); - pool.OpenL(SMILGenericElements::Table); - - TInt numTableEntries = SMILGenericElements::Table.iCount; - if(numTableEntries != 0) - { - // Using a binary search since the table is always sorted alphabetically by element. - - // Set us search indices to outer bounds of array - TInt left = 0; - TInt right = numTableEntries - 1; - TInt pos; - while (right >= left) - { - pos = (left + right) / 2; - - RStringF elementAndGeneric = pool.StringF(pos, SMILGenericElements::Table); - - HBufC* buf = HBufC::NewLC(elementAndGeneric.DesC().Length()); - buf->Des().Copy(elementAndGeneric.DesC()); - TLex string(*buf); - - TPtrC token = string.NextToken(); - TInt compare = aElement.Compare(token); - - if(compare == 0) - { - // We've got a match so use the generic name - // This isn't pushed on the CleanupStack here as we need to be able to pop - // buf and pool whilst genericElementName is still in scope. It will be - // pushed once these aren't necessary. Because of this THERE MUST BE - // NOTHING THAT LEAVES UNTIL genericElementName IS PUT ONTO THE CLEANUPSTACK - genericElementName =(string.NextToken()).AllocL(); - } - - CleanupStack::PopAndDestroy(buf); //buf - - - if(compare == 0) - break; - else if (compare > 0) - left = pos + 1; - else - right = pos - 1; - } - } - - CleanupStack::PopAndDestroy(); // Close pool - - if(genericElementName != NULL) - { - CleanupStack::PushL(genericElementName); - } - else - { - // We didn't find a generic name so use the element name passed in - genericElementName = HBufC::NewLC(aElement.Length()); - genericElementName->Des().Copy(aElement); - } - - // Using the generic element name test to see if we have a valid attribute and value - - // assume the attribute name is invalid - TInt error = KErrXMLBadAttributeName; - - // retrieve the attributeValue string table - // this is of the form elementName attributeName attribValue1 attribValue2 ... - - CleanupClosePushL(pool); - pool.OpenL(SMILAttributes::Table); - - numTableEntries = SMILAttributes::Table.iCount; - if(numTableEntries != 0) - { - // Using a binary search since the table is always sorted alphabetically by element+attribute. - - // Set us search indices to outer bounds of array - TInt left = 0; - TInt right = numTableEntries - 1; - TInt compareResult = 0; - TInt pos; - while (right >= left) - { - pos = (left + right) / 2; - - RStringF tableEntry = pool.StringF(pos, SMILAttributes::Table); - HBufC* buf = HBufC::NewLC(tableEntry.DesC().Length()); - buf->Des().Copy(tableEntry.DesC()); - - TLex string(*buf); - - // Get the element name from the string table (the first token) - TPtrC token = string.NextToken(); - // Is this the element name we are interested in - compareResult = genericElementName->Compare(token); - if(compareResult == 0) - { - // we're looking at an entry in the string table for this element - // so test to see if it's the correct attribute too. - token.Set(string.NextToken()); - compareResult = aAttribute.Compare(token); - if(compareResult == 0) - { - // we've got the correct entry in the table (both element & attribute match) - // so now assume the error is an incorrect attribute value - error = KErrXMLBadAttributeValue; - - // get hold of the first valid attribure value - token.Set(string.NextToken()); - // if we don't have a list of attribute values then we can assume whatever we've got is valid - // so set the error to KErrNone - if (token.Length() == 0) - error = KErrNone; - else - { - // Cycle through all listed attribute values to see if we have a valid one - while (token.Length() != 0) - { - if (aAttributeValue.Compare(token) == 0) - { - // value of attribute is valid - error = KErrNone; - break; - } - else - token.Set(string.NextToken()); - - } - } - - } - - } - CleanupStack::PopAndDestroy(buf); // buf - if (compareResult == 0) // Matching item found - break; - else if (compareResult > 0) - left = pos + 1; - else - right = pos - 1; - } - - } - CleanupStack::PopAndDestroy(2); // pool, genericElementName - - return error; - } - -TBool CSMILDtd::AreValidChildElementsL(const TDesC& aParentElement, const CDesCArray& aChildElements) const -// Function to determine whether the parent/child relationship is valid in DTD -// @return ETrue if parent/child relationship is valid -// @param aParentElement the name of the parent element to be tested -// @param aChildElements an array of child element name to be tested -// @leave leave due to OOM -// - { - TBool retVal = EFalse; - - - - if(aParentElement == KSMILDTDElta) - { - retVal = CheckValidChildren(SMILDTDAChildStates,KSMILDTDAChildStateTranCount, aChildElements); - } - - else if( aParentElement == KSMILDTDEltDoc) - { - retVal = ETrue; - } - - - else if(aParentElement == KSMILDTDEltanimation || aParentElement == KSMILDTDEltaudio || aParentElement == KSMILDTDEltimg || aParentElement == KSMILDTDEltref - || aParentElement == KSMILDTDElttext || aParentElement == KSMILDTDElttextstream || aParentElement == KSMILDTDEltvideo) - { - retVal = CheckValidChildren(SMILDTDMediaChildStates, KSMILDTDMediaChildStateTranCount, aChildElements); - } - - else if(aParentElement == KSMILDTDEltbody) - { - retVal = CheckValidChildren(SMILDTDBodyChildStates, KSMILDTDBodyChildStateTranCount, aChildElements); - } - - else if(aParentElement == KSMILDTDElthead) - { - retVal = CheckValidChildren(SMILDTDHeadChildStates, KSMILDTDHeadChildStateTranCount, aChildElements); - } - - else if(aParentElement == KSMILDTDEltlayout) - { - retVal = CheckValidChildren(SMILDTDLayoutChildStates, KSMILDTDLayoutChildStateTranCount, aChildElements); - } - - else if(aParentElement == KSMILDTDEltpar || aParentElement == KSMILDTDEltseq) - { - retVal = CheckValidChildren(SMILDTDTimingChildStates, KSMILDTDTimingChildStateTranCount, aChildElements); - } - - else if(aParentElement == KSMILDTDEltsmil) - { - retVal = CheckValidChildren(SMILDTDSmilChildStates, KSMILDTDSmilChildStateTranCount, aChildElements); - } - - else if(aParentElement == KSMILDTDEltswitch) - { - retVal = CheckValidChildren(SMILDTDSwitchChildStates, KSMILDTDSwitchChildStateTranCount, aChildElements); - } - - return retVal; - } - - -TBool CSMILDtd::CheckValidChildren(const TSMILDTDChildStateType aStateTrans[],TInt aStateCount, const CDesCArray& aChildElements) const -// -// Checks child element ownership based on a Finite State Machine -// @param aFirstChild - pointer to first child element -// @param aStateTrans - Array of state transition elements. -// The elements must be ordered by tag name first and then starting state -// as this routine uses the ordering to drive an efficient search. -// @param aStateCount - the number of state transitions in the array -// @return true if the list of children matches the defined state machine -// - { - // This routine works by considering the allowed set of child elements as a Finite State - // Machine. When tracing through the list of children, each child encountered causes - // a state transition. The actual states are 'between' elements. The states are - // simply referred to by numbers, 0 is the starting state, the legal final state is - // state -1, other states are positive integers (the actual values have no significance, - // only the transitions and the start and end are of importance. - // When the list of children ends, a special 'empty tag' element is considered to be - // found. If this empty tag element causes a transition to the final state then the list - // has been successfully traversed. - // If, at any point, a child element is encountered which does not lead to a valid - // transition from the current state then the list is invalid. By considering the - // empty tag element to be on the end of the list we handle the requirements for valid - // completion. - // This routine is general - it just needs to be fed a set of state transitions for a specific - // element type. - - TBool returnValue = true; // We are successful until proved otherwise - if( aStateCount < 1 ) - { - returnValue = false; // Just check for a duff count - } - TInt fromState=KSMILDTDStartState; // Current state - the one we are looking for a transition from - TInt toState=KSMILDTDEndState; // State to which this tag leads us - initialised to avoid warning - TInt midPoint= aStateCount / 2; // Middle of the state array, used for binary search - TInt initJump = midPoint / 2; // Size of initial jump for binary search - TInt tranArrInd; // Index into the state transition array - - // Prime the search with the initial state and the tag for the first element - // We skip nodes which are not elements (e.g. text, comments or processing instructions) - - - for (TInt i = 0; i 0) - { - tranArrInd += jump; - } - jump = jump / 2; - if((compVal == 0) || (jump < KSMILDTDMinJump)) - { - keepChopping = false; - } - }// endwhile - // We have now finished binary chopping, either because we matched the tag or because - // We got to a small jump size. Now do a linear scan, up or down, to fimd a match. - - TBool up = true; // Direction of scan - tranTag.Set( aStateTrans[tranArrInd].TagName, aStateTrans[tranArrInd].TagLength); - compVal = aChildElements[i].Compare(tranTag); - if((compVal < 0) || - ((compVal == 0) && (fromState < aStateTrans[tranArrInd].FromState))) - { - up = false; - } - if( up ) - { - while((tranArrInd < aStateCount) && - ((compVal > 0) || - ((compVal == 0) && (fromState > aStateTrans[tranArrInd].FromState)))) - { - tranArrInd ++; - tranTag.Set( aStateTrans[tranArrInd].TagName, aStateTrans[tranArrInd].TagLength); - if(tranArrInd < aStateCount) - { - compVal = aChildElements[i].Compare(tranTag); - } - }// endwhile stepping up - } - else - { - while((tranArrInd >= 0) && - ((compVal < 0) || - ((compVal == 0) && (fromState < aStateTrans[tranArrInd].FromState)))) - { - tranArrInd --; - tranTag.Set( aStateTrans[tranArrInd].TagName, aStateTrans[tranArrInd].TagLength); - if(tranArrInd >= 0) - { - compVal = aChildElements[i].Compare(tranTag); - } - }// endwhile stepping down - } - // If we have a match, fine, else this is an illegal transition - if((tranArrInd >= 0) && (tranArrInd < aStateCount) && - (compVal == 0) && (fromState == aStateTrans[tranArrInd].FromState)) - { - toState = aStateTrans[tranArrInd].ToState; - } - else - { - returnValue = false; - break; - } - }//end else not reached end of list of children - - fromState = toState; - }// endfor - - if(returnValue) - { - tranArrInd = 0; - while((tranArrInd < aStateCount) && - (aStateTrans[tranArrInd].FromState != fromState) && - (aStateTrans[tranArrInd].TagLength == 0)) - { - tranArrInd++; - } - if((tranArrInd < aStateCount) && - (aStateTrans[tranArrInd].FromState == fromState) && - (aStateTrans[tranArrInd].TagLength == 0)) - { - toState = aStateTrans[tranArrInd].ToState ; // Better be the final state! - } - else - { - returnValue = false ; // No legal transition - } - } - - - return returnValue; - } - - - - -TBool CSMILDtd::CanElementHaveChildren(const TDesC& aElement) const -// -// Function to determine whether it is valid for a particular element to -// have children -// @param aElement the name of the element to be tested -// @return ETrue if it is valid for element to have children -// - { - TBool retVal = ETrue; - if(aElement == KSMILDTDEltanchor || aElement == KSMILDTDEltmeta || aElement == KSMILDTDEltroot_layout - || aElement == KSMILDTDEltregion || aElement == KSMILDTDEltarea || aElement == KSMILDTDEltmetadata - || aElement == KSMILDTDEltprefetch || aElement == KSMILDTDEltTrans) - retVal = EFalse; - - return retVal; - - }