--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsxml/src/senxmlelement.cpp Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,1615 @@
+/*
+* Copyright (c) 2005 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 "SenXmlElement.h"
+#include "SenXmlConstants.h" // KSenColon, ++
+#include "SenXmlUtils.h"
+
+#include "senxmldebug.h"
+
+#ifdef SYMBIAN_SECURE_ECOM
+ // for 2.8, 3.0 or newer:
+ #include <xml/attribute.h> // needed for RAttributeArray
+#else // for 2.6 or older
+ #include "Attribute.h"
+#endif
+
+using namespace Xml;
+
+namespace
+ {
+
+// _LIT8(KColon, ":");
+// _LIT8(KLessThan, "<");
+// _LIT8(KGreaterThan, ">");
+// _LIT8(KSpace, " ");
+// _LIT8(KDblQuot, "\"");
+// _LIT8(KEqualsDblQuot, "=\"");
+// _LIT8(KSlashGreaterThan, "/>");
+// _LIT8(KSenLessThanSlash, "</");
+// _LIT8(KSpaceXmlns, " xmlns");
+// _LIT8(KXmlns, "xmlns");
+// _LIT8(KXmlNsAttNamePlusColon, "xmlns:");
+ const TInt KFlatBufSize = 64;
+ }
+
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aLocalName)
+ {
+ CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+ CleanupStack::PushL(pNew);
+ pNew->BaseConstructL(aLocalName);
+ CleanupStack::Pop(); // pNew;
+ return pNew;
+ }
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+ const TDesC8& aLocalName)
+ {
+ CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+ CleanupStack::PushL(pNew);
+ pNew->BaseConstructL(aNsUri, aLocalName);
+ CleanupStack::Pop(); // pNew;
+ return pNew;
+ }
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName)
+ {
+ CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+ CleanupStack::PushL(pNew);
+ pNew->BaseConstructL(aNsUri, aLocalName, aQName);
+ CleanupStack::Pop(); // pNew;
+ return pNew;
+ }
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName,
+ const RAttributeArray& apAttrs)
+ {
+ CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+ CleanupStack::PushL(pNew);
+ pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs);
+ CleanupStack::Pop(); // pNew;
+ return pNew;
+ }
+
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName,
+ const RAttributeArray& apAttrs,
+ CSenElement& aParent)
+ {
+ CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+ CleanupStack::PushL(pNew);
+ pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs, aParent);
+ CleanupStack::Pop(); // pNew;
+ return pNew;
+ }
+
+EXPORT_C CSenXmlElement::CSenXmlElement()
+: ipLocalName(NULL),
+ ipContentBuf(NULL),
+ ipParent(NULL),
+ ipNamespace(NULL)
+ {
+ }
+
+EXPORT_C CSenXmlElement::~CSenXmlElement()
+ {
+ if(ipContentWriteStream)
+ {
+ ipContentWriteStream->Close();
+ delete ipContentWriteStream;
+ ipContentWriteStream = NULL;
+ }
+
+ if(ipAttrs)
+ {
+ ipAttrs->ResetAndDestroy();
+ delete ipAttrs;
+ ipAttrs = NULL; // not required
+ }
+ if(ipElements)
+ {
+ ipElements->ResetAndDestroy();
+ delete ipElements;
+ ipElements = NULL; // not required
+ }
+ if(ipNamespaces)
+ {
+ ipNamespaces->ResetAndDestroy();
+ delete ipNamespaces;
+ ipNamespaces = NULL; // not required
+ }
+
+ delete ipLocalName;
+ ipLocalName = NULL; // not required
+
+
+ delete ipContentBuf;
+ ipContentBuf = NULL; // not required
+
+ }
+
+
+
+EXPORT_C void CSenXmlElement::BaseConstructL(const TDesC8& aLocalName)
+ {
+ SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
+ ipLocalName = aLocalName.AllocL();
+ }
+
+EXPORT_C void CSenXmlElement::BaseConstructL(const TDesC8& aNsUri,
+ const TDesC8& aLocalName)
+ {
+ SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
+ if(aNsUri.Length()>0)
+ {
+ SetNamespaceL(aNsUri);
+ }
+ ipLocalName = aLocalName.AllocL();
+ }
+
+EXPORT_C void CSenXmlElement::BaseConstructL( const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName)
+ {
+ SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
+ SenXmlUtils::LeaveOnInvalidElementNameL(aQName);
+ ipLocalName = aLocalName.AllocL();
+ TPtrC8 ptrPrefix(KNullDesC8);
+
+ if (aQName.Length() > 0 )
+ {
+ TInt colon = aQName.Locate(':');
+ if (colon > 0) // Note: 0 also treated as no prefix
+ {
+ ptrPrefix.Set(aQName.Ptr(),colon);
+ }
+ }
+
+ SetNamespaceL(ptrPrefix, aNsUri);
+ }
+
+EXPORT_C void CSenXmlElement::BaseConstructL( const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName,
+ const RAttributeArray& apAttrs)
+ {
+ BaseConstructL(aNsUri, aLocalName, aQName);
+ SetAttributesL(apAttrs);
+ }
+
+EXPORT_C void CSenXmlElement::BaseConstructL( const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName,
+ const RAttributeArray& apAttrs,
+ CSenElement& aParent )
+ {
+ // parent must be set here at first line, because
+ // namespace setting dependends of it(!)
+ ipParent = &aParent;
+
+ BaseConstructL(aNsUri, aLocalName, aQName);
+ SetAttributesL(apAttrs);
+ }
+
+EXPORT_C void CSenXmlElement::SetAttributesL(const RAttributeArray& apAttrs)
+ {
+ AddAttributesL(apAttrs);
+ }
+
+
+EXPORT_C void CSenXmlElement::AddAttributesL(const RAttributeArray& apAttrs)
+ {
+ TInt count(apAttrs.Count());
+ HBufC8* qName = NULL;
+ for(TInt i=0; i<count; i++)
+ {
+ const TPtrC8 localname = apAttrs[i].Attribute().LocalName().DesC();
+ const TPtrC8 prefix = apAttrs[i].Attribute().Prefix().DesC();
+ const TPtrC8 value = apAttrs[i].Value().DesC();
+
+ SenXmlUtils::BuildQNameL(prefix, localname, qName);
+
+ CleanupStack::PushL(qName);
+
+ HBufC8* encodedValue = NULL;
+ TBool encoded =
+ SenXmlUtils::EncodeHttpCharactersL(value, encodedValue);
+
+ if (encoded)
+ {
+ CleanupStack::PushL(encodedValue);
+ AddAttributeL(*qName, localname, *encodedValue);
+ // note: this intentionally
+ // skips the 2 param
+ // AddAttributeL() function
+
+ CleanupStack::PopAndDestroy(); // encodedValue
+ }
+ else
+ {
+ AddAttributeL(*qName, localname, value);
+ // note: this intentionally
+ // skips the 2 param
+ // AddAttributeL() function
+ }
+
+ CleanupStack::PopAndDestroy(); // qName
+ }
+ }
+
+EXPORT_C const TDesC8& CSenXmlElement::AddAttributeL(const TDesC8& aQName,
+ const TDesC8& aLocalName,
+ const TDesC8& aValue)
+ {
+ const TDesC8& nsPrefix = NsPrefix();
+ // first we check for possible namespace declarations...
+ if ( aQName == KSenXmlns || aLocalName == KSenXmlns)
+ {
+ if(nsPrefix.Length() > 0)
+ {
+ // we have an additional namespace declaration
+ AddNamespaceL(KNullDesC8(), aValue);
+ }
+ else
+ {
+ // this is a default name space declaration
+ SetNamespaceL(aValue);
+ }
+
+ }
+ else if (aLocalName == NsPrefix())
+ {
+ //we have a new declaration for the namespace of this element
+ SetNamespaceL(aLocalName, aValue);
+ }
+ else if(aQName.Find(KSenXmlNsAttNamePlusColon) == 0)
+ {
+ // we have an additional namespace declaration
+ AddNamespaceL(aLocalName, aValue);
+ }
+ else
+ {
+ // we have a real attribute!
+ CSenBaseAttribute* pAttribute = CSenBaseAttribute::NewL(aQName,
+ aLocalName,
+ aValue);
+ AddAttributeL(pAttribute);
+ }
+ return aValue;
+ }
+
+
+
+EXPORT_C const TDesC8& CSenXmlElement::AddAttributeL(const TDesC8& aAttrName,
+ const TDesC8& aValue)
+ {
+ // note, the aAttrName may be a qualified name or simply localname
+ // strip off the possible prefix from possible qualified name:
+ TPtrC8 localName = SenXmlUtils::LocalName(aAttrName);
+ return AddAttributeL(aAttrName, localName, aValue);
+ }
+
+// takes the ownership of aAttribute
+EXPORT_C const TDesC8& CSenXmlElement::AddAttributeL(
+ CSenBaseAttribute* apAttribute)
+ {
+ CSenBaseAttribute* pOldAtt = FindAttr(apAttribute->Name());
+
+ // if attribute array is not yet allocated, instantiate here
+ if(!ipAttrs)
+ {
+ ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+ }
+
+ if(!pOldAtt)
+ {
+ // transfrer the ownership to this class:
+ ipAttrs->Append(apAttribute);
+ return apAttribute->Value();
+ }
+ else
+ {
+ pOldAtt->SetValueL(apAttribute->Value());
+ delete apAttribute;
+ apAttribute = NULL;
+ return pOldAtt->Value();
+ }
+ }
+
+
+EXPORT_C CSenBaseAttribute* CSenXmlElement::FindAttr(const TDesC8& aName)
+ {
+ if(ipAttrs)
+ {
+ TInt count(ipAttrs->Count());
+ for (TInt i = 0; i < count; i++)
+ {
+ CSenBaseAttribute* pAttribute = (*ipAttrs)[i];
+ if(pAttribute->Name() == aName)
+ {
+ return pAttribute;
+ }
+ }
+ }
+ return NULL;
+ }
+
+
+EXPORT_C TInt CSenXmlElement::IndexOfElement(const TDesC8& aNsUri,
+ const TDesC8& aLocalName) const
+ {
+ if(ipElements)
+ {
+ TInt count(ipElements->Count());
+
+ for (TInt i = 0; i < count; i++)
+ {
+ CSenElement* pElement = (*ipElements)[i];
+ const TDesC8& nsUri = pElement->NamespaceURI();
+ const TDesC8& localName = pElement->LocalName();
+ if ((nsUri == aNsUri) && (localName == aLocalName))
+ {
+ return i;
+ }
+ }
+ }
+ return KErrNotFound;
+ }
+
+EXPORT_C const TDesC8& CSenXmlElement::LocalName() const
+ {
+ if (ipLocalName == NULL)
+ {
+ return KNullDesC8();
+ }
+ else
+ {
+ return *ipLocalName;
+ }
+ }
+
+EXPORT_C const TDesC8& CSenXmlElement::NamespaceURI() const
+ {
+ if (ipNamespace)
+ {
+ return ipNamespace->URI();
+ }
+ else
+ {
+ return KNullDesC8();
+ }
+ }
+
+EXPORT_C const TDesC8& CSenXmlElement::NsPrefix() const
+ {
+ if (!ipNamespace)
+ {
+ return KNullDesC8();
+ }
+ else
+ {
+ return ipNamespace->Prefix();
+ }
+ }
+
+EXPORT_C TBool CSenXmlElement::HasContent() const
+ {
+ if (!ipContentBuf)
+ {
+ return EFalse;
+ }
+ else
+ {
+ return (ipContentBuf->Size() > 0);
+ }
+ }
+
+EXPORT_C TPtrC8 CSenXmlElement::Content() const
+ {
+ if (!ipContentBuf)
+ {
+ return KNullDesC8();
+ }
+ else
+ {
+ TPtrC8 p8 = ipContentBuf->Ptr(0);
+ return p8;
+ }
+ }
+
+
+EXPORT_C HBufC* CSenXmlElement::ContentUnicodeL() const
+ {
+ HBufC* pRet = SenXmlUtils::ToUnicodeLC(Content());
+ CleanupStack::Pop(); // pRet;
+ return pRet;
+ }
+
+EXPORT_C TPtrC8 CSenXmlElement::SetContentL(const TDesC8& aContent)
+ {
+ AllocContentBufL();
+ if(ipContentBuf)
+ {
+ ipContentBuf->ResizeL(aContent.Size());
+ ipContentBuf->Write(0,
+ TPtrC8(REINTERPRET_CAST(const TUint8*, aContent.Ptr()),
+ aContent.Size())
+ );
+ if(ipContentWriteStream)
+ {
+ // Reset stream
+ ipContentWriteStream->Open(*ipContentBuf);
+ }
+ }
+ return Content();
+ }
+
+EXPORT_C RWriteStream& CSenXmlElement::ContentWriteStreamL()
+ {
+ AllocContentBufL();
+ // Allocate stream
+ if(!ipContentWriteStream)
+ {
+ ipContentWriteStream = new (ELeave) RBufWriteStream;
+ }
+ ipContentWriteStream->Open(*ipContentBuf);
+ return *ipContentWriteStream;
+ }
+
+// NOTE: assumes(!) that the namespace is same(!)
+// Optimization
+// RPointerArray<CSenElement>* or NULL if no elements have been added!
+EXPORT_C RPointerArray<CSenElement>& CSenXmlElement::ElementsL()
+ {
+ if(!ipElements)
+ {
+ ipElements = new (ELeave) RPointerArray<CSenElement>;
+ }
+ return *ipElements;
+ }
+
+EXPORT_C TInt CSenXmlElement::ElementsL(
+ RPointerArray<CSenElement>& aElementArray,
+ const TDesC8& aNsUri,
+ const TDesC8& aLocalName)
+ {
+ TInt retVal(KErrNotFound);
+
+ if(ipElements) // return KErrNotFound, if zero elements have been added
+ {
+ TInt count(ipElements->Count());
+
+ if (count > 0) // return KErrNotFound, if owned array is empty
+ {
+ CSenElement* pElement = NULL;
+ for (TInt i=0; i<count; i++)
+ {
+ pElement = (*ipElements)[i];
+ if ( (aLocalName == pElement->LocalName()) &&
+ (aNsUri == pElement->NamespaceURI()) )
+ {
+ aElementArray.Append(pElement);
+ }
+ }
+ retVal = KErrNone;
+ }
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CSenXmlElement::ElementsL(
+ RPointerArray<CSenElement>& aElementArray,
+ const TDesC8& aLocalName)
+ {
+ return ElementsL(aElementArray,NamespaceURI(),aLocalName);
+ }
+
+EXPORT_C const TDesC8* CSenXmlElement::AttrValue(const TDesC8& aName)
+ {
+ CSenBaseAttribute* pAttr = FindAttr(aName);
+ if (pAttr == NULL)
+ {
+ return NULL;
+ }
+ else
+ {
+ return &(pAttr->Value());
+ }
+ }
+
+EXPORT_C void CSenXmlElement::AddAttrL(const TDesC8& aName,
+ const TDesC8& aValue)
+ {
+ CSenBaseAttribute* pAttr = FindAttr(aName);
+ if (!pAttr)
+ {
+ if(!ipAttrs)
+ {
+ ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+ }
+
+ User::LeaveIfError(ipAttrs->Append(CSenBaseAttribute::NewL(aName,
+ aValue)));
+ }
+ else
+ {
+ pAttr->SetValueL(aValue);
+ }
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::Parent()
+ {
+ return ipParent;
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::SetParent(CSenElement* apParent) // IOP
+ {
+ if (apParent && ipParent != apParent)
+ {
+ ipParent = apParent;
+ if (!ipNamespace)
+ {
+ // check if there is a default namespace declared in the scope of
+ // the parent
+ const CSenNamespace* pParentNamespace =
+ ((CSenXmlElement*) ipParent)->Namespace(KNullDesC8,ETrue);
+ if (pParentNamespace && pParentNamespace->Prefix() == KNullDesC8)
+ {
+ ipNamespace = (CSenNamespace*)pParentNamespace;
+ }
+ }
+ else
+ {
+ //check if the parent already has a namespace for this element
+ // if so remove it from the local namespace table
+ const CSenNamespace* pNs = ipParent->Namespace(KNullDesC8,
+ ipNamespace->URI());
+ if (pNs && pNs != ipNamespace)
+ {
+ if (ipNamespace->Compare(*pNs) ||
+ ipNamespace->Prefix().Length() == 0)
+ {
+ //prefix is also identical or this element has no prefix
+ if(ipNamespaces)
+ {
+ TInt nsIndex = ipNamespaces->Find(ipNamespace);
+ if ( nsIndex != KErrNotFound)
+ {
+ ipNamespaces->Remove(nsIndex);
+ }
+ }
+ delete ipNamespace;
+ ipNamespace = NULL;
+ ipNamespace = (CSenNamespace*)pNs;
+ }
+ }
+
+ }
+ }
+ return apParent;
+ }
+
+EXPORT_C MSenElement& CSenXmlElement::Root()
+ {
+ if (ipParent == NULL)
+ {
+ return *this;
+ }
+ else
+ {
+ return ipParent->Root();
+ }
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::Element(const TDesC8& aLocalName)
+ {
+ return Element(NamespaceURI(), aLocalName);
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::Element(const TDesC8& aNsUri,
+ const TDesC8& aLocalName)
+ {
+ if(ipElements)
+ {
+ TInt idx = IndexOfElement(aNsUri, aLocalName);
+ if (idx < 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ return (*ipElements)[idx];
+ }
+ }
+ return NULL;
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::CreateElementL(const TDesC8& aNsPrefix,
+ const TDesC8& aLocalName)
+ {
+ CSenElement* pNewElement = NULL;
+
+ if (aNsPrefix.Length() > 0)
+ {
+ CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aNsPrefix);
+ if (pNamespace)
+ {
+ HBufC8 *pQName =
+ HBufC8::NewLC(aNsPrefix.Length() + aLocalName.Length() +5);
+ TPtr8 ptr = pQName->Des();
+ ptr.Append(aNsPrefix);
+ ptr.Append(':');
+ ptr.Append(aLocalName);
+ pNewElement =
+ CSenXmlElement::NewL(pNamespace->URI(), aLocalName, *pQName);
+ CleanupStack::PopAndDestroy(); // pQName
+ }
+ }
+ else
+ {
+ pNewElement = CSenXmlElement::NewL(aLocalName);
+ }
+
+ return pNewElement; // Returns NULL if required namespace can not be found!
+ }
+
+EXPORT_C CSenElement& CSenXmlElement::InsertElementL(
+ CSenElement& aElement,
+ const CSenElement& aBeforeElement)
+ {
+ TInt index(KErrNotFound);
+
+ // allocate element array, if not already reserved
+ if(!ipElements)
+ {
+ ipElements = new (ELeave) RPointerArray<CSenElement>;
+ }
+ else
+ {
+ // search only if array is not brand new
+ index = ipElements->Find(&aBeforeElement);
+ }
+
+ if (index != KErrNotFound)
+ {
+ // repleace element
+ User::LeaveIfError(ipElements->Insert(&aElement,index));
+ }
+ else
+ {
+ // add new element
+ User::LeaveIfError(ipElements->Append(&aElement));
+ }
+ aElement.SetParent(this);
+ return aElement;
+ }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(CSenElement& aElement)
+ {
+ // allocate element array, if not already reserved
+ if(!ipElements)
+ {
+ ipElements = new (ELeave) RPointerArray<CSenElement>;
+ }
+
+ User::LeaveIfError(ipElements->Append(&aElement));
+ aElement.SetParent(this);
+ return aElement;
+ }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(const TDesC8& aNsUri,
+ const TDesC8& aLocalName)
+ {
+ return AddElementL(*CSenXmlElement::NewL(aNsUri, aLocalName));
+ }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(
+ const TDesC8& aNsUri,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName
+ )
+ {
+ return AddElementL(*CSenXmlElement::NewL(aNsUri, aLocalName, aQName));
+ }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(const TDesC8& aLocalName)
+ {
+ return AddElementL(*CSenXmlElement::NewL(aLocalName));
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::RemoveElement(CSenElement& aElement)
+ {
+ CSenElement* pElement = NULL;
+
+ if(ipElements)
+ {
+ TInt idx = ipElements->Find(&aElement);
+ if (idx >= 0)
+ {
+ pElement = (*ipElements)[idx];
+ ipElements->Remove(idx);
+ pElement->SetParent(NULL);
+ return pElement;
+ }
+ }
+ return pElement;
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::RemoveElement(const TDesC8& aNsUri,
+ const TDesC8& aLocalName)
+ {
+ TInt idx = IndexOfElement(aNsUri, aLocalName);
+ if (idx >= 0)
+ {
+ CSenElement* pElement = (*ipElements)[idx];
+ ipElements->Remove(idx);
+ pElement->SetParent(NULL);
+ return pElement;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::RemoveElement(const TDesC8& aLocalName)
+ {
+ return RemoveElement(NamespaceURI(), aLocalName);
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::ReplaceElementL(CSenElement& aElement)
+ {
+ CSenElement* pOldElement =
+ RemoveElement(aElement.NamespaceURI(), aElement.LocalName());
+ CleanupStack::PushL(pOldElement);
+ AddElementL(aElement);
+ CleanupStack::Pop(); // pOldElement;
+ return pOldElement;
+ }
+
+EXPORT_C HBufC8* CSenXmlElement::AsXmlL()
+ {
+ CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+ CleanupStack::PushL(pBuf);
+ TPtrC8 p = WriteToBufL(*pBuf);
+ HBufC8* pRet = p.AllocL();
+ CleanupStack::PopAndDestroy(); // pBuf;
+ return pRet;
+
+ }
+
+EXPORT_C HBufC* CSenXmlElement::AsXmlUnicodeL()
+ {
+ CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+ CleanupStack::PushL(pBuf);
+ TPtrC8 p8 = WriteToBufL(*pBuf);
+ HBufC* pRet = SenXmlUtils::ToUnicodeLC(p8);
+ CleanupStack::Pop(); // pop pRet;
+ CleanupStack::PopAndDestroy(); // pBuf;
+ return pRet;
+ }
+
+EXPORT_C TPtrC8 CSenXmlElement::WriteToBufL(CBufBase& aBuf)
+ {
+ RBufWriteStream bufWs(aBuf);
+ CleanupClosePushL(bufWs);
+ this->WriteAsXMLToL(bufWs);
+ CleanupStack::PopAndDestroy(); // bufWs.Close();
+ return aBuf.Ptr(0);
+ }
+
+EXPORT_C void CSenXmlElement::WriteAsXMLToL(RWriteStream& aWriteStream)
+ {
+ // Find out whether we should declare the namespace
+ TPtrC8 nsPrefix = NsPrefix();
+
+ // Element name
+ aWriteStream.WriteL(KSenLessThan);
+ if (nsPrefix.Length() > 0)
+ {
+ aWriteStream.WriteL(nsPrefix);
+ aWriteStream.WriteL(KSenColon);
+ }
+ aWriteStream.WriteL(*ipLocalName);
+
+
+ if ((ipAttrs && ipAttrs->Count() > 0) ||
+ (ipNamespaces && ipNamespaces->Count() > 0))
+ {
+ WriteNamespacesToL(aWriteStream);
+ WriteAttrsToL(aWriteStream);
+ }
+
+ // Elements and content
+ if ((ipElements && ipElements->Count() > 0) || HasContent())
+ {
+ aWriteStream.WriteL(KSenGreaterThan);
+
+ // Body
+ WriteElementsToL(aWriteStream);
+ WriteContentToL(aWriteStream);
+
+ // Closing element
+ aWriteStream.WriteL(KSenLessThanSlash);
+ if (nsPrefix.Length() > 0)
+ {
+ aWriteStream.WriteL(nsPrefix);
+ aWriteStream.WriteL(KSenColon);
+ }
+ aWriteStream.WriteL(*ipLocalName);
+ aWriteStream.WriteL(KSenGreaterThan);
+ }
+ else
+ {
+ aWriteStream.WriteL(KSenSlashGreaterThan);
+ }
+ }
+
+EXPORT_C void CSenXmlElement::WriteAttrToL(RWriteStream& aWriteStream,
+ const TDesC8& aName,
+ const TDesC8& aValue)
+ {
+ aWriteStream.WriteL(KSenSpace);
+ aWriteStream.WriteL(aName);
+ aWriteStream.WriteL(KSenEqualsDblQuot);
+ aWriteStream.WriteL(aValue);
+ aWriteStream.WriteL(KSenDblQuot);
+ }
+
+EXPORT_C void CSenXmlElement::WriteAttrsToL(RWriteStream& aWriteStream)
+ {
+ if(ipAttrs)
+ {
+ TInt count(ipAttrs->Count());
+ for (TInt i = 0; i < count; i++)
+ {
+ WriteAttrToL(aWriteStream, (*ipAttrs)[i]->Name(), (*ipAttrs)[i]->Value());
+ }
+ }
+ }
+
+EXPORT_C void CSenXmlElement::WriteNamespacesToL(RWriteStream& aWriteStream)
+ {
+ if(ipNamespaces)
+ {
+ CSenNamespace* ns = NULL;
+ TInt count = ipNamespaces->Count();
+ for (TInt i=0; i < count; i++)
+ {
+ ns = (*ipNamespaces)[i];
+ if (ns)
+ {
+ aWriteStream.WriteL(KSenSpaceXmlns);
+ if (ns->Prefix().Length() > 0)
+ {
+ aWriteStream.WriteL(KSenColon);
+ aWriteStream.WriteL(ns->Prefix());
+ }
+ aWriteStream.WriteL(KSenEqualsDblQuot);
+ aWriteStream.WriteL(ns->URI());
+ aWriteStream.WriteL(KSenDblQuot);
+ }
+ }
+ }
+ }
+
+EXPORT_C void CSenXmlElement::WriteElementsToL(RWriteStream& aWriteStream)
+ {
+ if(ipElements)
+ {
+ TInt elementCount(ipElements->Count());
+ for (TInt i=0; i<elementCount; i++)
+ {
+ (*ipElements)[i]->WriteAsXMLToL(aWriteStream);
+ }
+ }
+ }
+
+EXPORT_C void CSenXmlElement::WriteContentToL(RWriteStream& aWriteStream)
+ {
+ aWriteStream.WriteL(Content());
+ }
+
+EXPORT_C MSenElement* CSenXmlElement::AsElement()
+ {
+ return this;
+ }
+
+EXPORT_C void CSenXmlElement::AllocContentBufL()
+ {
+ if(!ipContentBuf)
+ {
+ ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+ }
+ }
+
+EXPORT_C void CSenXmlElement::SetNamespaceL(const TDesC8& aNsUri)
+ {
+ SetNamespaceL(KNullDesC8, aNsUri);
+ }
+
+EXPORT_C void CSenXmlElement::SetNamespaceL(const TDesC8& aNsPrefix,
+ const TDesC8& aNsUri)
+ {
+ if (aNsUri.Length() > 0)
+ {
+ ipNamespace = (CSenNamespace*) Namespace(aNsPrefix, aNsUri);
+ if (!ipNamespace) // not already defined
+ {
+ // allocate array if not already reserved
+ if(!ipNamespaces)
+ {
+ ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+ }
+ ipNamespace = CSenNamespace::NewL(aNsPrefix, aNsUri);
+ ipNamespaces->Append(ipNamespace);
+ }
+ }
+ }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace()
+ {
+ return ipNamespace;
+ }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace(
+ const TDesC8& aNsPrefix)
+ {
+ return Namespace(aNsPrefix,ETrue);
+ }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace(
+ const TDesC8& aNsPrefix,
+ const TBool aCheckInParent)
+ {
+ if (aNsPrefix.Length() == 0) return NULL;
+
+ const CSenNamespace* pNamespace = NULL;
+
+ if(ipNamespaces)
+ {
+ TInt count(ipNamespaces->Count());
+ for (TInt i=0; i<count && pNamespace == NULL; i++)
+ {
+ pNamespace = (*ipNamespaces)[i];
+ if (pNamespace)
+ {
+ if (pNamespace->Prefix() != aNsPrefix) pNamespace = NULL;
+ }
+ }
+ }
+
+ if (pNamespace == NULL && ipParent && aCheckInParent)
+ {
+ pNamespace = ipParent->Namespace(aNsPrefix);
+ }
+
+ return pNamespace;
+ }
+
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace(
+ const TDesC8& aNsPrefix,
+ const TDesC8& aUri)
+ {
+ // If prefix == NULL, then any prefix is ok
+ const CSenNamespace* pNs = NULL;
+ // Check if the namespace has already been declared
+
+ if(ipNamespaces)
+ {
+ TInt count = ipNamespaces->Count();
+ if (count != 0)
+ {
+ for (TInt i=0; i<count; i++)
+ {
+ pNs = (*ipNamespaces)[i];
+ if (!pNs->Compare(aNsPrefix, aUri))
+ {
+ pNs = NULL; // not equal
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ if (pNs == NULL && ipParent != NULL)
+ {
+ // if no namespace defined, but there is a parent, ask its namespace
+ pNs = ipParent->Namespace(aNsPrefix, aUri);
+ }
+ return pNs;
+ }
+
+EXPORT_C RPointerArray<CSenBaseAttribute>& CSenXmlElement::AttributesL()
+ {
+ // if attribute array is not yet allocated, instantiate here
+ if(!ipAttrs)
+ {
+ ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+ }
+ return *ipAttrs;
+ }
+
+EXPORT_C RPointerArray<CSenNamespace>& CSenXmlElement::NamespacesL()
+ {
+ if(!ipNamespaces)
+ {
+ ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+ }
+ return *ipNamespaces;
+ }
+
+EXPORT_C void CSenXmlElement::CopyFromL(CSenElement& aSource)
+ {
+ TPtrC8 sourceContent = aSource.Content();
+ if (sourceContent.Length() > 0)
+ {
+ if (ipContentBuf == NULL)
+ {
+ SetContentL(sourceContent);
+ }
+ else
+ {
+ RBufWriteStream bufWs(*ipContentBuf);
+ CleanupClosePushL(bufWs);
+ bufWs.WriteL(sourceContent);
+ CleanupStack::PopAndDestroy(); // close bufWs
+ }
+ }
+
+ RPointerArray<CSenNamespace> sourceNamespaces = aSource.NamespacesL();
+ if (sourceNamespaces.Count() > 0)
+ {
+ for (TInt i=0;i<sourceNamespaces.Count(); i++)
+ {
+ CSenNamespace* pNamespace = sourceNamespaces[i];
+ CSenNamespace* pNewNamespace =
+ CSenNamespace::NewL(pNamespace->Prefix(),pNamespace->URI());
+ CleanupStack::PushL(pNewNamespace);
+
+ // allocate array if not already reserved
+ if(!ipNamespaces)
+ {
+ ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+ }
+
+#ifdef EKA2
+ ipNamespaces->AppendL(pNewNamespace);
+#else
+ User::LeaveIfError(ipNamespaces->Append(pNewNamespace));
+#endif
+ CleanupStack::Pop(pNewNamespace);
+ }
+ }
+ SetNamespaceL(aSource.NsPrefix(), aSource.NamespaceURI());
+
+ RPointerArray<CSenBaseAttribute> sourceAttributes = aSource.AttributesL();
+ if (sourceAttributes.Count() > 0)
+ {
+ for (TInt i=0;i<sourceAttributes.Count(); i++)
+ {
+ CSenBaseAttribute* pBaseAttribute = sourceAttributes[i];
+
+ // 2005-04-28: check for duplicate and override existing value if
+ // attribute already exists.
+ CSenBaseAttribute* pOriginal = FindAttr(pBaseAttribute->Name());
+ if (pOriginal)
+ {
+ pOriginal->SetValueL(pBaseAttribute->Value());
+ continue;
+ }
+
+ CSenBaseAttribute* pNewBaseAttribute =
+ CSenBaseAttribute::NewL(pBaseAttribute->Name(),
+ pBaseAttribute->Value());
+ CleanupStack::PushL(pNewBaseAttribute);
+
+ // if attribute array is not yet allocated, instantiate here
+ if(!ipAttrs)
+ {
+ ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+ }
+
+#ifdef EKA2
+ ipAttrs->AppendL(pNewBaseAttribute);
+#else
+ User::LeaveIfError(ipAttrs->Append(pNewBaseAttribute));
+#endif
+ CleanupStack::Pop(pNewBaseAttribute);
+ }
+ }
+
+ RPointerArray<CSenElement> sourceElements = aSource.ElementsL();
+ if (sourceElements.Count() > 0)
+ {
+ for (TInt i=0;i<sourceElements.Count(); i++)
+ {
+ CSenElement* pElement = sourceElements[i];
+ CSenElement* pNewElement =
+ CSenXmlElement::NewL(pElement->LocalName());
+ CleanupStack::PushL(pNewElement);
+ pNewElement->SetParent(this);
+ pNewElement->CopyFromL(*pElement);
+
+ if(!ipElements)
+ {
+ ipElements = new (ELeave) RPointerArray<CSenElement>;
+ }
+
+#ifdef EKA2
+ ipElements->AppendL(pNewElement);
+#else
+ User::LeaveIfError(ipElements->Append(pNewElement));
+#endif // EKA2
+ CleanupStack::Pop(pNewElement);
+ }
+ }
+ }
+
+EXPORT_C void CSenXmlElement::SetPrefixL(const TDesC8& aPrefix)
+ {
+ if (ipNamespaces && ipNamespaces->Find(ipNamespace) > -1)
+ {
+ //the namespace was locally declared
+
+ // Check if element already has a namespace with given prefix
+ CSenNamespace* pNamespace = NULL;
+ TInt count(ipNamespaces->Count());
+ for (TInt i=0; i<count && pNamespace == NULL; i++)
+ {
+ pNamespace = (*ipNamespaces)[i];
+ if (pNamespace->Prefix() != aPrefix)
+ {
+ pNamespace = NULL;
+ }
+ }
+
+ if (pNamespace)
+ {
+ // Update existing namespace
+ const TDesC8& uri = ipNamespace->URI();
+ pNamespace->SetUriL(uri);
+ ipNamespace = pNamespace;
+ }
+ else
+ {
+ if(ipElements) // are there any child elements?
+ {
+ if (ipNamespace->Prefix().Length() > 0 && ipElements->Count() > 0)
+ {
+ // there may be children that depend on the old prefix in e.g. attribute names
+ const TDesC8& uri = ipNamespace->URI();
+ ipNamespace = CSenNamespace::NewL(aPrefix, uri);
+
+ // append as new namespace
+ ipNamespaces->Append(ipNamespace);
+ }
+ }
+ ipNamespace->SetPrefixL(aPrefix);
+ }
+ }
+ }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::AddNamespaceL(
+ CSenNamespace& aNewNamespace,
+ TBool aCheckInParent)
+ {
+ const CSenNamespace* pNamespace =
+ Namespace(aNewNamespace.Prefix(), aCheckInParent);
+
+ if (pNamespace == NULL) // does not exist
+ {
+ CSenNamespace* pNewNamespace =
+ CSenNamespace::NewL(aNewNamespace.Prefix(), aNewNamespace.URI());
+
+ // allocate array if not already reserved
+ if(!ipNamespaces)
+ {
+ ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+ }
+ ipNamespaces->Append(pNewNamespace);
+ pNamespace = pNewNamespace;
+ }
+ return pNamespace;
+ }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::AddNamespaceL(
+ const TDesC8& aPrefix,
+ const TDesC8& aUri)
+ {
+ CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aPrefix);
+ if (!pNamespace)
+ {
+ if ( aUri.Length() > 0)
+ {
+ pNamespace = CSenNamespace::NewL(aPrefix, aUri);
+ // allocate array if not already reserved
+ if(!ipNamespaces)
+ {
+ ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+ }
+ ipNamespaces->Append(pNamespace);
+ }
+ }
+ else
+ {
+ pNamespace->SetUriL(aUri); // override current namespace URI with new one
+
+ }
+
+ return pNamespace;
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::DetachL()
+ {
+ if (!ipParent)
+ {
+ return NULL;
+ }
+
+ // allocate array if not already reserved
+ if(!ipNamespaces)
+ {
+ ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+ }
+
+ AddNamespaceMissingFromL(*ipNamespaces);
+
+ // optimization: if nothing was added, free the array allocation
+ if(ipNamespaces && ipNamespaces->Count()==0)
+ {
+ ipNamespaces->ResetAndDestroy();
+ delete ipNamespaces;
+
+ ipNamespaces = NULL;
+ }
+
+ ipParent->RemoveElement(*this);
+ return this;
+ }
+
+void CSenXmlElement::AddNamespaceMissingFromL( RPointerArray<CSenNamespace>& aNamespaces )
+ {
+ // Add namespace of this element (possibly copied from parent)
+ // if that namespace is not already defined in
+ // aNamespaces array.
+ if ( ipNamespace && aNamespaces.Find(ipNamespace) == -1)
+ {
+ // Check if namespace declaration of this element can
+ // be found from aNamespaces array
+ TInt count(aNamespaces.Count());
+ TBool found(EFalse);
+ TInt i = 0;
+ for (; i<count; i++)
+ {
+ if ( aNamespaces[i]->URI() == ipNamespace->URI() &&
+ aNamespaces[i]->Prefix() == ipNamespace->Prefix() )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ if ( !found )
+ {
+ //If not found then check in namespace usage array that namspace declaration
+ //is present or not. If yes then continue without adding.
+ if((ipNamespaces && ipNamespaces->Find(ipNamespace) == -1) || !ipNamespaces)
+ {
+
+ // Not found
+ // => Create a copy of namespace declaration
+ // and append it into aNamespaces array
+ CSenNamespace* pCopy =
+ CSenNamespace::NewL(ipNamespace->Prefix(), ipNamespace->URI());
+ CleanupStack::PushL(pCopy);
+ #ifdef EKA2
+ aNamespaces.AppendL(pCopy);
+ #else
+ User::LeaveIfError(aNamespaces.Append(pCopy));
+ #endif
+ CleanupStack::Pop(pCopy);
+
+ // Change namespace object for this element to namespace object
+ // which can be found from aNamespaces array
+ ipNamespace = pCopy;
+ }
+ }
+ else
+ {
+ // Change namespace object for this element to namespace object
+ // which can be found from aNamespaces array
+ ipNamespace = aNamespaces[i];
+ }
+ }
+
+ // Add namespaces from this element's attributes
+ // if those namespaces are not already defined in
+ // aNamespaces array.
+ if ( ipAttrs && ipAttrs->Count() > 0 )
+ {
+ TInt colon = -1;
+ const CSenNamespace* pNamespace = NULL;
+
+ TInt count(ipAttrs->Count());
+ for(TInt i=0; i<count; i++)
+ {
+ CSenBaseAttribute* pAttribute = (*ipAttrs)[i];
+
+ // Check namespace assigned to Name
+ colon = pAttribute->Name().Locate(':');
+ if ( colon > 0 )
+ {
+ pNamespace =
+ Namespace(pAttribute->Name().Mid(0, colon), KNullDesC8);
+ }
+ if ( pNamespace && (aNamespaces.Find(pNamespace) == -1) )
+ {
+ // Check if namespace declaration for handled attribute
+ // _name_ can be found from aNamespaces array.
+ TInt count(aNamespaces.Count());
+ TBool found(EFalse);
+ for (TInt i = 0; i<count; i++)
+ {
+ if ( aNamespaces[i]->URI() == pNamespace->URI() &&
+ aNamespaces[i]->Prefix() == pNamespace->Prefix() )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ if ( !found )
+ {
+ //If not found then check in namespace usage array that
+ //namespace declaration is present or not. If yes then
+ //continue without adding.
+ if((ipNamespaces && ipNamespaces->Find(pNamespace) == -1) || !ipNamespaces)
+ {
+
+ // Not found
+ // => Create a copy of namespace declaration
+ // and append it into aNamespaces array
+ CSenNamespace* pCopy =
+ CSenNamespace::NewL(pNamespace->Prefix(),
+ pNamespace->URI());
+ CleanupStack::PushL(pCopy);
+ #ifdef EKA2
+ aNamespaces.AppendL(pCopy);
+ #else
+ User::LeaveIfError(aNamespaces.Append(pCopy));
+ #endif
+ CleanupStack::Pop(pCopy);
+ }
+ }
+ }
+ pNamespace = NULL;
+
+ // Check namespace assigned to Value
+ colon = pAttribute->Value().Locate(':');
+ if ( colon > 0 )
+ {
+ pNamespace =
+ Namespace(pAttribute->Value().Mid(0, colon), KNullDesC8);
+ }
+ if ( pNamespace && (aNamespaces.Find(pNamespace) == -1) )
+ {
+ // Check if namespace declaration for handled attribute
+ // _value_ can be found from aNamespaces array.
+ TInt count(aNamespaces.Count());
+ TBool found(EFalse);
+ for (TInt i = 0; i<count; i++)
+ {
+ if ( aNamespaces[i]->URI() == pNamespace->URI() &&
+ aNamespaces[i]->Prefix() == pNamespace->Prefix() )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+ if ( !found )
+ {
+ //If not found then check in namespace usage array that
+ //namspace declaration is present or not.If yes then
+ //continue without adding.
+ if(ipNamespaces && ipNamespaces->Find(pNamespace) == -1)
+ {
+
+ // Not found
+ // => Create a copy of namespace declaration
+ // and append it into aNamespaces array
+ CSenNamespace* pCopy =
+ CSenNamespace::NewL(pNamespace->Prefix(),
+ pNamespace->URI());
+ CleanupStack::PushL(pCopy);
+ #ifdef EKA2
+ aNamespaces.AppendL(pCopy);
+ #else
+ User::LeaveIfError(aNamespaces.Append(pCopy));
+ #endif
+ CleanupStack::Pop(pCopy);
+ }
+ }
+ }
+ pNamespace = NULL;
+ }
+ }
+
+ if(ipElements && ipElements->Count() > 0)
+ {
+ TInt count(ipElements->Count());
+ for(TInt i=0; i<count; i++)
+ {
+ CSenXmlElement* pElement = (CSenXmlElement*) (*ipElements)[i];
+ pElement->AddNamespaceMissingFromL(aNamespaces);
+ }
+ }
+ }
+
+
+EXPORT_C void CSenXmlElement::Set(const TDesC8& aNamespaceURI,
+ const TDesC8& aLocalName,
+ const TDesC8& aQName)
+ {
+ delete ipLocalName;
+ ipLocalName = NULL;
+ HBufC8* pTemp = aLocalName.Alloc();
+ if(pTemp)
+ {
+ ipLocalName = pTemp;
+ }
+
+ TPtrC8 prefix(KNullDesC8);
+
+ if(aQName != KNullDesC8)
+ {
+ TInt colon(KErrNotFound);
+ colon = aQName.Locate(':');
+ if(colon!=KErrNotFound)
+ {
+ prefix.Set(aQName.Left(colon));
+ }
+ }
+ TInt leaveCode(KErrNone);
+ TRAP(leaveCode, SetNamespaceL(prefix, aNamespaceURI);)
+ leaveCode=0;
+
+ //if (err) ;
+ }
+
+EXPORT_C CSenElement* CSenXmlElement::Child(TInt aIndex)
+ {
+ CSenElement* pElement = NULL;
+ if(ipElements && aIndex < ipElements->Count())
+ {
+ pElement = (CSenXmlElement*) (*ipElements)[aIndex];
+ }
+ return pElement;
+ }
+
+EXPORT_C TBool CSenXmlElement::ConsistsOfL(MSenElement& aCandidate)
+ {
+ // First check the names and namespaces
+ if ( aCandidate.LocalName() != this->LocalName()
+ || aCandidate.NamespaceURI() != this->NamespaceURI()
+ || aCandidate.NsPrefix() != this->NsPrefix()
+ )
+ {
+ return EFalse;
+ }
+
+ // Then check content if it exists
+ if (aCandidate.HasContent())
+ {
+ if (aCandidate.Content() != this->Content())
+ {
+ return EFalse; // Content doesn't match => no match
+ }
+ }
+
+ // Then handle the children
+ RPointerArray<CSenElement>& children = aCandidate.ElementsL();
+ TInt childCount = children.Count();
+ TInt i=0;
+ while (i < childCount)
+ {
+ CSenElement* pMatchChild = children[i];
+ CSenElement* pChild = this->Element(pMatchChild->LocalName());
+ if (!pChild)
+ {
+ return EFalse; // no child with same name found in children,
+ // => no match
+ }
+ else
+ {
+ if (!pChild->ConsistsOfL(*pMatchChild))
+ {
+ return EFalse; // a non matching child was found => No match
+ }
+ }
+ i++;
+ }
+ return ETrue;
+ }
+
+void CSenXmlElement::Compress()
+ {
+ if(ipContentWriteStream)
+ {
+ ipContentWriteStream->Close();
+ delete ipContentWriteStream;
+ ipContentWriteStream = NULL;
+ }
+ if (ipContentBuf) ipContentBuf->Compress();
+ if(ipElements)
+ {
+ TInt count(ipElements->Count());
+
+ for (TInt i = 0; i < count; i++)
+ {
+ CSenElement* pElement = (*ipElements)[i];
+ ((CSenXmlElement*)pElement)->Compress();
+ }
+ }
+
+ }
+
+// New methods; problem: assume, that one cannot change CSenElement (abstract)
+// class definition (virtual function tables); therefore one must be cautious
+// and avoid class casting to internal element in base fragment layer(!) in
+// order to access these methods! What if someone added a baseelement? -> crash
+
+// Optimized variant
+// @return NULL if this element has no child elements
+/*
+RPointerArray<CSenElement>* CSenXmlElement::ElementsL()
+ {
+ return ipElements;
+ }
+
+// Optimized variant
+//@return NULL if this element has no attributes
+RPointerArray<CSenBaseAttribute>* CSenXmlElement::AttributesL()
+ {
+ return ipAttrs;
+ }
+
+// Optimized variant
+// @return RPointerArray<CSenNamespace>* or NULL if there are no attributes in this element
+RPointerArray<CSenNamespace>& CSenXmlElement::NamespacesL()
+ {
+ return ipNamespaces;
+ }
+*/
+
+// end of file