diff -r 000000000000 -r 62f9d29f7211 webservices/wsxml/src/senbaseelement.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webservices/wsxml/src/senbaseelement.cpp Thu Jan 07 16:19:19 2010 +0200 @@ -0,0 +1,1387 @@ +/* +* Copyright (c) 2002-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 "SenBaseElement.h" +#include "SenXmlUtils.h" +#include "senxmldebug.h" + +#include "SenXmlConstants.h" // KSenColon, ++ + + + +#ifdef SYMBIAN_SECURE_ECOM + // for S60 2nd edition FP3 (2.8) OR newer 3rd edition platform + #include // needed for RAttributeArray +#else + // for S60 2nd edition, up to FP2 (2.0 - 2.6) + #include "Attribute.h" // needed for RAttributeArray +#endif + +using namespace Xml; + +namespace + { +/* + _LIT8(KColon, ":"); + _LIT8(KLessThan, "<"); + _LIT8(KGreaterThan, ">"); + _LIT8(KSpace, " "); + _LIT8(KDblQuot, "\""); + _LIT8(KEqualsDblQuot, "=\""); + _LIT8(KSlashGreaterThan, "/>"); + _LIT8(KLessThanSlash, "BaseConstructL(aLocalName); + CleanupStack::Pop(); // pNew; + return pNew; + } + +EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri, + const TDesC8& aLocalName) + { + CSenBaseElement* pNew = new (ELeave) CSenBaseElement; + CleanupStack::PushL(pNew); + pNew->BaseConstructL(aNsUri, aLocalName); + CleanupStack::Pop(); // pNew; + return pNew; + } + +EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName) + { + CSenBaseElement* pNew = new (ELeave) CSenBaseElement; + CleanupStack::PushL(pNew); + pNew->BaseConstructL(aNsUri, aLocalName, aQName); + CleanupStack::Pop(); // pNew; + return pNew; + } + +EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName, + const RAttributeArray& apAttrs) + { + CSenBaseElement* pNew = new (ELeave) CSenBaseElement; + CleanupStack::PushL(pNew); + pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs); + CleanupStack::Pop(); // pNew; + return pNew; + } + + +EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName, + const RAttributeArray& apAttrs, + CSenElement& aParent) + { + CSenBaseElement* pNew = new (ELeave) CSenBaseElement; + CleanupStack::PushL(pNew); + pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs, aParent); + CleanupStack::Pop(); // pNew; + return pNew; + } + +EXPORT_C CSenBaseElement::CSenBaseElement() +: ipLocalName(NULL), +// ipNsUri(NULL), + ipContentBuf(NULL), + ipParent(NULL), + ipNamespace(NULL) + { + } + +EXPORT_C CSenBaseElement::~CSenBaseElement() + { + delete ipLocalName; +// delete ipNsUri; + delete ipContentBuf; + + iAttrs.ResetAndDestroy(); + + iElements.ResetAndDestroy(); + iNamespaces.ResetAndDestroy(); + } + + + +EXPORT_C void CSenBaseElement::BaseConstructL(const TDesC8& aLocalName) + { + SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName); + ipLocalName = aLocalName.AllocL(); + } + +EXPORT_C void CSenBaseElement::BaseConstructL(const TDesC8& aNsUri, + const TDesC8& aLocalName) + { + SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName); + if(aNsUri.Length()>0) + { + SetNamespaceL(aNsUri); + } + ipLocalName = aLocalName.AllocL(); + } + +EXPORT_C void CSenBaseElement::BaseConstructL( const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName) + { + SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName); + SenXmlUtils::LeaveOnInvalidElementNameL(aQName); + ipLocalName = aLocalName.AllocL(); + TPtrC8 prefix(KNullDesC8); + if(aQName.Length()>0) + { + TInt colon = aQName.Locate(':'); + if(colon>0) // Note: 0 also treated as no prefix + { + prefix.Set(aQName.Ptr(), colon); + } + } + SetNamespaceL(prefix, aNsUri); + } + +EXPORT_C void CSenBaseElement::BaseConstructL( const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName, + const RAttributeArray& apAttrs) + { + BaseConstructL(aNsUri, aLocalName, aQName); + SetAttributesL(apAttrs); + } + +EXPORT_C void CSenBaseElement::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 CSenBaseElement::SetAttributesL(const RAttributeArray& apAttrs) + { + AddAttributesL(apAttrs); + } + + +EXPORT_C void CSenBaseElement::AddAttributesL(const RAttributeArray& apAttrs) + { + TInt count(apAttrs.Count()); + HBufC8* qName = NULL; + for(TInt i=0; iName()); + + if(!pOldAtt) + { + // transfrer the ownership to this class: +#ifdef EKA2 + iAttrs.AppendL(apAttribute); +#else + User::LeaveIfError(iAttrs.Append(apAttribute)); +#endif // EKA2 + return apAttribute->Value(); + } + else + { + pOldAtt->SetValueL(apAttribute->Value()); + delete apAttribute; + apAttribute = NULL; + return pOldAtt->Value(); + } + } + + +EXPORT_C CSenBaseAttribute* CSenBaseElement::FindAttr(const TDesC8& aName) + { + for (TInt i = 0; i < iAttrs.Count(); i++) + { + if (iAttrs[i]->Name() == aName) + { + return iAttrs[i]; + } + } + return NULL; + } + + +EXPORT_C TInt CSenBaseElement::IndexOfElement(const TDesC8& aNsUri, + const TDesC8& aLocalName) const + { + for (TInt i = 0; i < iElements.Count(); i++) + { + CSenElement* pElement = iElements[i]; + const TDesC8& nsUri = pElement->NamespaceURI(); + const TDesC8& localName = pElement->LocalName(); + if ((nsUri == aNsUri) && (localName == aLocalName)) + { + return i; + } + } + return KErrNotFound; + } + +EXPORT_C const TDesC8& CSenBaseElement::LocalName() const + { + if (ipLocalName == NULL) + { + return KNullDesC8(); + } + else + { + return *ipLocalName; + } + } + +EXPORT_C const TDesC8& CSenBaseElement::NamespaceURI() const + { + if (ipNamespace) + { + return ipNamespace->URI(); + } + else + { + return KNullDesC8(); + } + } + +EXPORT_C const TDesC8& CSenBaseElement::NsPrefix() const + { + if (ipNamespace == NULL) + { + return KNullDesC8(); + } + else + { + return ipNamespace->Prefix(); + } + } + +EXPORT_C TBool CSenBaseElement::HasContent() const + { + if (ipContentBuf == NULL) + { + return EFalse; + } + else + { + return (ipContentBuf->Size() > 0); + } + } + +EXPORT_C TPtrC8 CSenBaseElement::Content() const + { + if (ipContentBuf == NULL) + { + return KNullDesC8(); + } + else + { + TPtrC8 p8 = ipContentBuf->Ptr(0); + return p8; + } + } + + +EXPORT_C HBufC* CSenBaseElement::ContentUnicodeL() const + { + HBufC* pRet = SenXmlUtils::ToUnicodeLC(Content()); + CleanupStack::Pop(); // pRet; + return pRet; + } + +EXPORT_C TPtrC8 CSenBaseElement::SetContentL(const TDesC8& aContent) + { + AllocContentBufL(); // content length is _OK_ to be ZERO + ipContentBuf->ResizeL(aContent.Size()); + ipContentBuf->Write(0, aContent); + + // TPtrC8(REINTERPRET_CAST(const TUint8*, aContent.Ptr()), + // aContent.Size())); + // Reset stream + iContentWriteStream.Open(*ipContentBuf); + return Content(); + } + +EXPORT_C RWriteStream& CSenBaseElement::ContentWriteStreamL() + { + AllocContentBufL(); + iContentWriteStream.Open(*ipContentBuf); + return iContentWriteStream; + } + +// NOTE: assumes(!) that the namespace is same(!) +EXPORT_C RPointerArray& CSenBaseElement::ElementsL() + { + return iElements; + } + +EXPORT_C TInt CSenBaseElement::ElementsL( + RPointerArray& aElementArray, + const TDesC8& aNsUri, + const TDesC8& aLocalName) + { + if (iElements.Count() == 0) + return KErrNotFound; + + CSenElement* pElement = NULL; + TInt count(iElements.Count()); + for (TInt i=0; iLocalName()) && + (aNsUri == pElement->NamespaceURI()) ) + { +#ifdef EKA2 + aElementArray.AppendL(pElement); +#else + User::LeaveIfError(aElementArray.Append(pElement)); +#endif // EKA2 + } + } + + return KErrNone; + } + +EXPORT_C TInt CSenBaseElement::ElementsL( + RPointerArray& aElementArray, + const TDesC8& aLocalName) + { + return ElementsL(aElementArray,NamespaceURI(),aLocalName); + } + +EXPORT_C const TDesC8* CSenBaseElement::AttrValue(const TDesC8& aName) + { + CSenBaseAttribute* pAttr = FindAttr(aName); + if (pAttr == NULL) + { + return NULL; + } + else + { + return &(pAttr->Value()); + } + } + +EXPORT_C void CSenBaseElement::AddAttrL(const TDesC8& aName, + const TDesC8& aValue) + { + CSenBaseAttribute* pAttr = FindAttr(aName); + if (pAttr == NULL) + { + User::LeaveIfError(iAttrs.Append(CSenBaseAttribute::NewL(aName, + aValue))); + } + else + { + pAttr->SetValueL(aValue); + } + } + +EXPORT_C CSenElement* CSenBaseElement::Parent() + { + return ipParent; + } + +EXPORT_C CSenElement* CSenBaseElement::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 = + ((CSenBaseElement*) 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 + TInt nsIndex = iNamespaces.Find(ipNamespace); + if ( nsIndex != KErrNotFound) + { + iNamespaces.Remove(nsIndex); + } + delete ipNamespace; + ipNamespace = (CSenNamespace*)pNs; + } + } + + } + } + return apParent; + } + +EXPORT_C MSenElement& CSenBaseElement::Root() + { + if (ipParent == NULL) + { + return *this; + } + else + { + return ipParent->Root(); + } + } + +EXPORT_C CSenElement* CSenBaseElement::Element(const TDesC8& aLocalName) + { + return Element(NamespaceURI(), aLocalName); + } + +EXPORT_C CSenElement* CSenBaseElement::Element(const TDesC8& aNsUri, + const TDesC8& aLocalName) + { + TInt idx = IndexOfElement(aNsUri, aLocalName); + if (idx < 0) + { + return NULL; + } + else + { + return iElements[idx]; + } + } + +EXPORT_C CSenElement* CSenBaseElement::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 = + CSenBaseElement::NewL(pNamespace->URI(), aLocalName, *pQName); + CleanupStack::PopAndDestroy(); // pQName + } + } + else + { + pNewElement = CSenBaseElement::NewL(aLocalName); + } + + return pNewElement; // Returns NULL if required namespace can not be found! + } + +EXPORT_C CSenElement& CSenBaseElement::InsertElementL( + CSenElement& aElement, + const CSenElement& aBeforeElement) + { + TInt index(KErrNotFound); + index = iElements.Find(&aBeforeElement); + if (index != KErrNotFound) + { + User::LeaveIfError(iElements.Insert(&aElement,index)); + } + else + { + User::LeaveIfError(iElements.Append(&aElement)); + } + aElement.SetParent(this); + return aElement; + } + +EXPORT_C CSenElement& CSenBaseElement::AddElementL(CSenElement& aElement) + { + User::LeaveIfError(iElements.Append(&aElement)); + aElement.SetParent(this); + return aElement; + } + +EXPORT_C CSenElement& CSenBaseElement::AddElementL(const TDesC8& aNsUri, + const TDesC8& aLocalName) + { + return AddElementL(*CSenBaseElement::NewL(aNsUri, aLocalName)); + } + +EXPORT_C CSenElement& CSenBaseElement::AddElementL( + const TDesC8& aNsUri, + const TDesC8& aLocalName, + const TDesC8& aQName + ) + { + return AddElementL(*CSenBaseElement::NewL(aNsUri, aLocalName, aQName)); + } + +EXPORT_C CSenElement& CSenBaseElement::AddElementL(const TDesC8& aLocalName) + { + return AddElementL(*CSenBaseElement::NewL(aLocalName)); + } + +EXPORT_C CSenElement* CSenBaseElement::RemoveElement(CSenElement& aElement) + { + TInt idx = iElements.Find(&aElement); + if (idx >= 0) + { + CSenElement* pElement = iElements[idx]; + iElements.Remove(idx); + pElement->SetParent(NULL); + return pElement; + } + else + { + return NULL; + } + } + +EXPORT_C CSenElement* CSenBaseElement::RemoveElement(const TDesC8& aNsUri, + const TDesC8& aLocalName) + { + TInt idx = IndexOfElement(aNsUri, aLocalName); + if (idx >= 0) + { + CSenElement* pElement = iElements[idx]; + iElements.Remove(idx); + pElement->SetParent(NULL); + return pElement; + } + else + { + return NULL; + } + } + +EXPORT_C CSenElement* CSenBaseElement::RemoveElement(const TDesC8& aLocalName) + { + return RemoveElement(NamespaceURI(), aLocalName); + } + +EXPORT_C CSenElement* CSenBaseElement::ReplaceElementL(CSenElement& aElement) + { + CSenElement* pOldElement = + RemoveElement(aElement.NamespaceURI(), aElement.LocalName()); + CleanupStack::PushL(pOldElement); + AddElementL(aElement); + CleanupStack::Pop(); // pOldElement; + return pOldElement; + } + +EXPORT_C HBufC8* CSenBaseElement::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* CSenBaseElement::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 CSenBaseElement::WriteToBufL(CBufBase& aBuf) + { + RBufWriteStream bufWs(aBuf); + CleanupClosePushL(bufWs); + this->WriteAsXMLToL(bufWs); + CleanupStack::PopAndDestroy(); // bufWs.Close(); + return aBuf.Ptr(0); + } + +EXPORT_C void CSenBaseElement::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 (iAttrs.Count() > 0 || iNamespaces.Count() > 0) + { + WriteNamespacesToL(aWriteStream); + WriteAttrsToL(aWriteStream); + } + + // Elements and content + if ((iElements.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 CSenBaseElement::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 CSenBaseElement::WriteAttrsToL(RWriteStream& aWriteStream) + { + for (TInt i = 0; i < iAttrs.Count(); i++) + { + WriteAttrToL(aWriteStream, iAttrs[i]->Name(), iAttrs[i]->Value()); + } + } + +EXPORT_C void CSenBaseElement::WriteNamespacesToL(RWriteStream& aWriteStream) + { + TInt count = iNamespaces.Count(); + CSenNamespace* ns = NULL; + if (count > 0) + { + for (TInt i=0; i < count; i++) + { + ns = iNamespaces[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 CSenBaseElement::WriteElementsToL(RWriteStream& aWriteStream) + { + TInt elementCount(iElements.Count()); + for (TInt i=0; iWriteAsXMLToL(aWriteStream); + } + } + +EXPORT_C void CSenBaseElement::WriteContentToL(RWriteStream& aWriteStream) + { + aWriteStream.WriteL(Content()); + } + +EXPORT_C MSenElement* CSenBaseElement::AsElement() + { + return this; + } + +EXPORT_C void CSenBaseElement::AllocContentBufL() + { + if(!ipContentBuf) + { + ipContentBuf = CBufFlat::NewL(KFlatBufSize); + } + } + +EXPORT_C void CSenBaseElement::SetNamespaceL(const TDesC8& aNsUri) + { + SetNamespaceL(KNullDesC8, aNsUri); + } + +EXPORT_C void CSenBaseElement::SetNamespaceL(const TDesC8& aNsPrefix, + const TDesC8& aNsUri) + { + if (aNsUri.Length() > 0) + { + ipNamespace = (CSenNamespace*) Namespace(aNsPrefix, aNsUri); + if (!ipNamespace) + { + ipNamespace = CSenNamespace::NewL(aNsPrefix, aNsUri); + +#ifdef EKA2 + iNamespaces.AppendL(ipNamespace); +#else + User::LeaveIfError(iNamespaces.Append(ipNamespace)); +#endif // EKA2 + } + } + } + +EXPORT_C const CSenNamespace* CSenBaseElement::Namespace() + { + return ipNamespace; + } + +EXPORT_C const CSenNamespace* CSenBaseElement::Namespace( + const TDesC8& aNsPrefix) + { + return Namespace(aNsPrefix,ETrue); + } + +EXPORT_C const CSenNamespace* CSenBaseElement::Namespace( + const TDesC8& aNsPrefix, + const TBool aCheckInParent) + { + if (aNsPrefix.Length() == 0) return NULL; + + const CSenNamespace* pNamespace = NULL; + + TInt count(iNamespaces.Count()); + for (TInt i=0; iPrefix() != aNsPrefix) pNamespace = NULL; + } + } + + if (pNamespace == NULL && ipParent && aCheckInParent) + { + pNamespace = ipParent->Namespace(aNsPrefix); + } + + return pNamespace; + } + + +EXPORT_C const CSenNamespace* CSenBaseElement::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 + TInt count = iNamespaces.Count(); + if (count != 0) + { + for (TInt i=0; iCompare(aNsPrefix, aUri)) + { + pNs = NULL; + } + 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& CSenBaseElement::AttributesL() + { + return iAttrs; + } + +EXPORT_C RPointerArray& CSenBaseElement::NamespacesL() + { + return iNamespaces; + } + +EXPORT_C void CSenBaseElement::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 sourceNamespaces = aSource.NamespacesL(); + if (sourceNamespaces.Count() > 0) + { + for (TInt i=0;iPrefix(),pNamespace->URI()); + CleanupStack::PushL(pNewNamespace); +#ifdef EKA2 + iNamespaces.AppendL(pNewNamespace); +#else + User::LeaveIfError(iNamespaces.Append(pNewNamespace)); +#endif + + CleanupStack::Pop(pNewNamespace); + } + } + SetNamespaceL(aSource.NsPrefix(), aSource.NamespaceURI()); + + RPointerArray sourceAttributes = aSource.AttributesL(); + if (sourceAttributes.Count() > 0) + { + for (TInt i=0;iName()); + if (pOriginal) + { + pOriginal->SetValueL(pBaseAttribute->Value()); + continue; + } + + CSenBaseAttribute* pNewBaseAttribute = + CSenBaseAttribute::NewL(pBaseAttribute->Name(), + pBaseAttribute->Value()); + CleanupStack::PushL(pNewBaseAttribute); +#ifdef EKA2 + iAttrs.AppendL(pNewBaseAttribute); +#else + User::LeaveIfError(iAttrs.Append(pNewBaseAttribute)); +#endif + CleanupStack::Pop(pNewBaseAttribute); + } + } + + RPointerArray sourceElements = aSource.ElementsL(); + if (sourceElements.Count() > 0) + { + for (TInt i=0;iLocalName()); + pNewElement->SetParent(this); + CleanupStack::PushL(pNewElement); + pNewElement->CopyFromL(*pElement); +#ifdef EKA2 + iElements.AppendL(pNewElement); +#else + User::LeaveIfError(iElements.Append(pNewElement)); +#endif // EKA2 + CleanupStack::Pop(pNewElement); + } + } + } + +EXPORT_C void CSenBaseElement::SetPrefixL(const TDesC8& aPrefix) + { + if (iNamespaces.Find(ipNamespace) > -1) + { + //the namespace was locally declared + + // Check if element already has a namespace with given prefix + CSenNamespace* pNamespace = NULL; + TInt count(iNamespaces.Count()); + for (TInt i=0; iPrefix() != aPrefix) pNamespace = NULL; + } + + if (pNamespace) + { + // Update existing namespace + const TDesC8& uri = ipNamespace->URI(); + pNamespace->SetUriL(uri); + ipNamespace = pNamespace; + } + else + { + if (ipNamespace->Prefix().Length() > 0 && iElements.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); +#ifdef EKA2 + iNamespaces.AppendL(ipNamespace); +#else + User::LeaveIfError(iNamespaces.Append(ipNamespace)); +#endif + } + ipNamespace->SetPrefixL(aPrefix); + } + } + } + +EXPORT_C const CSenNamespace* CSenBaseElement::AddNamespaceL( + CSenNamespace& aNewNamespace, + TBool aCheckInParent) + { + const CSenNamespace* pNamespace = + Namespace(aNewNamespace.Prefix(), aCheckInParent); + if (pNamespace == NULL) + { + CSenNamespace* pNewNamespace = + CSenNamespace::NewL(aNewNamespace.Prefix(), aNewNamespace.URI()); + CleanupStack::PushL(pNewNamespace); +#ifdef EKA2 + iNamespaces.AppendL(pNewNamespace); +#else + User::LeaveIfError(iNamespaces.Append(pNewNamespace)); +#endif + CleanupStack::Pop(); // pNewNamespace + pNamespace = pNewNamespace; + } + return pNamespace; + } + +EXPORT_C const CSenNamespace* CSenBaseElement::AddNamespaceL( + const TDesC8& aPrefix, + const TDesC8& aUri) + { + CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aPrefix); + if (!pNamespace) + { + if (aUri.Length() > 0) + { + pNamespace = CSenNamespace::NewL(aPrefix, aUri); + CleanupStack::PushL(pNamespace); +#ifdef EKA2 + iNamespaces.AppendL(pNamespace); +#else + User::LeaveIfError(iNamespaces.Append(pNamespace)); +#endif + CleanupStack::Pop(); // pNamespace + } + } + else + { + pNamespace->SetUriL(aUri); + } + + + return pNamespace; + } + +EXPORT_C CSenElement* CSenBaseElement::DetachL() + { + if (!ipParent) + { + return NULL; + } + AddNamespaceMissingFromL(iNamespaces); + ipParent->RemoveElement(*this); + return this; + } + +void CSenBaseElement::AddNamespaceMissingFromL( + RPointerArray& 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 (; iURI() == ipNamespace->URI() && + aNamespaces[i]->Prefix() == ipNamespace->Prefix() ) + { + found = ETrue; + break; + } + } + if ( !found ) + { + // 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 ( iAttrs.Count() > 0 ) + { + TInt colon = -1; + const CSenNamespace* pNamespace = NULL; + + TInt count(iAttrs.Count()); + for (TInt i=0; iName().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; iURI() == pNamespace->URI() && + aNamespaces[i]->Prefix() == pNamespace->Prefix() ) + { + found = ETrue; + break; + } + } + if ( !found ) + { + // 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; iURI() == pNamespace->URI() && + aNamespaces[i]->Prefix() == pNamespace->Prefix() ) + { + found = ETrue; + break; + } + } + if ( !found ) + { + // 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; + } + } + + // Do recursive search for all child elements and for all child + // elements of all child elements and so on. + if ( iElements.Count() > 0 ) + { + TInt count(iElements.Count()); + for (TInt i=0; iAddNamespaceMissingFromL(aNamespaces); + } + } + } + + +EXPORT_C void CSenBaseElement::Set(const TDesC8& aNamespaceURI, + const TDesC8& aLocalName, + const TDesC8& aQName) + { + + HBufC8* pTemp = aLocalName.Alloc(); + if(pTemp) + { + delete ipLocalName; + ipLocalName = NULL; + 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* CSenBaseElement::Child(TInt aIndex) + { + CSenElement* pElement = NULL; + if (aIndex < iElements.Count()) + { + pElement = (CSenBaseElement*) iElements[aIndex]; + } + return pElement; + } + +EXPORT_C TBool CSenBaseElement::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& 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; + } + +// End of File +