--- 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 <stringpool.h>
-#include "smilelements.h"
-#include "smilattributes.h"
-#include "smilgenericelements.h"
-#include <gmxmlconstants.h>
-
-//
-// 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<aChildElements.Count(); i++)
- {
- // Check for the 'empty tag'. We could take a local copy but that would
- // not be most efficient so we have slightly more complex code.
-
- {
- // Given a current state and tag, find a valid transition.
- // Use a binary search - the array is sorted on tag name first and then
- // from state. We binary chop to a suitable level and then do a linear
- // search until we hit pay-dirt or find an element which proves. We
- // only bother to binary search based on the tag name.
- // This is a home baked binary chop and could potentially be made more elegant.
-
- tranArrInd = midPoint;
- TInt jump = initJump;
- TBool keepChopping = true;
- TInt compVal;
- TPtrC tranTag;
- while(keepChopping)
- {
- tranTag.Set( aStateTrans[tranArrInd].TagName, aStateTrans[tranArrInd].TagLength);
-
- compVal = aChildElements[i].Compare(tranTag);
- if(compVal < 0)
- {
- tranArrInd -= jump;
- }
- else if(compVal > 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;
-
- }