--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgutils/unidatautils/unidatamodel/src/ConformanceChecker.cpp Mon May 03 12:29:07 2010 +0300
@@ -0,0 +1,658 @@
+/*
+* Copyright (c) 2003 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 FILES
+#include "ConformanceChecker.h"
+
+#include <gmxmldocument.h>
+#include <gmxmlelement.h>
+
+#include "smilliterals.h"
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CConformanceChecker::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C
+CConformanceChecker* CConformanceChecker::NewL()
+ {
+ CConformanceChecker* self = new( ELeave ) CConformanceChecker;
+ return self;
+ }
+
+
+// Destructor
+CConformanceChecker::~CConformanceChecker()
+ {
+ }
+
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::Check(CMDXMLDocument* aXmldoc)
+//
+// Checks if the DOM tree's content is legacy content or not.
+// ----------------------------------------------------------
+//
+
+TBool CConformanceChecker::Check(CMDXMLDocument* aXmldoc, TMmsSmilVersion aVersion, TInt aFlags)
+ {
+ //Initializing the flags according to the CF document version
+ switch ( aVersion )
+ {
+ case EMmsSmil_v2_0:
+ iFlags = 0;
+ break;
+ case EMmsSmil_v3_0: //Not implemented yet
+ return EFalse;
+ default:
+ iFlags = 0;
+ }
+ //Combine the implicit flags with the explicitly specified flags
+ iFlags=iFlags | aFlags;
+
+ if (!aXmldoc) return EFalse;
+
+ CMDXMLElement* root = aXmldoc->DocumentElement();
+ if (!root) return EFalse;
+
+ CMDXMLNode* smil = NULL;
+ CMDXMLNode* head = NULL;
+ CMDXMLNode* body = NULL;
+
+ CMDXMLNode* node = root->FirstChild();
+ while (node && node->NodeName() != KSmilTag)
+ {
+ node=node->NextSibling();
+ }
+
+ if ( node ) smil = node;
+ else return EFalse;
+
+ node = smil->FirstChild();
+ while (node && node->NodeType() != CMDXMLNode::EElementNode)
+ {
+ node = node->NextSibling();
+ }
+
+ if (node && node->NodeName() == KHeadTag)
+ {
+ head = node;
+ if (!CheckHeadStructure(head))
+ return EFalse;
+ //Going forward in the DOM to find next element
+ node = head->NextSibling();
+ while (node && node->NodeType() != CMDXMLNode::EElementNode)
+ {
+ node = node->NextSibling();
+ }
+ }
+ if (node && node->NodeName() == KBodyTag)
+ {
+ body = node;
+ if (!CheckBodyStructure(body))
+ return EFalse;
+ }
+ else if ( node ) return EFalse; //there is some other element (not head or body in the smil element)
+ //Checking the head content
+ if ( head )
+ {
+ node = head->FirstChild();
+ }
+ else
+ {
+ node = NULL;
+ }
+
+ while (node && node->NodeName() != KLayoutTag)
+ {
+ node = node->NextSibling();
+ }
+ //Checking the content of the layout
+ if (!CheckLayoutContent(node))
+ return EFalse;
+ //Checking the body content
+ if (!CheckBodyContent(body))
+ return EFalse;
+
+ return ETrue;
+ } //End of Check()
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckHeadStructure(CMDXMLNode* aHead)
+//
+// Checks the structure of the head element: allowed to contain only layout and meta element
+// ----------------------------------------------------------
+//
+
+TBool CConformanceChecker::CheckHeadStructure(CMDXMLNode* aHead)
+ {
+ //Checking that the head has only layout and meta element
+ if (!aHead)
+ {
+ return ETrue;
+ }
+ CMDXMLNode* node = aHead->FirstChild();
+ while (node)
+ {
+ if (node->NodeType() == CMDXMLNode::EElementNode
+ && node->NodeName() != KLayoutTag
+ && node->NodeName() != KMetaTag)
+ {
+ return EFalse;
+ }
+ else
+ {
+ node = node->NextSibling();
+ }
+ }
+ return ETrue;
+ }
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckBodyStructure(CMDXMLNode* aBody)
+//
+// Checks the structure of the body element: allowed to contain only par elements
+// (one including seq element right after the body is allowed)
+// ----------------------------------------------------------
+//
+TBool CConformanceChecker::CheckBodyStructure(CMDXMLNode* aBody)
+ {
+ //Checking that the body has only par elements
+ if (!aBody)
+ {
+ return ETrue;
+ }
+ CMDXMLNode* node = aBody->FirstChild();
+ while (node && node->NodeType() != CMDXMLNode::EElementNode)
+ {
+ node = node->NextSibling();
+ }
+
+ //One seq element right after the body is allowed if EAllowSeqTag is set
+ if ((iFlags & EAllowSeqTag)!=0 && node && node->NodeName() == KSeqTag)
+ {
+ if (node->NextSibling())
+ {
+ return EFalse;
+ }
+ else
+ {
+ node = node->FirstChild();
+ }
+ }
+ while (node)
+ {
+ if (node->NodeType() == CMDXMLNode::EElementNode && node->NodeName() != KParTag)
+ {
+ return EFalse;
+ }
+ else
+ {
+ node = node->NextSibling();
+ }
+ }
+ return ETrue;
+ }
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckLayoutContent(CMDXMLNode* aLayout)
+//
+// Checks the content of the layout element
+// - root-layout and max. 2 region elements are allowed
+// - checks the width/height values for root-layout (pixel is allowed)
+// - checks the width/height/top/left values for region
+// if EAllowMixedRegionDimensions is not set no mixed pixel/percent allowed
+// ----------------------------------------------------------
+//
+
+TBool CConformanceChecker::CheckLayoutContent(CMDXMLNode* aLayout)
+ {
+ TInt rl_nr = 0;
+ TInt r_nr = 0;
+ if (!aLayout)
+ {
+ return ETrue;
+ }
+ CMDXMLNode* node = aLayout->FirstChild();
+ TBool foundImage = EFalse;
+ TBool foundText = EFalse;
+ while (node)
+ {
+ if (node->NodeType() == CMDXMLNode::EElementNode)
+ {
+ if (node->NodeName() == KRootLayoutTag)
+ {
+ if (++rl_nr > 1)
+ return EFalse;
+ //Check the attributes
+ CMDXMLElement* elem = static_cast<CMDXMLElement*>(node);
+ TInt n = elem->NumAttributes();
+ for (TInt i = 0; i < n; ++i)
+ {
+ TPtrC name, value;
+ elem->AttributeDetails(i,name,value);
+ if ( (iFlags & EAllowAllAttributes) == 0 &&
+ name != KWidthAttr && name != KHeightAttr )
+ {
+ return EFalse;
+ }
+ if (name == KWidthAttr || name == KHeightAttr)
+ {
+ TBool pixel = EFalse; // WB!
+ TBool percent = EFalse;
+ if (!CheckMixedRegionAttribute(value,percent,pixel))
+ {
+ return EFalse;
+ }
+ }
+ }
+ }
+ else if (node->NodeName() == KRegionTag)
+ {
+ if (++r_nr > 2)
+ {
+ return EFalse;
+ }
+ //Check the attributes
+ TBool foundPixel = EFalse;
+ TBool foundPercent = EFalse;
+
+ CMDXMLElement* elem = static_cast<CMDXMLElement*>(node);
+ TInt n = elem->NumAttributes();
+ for (TInt i = 0; i < n; ++i)
+ {
+ TPtrC name, value;
+ elem->AttributeDetails(i,name,value);
+
+ if ((iFlags & EAllowAllAttributes) == 0 && name != KIdAttr
+ && name != KWidthAttr && name != KHeightAttr
+ && name != KFitAttr && name != KLeftAttr && name != KTopAttr)
+ {
+ return EFalse;
+ }
+ if ((iFlags & EAllowMixedRegionDimensions)==0 &&
+ (name == KWidthAttr || name == KHeightAttr
+ || name == KTopAttr || name == KLeftAttr)
+ && !CheckMixedRegionAttribute(value,foundPercent,foundPixel))
+ {
+ return EFalse;
+ }
+ if ((iFlags & EAllowAnyRegionNames)==0 && name == KIdAttr
+ && !CheckRegionNames(value,foundImage,foundText))
+ {
+ return EFalse;
+ }
+
+ }//for
+ }
+ else
+ {
+ return EFalse;
+ }
+
+ }
+ node = node->NextSibling();
+ }//while
+ return ETrue;
+ }
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckMixedRegionAttribute
+// Checks if the given value is ending with percent or pixel
+// and if this is conforming to the values of aPixel, aPercent.
+// Returns true - if the value is not mixed
+// false - if mixed
+// ----------------------------------------------------------
+//
+TBool CConformanceChecker::CheckMixedRegionAttribute(TDesC& aValue,
+ TBool& aPercent, TBool& aPixel) const
+ {
+ TInt valueLength = aValue.Length();
+ TInt j = 0;
+ TBool success = ETrue;
+ while (j < valueLength && static_cast<TChar>(aValue[j]).IsDigit())
+ {
+ j++;
+ }
+ HBufC* ending = aValue.Right(valueLength-j).Alloc();
+ if (!ending)
+ {
+ success = EFalse;
+ }
+ else
+ {
+ TPtr endingPtr = ending -> Des();
+ endingPtr.LowerCase();
+ endingPtr.TrimRight();
+ if (endingPtr==KPercent)
+ {
+ aPercent = ETrue;
+ if (aPixel)
+ {
+ success = EFalse;
+ }
+ }
+ else if (endingPtr==KNullDesC || endingPtr==KPx)
+ {
+ aPixel = ETrue;
+ if (aPercent)
+ {
+ success = EFalse;
+ }
+ }
+ else
+ success = EFalse; //Cannot be other then pixel or percent
+ }
+ delete ending;
+ return success;
+ }
+
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckRegionNames
+// Checks if the given value is exactly "Image" or "Text" and if it
+// is duplicated (checking the transmitted boolean parameters).
+// Returns true - if the value is "Image" or "Text" and it's not duplicated
+// false - otherwise
+// ----------------------------------------------------------
+//
+TBool CConformanceChecker::CheckRegionNames(TDesC& aValue,
+ TBool& aFoundImage, TBool& aFoundText) const
+{
+ if (aValue == KImage)
+ {
+ if (aFoundImage)
+ {
+ return EFalse;
+ }
+ else
+ {
+ aFoundImage = ETrue;
+ }
+ }
+ else if (aValue == KText)
+ {
+ if (aFoundText)
+ {
+ return EFalse;
+ }
+ else
+ {
+ aFoundText = ETrue;
+ }
+ }
+ else
+ {
+ return EFalse;
+ }
+ return ETrue;
+}
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckBodyContent(CMDXMLNode* aBody)
+//
+// Checks the content of the body element
+// ----------------------------------------------------------
+//
+TBool CConformanceChecker::CheckBodyContent(CMDXMLNode* aBody)
+ {
+ if (!aBody)
+ {
+ return ETrue;
+ }
+ CMDXMLNode* node = aBody->FirstChild();
+ //One seq element right after the body is allowed if EAllowSeqTag is set
+ if ((iFlags & EAllowSeqTag)!=0 && node && node->NodeName() == KSeqTag)
+ {
+ node = node->FirstChild();
+ }
+ while (node)
+ {
+ if (node->NodeName() == KParTag)
+ {
+ //Checking the attributes of par element
+ //only dur is allowed, dur='indefinite' illegal
+ //checking dur is in ms
+ CMDXMLElement* elem = static_cast<CMDXMLElement*>(node);
+ if (elem->NumAttributes() > 1 && (iFlags & EAllowAllAttributes) == 0)
+ {
+ return EFalse;
+ }
+ for (TInt i = 0; i < elem->NumAttributes(); ++i)
+ {
+ TPtrC name, value;
+ elem->AttributeDetails(i,name,value);
+
+ if (name == KDurAttr && value == KIndefiniteVal)
+ {
+ return EFalse;
+ }
+ if ((iFlags & EAllowAllAttributes) == 0 && (name != KDurAttr ))
+ {
+ return EFalse;
+ }
+ if (name == KDurAttr && (iFlags & EAllowNonMilliseconds) == 0
+ && !IsInMilliseconds(value))
+ {
+ return EFalse;
+ }
+
+ }
+ if (!CheckParContent(node))
+ return EFalse;
+ }
+ node = node->NextSibling();
+ }
+ return ETrue;
+ }
+
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::CheckParContent(CMDXMLNode* aPar)
+//
+// Checks the content of the par element
+// ----------------------------------------------------------
+//
+
+TBool CConformanceChecker::CheckParContent(CMDXMLNode* aPar)
+ {
+ if (!aPar)
+ {
+ return ETrue;
+ }
+ TBool hasImage=EFalse;
+ TBool hasText=EFalse;
+ TBool hasAudio=EFalse;
+ TBool hasRef=EFalse;
+ TBool hasVideo=EFalse;
+
+ RArray<TPtrC> regionNames;
+ CMDXMLNode* innernode = aPar->FirstChild();
+ TBool legacy = ETrue;
+ while (legacy && innernode)
+ {
+ if (innernode->NodeType() == CMDXMLNode::EElementNode)
+ {
+ //Checking one type of media per par element
+ if (innernode->NodeName() == KImageTag)
+ if (hasImage)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ hasImage = ETrue;
+ }
+ else if (innernode->NodeName() == KTextTag)
+ if (hasText)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ hasText = ETrue;
+ }
+ else if (innernode->NodeName() == KAudioTag)
+ if (hasAudio)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ hasAudio = ETrue;
+ }
+ else if (innernode->NodeName() == KRefTag)
+ if (hasRef)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ hasRef = ETrue;
+ }
+ else if (innernode->NodeName() == KVideoTag)
+ if ((iFlags & EAllowVideoTag) == 0)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ if (hasVideo)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ hasVideo=ETrue;
+ }
+ }
+ else legacy = EFalse; //No other elements are allowed then img,text, audio, ref, video
+ //Check attributes
+ CMDXMLElement* elem = static_cast<CMDXMLElement*>(innernode);
+ TInt n = elem->NumAttributes();
+ for (TInt i = 0; legacy && (i < n); ++i)
+ {
+ TPtrC name, value;
+ elem->AttributeDetails(i,name,value);
+ //Check one region is used only once per par element
+ if (name == KRegionAttr)
+ {
+ if ((iFlags & EAllowAnyRegionNames) == 0
+ && value != KImage && value != KText)
+ {
+ legacy = EFalse;
+ }
+ TInt nr = regionNames.Count();
+ TInt j = 0;
+ while (j < nr && legacy)
+ {
+ if (regionNames[j]==value)
+ {
+ legacy = EFalse;
+ }
+ else
+ {
+ ++j;
+ }
+ }
+ if (legacy)
+ {
+ regionNames.Append(value);
+ if (regionNames.Count()>2)
+ {
+ legacy = EFalse;
+ }
+ }
+
+ }
+ else if ((iFlags & EAllowAllAttributes) == 0 && name != KSrcAttr
+ && name != KAltAttr && name != KBeginAttr && name != KEndAttr)
+ {
+ legacy = EFalse;
+ }
+ //checking the src attribute
+ if (name == KSrcAttr && (iFlags & EAllowNonUsAscii) == 0)
+ {
+ TInt valueLength=value.Length();
+ for (TInt i = 0; legacy && (i < valueLength); ++i)
+ {
+ TInt v = value[i];
+ if (v < KUSAsciiMinCode || v > KUSAsciiMaxCode)
+ {
+ legacy = EFalse;
+ }
+ }
+ }
+ //checking begin and end in ms
+ if ((name == KBeginAttr || name == KEndAttr)
+ && (iFlags & EAllowNonMilliseconds) == 0
+ && !IsInMilliseconds(value))
+ {
+ legacy = EFalse;
+ }
+ }//for
+ }
+ innernode = innernode->NextSibling();
+ } //while
+ regionNames.Close();
+ return legacy;
+ }
+
+//
+// ----------------------------------------------------------
+// CConformanceChecker::IsInMilliseconds(TDesC aValue);
+//
+// Checks if aValue is ending with 'ms'
+// ----------------------------------------------------------
+//
+
+TBool CConformanceChecker::IsInMilliseconds(TDesC& aValue) const
+ {
+ TBuf<2> ending;
+ TInt j = 0;
+ TInt n = aValue.Length();
+ TInt trimmedEndingLength = 2;
+ //Processing till all the white spaces are eliminated from the end
+ do
+ {
+ j+=2-trimmedEndingLength;
+ if (n>=j+2)
+ ending = aValue.Mid(n-2-j,2);
+ ending.TrimRight();
+ trimmedEndingLength = ending.Length();
+ }
+ while (trimmedEndingLength!=2 && n>j+2);
+ ending.LowerCase();
+ if (ending != KMs) return EFalse;
+ return ETrue;
+ }
+
+// End of File