mpx/commonframework/common/src/mpxclientlist.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Encapsulates all the clients
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include <mpxlog.h>
       
    21 #include "mpxuser.h"
       
    22 #include "mpxmessagequeue.h"
       
    23 #include "mpxclientlistobserver.h"
       
    24 #include "mpxclientlist.h"
       
    25 #include <mpxsubscription.h>
       
    26 
       
    27 // ============================ MEMBER FUNCTIONS ==============================
       
    28 
       
    29 // ----------------------------------------------------------------------------
       
    30 // Two-phased constructor.
       
    31 // ----------------------------------------------------------------------------
       
    32 //
       
    33 EXPORT_C CMPXClientList* CMPXClientList::NewL(
       
    34     MMPXClientlistObserver* aObserver /*=NULL*/)
       
    35     {
       
    36     CMPXClientList* list=new(ELeave)CMPXClientList(aObserver);
       
    37     CleanupStack::PushL(list);
       
    38     list->ConstructL();
       
    39     CleanupStack::Pop(list);
       
    40     return list;
       
    41     }
       
    42 
       
    43 // ----------------------------------------------------------------------------
       
    44 // Constructor.
       
    45 // ----------------------------------------------------------------------------
       
    46 //
       
    47 CMPXClientList::CMPXClientList(MMPXClientlistObserver* aObserver)
       
    48     : iIdentity(CMPXClientList::ClientsMatch),
       
    49     iObserver(aObserver)
       
    50     {}
       
    51 
       
    52 // ----------------------------------------------------------------------------
       
    53 // 2nd phase constructor.
       
    54 // ----------------------------------------------------------------------------
       
    55 //
       
    56 void CMPXClientList::ConstructL()
       
    57     {
       
    58     }
       
    59 
       
    60 // ----------------------------------------------------------------------------
       
    61 // Destructor
       
    62 // ----------------------------------------------------------------------------
       
    63 //
       
    64 EXPORT_C CMPXClientList::~CMPXClientList()
       
    65     {
       
    66     iClients.ResetAndDestroy();
       
    67     iClients.Close();
       
    68     iClientProcesses.Close();
       
    69     }
       
    70 
       
    71 // ----------------------------------------------------------------------------
       
    72 // Add a client into the client list
       
    73 // ----------------------------------------------------------------------------
       
    74 //
       
    75 EXPORT_C void CMPXClientList::AddClientL(
       
    76     TThreadId aId,
       
    77     CMPXMessageQueue* aMsgQueue)
       
    78     {
       
    79     AddClientL(aId, KErrUnknown, aMsgQueue);
       
    80     }
       
    81 
       
    82 // ----------------------------------------------------------------------------
       
    83 // Add a client into the client list
       
    84 // ----------------------------------------------------------------------------
       
    85 //
       
    86 EXPORT_C void CMPXClientList::AddClientL(
       
    87     TThreadId aId,
       
    88     TInt aMode,
       
    89     CMPXMessageQueue* aMsgQueue)
       
    90     {
       
    91     TProcessId pid=MPXUser::ProcessIdL(aId);
       
    92     CClientId* newClient = new(ELeave) CClientId(aId,pid,aMode,aMsgQueue);
       
    93     CleanupStack::PushL(newClient);
       
    94 
       
    95     // add an empty subscription by default
       
    96     CMPXSubscription* subscription = CMPXSubscription::NewL();
       
    97     CleanupStack::PushL(subscription);
       
    98 
       
    99     // transfer the ownership
       
   100     newClient->iSubscriptions.AppendL(subscription);
       
   101     CleanupStack::Pop(subscription);
       
   102 
       
   103     iClients.AppendL(newClient);
       
   104     CleanupStack::Pop(newClient);
       
   105 
       
   106     if (iClientProcesses.Find(pid)==KErrNotFound)
       
   107         {
       
   108         iClientProcesses.AppendL(pid);
       
   109         if (iObserver)
       
   110             {
       
   111             iObserver->HandleClientChange(pid, MMPXClientlistObserver::EAdd);
       
   112             }
       
   113         }
       
   114     }
       
   115 // ----------------------------------------------------------------------------
       
   116 // Add a client into the client list
       
   117 // ----------------------------------------------------------------------------
       
   118 //
       
   119 
       
   120 EXPORT_C void CMPXClientList::AddClientL(
       
   121     TThreadId aId,
       
   122     TInt aMode,
       
   123     CMPXMessageQueue* aMsgQueue,
       
   124     const TInt aCategory)
       
   125     {
       
   126     TProcessId pid=MPXUser::ProcessIdL(aId);
       
   127     CClientId* newClient = new(ELeave) CClientId(aId,pid,aMode,aMsgQueue, aCategory);
       
   128     CleanupStack::PushL(newClient);
       
   129     // add an empty subscription by default
       
   130     CMPXSubscription* subscription = CMPXSubscription::NewL();
       
   131     CleanupStack::PushL(subscription);
       
   132     // transfer the ownership
       
   133     newClient->iSubscriptions.AppendL(subscription);
       
   134     CleanupStack::Pop(subscription);
       
   135     iClients.AppendL(newClient);
       
   136     CleanupStack::Pop(newClient);
       
   137     if (iClientProcesses.Find(pid)==KErrNotFound)
       
   138         {
       
   139         iClientProcesses.AppendL(pid);
       
   140         if (iObserver)
       
   141             {
       
   142             iObserver->HandleClientChange(pid, MMPXClientlistObserver::EAdd);
       
   143             }
       
   144         }
       
   145     }
       
   146 // SK
       
   147 // ----------------------------------------------------------------------------
       
   148 // Remove a client from the list
       
   149 // ----------------------------------------------------------------------------
       
   150 //
       
   151 EXPORT_C void CMPXClientList::RemoveClient(TInt aIndex)
       
   152     {
       
   153     // USER panic 130, if aIndex is negative or is greater than the number of
       
   154     // objects currently in the array.
       
   155     CClientId* id( iClients[aIndex] );
       
   156     iClients.Remove(aIndex);
       
   157 
       
   158     CClientId removeId( id->iPid );
       
   159     if ( iClients.Find( &removeId, iIdentity ) == KErrNotFound )
       
   160         //
       
   161         // There's no other client from the same process, so
       
   162         // remove it from the process list
       
   163         //
       
   164         {
       
   165         TInt i=iClientProcesses.Find(id->iPid);
       
   166         if (KErrNotFound != i)
       
   167             {
       
   168             if (iObserver)
       
   169                 {
       
   170                 iObserver->HandleClientChange(id->iPid, MMPXClientlistObserver::ERemove);
       
   171                 }
       
   172             iClientProcesses.Remove(i);
       
   173             }
       
   174         }
       
   175     delete id;
       
   176     }
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // Return the number of clients
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 EXPORT_C TInt CMPXClientList::ClientCount() const
       
   183     {
       
   184     return iClients.Count();
       
   185     }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // Return array of client process ids
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 EXPORT_C TArray<TProcessId> CMPXClientList::ClientProcessList() const
       
   192     {
       
   193     return iClientProcesses.Array();
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // Check if the client in the client list or not
       
   198 // -----------------------------------------------------------------------------
       
   199 //
       
   200 EXPORT_C TBool CMPXClientList::IsClient(TThreadId aId) const
       
   201     {
       
   202     return (KErrNotFound != Find(aId));
       
   203     }
       
   204 
       
   205 // -----------------------------------------------------------------------------
       
   206 // Find a client denoted by message queue in this list.
       
   207 // -----------------------------------------------------------------------------
       
   208 //
       
   209 EXPORT_C TInt CMPXClientList::Find(const CMPXMessageQueue& aMsgQueue) const
       
   210     {
       
   211     CClientId id( const_cast<CMPXMessageQueue*>( &aMsgQueue ));
       
   212     return iClients.Find( &id, iIdentity );
       
   213     }
       
   214 
       
   215 // -----------------------------------------------------------------------------
       
   216 // Found a client by Id
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 EXPORT_C TInt CMPXClientList::Find(TThreadId aId) const
       
   220     {
       
   221     CClientId id( aId );
       
   222     return iClients.Find( &id ,iIdentity );
       
   223     }
       
   224 
       
   225 // -----------------------------------------------------------------------------
       
   226 // Return client mode
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 EXPORT_C TInt CMPXClientList::ClientMode(TInt aIndex) const
       
   230     {
       
   231     MPX_ASSERT(aIndex>=0 && aIndex<ClientCount());
       
   232     return iClients[aIndex]->iMode;
       
   233     }
       
   234 	
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // Return client category
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 EXPORT_C TInt CMPXClientList::ClientCategory(TInt aIndex) const
       
   241     {
       
   242     MPX_ASSERT(aIndex>=0 && aIndex<ClientCount());
       
   243     TInt category = iClients[aIndex]->iCategory;
       
   244     return category;
       
   245     }
       
   246 
       
   247 	
       
   248 // -----------------------------------------------------------------------------
       
   249 // Send message to all clients in the list
       
   250 // -----------------------------------------------------------------------------
       
   251 //
       
   252 EXPORT_C void CMPXClientList::SendMsg(const CMPXMessage* aMsg, TInt aError)
       
   253     {
       
   254     MPX_FUNC_EX("CMPXClientList::SendMsg");
       
   255     for (TInt i=iClients.Count();--i>=0;)
       
   256         {
       
   257         SendMsg( i, aMsg, aError );
       
   258         }
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // Send message to a client
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 EXPORT_C void CMPXClientList::SendMsg(
       
   266     TInt aIndex,
       
   267     const CMPXMessage* aMsg,
       
   268     TInt aError)
       
   269     {
       
   270     MPX_FUNC_EX("CMPXClientList::SendMsgL(aIndex)");
       
   271     MPX_ASSERT(aIndex>=0 && aIndex<iClients.Count());
       
   272     MPX_ASSERT(iClients[aIndex]->iMsgQueue);
       
   273 
       
   274     // check the subscriptions
       
   275     TBool send(EFalse);
       
   276     TInt err(KErrNone);
       
   277     if (aMsg)
       
   278         {
       
   279         TRAP(err, send = IsMsgSubscribedL(aIndex, aMsg));
       
   280         }
       
   281     else
       
   282         {
       
   283         send = ETrue; // broadcast error message aError
       
   284         }
       
   285 
       
   286     // only send if the client has subscribed for it
       
   287     if (send && KErrNone == err)
       
   288         {
       
   289         iClients[aIndex]->iMsgQueue->Add(aMsg, aError);
       
   290         }
       
   291     }
       
   292 
       
   293 // -----------------------------------------------------------------------------
       
   294 // CMPXClientList::AddSubscriptionL
       
   295 // -----------------------------------------------------------------------------
       
   296 //
       
   297 EXPORT_C void CMPXClientList::AddSubscriptionL(
       
   298     TInt aIndex,
       
   299     CMPXSubscription* aSubscription)
       
   300     {
       
   301     MPX_FUNC("CMPXClientList::AddSubscriptionL");
       
   302 
       
   303     CClientId* id( iClients[aIndex] );
       
   304     TInt subCount( id->iSubscriptions.Count() );
       
   305     const CMPXMediaArray* items = id->iSubscriptions[0]->ItemsL();
       
   306     // check if it has an empty subscription
       
   307     if ( 1 == subCount  &&  items->Count() )
       
   308         {
       
   309         // remove it if so
       
   310         id->RemoveAllSubscriptionsL();
       
   311         }
       
   312 
       
   313     // add the new subscription
       
   314     id->AddSubscriptionL(aSubscription);
       
   315     }
       
   316 
       
   317 // -----------------------------------------------------------------------------
       
   318 // CMPXClientList::RemoveSubscriptionL
       
   319 // -----------------------------------------------------------------------------
       
   320 //
       
   321 EXPORT_C void CMPXClientList::RemoveSubscriptionL(
       
   322     TInt aIndex,
       
   323     const CMPXSubscription& aSubscription)
       
   324     {
       
   325     MPX_FUNC("CMPXClientList::RemoveSubscriptionL");
       
   326 
       
   327     iClients[aIndex]->RemoveSubscriptionL(aSubscription);
       
   328     }
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // CMPXClientList::RemoveAllSubscriptionsL
       
   332 // -----------------------------------------------------------------------------
       
   333 //
       
   334 EXPORT_C void CMPXClientList::RemoveAllSubscriptionsL(
       
   335     TInt aIndex)
       
   336     {
       
   337     MPX_FUNC("CMPXClientList::RemoveAllSubscriptionsL");
       
   338 
       
   339     iClients[aIndex]->RemoveAllSubscriptionsL();
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CMPXClientList::IsMsgSubscribedL
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 TBool CMPXClientList::IsMsgSubscribedL(TInt aIndex, const CMPXMessage* aMsg)
       
   347     {
       
   348     // check the subscriptions
       
   349     TBool IsSubScribed(EFalse);
       
   350     TInt subCount(iClients[aIndex]->iSubscriptions.Count());
       
   351 
       
   352     if (subCount)
       
   353         {
       
   354         const CMPXMediaArray* subscriptionItems =
       
   355                                  iClients[aIndex]->iSubscriptions[0]->ItemsL();
       
   356         if (1==subCount && (0== subscriptionItems->Count()))
       
   357             {// one empty subscription - send everything
       
   358             IsSubScribed = ETrue;
       
   359             }
       
   360         else
       
   361             {// have to check the message against the subscriptions.
       
   362             MPX_ASSERT(aMsg);
       
   363             const TArray<TMPXAttribute> msgAttrs = aMsg->Attributes();
       
   364             TInt msgAttrCount(msgAttrs.Count());
       
   365             // iterate subscriptions
       
   366             for (TInt subIndex = 0; subIndex<subCount && !IsSubScribed; ++subIndex)
       
   367                 {
       
   368                 // iterate items for the current subscription
       
   369                 subscriptionItems =
       
   370                             iClients[aIndex]->iSubscriptions[subIndex]->ItemsL();
       
   371                 TInt itemCount(subscriptionItems->Count());
       
   372                 for (TInt itemIndex = 0; itemIndex < itemCount; ++itemIndex)
       
   373                     {
       
   374                     // check the message attributes for the current subscription item
       
   375                     TBool subMatch(ETrue);
       
   376                     TInt attrMatchCount(0);
       
   377                     CMPXSubscriptionItem* subItem(subscriptionItems->AtL(itemIndex));
       
   378 
       
   379                     for (TInt msgAttrIndex = 0; msgAttrIndex < msgAttrCount; ++msgAttrIndex)
       
   380                         {
       
   381                         TBool attrExists(EFalse);
       
   382                         TBool attrMatch(EFalse);
       
   383                         const TMPXAttribute& msgAttr( msgAttrs[msgAttrIndex] );
       
   384 
       
   385                         if ( subItem->IsSupported(msgAttr))
       
   386                             {
       
   387                             attrExists = ETrue;
       
   388 
       
   389                             if ( subItem->Match( *aMsg, msgAttr ))
       
   390                                 {
       
   391                                 attrMatch = ETrue;
       
   392                                 attrMatchCount++;
       
   393                                 }
       
   394                             }
       
   395 
       
   396                         if (attrExists && !attrMatch)
       
   397                             {
       
   398                             subMatch = EFalse;
       
   399                             break;
       
   400                             }
       
   401                         }
       
   402 
       
   403                     // send the message if all attributes that exist in both the message and the subscription
       
   404                     // have the same values and all subscription attributes match
       
   405                     if ( subMatch && ( attrMatchCount == subItem->Count()) )
       
   406                         {
       
   407                         IsSubScribed = ETrue;
       
   408                         break;
       
   409                         }
       
   410                     }
       
   411                 }
       
   412             }
       
   413         } // else subCount = 0, IsSubScribed = EFalse (default)
       
   414     return IsSubScribed;
       
   415     }
       
   416 
       
   417 // ----------------------------------------------------------------------------
       
   418 // Comparison function. If the names are set in the client objects, then
       
   419 // that's used to test for equality. Otherwise, if the thread ids are set,
       
   420 // that's used. Else, it's assumed that the equality test is based on process
       
   421 //  ids.
       
   422 // ----------------------------------------------------------------------------
       
   423 //
       
   424 TBool CMPXClientList::ClientsMatch(const CClientId& aClient1,
       
   425                                    const CClientId& aClient2)
       
   426     {
       
   427     TBool match=EFalse;
       
   428     if (aClient1.iMsgQueue && aClient2.iMsgQueue)
       
   429         {
       
   430         match=aClient1.iMsgQueue==aClient2.iMsgQueue;
       
   431         }
       
   432     else if (aClient1.iTid.Id()!=KNullThreadId &&
       
   433              aClient2.iTid.Id()!=KNullThreadId)
       
   434         {
       
   435         match=(aClient1.iTid==aClient2.iTid);
       
   436         }
       
   437     else
       
   438         {
       
   439         match=(aClient1.iPid==aClient2.iPid);
       
   440         }
       
   441     return match;
       
   442     }
       
   443 
       
   444 // -----------------------------------------------------------------------------
       
   445 // C++ constructor
       
   446 // -----------------------------------------------------------------------------
       
   447 //
       
   448 CMPXClientList::CClientId::CClientId(
       
   449     TThreadId aTid,
       
   450     TProcessId aPid,
       
   451     CMPXMessageQueue* aMsgQueue)
       
   452 :   iTid(aTid),
       
   453     iPid(aPid),
       
   454     iMode(KErrNotFound),
       
   455     iMsgQueue(aMsgQueue)
       
   456     {}
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 // C++ constructor
       
   460 // -----------------------------------------------------------------------------
       
   461 //
       
   462 CMPXClientList::CClientId::CClientId(
       
   463     TThreadId aTid,
       
   464     TProcessId aPid,
       
   465     TInt aMode,
       
   466     CMPXMessageQueue* aMsgQueue)
       
   467 :   iTid(aTid),
       
   468     iPid(aPid),
       
   469     iMode(aMode),
       
   470     iMsgQueue(aMsgQueue)
       
   471     {}
       
   472 
       
   473 
       
   474 // -----------------------------------------------------------------------------
       
   475 // C++ constructor
       
   476 // -----------------------------------------------------------------------------
       
   477 //
       
   478     CMPXClientList::CClientId::CClientId(
       
   479         TThreadId aTid,
       
   480         TProcessId aPid,
       
   481         TInt aMode,
       
   482         CMPXMessageQueue* aMsgQueue,
       
   483         TInt aCategory)
       
   484     :   iTid(aTid),
       
   485         iPid(aPid),
       
   486         iMode(aMode),
       
   487         iMsgQueue(aMsgQueue),
       
   488         iCategory(aCategory)
       
   489         {}
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // C++ constructor
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 CMPXClientList::CClientId::CClientId(CMPXMessageQueue* aMsgQueue)
       
   496     :iTid(static_cast<TUint64>(KNullThreadId)),
       
   497      iPid(static_cast<TUint64>(KNullProcessId)),
       
   498      iMode(KErrUnknown),
       
   499      iMsgQueue(aMsgQueue)
       
   500     {}
       
   501 
       
   502 // -----------------------------------------------------------------------------
       
   503 // C++ constructor
       
   504 // -----------------------------------------------------------------------------
       
   505 //
       
   506 CMPXClientList::CClientId::CClientId(TThreadId aTid)
       
   507 :   iTid(aTid),
       
   508     iPid(static_cast<TUint64>(KNullProcessId)),
       
   509     iMode(KErrUnknown),
       
   510     iMsgQueue(NULL)
       
   511     {}
       
   512 
       
   513 // -----------------------------------------------------------------------------
       
   514 // C++ constructor
       
   515 // -----------------------------------------------------------------------------
       
   516 //
       
   517 CMPXClientList::CClientId::CClientId(TProcessId aPid)
       
   518 :   iTid(static_cast<TUint64>(KNullThreadId)),
       
   519     iPid(aPid),
       
   520     iMode(KErrUnknown),
       
   521     iMsgQueue(NULL)
       
   522     {}
       
   523 
       
   524 // -----------------------------------------------------------------------------
       
   525 // Destructor
       
   526 // -----------------------------------------------------------------------------
       
   527 //
       
   528 CMPXClientList::CClientId::~CClientId()
       
   529     {
       
   530     iSubscriptions.ResetAndDestroy();
       
   531     }
       
   532 
       
   533 // -----------------------------------------------------------------------------
       
   534 // CClientId::operator=
       
   535 // -----------------------------------------------------------------------------
       
   536 //
       
   537 CMPXClientList::CClientId& CMPXClientList::CClientId::operator=(
       
   538     const CClientId& aClient)
       
   539     {
       
   540     iTid = aClient.iTid;
       
   541     iPid = aClient.iPid;
       
   542     iMode = aClient.iMode;
       
   543     iMsgQueue = aClient.iMsgQueue;
       
   544 
       
   545     RemoveAllSubscriptionsL();
       
   546 
       
   547     // copy the subscriptions
       
   548     TInt count(aClient.iSubscriptions.Count());
       
   549     for (TInt index = 0; index < count; ++index)
       
   550         {
       
   551         CMPXSubscription* subscription = static_cast<CMPXSubscription*>(
       
   552             CMPXMedia::NewL(*(aClient.iSubscriptions[index])));
       
   553         CleanupStack::PushL(subscription);
       
   554 
       
   555         // transfer the ownership
       
   556         iSubscriptions.AppendL(subscription);
       
   557 
       
   558         CleanupStack::Pop(subscription);
       
   559         }
       
   560     return *this;
       
   561     }
       
   562 
       
   563 // -----------------------------------------------------------------------------
       
   564 // CClientId::AddSubscriptionL
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 void CMPXClientList::CClientId::AddSubscriptionL(
       
   568     CMPXSubscription* aSubscription)
       
   569     {
       
   570     // add the subscription
       
   571     iSubscriptions.AppendL(aSubscription);
       
   572     }
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // CClientId::RemoveSubscriptionL
       
   576 // -----------------------------------------------------------------------------
       
   577 //
       
   578 void CMPXClientList::CClientId::RemoveSubscriptionL(
       
   579     const CMPXSubscription& aSubscription)
       
   580     {
       
   581     TInt count(iSubscriptions.Count());
       
   582     for (TInt index = 0; index < count; ++index)
       
   583         {
       
   584         CMPXSubscription* subscription = iSubscriptions[index];
       
   585         if (aSubscription == *subscription)
       
   586             {
       
   587             // found the subscription, remove it
       
   588             iSubscriptions.Remove(index);
       
   589             delete subscription;
       
   590             break;
       
   591             }
       
   592         }
       
   593     }
       
   594 
       
   595 // -----------------------------------------------------------------------------
       
   596 // CClientId::RemoveAllSubscriptionsL
       
   597 // -----------------------------------------------------------------------------
       
   598 //
       
   599 void CMPXClientList::CClientId::RemoveAllSubscriptionsL()
       
   600     {
       
   601     iSubscriptions.ResetAndDestroy();
       
   602     }
       
   603 
       
   604 // End of File