webservices/wsxml/src/senbaseelement.cpp
changeset 0 62f9d29f7211
child 20 f68f07157250
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:        
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 // INCLUDE FILES
       
    26 #include "SenBaseElement.h"
       
    27 #include "SenXmlUtils.h"
       
    28 #include "senxmldebug.h"
       
    29 
       
    30 #include "SenXmlConstants.h" // KSenColon, ++
       
    31 
       
    32 
       
    33 
       
    34 #ifdef SYMBIAN_SECURE_ECOM 
       
    35     // for S60 2nd edition FP3 (2.8) OR newer 3rd edition platform
       
    36     #include <xml/attribute.h> // needed for RAttributeArray
       
    37 #else 
       
    38     // for S60 2nd edition, up to FP2 (2.0 - 2.6)
       
    39     #include "Attribute.h" // needed for RAttributeArray
       
    40 #endif
       
    41 
       
    42 using namespace Xml;
       
    43 
       
    44 namespace
       
    45     {
       
    46 /*
       
    47     _LIT8(KColon,            ":");
       
    48     _LIT8(KLessThan,         "<");
       
    49     _LIT8(KGreaterThan,      ">");
       
    50     _LIT8(KSpace,            " ");
       
    51     _LIT8(KDblQuot,          "\"");
       
    52     _LIT8(KEqualsDblQuot,    "=\"");
       
    53     _LIT8(KSlashGreaterThan, "/>");
       
    54     _LIT8(KLessThanSlash,    "</");
       
    55     _LIT8(KSpaceXmlns,       " xmlns");
       
    56     _LIT8(KXmlns,            "xmlns");
       
    57     _LIT8(KXmlNsAttNamePlusColon,   "xmlns:"); 
       
    58 */
       
    59     const TInt KFlatBufSize          = 64;  // CBufFlat
       
    60     }
       
    61 
       
    62 EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aLocalName)
       
    63     {
       
    64     CSenBaseElement* pNew = new (ELeave) CSenBaseElement;
       
    65     CleanupStack::PushL(pNew);
       
    66     pNew->BaseConstructL(aLocalName);
       
    67     CleanupStack::Pop(); // pNew;
       
    68     return pNew;
       
    69     }
       
    70 
       
    71 EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri,
       
    72                                                 const TDesC8& aLocalName)
       
    73     {
       
    74     CSenBaseElement* pNew = new (ELeave) CSenBaseElement;
       
    75     CleanupStack::PushL(pNew);
       
    76     pNew->BaseConstructL(aNsUri, aLocalName);
       
    77     CleanupStack::Pop(); // pNew;
       
    78     return pNew;
       
    79     }
       
    80 
       
    81 EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri,
       
    82                                                 const TDesC8& aLocalName,
       
    83                                                 const TDesC8& aQName)
       
    84     {
       
    85     CSenBaseElement* pNew = new (ELeave) CSenBaseElement;
       
    86     CleanupStack::PushL(pNew);
       
    87     pNew->BaseConstructL(aNsUri, aLocalName, aQName);
       
    88     CleanupStack::Pop(); // pNew;
       
    89     return pNew;
       
    90     }
       
    91 
       
    92 EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri,
       
    93                                                 const TDesC8& aLocalName,
       
    94                                                 const TDesC8& aQName,
       
    95                                                 const RAttributeArray& apAttrs)
       
    96     {
       
    97     CSenBaseElement* pNew = new (ELeave) CSenBaseElement;
       
    98     CleanupStack::PushL(pNew);
       
    99     pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs);
       
   100     CleanupStack::Pop(); // pNew;
       
   101     return pNew;
       
   102     }
       
   103 
       
   104 
       
   105 EXPORT_C CSenBaseElement* CSenBaseElement::NewL(const TDesC8& aNsUri,
       
   106                                                 const TDesC8& aLocalName,
       
   107                                                 const TDesC8& aQName,
       
   108                                                 const RAttributeArray& apAttrs,
       
   109                                                 CSenElement& aParent)
       
   110     {
       
   111     CSenBaseElement* pNew = new (ELeave) CSenBaseElement;
       
   112     CleanupStack::PushL(pNew);
       
   113     pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs, aParent);
       
   114     CleanupStack::Pop(); // pNew;
       
   115     return pNew;
       
   116     }
       
   117 
       
   118 EXPORT_C CSenBaseElement::CSenBaseElement()
       
   119 : ipLocalName(NULL),
       
   120 //  ipNsUri(NULL),
       
   121   ipContentBuf(NULL),
       
   122   ipParent(NULL),
       
   123   ipNamespace(NULL)
       
   124     {
       
   125     }
       
   126 
       
   127 EXPORT_C CSenBaseElement::~CSenBaseElement()
       
   128     {
       
   129     delete ipLocalName;
       
   130 //    delete ipNsUri;
       
   131     delete ipContentBuf;
       
   132 
       
   133     iAttrs.ResetAndDestroy();
       
   134 
       
   135     iElements.ResetAndDestroy();
       
   136     iNamespaces.ResetAndDestroy();
       
   137     }
       
   138 
       
   139 
       
   140 
       
   141 EXPORT_C void CSenBaseElement::BaseConstructL(const TDesC8& aLocalName)
       
   142     {
       
   143     SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
       
   144     ipLocalName = aLocalName.AllocL();
       
   145     }
       
   146 
       
   147 EXPORT_C void CSenBaseElement::BaseConstructL(const TDesC8& aNsUri,
       
   148                                               const TDesC8& aLocalName)
       
   149     {
       
   150     SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
       
   151     if(aNsUri.Length()>0)
       
   152         {
       
   153         SetNamespaceL(aNsUri);
       
   154         }
       
   155     ipLocalName = aLocalName.AllocL();
       
   156     }
       
   157 
       
   158 EXPORT_C void CSenBaseElement::BaseConstructL(  const TDesC8& aNsUri,
       
   159                                                 const TDesC8& aLocalName,
       
   160                                                 const TDesC8& aQName)
       
   161     {
       
   162     SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
       
   163     SenXmlUtils::LeaveOnInvalidElementNameL(aQName);
       
   164     ipLocalName = aLocalName.AllocL();
       
   165     TPtrC8 prefix(KNullDesC8);
       
   166     if(aQName.Length()>0)
       
   167         {
       
   168         TInt colon = aQName.Locate(':');
       
   169         if(colon>0) // Note: 0 also treated as no prefix
       
   170             {
       
   171             prefix.Set(aQName.Ptr(), colon);
       
   172             }
       
   173         }
       
   174     SetNamespaceL(prefix, aNsUri);
       
   175     }
       
   176 
       
   177 EXPORT_C void CSenBaseElement::BaseConstructL(  const TDesC8& aNsUri,
       
   178                                                 const TDesC8& aLocalName,
       
   179                                                 const TDesC8& aQName,
       
   180                                                 const RAttributeArray& apAttrs)
       
   181     {
       
   182     BaseConstructL(aNsUri, aLocalName, aQName);
       
   183     SetAttributesL(apAttrs);
       
   184     }
       
   185 
       
   186 EXPORT_C void CSenBaseElement::BaseConstructL(  const TDesC8& aNsUri,
       
   187                                                 const TDesC8& aLocalName,
       
   188                                                 const TDesC8& aQName,
       
   189                                                 const RAttributeArray& apAttrs,
       
   190                                                 CSenElement& aParent    )
       
   191     {
       
   192     // parent must be set here at first line, because
       
   193     // namespace setting dependends of it(!)
       
   194     ipParent = &aParent;
       
   195 
       
   196     BaseConstructL(aNsUri, aLocalName, aQName);
       
   197     SetAttributesL(apAttrs);
       
   198     }
       
   199 
       
   200 EXPORT_C void CSenBaseElement::SetAttributesL(const RAttributeArray& apAttrs)
       
   201     {
       
   202     AddAttributesL(apAttrs);
       
   203     }
       
   204 
       
   205 
       
   206 EXPORT_C void CSenBaseElement::AddAttributesL(const RAttributeArray& apAttrs)
       
   207     {
       
   208     TInt count(apAttrs.Count());
       
   209     HBufC8* qName = NULL;
       
   210     for(TInt i=0; i<count; i++)
       
   211         {
       
   212         const TPtrC8 localname = apAttrs[i].Attribute().LocalName().DesC();
       
   213         const TPtrC8 prefix = apAttrs[i].Attribute().Prefix().DesC();
       
   214         const TPtrC8 value = apAttrs[i].Value().DesC();
       
   215 
       
   216         SenXmlUtils::BuildQNameL(prefix, localname, qName);
       
   217 
       
   218         CleanupStack::PushL(qName);
       
   219 
       
   220         HBufC8* encodedValue = NULL;
       
   221         TBool encoded = 
       
   222             SenXmlUtils::EncodeHttpCharactersL(value, encodedValue);
       
   223 
       
   224         if (encoded)
       
   225             {
       
   226             CleanupStack::PushL(encodedValue);
       
   227             AddAttributeL(*qName, localname, *encodedValue); 
       
   228             // note: this intentionally
       
   229             // skips the 2 param 
       
   230             // AddAttributeL() function
       
   231 
       
   232             CleanupStack::PopAndDestroy(); // encodedValue
       
   233             }
       
   234         else
       
   235             {
       
   236             AddAttributeL(*qName, localname, value); 
       
   237             // note: this intentionally
       
   238             // skips the 2 param 
       
   239             // AddAttributeL() function
       
   240             }
       
   241 
       
   242         CleanupStack::PopAndDestroy(); // qName
       
   243         }
       
   244     }
       
   245 
       
   246 EXPORT_C const TDesC8& CSenBaseElement::AddAttributeL(const TDesC8& aQName,
       
   247                                                      const TDesC8& aLocalName,
       
   248                                                      const TDesC8& aValue)
       
   249     {
       
   250     // first we check for possible namespace declarations...
       
   251     if ( aQName == KSenXmlns || aLocalName == KSenXmlns)
       
   252         {
       
   253         // this is a default name space declaration
       
   254         SetNamespaceL(aValue);
       
   255         }
       
   256     else if (aLocalName == NsPrefix())
       
   257         {
       
   258         //we have a new declaration for the namespace of this element
       
   259         SetNamespaceL(aLocalName, aValue);
       
   260         }
       
   261     else if(aQName.Find(KSenXmlNsAttNamePlusColon) == 0)
       
   262         {
       
   263         // we have an additional namespace declaration
       
   264         AddNamespaceL(aLocalName, aValue);
       
   265         }
       
   266     else
       
   267         {
       
   268         // we have a real attribute!
       
   269         CSenBaseAttribute* pAttribute = CSenBaseAttribute::NewL(aQName,
       
   270                                                                 aLocalName,
       
   271                                                                 aValue);
       
   272         AddAttributeL(pAttribute);
       
   273         }
       
   274     return aValue;
       
   275     }
       
   276 
       
   277 
       
   278 
       
   279 EXPORT_C const TDesC8& CSenBaseElement::AddAttributeL(const TDesC8& aAttrName,
       
   280                                                       const TDesC8& aValue)
       
   281     {
       
   282     // note, the aAttrName may be a qualified name or simply localname
       
   283     // strip off the possible prefix from possible qualified name:
       
   284     TPtrC8 localName = SenXmlUtils::LocalName(aAttrName);
       
   285     return AddAttributeL(aAttrName, localName, aValue);
       
   286     }
       
   287 
       
   288 // takes the ownership of aAttribute
       
   289 EXPORT_C const TDesC8& CSenBaseElement::AddAttributeL(CSenBaseAttribute* apAttribute)
       
   290     {
       
   291     CSenBaseAttribute* pOldAtt = FindAttr(apAttribute->Name());
       
   292 
       
   293     if(!pOldAtt)
       
   294         {
       
   295         // transfrer the ownership to this class:
       
   296 #ifdef EKA2
       
   297         iAttrs.AppendL(apAttribute);
       
   298 #else
       
   299         User::LeaveIfError(iAttrs.Append(apAttribute));
       
   300 #endif // EKA2
       
   301         return apAttribute->Value();
       
   302         }
       
   303     else
       
   304         {
       
   305         pOldAtt->SetValueL(apAttribute->Value());
       
   306         delete apAttribute;
       
   307         apAttribute = NULL;
       
   308         return pOldAtt->Value();
       
   309         }
       
   310     }
       
   311 
       
   312 
       
   313 EXPORT_C CSenBaseAttribute* CSenBaseElement::FindAttr(const TDesC8& aName)
       
   314     {
       
   315     for (TInt i = 0; i < iAttrs.Count(); i++)
       
   316         {
       
   317         if (iAttrs[i]->Name() == aName)
       
   318             {
       
   319             return iAttrs[i];
       
   320             }
       
   321         }
       
   322     return NULL;
       
   323     }
       
   324 
       
   325 
       
   326 EXPORT_C TInt CSenBaseElement::IndexOfElement(const TDesC8& aNsUri,
       
   327                                               const TDesC8& aLocalName) const
       
   328     {
       
   329     for (TInt i = 0; i < iElements.Count(); i++)
       
   330         {
       
   331         CSenElement* pElement = iElements[i];
       
   332         const TDesC8& nsUri = pElement->NamespaceURI();
       
   333         const TDesC8& localName = pElement->LocalName();
       
   334         if ((nsUri == aNsUri) && (localName == aLocalName))
       
   335             {
       
   336             return i;
       
   337             }
       
   338         }
       
   339     return KErrNotFound;
       
   340     }
       
   341 
       
   342 EXPORT_C const TDesC8& CSenBaseElement::LocalName() const
       
   343     {
       
   344     if (ipLocalName == NULL)
       
   345         {
       
   346         return KNullDesC8();
       
   347         }
       
   348     else
       
   349         {
       
   350         return *ipLocalName;
       
   351         }
       
   352     }
       
   353 
       
   354 EXPORT_C const TDesC8& CSenBaseElement::NamespaceURI() const
       
   355     {
       
   356     if (ipNamespace)
       
   357         {
       
   358         return ipNamespace->URI();
       
   359         }
       
   360     else
       
   361         {
       
   362         return KNullDesC8();
       
   363         }
       
   364     }
       
   365 
       
   366 EXPORT_C const TDesC8& CSenBaseElement::NsPrefix() const
       
   367     {
       
   368     if (ipNamespace == NULL)
       
   369         {
       
   370         return KNullDesC8();
       
   371         }
       
   372     else
       
   373         {
       
   374         return ipNamespace->Prefix();
       
   375         }
       
   376     }
       
   377 
       
   378 EXPORT_C TBool CSenBaseElement::HasContent() const
       
   379     {
       
   380     if (ipContentBuf == NULL)
       
   381         {
       
   382         return EFalse;
       
   383         }
       
   384     else
       
   385         {
       
   386         return (ipContentBuf->Size() > 0);
       
   387         }
       
   388     }
       
   389 
       
   390 EXPORT_C TPtrC8 CSenBaseElement::Content() const
       
   391     {
       
   392     if (ipContentBuf == NULL)
       
   393         {
       
   394         return KNullDesC8();
       
   395         }
       
   396     else
       
   397         {
       
   398         TPtrC8 p8 = ipContentBuf->Ptr(0);
       
   399         return p8;
       
   400         }
       
   401     }
       
   402 
       
   403 
       
   404 EXPORT_C HBufC* CSenBaseElement::ContentUnicodeL() const
       
   405     {
       
   406     HBufC* pRet = SenXmlUtils::ToUnicodeLC(Content());
       
   407     CleanupStack::Pop(); // pRet;
       
   408     return pRet;
       
   409     }
       
   410 
       
   411 EXPORT_C TPtrC8 CSenBaseElement::SetContentL(const TDesC8& aContent)
       
   412     {
       
   413     AllocContentBufL(); // content length is _OK_ to be ZERO
       
   414     ipContentBuf->ResizeL(aContent.Size());
       
   415     ipContentBuf->Write(0, aContent);
       
   416   
       
   417     //   TPtrC8(REINTERPRET_CAST(const TUint8*, aContent.Ptr()),
       
   418     //                                            aContent.Size()));
       
   419     // Reset stream
       
   420     iContentWriteStream.Open(*ipContentBuf);
       
   421     return Content();
       
   422     }
       
   423 
       
   424 EXPORT_C RWriteStream& CSenBaseElement::ContentWriteStreamL()
       
   425     {
       
   426     AllocContentBufL();
       
   427     iContentWriteStream.Open(*ipContentBuf);
       
   428     return iContentWriteStream;
       
   429     }
       
   430 
       
   431 // NOTE: assumes(!) that the namespace is same(!)
       
   432 EXPORT_C RPointerArray<CSenElement>& CSenBaseElement::ElementsL()
       
   433     {
       
   434     return iElements;
       
   435     }
       
   436 
       
   437 EXPORT_C TInt CSenBaseElement::ElementsL(
       
   438                                     RPointerArray<CSenElement>& aElementArray,
       
   439                                     const TDesC8& aNsUri,
       
   440                                     const TDesC8& aLocalName)
       
   441     {
       
   442     if (iElements.Count() == 0)
       
   443         return KErrNotFound;
       
   444 
       
   445     CSenElement* pElement = NULL;
       
   446     TInt count(iElements.Count());
       
   447     for (TInt i=0; i<count; i++)
       
   448         {
       
   449         pElement = iElements[i];
       
   450         if ( (aLocalName == pElement->LocalName()) &&
       
   451              (aNsUri == pElement->NamespaceURI()) )
       
   452             {
       
   453 #ifdef EKA2
       
   454             aElementArray.AppendL(pElement);
       
   455 #else
       
   456             User::LeaveIfError(aElementArray.Append(pElement));
       
   457 #endif // EKA2
       
   458             }
       
   459         }
       
   460 
       
   461     return KErrNone;
       
   462     }
       
   463 
       
   464 EXPORT_C TInt CSenBaseElement::ElementsL(
       
   465                                     RPointerArray<CSenElement>& aElementArray,
       
   466                                     const TDesC8& aLocalName)
       
   467     {
       
   468     return ElementsL(aElementArray,NamespaceURI(),aLocalName);
       
   469     }
       
   470 
       
   471 EXPORT_C const TDesC8* CSenBaseElement::AttrValue(const TDesC8& aName)
       
   472     {
       
   473     CSenBaseAttribute* pAttr = FindAttr(aName);
       
   474     if (pAttr == NULL)
       
   475         {
       
   476         return NULL;
       
   477         }
       
   478     else
       
   479         {
       
   480         return &(pAttr->Value());
       
   481         }
       
   482     }
       
   483 
       
   484 EXPORT_C void CSenBaseElement::AddAttrL(const TDesC8& aName,
       
   485                                         const TDesC8& aValue)
       
   486     {
       
   487     CSenBaseAttribute* pAttr = FindAttr(aName);
       
   488     if (pAttr == NULL)
       
   489         {
       
   490         User::LeaveIfError(iAttrs.Append(CSenBaseAttribute::NewL(aName,
       
   491                                                                  aValue)));
       
   492         }
       
   493     else
       
   494         {
       
   495         pAttr->SetValueL(aValue);
       
   496         }
       
   497     }
       
   498 
       
   499 EXPORT_C CSenElement* CSenBaseElement::Parent()
       
   500     {
       
   501     return ipParent;
       
   502     }
       
   503 
       
   504 EXPORT_C CSenElement* CSenBaseElement::SetParent(CSenElement* apParent)  // IOP
       
   505     {
       
   506     if (apParent && ipParent != apParent)
       
   507         {
       
   508         ipParent = apParent;
       
   509         if (!ipNamespace)
       
   510             {
       
   511             // check if there is a default namespace declared in the scope of
       
   512             // the parent
       
   513             const CSenNamespace* pParentNamespace =
       
   514                 ((CSenBaseElement*) ipParent)->Namespace(KNullDesC8,ETrue);
       
   515             if (pParentNamespace && pParentNamespace->Prefix() == KNullDesC8)
       
   516                 {
       
   517                 ipNamespace = (CSenNamespace*)pParentNamespace;
       
   518                 }
       
   519             }
       
   520         else
       
   521             {
       
   522             //check if the parent already has a namespace for this element
       
   523             // if so remove it from the local namespace table
       
   524             const CSenNamespace* pNs = ipParent->Namespace(KNullDesC8,
       
   525                                                     ipNamespace->URI());
       
   526             if (pNs && pNs != ipNamespace)
       
   527                 {
       
   528                 if (ipNamespace->Compare(*pNs) ||
       
   529                     ipNamespace->Prefix().Length() == 0)
       
   530                     {
       
   531                     //prefix is also identical or this element has no prefix
       
   532                     TInt nsIndex = iNamespaces.Find(ipNamespace);
       
   533                     if ( nsIndex != KErrNotFound)
       
   534                         {
       
   535                         iNamespaces.Remove(nsIndex);
       
   536                         }
       
   537                     delete ipNamespace;
       
   538                     ipNamespace = (CSenNamespace*)pNs;
       
   539                     }
       
   540                 }
       
   541 
       
   542             }
       
   543         }
       
   544     return apParent;
       
   545     }
       
   546 
       
   547 EXPORT_C MSenElement& CSenBaseElement::Root()
       
   548     {
       
   549     if (ipParent == NULL)
       
   550         {
       
   551         return *this;
       
   552         }
       
   553     else
       
   554         {
       
   555         return ipParent->Root();
       
   556         }
       
   557     }
       
   558 
       
   559 EXPORT_C CSenElement* CSenBaseElement::Element(const TDesC8& aLocalName)
       
   560     {
       
   561     return Element(NamespaceURI(), aLocalName);
       
   562     }
       
   563 
       
   564 EXPORT_C CSenElement* CSenBaseElement::Element(const TDesC8& aNsUri,
       
   565                                                const TDesC8& aLocalName)
       
   566     {
       
   567     TInt idx = IndexOfElement(aNsUri, aLocalName);
       
   568     if (idx < 0)
       
   569         {
       
   570         return NULL;
       
   571         }
       
   572     else
       
   573         {
       
   574         return iElements[idx];
       
   575         }
       
   576     }
       
   577 
       
   578 EXPORT_C CSenElement* CSenBaseElement::CreateElementL(const TDesC8& aNsPrefix,
       
   579                                                       const TDesC8& aLocalName)
       
   580     {
       
   581     CSenElement* pNewElement = NULL;
       
   582 
       
   583     if (aNsPrefix.Length() > 0)
       
   584         {
       
   585         CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aNsPrefix);
       
   586         if (pNamespace)
       
   587             {
       
   588             HBufC8 *pQName =
       
   589                 HBufC8::NewLC(aNsPrefix.Length() + aLocalName.Length() +5);
       
   590             TPtr8 ptr = pQName->Des();
       
   591             ptr.Append(aNsPrefix);
       
   592             ptr.Append(':');
       
   593             ptr.Append(aLocalName);
       
   594             pNewElement =
       
   595                 CSenBaseElement::NewL(pNamespace->URI(), aLocalName, *pQName);
       
   596             CleanupStack::PopAndDestroy(); // pQName
       
   597             }
       
   598         }
       
   599     else
       
   600         {
       
   601         pNewElement = CSenBaseElement::NewL(aLocalName);
       
   602         }
       
   603 
       
   604     return pNewElement; // Returns NULL if required namespace can not be found!
       
   605     }
       
   606 
       
   607 EXPORT_C CSenElement& CSenBaseElement::InsertElementL(
       
   608                                           CSenElement& aElement,
       
   609                                           const CSenElement& aBeforeElement)
       
   610     {
       
   611     TInt index(KErrNotFound);
       
   612     index = iElements.Find(&aBeforeElement);
       
   613     if (index != KErrNotFound)
       
   614         {
       
   615         User::LeaveIfError(iElements.Insert(&aElement,index));
       
   616         }
       
   617     else
       
   618         {
       
   619         User::LeaveIfError(iElements.Append(&aElement));
       
   620         }
       
   621     aElement.SetParent(this);
       
   622     return aElement;
       
   623     }
       
   624 
       
   625 EXPORT_C CSenElement& CSenBaseElement::AddElementL(CSenElement& aElement)
       
   626     {
       
   627     User::LeaveIfError(iElements.Append(&aElement));
       
   628     aElement.SetParent(this);
       
   629     return aElement;
       
   630     }
       
   631 
       
   632 EXPORT_C CSenElement& CSenBaseElement::AddElementL(const TDesC8& aNsUri,
       
   633                                                    const TDesC8& aLocalName)
       
   634     {
       
   635     return AddElementL(*CSenBaseElement::NewL(aNsUri, aLocalName));
       
   636     }
       
   637 
       
   638 EXPORT_C CSenElement& CSenBaseElement::AddElementL(
       
   639     const TDesC8& aNsUri,
       
   640     const TDesC8& aLocalName,
       
   641     const TDesC8& aQName
       
   642     )
       
   643     {
       
   644     return AddElementL(*CSenBaseElement::NewL(aNsUri, aLocalName, aQName));
       
   645     }
       
   646 
       
   647 EXPORT_C CSenElement& CSenBaseElement::AddElementL(const TDesC8& aLocalName)
       
   648     {
       
   649     return AddElementL(*CSenBaseElement::NewL(aLocalName));
       
   650     }
       
   651 
       
   652 EXPORT_C CSenElement* CSenBaseElement::RemoveElement(CSenElement& aElement)
       
   653     {
       
   654     TInt idx = iElements.Find(&aElement);
       
   655     if (idx >= 0)
       
   656         {
       
   657         CSenElement* pElement = iElements[idx];
       
   658         iElements.Remove(idx);
       
   659         pElement->SetParent(NULL);
       
   660         return pElement;
       
   661         }
       
   662     else
       
   663         {
       
   664         return NULL;
       
   665         }
       
   666     }
       
   667 
       
   668 EXPORT_C CSenElement* CSenBaseElement::RemoveElement(const TDesC8& aNsUri,
       
   669                                                      const TDesC8& aLocalName)
       
   670     {
       
   671     TInt idx = IndexOfElement(aNsUri, aLocalName);
       
   672     if (idx >= 0)
       
   673         {
       
   674         CSenElement* pElement = iElements[idx];
       
   675         iElements.Remove(idx);
       
   676         pElement->SetParent(NULL);
       
   677         return pElement;
       
   678         }
       
   679     else
       
   680         {
       
   681         return NULL;
       
   682         }
       
   683     }
       
   684 
       
   685 EXPORT_C CSenElement* CSenBaseElement::RemoveElement(const TDesC8& aLocalName)
       
   686     {
       
   687     return RemoveElement(NamespaceURI(), aLocalName);
       
   688     }
       
   689 
       
   690 EXPORT_C CSenElement* CSenBaseElement::ReplaceElementL(CSenElement& aElement)
       
   691     {
       
   692     CSenElement* pOldElement =
       
   693                 RemoveElement(aElement.NamespaceURI(), aElement.LocalName());
       
   694     CleanupStack::PushL(pOldElement);
       
   695     AddElementL(aElement);
       
   696     CleanupStack::Pop(); // pOldElement;
       
   697     return pOldElement;
       
   698     }
       
   699 
       
   700 EXPORT_C HBufC8* CSenBaseElement::AsXmlL()
       
   701     {
       
   702     CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
       
   703     CleanupStack::PushL(pBuf);
       
   704     TPtrC8 p = WriteToBufL(*pBuf);
       
   705     HBufC8* pRet = p.AllocL();
       
   706     CleanupStack::PopAndDestroy(); // pBuf;
       
   707     return pRet;
       
   708 
       
   709     }
       
   710 
       
   711 EXPORT_C HBufC* CSenBaseElement::AsXmlUnicodeL()
       
   712     {
       
   713     CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
       
   714     CleanupStack::PushL(pBuf);
       
   715     TPtrC8 p8 = WriteToBufL(*pBuf);
       
   716     HBufC* pRet = SenXmlUtils::ToUnicodeLC(p8);
       
   717     CleanupStack::Pop(); // pop pRet;
       
   718     CleanupStack::PopAndDestroy(); // pBuf;
       
   719     return pRet;
       
   720     }
       
   721 
       
   722 EXPORT_C TPtrC8 CSenBaseElement::WriteToBufL(CBufBase& aBuf)
       
   723     {
       
   724     RBufWriteStream bufWs(aBuf);
       
   725     CleanupClosePushL(bufWs);
       
   726     this->WriteAsXMLToL(bufWs);
       
   727     CleanupStack::PopAndDestroy(); // bufWs.Close();
       
   728     return aBuf.Ptr(0);
       
   729     }
       
   730 
       
   731 EXPORT_C void CSenBaseElement::WriteAsXMLToL(RWriteStream& aWriteStream)
       
   732     {
       
   733     // Find out whether we should declare the namespace
       
   734     TPtrC8 nsPrefix = NsPrefix();
       
   735 
       
   736     // Element name
       
   737     aWriteStream.WriteL(KSenLessThan);
       
   738     if (nsPrefix.Length() > 0)
       
   739         {
       
   740         aWriteStream.WriteL(nsPrefix);
       
   741         aWriteStream.WriteL(KSenColon);
       
   742         }
       
   743     aWriteStream.WriteL(*ipLocalName);
       
   744 
       
   745     if (iAttrs.Count() > 0 || iNamespaces.Count() > 0)
       
   746         {
       
   747         WriteNamespacesToL(aWriteStream);
       
   748         WriteAttrsToL(aWriteStream);
       
   749         }
       
   750 
       
   751     // Elements and content
       
   752     if ((iElements.Count() > 0) || HasContent())
       
   753         {
       
   754         aWriteStream.WriteL(KSenGreaterThan);
       
   755 
       
   756         // Body
       
   757         WriteElementsToL(aWriteStream);
       
   758         WriteContentToL(aWriteStream);
       
   759 
       
   760         // Closing element
       
   761         aWriteStream.WriteL(KSenLessThanSlash);
       
   762         if (nsPrefix.Length() > 0)
       
   763             {
       
   764             aWriteStream.WriteL(nsPrefix);
       
   765             aWriteStream.WriteL(KSenColon);
       
   766             }
       
   767         aWriteStream.WriteL(*ipLocalName);
       
   768         aWriteStream.WriteL(KSenGreaterThan);
       
   769         }
       
   770     else
       
   771         {
       
   772         aWriteStream.WriteL(KSenSlashGreaterThan);
       
   773         }
       
   774     }
       
   775 
       
   776 EXPORT_C void CSenBaseElement::WriteAttrToL(RWriteStream& aWriteStream,
       
   777                                             const TDesC8& aName,
       
   778                                             const TDesC8& aValue)
       
   779     {
       
   780     aWriteStream.WriteL(KSenSpace);
       
   781     aWriteStream.WriteL(aName);
       
   782     aWriteStream.WriteL(KSenEqualsDblQuot);
       
   783     aWriteStream.WriteL(aValue);
       
   784     aWriteStream.WriteL(KSenDblQuot);
       
   785     }
       
   786 
       
   787 EXPORT_C void CSenBaseElement::WriteAttrsToL(RWriteStream& aWriteStream)
       
   788     {
       
   789     for (TInt i = 0; i < iAttrs.Count(); i++)
       
   790         {
       
   791         WriteAttrToL(aWriteStream, iAttrs[i]->Name(), iAttrs[i]->Value());
       
   792         }
       
   793     }
       
   794 
       
   795 EXPORT_C void CSenBaseElement::WriteNamespacesToL(RWriteStream& aWriteStream)
       
   796     {
       
   797     TInt count = iNamespaces.Count();
       
   798     CSenNamespace* ns = NULL;
       
   799     if (count > 0)
       
   800         {
       
   801         for (TInt i=0; i < count; i++)
       
   802             {
       
   803             ns = iNamespaces[i];
       
   804             if (ns)
       
   805                 {
       
   806                 aWriteStream.WriteL(KSenSpaceXmlns);
       
   807                 if (ns->Prefix().Length() > 0)
       
   808                     {
       
   809                     aWriteStream.WriteL(KSenColon);
       
   810                     aWriteStream.WriteL(ns->Prefix());
       
   811                     }
       
   812                 aWriteStream.WriteL(KSenEqualsDblQuot);
       
   813                 aWriteStream.WriteL(ns->URI());
       
   814                 aWriteStream.WriteL(KSenDblQuot);
       
   815                 }
       
   816             }
       
   817         }
       
   818     }
       
   819 
       
   820 EXPORT_C void CSenBaseElement::WriteElementsToL(RWriteStream& aWriteStream)
       
   821     {
       
   822     TInt elementCount(iElements.Count());
       
   823     for (TInt i=0; i<elementCount; i++)
       
   824         {
       
   825         iElements[i]->WriteAsXMLToL(aWriteStream);
       
   826         }
       
   827     }
       
   828 
       
   829 EXPORT_C void CSenBaseElement::WriteContentToL(RWriteStream& aWriteStream)
       
   830     {
       
   831     aWriteStream.WriteL(Content());
       
   832     }
       
   833 
       
   834 EXPORT_C MSenElement* CSenBaseElement::AsElement()
       
   835     {
       
   836     return this;
       
   837     }
       
   838 
       
   839 EXPORT_C void CSenBaseElement::AllocContentBufL()
       
   840     {
       
   841     if(!ipContentBuf)
       
   842         {
       
   843         ipContentBuf = CBufFlat::NewL(KFlatBufSize);
       
   844         }
       
   845     }
       
   846 
       
   847 EXPORT_C void CSenBaseElement::SetNamespaceL(const TDesC8& aNsUri)
       
   848     {
       
   849     SetNamespaceL(KNullDesC8, aNsUri);
       
   850     }
       
   851 
       
   852 EXPORT_C void CSenBaseElement::SetNamespaceL(const TDesC8& aNsPrefix,
       
   853                                              const TDesC8& aNsUri)
       
   854     {
       
   855     if (aNsUri.Length() > 0)
       
   856         {
       
   857         ipNamespace = (CSenNamespace*) Namespace(aNsPrefix, aNsUri);
       
   858         if (!ipNamespace)
       
   859             {
       
   860             ipNamespace = CSenNamespace::NewL(aNsPrefix, aNsUri);
       
   861 
       
   862 #ifdef EKA2
       
   863             iNamespaces.AppendL(ipNamespace);
       
   864 #else
       
   865             User::LeaveIfError(iNamespaces.Append(ipNamespace));
       
   866 #endif // EKA2
       
   867             }
       
   868         }
       
   869     }
       
   870 
       
   871 EXPORT_C const CSenNamespace* CSenBaseElement::Namespace()
       
   872     {
       
   873     return ipNamespace;
       
   874     }
       
   875 
       
   876 EXPORT_C const CSenNamespace* CSenBaseElement::Namespace(
       
   877                                                     const TDesC8& aNsPrefix)
       
   878     {
       
   879     return Namespace(aNsPrefix,ETrue);
       
   880     }
       
   881 
       
   882 EXPORT_C const CSenNamespace* CSenBaseElement::Namespace(
       
   883                                                     const TDesC8& aNsPrefix,
       
   884                                                     const TBool aCheckInParent)
       
   885     {
       
   886     if (aNsPrefix.Length() == 0) return NULL;
       
   887 
       
   888     const CSenNamespace* pNamespace = NULL;
       
   889 
       
   890     TInt count(iNamespaces.Count());
       
   891     for (TInt i=0; i<count && pNamespace == NULL; i++)
       
   892         {
       
   893         pNamespace = iNamespaces[i];
       
   894         if (pNamespace)
       
   895             {
       
   896             if (pNamespace->Prefix() != aNsPrefix) pNamespace = NULL;
       
   897             }
       
   898         }
       
   899 
       
   900     if (pNamespace == NULL && ipParent && aCheckInParent)
       
   901         {
       
   902         pNamespace = ipParent->Namespace(aNsPrefix);
       
   903         }
       
   904 
       
   905     return pNamespace;
       
   906     }
       
   907 
       
   908 
       
   909 EXPORT_C const CSenNamespace* CSenBaseElement::Namespace(
       
   910                                                     const TDesC8& aNsPrefix,
       
   911                                                     const TDesC8& aUri)
       
   912     {
       
   913     // If prefix == NULL, then any prefix is ok
       
   914     const CSenNamespace* pNs = NULL;
       
   915     // Check if the namespace has already been declared
       
   916     TInt count = iNamespaces.Count();
       
   917     if (count != 0)
       
   918         {
       
   919         for (TInt i=0; i<count; i++)
       
   920             {
       
   921             pNs = iNamespaces[i];
       
   922             if (!pNs->Compare(aNsPrefix, aUri))
       
   923                 {
       
   924                 pNs = NULL;
       
   925                 }
       
   926             else
       
   927                 {
       
   928                 break;
       
   929                 }
       
   930             }
       
   931         }
       
   932     if (pNs == NULL && ipParent != NULL)
       
   933         {
       
   934         // if no namespace defined, but there is a parent, ask its namespace
       
   935         pNs = ipParent->Namespace(aNsPrefix, aUri);
       
   936         }
       
   937     return pNs;
       
   938     }
       
   939 
       
   940 EXPORT_C RPointerArray<CSenBaseAttribute>& CSenBaseElement::AttributesL()
       
   941     {
       
   942     return iAttrs;
       
   943     }
       
   944 
       
   945 EXPORT_C RPointerArray<CSenNamespace>& CSenBaseElement::NamespacesL()
       
   946     {
       
   947     return iNamespaces;
       
   948     }
       
   949 
       
   950 EXPORT_C void CSenBaseElement::CopyFromL(CSenElement& aSource)
       
   951     {
       
   952     TPtrC8 sourceContent = aSource.Content();
       
   953     if (sourceContent.Length() > 0)
       
   954         {
       
   955         if (ipContentBuf == NULL)
       
   956             {
       
   957             SetContentL(sourceContent);
       
   958             }
       
   959         else
       
   960             {
       
   961             RBufWriteStream bufWs(*ipContentBuf);
       
   962             CleanupClosePushL(bufWs);
       
   963             bufWs.WriteL(sourceContent);
       
   964             CleanupStack::PopAndDestroy(); // close bufWs
       
   965             }
       
   966         }
       
   967 
       
   968     RPointerArray<CSenNamespace> sourceNamespaces = aSource.NamespacesL();
       
   969     if (sourceNamespaces.Count() > 0)
       
   970         {
       
   971         for (TInt i=0;i<sourceNamespaces.Count(); i++)
       
   972             {
       
   973             CSenNamespace* pNamespace = sourceNamespaces[i];
       
   974             CSenNamespace* pNewNamespace =
       
   975                 CSenNamespace::NewL(pNamespace->Prefix(),pNamespace->URI());
       
   976             CleanupStack::PushL(pNewNamespace);
       
   977 #ifdef EKA2
       
   978             iNamespaces.AppendL(pNewNamespace);
       
   979 #else
       
   980             User::LeaveIfError(iNamespaces.Append(pNewNamespace));
       
   981 #endif
       
   982 
       
   983             CleanupStack::Pop(pNewNamespace);
       
   984             }
       
   985         }
       
   986     SetNamespaceL(aSource.NsPrefix(), aSource.NamespaceURI());
       
   987 
       
   988     RPointerArray<CSenBaseAttribute> sourceAttributes = aSource.AttributesL();
       
   989     if (sourceAttributes.Count() > 0)
       
   990         {
       
   991         for (TInt i=0;i<sourceAttributes.Count(); i++)
       
   992             {
       
   993             CSenBaseAttribute* pBaseAttribute = sourceAttributes[i];
       
   994 
       
   995             // duplicate check. Now overrides the original value
       
   996             CSenBaseAttribute* pOriginal = FindAttr(pBaseAttribute->Name());
       
   997             if (pOriginal)
       
   998                 {
       
   999                 pOriginal->SetValueL(pBaseAttribute->Value());
       
  1000                 continue;
       
  1001                 }
       
  1002 
       
  1003             CSenBaseAttribute* pNewBaseAttribute =
       
  1004                 CSenBaseAttribute::NewL(pBaseAttribute->Name(),
       
  1005                                         pBaseAttribute->Value());
       
  1006             CleanupStack::PushL(pNewBaseAttribute);
       
  1007 #ifdef EKA2
       
  1008             iAttrs.AppendL(pNewBaseAttribute);
       
  1009 #else
       
  1010             User::LeaveIfError(iAttrs.Append(pNewBaseAttribute));
       
  1011 #endif
       
  1012             CleanupStack::Pop(pNewBaseAttribute);
       
  1013             }
       
  1014         }
       
  1015 
       
  1016     RPointerArray<CSenElement> sourceElements = aSource.ElementsL();
       
  1017     if (sourceElements.Count() > 0)
       
  1018         {
       
  1019         for (TInt i=0;i<sourceElements.Count(); i++)
       
  1020             {
       
  1021             CSenElement* pElement = sourceElements[i];
       
  1022             CSenElement* pNewElement =
       
  1023                                 CSenBaseElement::NewL(pElement->LocalName());
       
  1024             pNewElement->SetParent(this);
       
  1025             CleanupStack::PushL(pNewElement);
       
  1026             pNewElement->CopyFromL(*pElement);
       
  1027 #ifdef EKA2
       
  1028             iElements.AppendL(pNewElement);
       
  1029 #else
       
  1030             User::LeaveIfError(iElements.Append(pNewElement));
       
  1031 #endif // EKA2
       
  1032             CleanupStack::Pop(pNewElement);
       
  1033             }
       
  1034         }
       
  1035     }
       
  1036 
       
  1037 EXPORT_C void CSenBaseElement::SetPrefixL(const TDesC8& aPrefix)
       
  1038     {
       
  1039     if (iNamespaces.Find(ipNamespace) > -1)
       
  1040         {
       
  1041         //the namespace was locally declared
       
  1042 
       
  1043         // Check if element already has a namespace with given prefix
       
  1044         CSenNamespace* pNamespace = NULL;
       
  1045         TInt count(iNamespaces.Count());
       
  1046         for (TInt i=0; i<count && pNamespace == NULL; i++)
       
  1047             {
       
  1048             pNamespace = iNamespaces[i];
       
  1049             if (pNamespace->Prefix() != aPrefix) pNamespace = NULL;
       
  1050             }
       
  1051 
       
  1052         if (pNamespace)
       
  1053             {
       
  1054             // Update existing namespace
       
  1055             const TDesC8& uri = ipNamespace->URI();
       
  1056             pNamespace->SetUriL(uri);
       
  1057             ipNamespace = pNamespace;
       
  1058             }
       
  1059         else
       
  1060             {
       
  1061             if (ipNamespace->Prefix().Length() > 0 && iElements.Count() > 0)
       
  1062                 {
       
  1063                 // there may be children that depend on the old prefix in e.g. attribute names
       
  1064                 const TDesC8& uri = ipNamespace->URI();
       
  1065                 ipNamespace = CSenNamespace::NewL(aPrefix, uri);
       
  1066 #ifdef EKA2
       
  1067                 iNamespaces.AppendL(ipNamespace);
       
  1068 #else
       
  1069                 User::LeaveIfError(iNamespaces.Append(ipNamespace));
       
  1070 #endif
       
  1071                 }
       
  1072             ipNamespace->SetPrefixL(aPrefix);
       
  1073             }
       
  1074         }
       
  1075     }
       
  1076 
       
  1077 EXPORT_C const CSenNamespace* CSenBaseElement::AddNamespaceL(
       
  1078                                                 CSenNamespace& aNewNamespace,
       
  1079                                                 TBool aCheckInParent)
       
  1080     {
       
  1081     const CSenNamespace* pNamespace =
       
  1082                         Namespace(aNewNamespace.Prefix(), aCheckInParent);
       
  1083     if (pNamespace == NULL)
       
  1084         {
       
  1085         CSenNamespace* pNewNamespace =
       
  1086             CSenNamespace::NewL(aNewNamespace.Prefix(), aNewNamespace.URI());
       
  1087         CleanupStack::PushL(pNewNamespace);
       
  1088 #ifdef EKA2
       
  1089         iNamespaces.AppendL(pNewNamespace);
       
  1090 #else
       
  1091         User::LeaveIfError(iNamespaces.Append(pNewNamespace));
       
  1092 #endif
       
  1093         CleanupStack::Pop(); // pNewNamespace
       
  1094         pNamespace = pNewNamespace;
       
  1095         }
       
  1096     return pNamespace;
       
  1097     }
       
  1098 
       
  1099 EXPORT_C const CSenNamespace* CSenBaseElement::AddNamespaceL(
       
  1100                                                          const TDesC8& aPrefix,
       
  1101                                                          const TDesC8& aUri)
       
  1102     {
       
  1103     CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aPrefix);
       
  1104 		if (!pNamespace)
       
  1105 		{
       
  1106     	if (aUri.Length() > 0)
       
  1107         	{
       
  1108         	pNamespace = CSenNamespace::NewL(aPrefix, aUri);
       
  1109         	CleanupStack::PushL(pNamespace);
       
  1110 #ifdef EKA2
       
  1111         	iNamespaces.AppendL(pNamespace);
       
  1112 #else
       
  1113         	User::LeaveIfError(iNamespaces.Append(pNamespace));
       
  1114 #endif
       
  1115         	CleanupStack::Pop(); // pNamespace
       
  1116         	}
       
  1117         }
       
  1118 	    else
       
  1119 	        {
       
  1120 	        pNamespace->SetUriL(aUri); 
       
  1121 	        }
       
  1122 		
       
  1123 
       
  1124     return pNamespace;
       
  1125     }
       
  1126 
       
  1127 EXPORT_C CSenElement* CSenBaseElement::DetachL()
       
  1128     {
       
  1129     if (!ipParent)
       
  1130         {
       
  1131         return NULL;
       
  1132         }
       
  1133     AddNamespaceMissingFromL(iNamespaces);
       
  1134     ipParent->RemoveElement(*this);
       
  1135     return this;
       
  1136     }
       
  1137 
       
  1138 void CSenBaseElement::AddNamespaceMissingFromL(
       
  1139                                     RPointerArray<CSenNamespace>& aNamespaces)
       
  1140     {
       
  1141     // Add namespace of this element (possibly copied from parent)
       
  1142     // if that namespace is not already defined in
       
  1143     // aNamespaces array.
       
  1144     if ( ipNamespace && aNamespaces.Find(ipNamespace) == -1)
       
  1145         {
       
  1146         // Check if namespace declaration of this element can
       
  1147         // be found from aNamespaces array
       
  1148         TInt count(aNamespaces.Count());
       
  1149         TBool found(EFalse);
       
  1150         TInt i = 0;
       
  1151         for (; i<count; i++)
       
  1152             {
       
  1153             if ( aNamespaces[i]->URI() == ipNamespace->URI() && 
       
  1154                  aNamespaces[i]->Prefix() == ipNamespace->Prefix() )
       
  1155                 {
       
  1156                 found = ETrue;
       
  1157                 break;
       
  1158                 }
       
  1159             }
       
  1160         if ( !found )
       
  1161             {
       
  1162             // Not found 
       
  1163             // => Create a copy of namespace declaration
       
  1164             //    and append it into aNamespaces array
       
  1165             CSenNamespace* pCopy =
       
  1166                     CSenNamespace::NewL(ipNamespace->Prefix(), ipNamespace->URI());
       
  1167             CleanupStack::PushL(pCopy);
       
  1168 #ifdef EKA2
       
  1169             aNamespaces.AppendL(pCopy);
       
  1170 #else
       
  1171             User::LeaveIfError(aNamespaces.Append(pCopy));
       
  1172 #endif
       
  1173             CleanupStack::Pop(pCopy);
       
  1174 
       
  1175             // Change namespace object for this element to namespace object
       
  1176             // which can be found from aNamespaces array
       
  1177             ipNamespace = pCopy;
       
  1178             }
       
  1179         else
       
  1180             {
       
  1181             // Change namespace object for this element to namespace object
       
  1182             // which can be found from aNamespaces array
       
  1183             
       
  1184             ipNamespace = aNamespaces[i];
       
  1185             }
       
  1186         }
       
  1187 
       
  1188     // Add namespaces from this element's attributes
       
  1189     // if those namespaces are not already defined in
       
  1190     // aNamespaces array.
       
  1191     if ( iAttrs.Count() > 0 )
       
  1192         {
       
  1193         TInt colon = -1;
       
  1194         const CSenNamespace* pNamespace = NULL;
       
  1195 
       
  1196         TInt count(iAttrs.Count());
       
  1197         for (TInt i=0; i<count; i++)
       
  1198             {
       
  1199             CSenBaseAttribute* pAttribute = iAttrs[i];
       
  1200 
       
  1201             // Check namespace assigned to Name
       
  1202             colon = pAttribute->Name().Locate(':');
       
  1203             if ( colon > 0 )
       
  1204                 {
       
  1205                 pNamespace =
       
  1206                     Namespace(pAttribute->Name().Mid(0, colon), KNullDesC8);
       
  1207                 }
       
  1208             if ( pNamespace && (aNamespaces.Find(pNamespace) == -1) )
       
  1209                 {
       
  1210                 // Check if namespace declaration for handled attribute
       
  1211                 // _name_ can be found from aNamespaces array.
       
  1212                 TInt count(aNamespaces.Count());
       
  1213                 TBool found(EFalse);
       
  1214                 for (TInt i = 0; i<count; i++)
       
  1215                     {
       
  1216                     if ( aNamespaces[i]->URI() == pNamespace->URI() && 
       
  1217                          aNamespaces[i]->Prefix() == pNamespace->Prefix() )
       
  1218                         {
       
  1219                         found = ETrue;
       
  1220                         break;
       
  1221                         }
       
  1222                     }
       
  1223                 if ( !found )
       
  1224                     {
       
  1225                     // Not found 
       
  1226                     // => Create a copy of namespace declaration
       
  1227                     //    and append it into aNamespaces array
       
  1228                     CSenNamespace* pCopy =
       
  1229                             CSenNamespace::NewL(pNamespace->Prefix(),
       
  1230                                                 pNamespace->URI());
       
  1231                     CleanupStack::PushL(pCopy);
       
  1232 #ifdef EKA2
       
  1233                     aNamespaces.AppendL(pCopy);
       
  1234 #else
       
  1235                     User::LeaveIfError(aNamespaces.Append(pCopy));
       
  1236 #endif
       
  1237                     CleanupStack::Pop(pCopy);
       
  1238                     }
       
  1239                 }
       
  1240             pNamespace = NULL;
       
  1241 
       
  1242             // Check namespace assigned to Value
       
  1243             colon = pAttribute->Value().Locate(':');
       
  1244             if ( colon > 0 )
       
  1245                 {
       
  1246                 pNamespace =
       
  1247                     Namespace(pAttribute->Value().Mid(0, colon), KNullDesC8);
       
  1248                 }
       
  1249             if ( pNamespace && (aNamespaces.Find(pNamespace) == -1) )
       
  1250                 {
       
  1251                 // Check if namespace declaration for handled attribute
       
  1252                 // _value_ can be found from aNamespaces array.
       
  1253                 TInt count(aNamespaces.Count());
       
  1254                 TBool found(EFalse);
       
  1255                 for (TInt i = 0; i<count; i++)
       
  1256                     {
       
  1257                     if ( aNamespaces[i]->URI() == pNamespace->URI() && 
       
  1258                          aNamespaces[i]->Prefix() == pNamespace->Prefix() )
       
  1259                         {
       
  1260                         found = ETrue;
       
  1261                         break;
       
  1262                         }
       
  1263                     }
       
  1264                 if ( !found )
       
  1265                     {
       
  1266                     // Not found 
       
  1267                     // => Create a copy of namespace declaration
       
  1268                     //    and append it into aNamespaces array
       
  1269                     CSenNamespace* pCopy =
       
  1270                             CSenNamespace::NewL(pNamespace->Prefix(), 
       
  1271                                                 pNamespace->URI());
       
  1272                     CleanupStack::PushL(pCopy);
       
  1273 #ifdef EKA2
       
  1274                     aNamespaces.AppendL(pCopy);
       
  1275 #else
       
  1276                     User::LeaveIfError(aNamespaces.Append(pCopy));
       
  1277 #endif
       
  1278                     CleanupStack::Pop(pCopy);
       
  1279                     }
       
  1280                 }
       
  1281             pNamespace = NULL;
       
  1282             }
       
  1283         }
       
  1284 
       
  1285     // Do recursive search for all child elements and for all child
       
  1286     // elements of all child elements and so on.
       
  1287     if ( iElements.Count() > 0 )
       
  1288         {
       
  1289         TInt count(iElements.Count());
       
  1290         for (TInt i=0; i<count; i++)
       
  1291             {
       
  1292             CSenBaseElement* pElement = (CSenBaseElement*) iElements[i];
       
  1293             pElement->AddNamespaceMissingFromL(aNamespaces);
       
  1294             }
       
  1295         }
       
  1296     }
       
  1297 
       
  1298 
       
  1299 EXPORT_C void CSenBaseElement::Set(const TDesC8& aNamespaceURI,
       
  1300                                    const TDesC8& aLocalName,
       
  1301                                    const TDesC8& aQName)
       
  1302     {
       
  1303     
       
  1304     HBufC8* pTemp = aLocalName.Alloc();
       
  1305     if(pTemp)
       
  1306         {
       
  1307         delete ipLocalName;
       
  1308         ipLocalName = NULL;
       
  1309         ipLocalName = pTemp;
       
  1310         }
       
  1311 
       
  1312 
       
  1313     TPtrC8 prefix(KNullDesC8);
       
  1314 
       
  1315     if(aQName != KNullDesC8)
       
  1316         {
       
  1317         TInt colon(KErrNotFound);
       
  1318         colon = aQName.Locate(':');
       
  1319         if(colon!=KErrNotFound)
       
  1320             {
       
  1321             prefix.Set(aQName.Left(colon));
       
  1322             }
       
  1323         }
       
  1324     TInt leaveCode(KErrNone);
       
  1325     TRAP(leaveCode, SetNamespaceL(prefix, aNamespaceURI);)
       
  1326     leaveCode=0;
       
  1327     
       
  1328     //if (err) ; 
       
  1329     }
       
  1330 
       
  1331 EXPORT_C CSenElement* CSenBaseElement::Child(TInt aIndex)
       
  1332     {
       
  1333     CSenElement* pElement = NULL;
       
  1334     if (aIndex < iElements.Count())
       
  1335         {
       
  1336         pElement = (CSenBaseElement*) iElements[aIndex];
       
  1337         }
       
  1338     return pElement;
       
  1339     }
       
  1340 
       
  1341 EXPORT_C TBool CSenBaseElement::ConsistsOfL(MSenElement& aCandidate)
       
  1342     {
       
  1343     // First check the names and namespaces
       
  1344     if (    aCandidate.LocalName() != this->LocalName()
       
  1345         ||  aCandidate.NamespaceURI() != this->NamespaceURI()
       
  1346         ||  aCandidate.NsPrefix() != this->NsPrefix()
       
  1347         )
       
  1348         {
       
  1349         return EFalse;
       
  1350         }
       
  1351 
       
  1352     // Then check content if it exists
       
  1353     if (aCandidate.HasContent())
       
  1354         {
       
  1355         if (aCandidate.Content() != this->Content())
       
  1356             {
       
  1357             return EFalse;  // Content doesn't match => no match
       
  1358             }
       
  1359         }
       
  1360 
       
  1361     // Then handle the children
       
  1362     RPointerArray<CSenElement>& children = aCandidate.ElementsL();
       
  1363     TInt childCount = children.Count();
       
  1364     TInt i=0;
       
  1365     while (i < childCount)
       
  1366         {
       
  1367         CSenElement* pMatchChild = children[i];
       
  1368         CSenElement* pChild = this->Element(pMatchChild->LocalName());
       
  1369         if (!pChild)
       
  1370             {
       
  1371             return EFalse;  // no child with same name found in children, 
       
  1372                             // => no match
       
  1373             }
       
  1374         else
       
  1375             {
       
  1376             if (!pChild->ConsistsOfL(*pMatchChild))
       
  1377                 {
       
  1378                 return EFalse; // a non matching child was found => No match
       
  1379                 }
       
  1380             }
       
  1381         i++;
       
  1382         }
       
  1383     return ETrue;
       
  1384     }
       
  1385 
       
  1386 // End of File
       
  1387