os/persistentdata/persistentstorage/centralrepository/cenrepcli/clirep.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "clirep.h"
    17 #include <e32math.h>
    18 #include "srvparams.h"
    19 #include "srvreqs.h"
    20 
    21 using namespace NCentralRepositoryConstants;
    22 
    23 RRepositorySession* CClientRepository::Session()
    24 	{
    25 	return static_cast<RRepositorySession*>(Dll::Tls());
    26 	}
    27 	
    28 CClientRepository* CClientRepository::NewLC(TUid aRepositoryUid)
    29 	{
    30 	CClientRepository* rep = new(ELeave) CClientRepository();
    31 	CleanupStack::PushL(rep);
    32 	rep->ConstructL(aRepositoryUid);
    33 	return rep;
    34 	}
    35 
    36 void CClientRepository::ConstructL(TUid aRepositoryUid)
    37 	{
    38 	RRepositorySession* session = Session();
    39 	
    40 	if(session == NULL)
    41 		{
    42 		session = new (ELeave) RRepositorySession();
    43 		CleanupStack::PushL(session);
    44 		User::LeaveIfError(Dll::SetTls(session));
    45 		CleanupStack::Pop(session);
    46 		User::LeaveIfError(session->Connect());
    47 		}
    48 	else
    49 		{
    50 		session->IncrementSubSessionCounter();
    51 		}
    52 
    53 	iSubSession = new (ELeave) RRepositorySubSession();
    54 	User::LeaveIfError(iSubSession->Open(session, EInitialise, TIpcArgs(aRepositoryUid.iUid)));
    55 	}
    56 
    57 CClientRepository::CClientRepository()
    58 	{
    59 	}
    60 
    61 CClientRepository::~CClientRepository()
    62 	{
    63 	if(iSubSession)
    64 		{
    65 		iSubSession->Close();
    66 		delete iSubSession;
    67 		}
    68 	RRepositorySession* session = Session();
    69 	if(session && session->DecrementSubSessionCounter() == 0)
    70 		{
    71 		//The last subSesssion is closed. Time to close the session.
    72 		session->Close();
    73 		delete session;
    74 		Dll::FreeTls();
    75 		//SetSession(NULL);
    76 		}
    77 	}
    78 
    79 TInt CClientRepository::Create(TUint32 aId, TInt aVal)
    80 	{
    81 	return iSubSession->SendReceive(ECreateInt, TIpcArgs(aId, aVal));
    82 	}
    83 
    84 TInt CClientRepository::Create(TUint32 aId, const TReal& aVal)
    85 	{
    86 	TPckg<TReal> p(aVal);
    87 	return iSubSession->SendReceive(ECreateReal, TIpcArgs(aId, &p));
    88 	}
    89 	
    90 TInt CClientRepository::Create(TUint32 aId, const TDesC8& aVal)
    91 	{
    92 	return iSubSession->SendReceive(ECreateString, TIpcArgs(aId, &aVal));
    93 	}
    94 
    95 TInt CClientRepository::Create(TUint32 aId, const TDesC16& aVal)
    96 	{
    97 	TPtrC8 ptr8((const TUint8*)aVal.Ptr(), aVal.Size());
    98 	return iSubSession->SendReceive(ECreateString, TIpcArgs(aId, &ptr8));
    99 	}
   100 
   101 TInt CClientRepository::Delete(TUint32 aId)
   102 	{
   103 	return iSubSession->SendReceive(EDelete, TIpcArgs(aId));
   104 	}
   105 	
   106 TInt CClientRepository::Delete(TUint32 aPartialKey, TUint32 aMask, TUint32 &aErrorKey)
   107 	{
   108 	aErrorKey = KUnspecifiedKey; // set in case not filled by server
   109 	TPckg<TUint32> p(aErrorKey);
   110 	return iSubSession->SendReceive(EDeleteRange, TIpcArgs(aPartialKey, aMask, &p));
   111 	}
   112 
   113 TInt CClientRepository::Get(TUint32 aId, TInt& aVal)
   114 	{
   115 	TPckg<TInt> p(aVal);
   116 	return iSubSession->SendReceive(EGetInt, TIpcArgs(aId, &p));
   117 	}
   118 
   119 TInt CClientRepository::Set(TUint32 aId, TInt aVal)
   120 	{
   121 	return iSubSession->SendReceive(ESetInt, TIpcArgs(aId, aVal));
   122 	}
   123 
   124 TInt CClientRepository::Get(TUint32 aId, TReal& aVal)
   125 	{
   126 	TPckg<TReal> p(aVal);
   127 	return iSubSession->SendReceive(EGetReal, TIpcArgs(aId, &p));
   128 	}
   129 
   130 TInt CClientRepository::Set(TUint32 aId, const TReal& aVal)
   131 	{
   132 	TPckg<TReal> p(aVal);
   133 	return iSubSession->SendReceive(ESetReal, TIpcArgs(aId, &p));
   134 	}
   135 
   136 TInt CClientRepository::Get(TUint32 aId, TDes8& aVal)
   137 	{
   138 	TPckg<TInt> p(aVal.MaxLength());
   139 	return iSubSession->SendReceive(EGetString, TIpcArgs(aId, &aVal, &p));
   140 	}
   141 
   142 TInt CClientRepository::Get(TUint32 aId, TDes8& aVal, TInt& aActualLen)
   143 	{
   144 	aActualLen = aVal.MaxLength();
   145 	TPckg<TInt> p(aActualLen);
   146 	return iSubSession->SendReceive(EGetString, TIpcArgs(aId, &aVal, &p));
   147 	}
   148 
   149 TInt CClientRepository::Set(TUint32 aId, const TDesC8& aVal)
   150 	{
   151 	return iSubSession->SendReceive(ESetString, TIpcArgs(aId, &aVal));
   152 	}
   153 
   154 TInt CClientRepository::Get(TUint32 aId, TDes& aVal)
   155 	{
   156 	TPtr8 ptr8((TUint8*)aVal.Ptr(), 0, aVal.MaxSize());
   157 	
   158 	TPckg<TInt> p(ptr8.MaxLength());
   159 	
   160 	TInt r = iSubSession->SendReceive(EGetString, TIpcArgs(aId, &ptr8, &p));
   161 
   162 	if(r==KErrNone || r==KErrOverflow)
   163 		{
   164 		TInt len = ptr8.Length();
   165 		// note the following handles the case where client is getting an odd-length 8-bit
   166 		// descriptor into 16-bit aVal. Round up length and ensure the extra byte is zero.
   167 		if(len&1)
   168 			{
   169 			ptr8.SetLength(len+1);   // set the length before trying to write the value			
   170 			ptr8[len] = 0;
   171 			}
   172 		aVal.SetLength((len + 1)/2);
   173 		}
   174 
   175 	return r;
   176 	}
   177 	
   178 TInt CClientRepository::Get(TUint32 aId, TDes& aVal, TInt& aActualLen)
   179 	{
   180 	TPtr8 ptr8((TUint8*)aVal.Ptr(), 0, aVal.MaxSize());
   181 
   182 	aActualLen = ptr8.MaxLength();
   183 	TPckg<TInt> p(aActualLen);
   184 
   185 	TInt r = iSubSession->SendReceive(EGetString, TIpcArgs(aId, &ptr8, &p));
   186 
   187 	if(r==KErrNone || r==KErrOverflow)
   188 		{
   189 		TInt len = ptr8.Length();
   190 		// note the following handles the case where client is getting an odd-length 8-bit
   191 		// descriptor into 16-bit aVal. Round up length and ensure the extra byte is zero.
   192 		if(len&1)
   193 			{
   194 			ptr8.SetLength(len+1);   // set the length before trying to write the value			
   195 			ptr8[len] = 0;
   196 			}
   197 		aVal.SetLength((len + 1)/2);
   198 		aActualLen = ((aActualLen + 1)/2);
   199 		}
   200 
   201 	return r;
   202 	}
   203 
   204 TInt CClientRepository::Set(TUint32 aId, const TDesC& aVal)
   205 	{
   206 	TPtrC8 ptr8((const TUint8*)aVal.Ptr(), aVal.Size());
   207 	return iSubSession->SendReceive(ESetString, TIpcArgs(aId, &ptr8));
   208 	}
   209 
   210 TInt CClientRepository::GetMeta(TUint32 aId, TUint32& aMeta)
   211 	{
   212 	TPckg<TUint32> p(aMeta);
   213 	return iSubSession->SendReceive(EGetMeta, TIpcArgs(aId, &p));
   214 	}
   215 
   216 TInt CClientRepository::Move(TUint32 aSourcePartialId, TUint32 aTargetPartialId,
   217                              TUint32 aIdMask, TUint32 &aErrorId)
   218 	{
   219 	aErrorId = KUnspecifiedKey; // set in case not filled by server
   220 	TPckg<TUint32> p(aErrorId);
   221 	TKeyFilter srcKeyIdentifier = {aSourcePartialId, aIdMask};
   222 	TKeyFilter tgtKeyIdentifier = {aTargetPartialId, aIdMask};
   223 	TPckg<TKeyFilter> pSrc(srcKeyIdentifier);
   224 	TPckg<TKeyFilter> pTrg(tgtKeyIdentifier);
   225 	
   226 	TInt r = iSubSession->SendReceive(EMove, TIpcArgs(&pSrc, &pTrg, &p));
   227 	
   228 	return r;
   229 	}
   230 	
   231 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   232 //operations valid in transactions.
   233 TInt CClientRepository::FindL(TUint32 aPartialId, TUint32 aIdMask,
   234 	RArray<TUint32>& aFoundIds)
   235 	{
   236     CleanupFailTransactionPushL();
   237 	aFoundIds.Reset();	
   238 	
   239 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   240 	TUint32* start = uids.Begin();
   241 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   242 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   243 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   244 
   245 	TInt r = iSubSession->SendReceive(EFind, TIpcArgs(&pIdentifier, 0, &ptr));
   246 
   247 	if(r == KErrNone)
   248 		{
   249 		r = GetFindResult(uids, aFoundIds);
   250 		if (r==KErrNoMemory)
   251 			User::LeaveNoMemory();
   252 		}
   253 		
   254     CleanupStack::Pop();
   255 	
   256 	return r;
   257 	}
   258 
   259 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   260 //operations valid in transactions.
   261 TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask, TInt aVal,
   262 	RArray<TUint32>& aFoundIds)
   263 	{
   264     CleanupFailTransactionPushL();
   265 	aFoundIds.Reset();	
   266 	
   267 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   268 	TUint32* start = uids.Begin();
   269 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   270 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   271 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   272 
   273 	TInt r = iSubSession->SendReceive(EFindEqInt, TIpcArgs(&pIdentifier, aVal, &ptr));
   274 
   275 	if(r == KErrNone)
   276 		{
   277 		r = GetFindResult(uids, aFoundIds);
   278 		if (r==KErrNoMemory)
   279 			User::LeaveNoMemory();
   280 		}
   281 		
   282     CleanupStack::Pop();
   283 	
   284 	return r;
   285 	}
   286 
   287 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   288 //operations valid in transactions.
   289 TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask,
   290 	const TReal& aVal, RArray<TUint32>& aFoundIds)
   291 	{
   292     CleanupFailTransactionPushL();
   293 	aFoundIds.Reset();	
   294 	
   295 	TPckg<TReal> pVal(aVal);
   296 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   297 	TUint32* start = uids.Begin();
   298 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   299 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   300 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   301 
   302 	TInt r = iSubSession->SendReceive(EFindEqReal, TIpcArgs(&pIdentifier, &pVal, &ptr));
   303 
   304 	if(r == KErrNone)
   305 		{
   306 		r = GetFindResult(uids, aFoundIds);
   307 		if (r==KErrNoMemory)
   308 			User::LeaveNoMemory();
   309 		}
   310 		
   311     CleanupStack::Pop();
   312 	
   313 	return r;
   314 	}
   315 
   316 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   317 //operations valid in transactions.
   318 TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask,
   319 	const TDesC8& aVal, RArray<TUint32>& aFoundIds)
   320 	{
   321     CleanupFailTransactionPushL();
   322 	aFoundIds.Reset();	
   323 	
   324 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   325 	TUint32* start = uids.Begin();
   326 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   327 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   328 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   329 
   330 	TInt r = iSubSession->SendReceive(EFindEqString, TIpcArgs(&pIdentifier, &aVal, &ptr));
   331 
   332 	if(r == KErrNone)
   333 		{
   334 		r = GetFindResult(uids, aFoundIds);
   335 		if (r==KErrNoMemory)
   336 			User::LeaveNoMemory();
   337 		}
   338 		
   339     CleanupStack::Pop();
   340 	
   341 	return r;
   342 	}
   343 
   344 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   345 //operations valid in transactions.
   346 TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask,
   347 	const TDesC& aVal, RArray<TUint32>& aFoundIds)
   348 	{
   349     CleanupFailTransactionPushL();
   350 	aFoundIds.Reset();	
   351 	
   352 	TPtrC8 pVal((const TUint8*)aVal.Ptr(), aVal.Length()*2);
   353 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   354 	TUint32* start = uids.Begin();
   355 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   356 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   357 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   358 
   359 	TInt r = iSubSession->SendReceive(EFindEqString, TIpcArgs(&pIdentifier, &pVal, &ptr));
   360 
   361 	if(r == KErrNone)
   362 		{
   363 		r = GetFindResult(uids, aFoundIds);
   364 		if (r==KErrNoMemory)
   365 			User::LeaveNoMemory();
   366 		}
   367 		
   368     CleanupStack::Pop();
   369 	
   370 	return r;
   371 	}
   372 
   373 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   374 //operations valid in transactions.
   375 TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
   376 	TInt aVal, RArray<TUint32>& aFoundIds)
   377 	{
   378     CleanupFailTransactionPushL();
   379 	aFoundIds.Reset();	
   380 	
   381 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   382 	TUint32* start = uids.Begin();
   383 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   384 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   385 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   386 
   387 	TInt r = iSubSession->SendReceive(EFindNeqInt, TIpcArgs(&pIdentifier, aVal, &ptr));
   388 
   389 	if(r == KErrNone)
   390 		{
   391 		r = GetFindResult(uids, aFoundIds);
   392 		if (r==KErrNoMemory)
   393 			User::LeaveNoMemory();
   394 		}
   395 		
   396     CleanupStack::Pop();
   397 	
   398 	return r;
   399 	}
   400 
   401 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   402 //operations valid in transactions.
   403 TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
   404 	const TReal& aVal, RArray<TUint32>& aFoundIds)
   405 	{
   406     CleanupFailTransactionPushL();
   407 	aFoundIds.Reset();	
   408 	
   409 	TPckg<TReal> pVal(aVal);
   410 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   411 	TUint32* start = uids.Begin();
   412 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   413 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   414 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   415 
   416 	TInt r = iSubSession->SendReceive(EFindNeqReal, TIpcArgs(&pIdentifier, &pVal, &ptr));
   417 
   418 	if(r == KErrNone)
   419 		{
   420 		r = GetFindResult(uids, aFoundIds);
   421 		if (r==KErrNoMemory)
   422 			User::LeaveNoMemory();
   423 		}
   424 		
   425     CleanupStack::Pop();
   426 	
   427 	return r;
   428 	}
   429 
   430 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   431 //operations valid in transactions.
   432 TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
   433 	const TDesC8& aVal, RArray<TUint32>& aFoundIds)
   434 	{
   435     CleanupFailTransactionPushL();
   436 	aFoundIds.Reset();	
   437 	
   438 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   439 	TUint32* start = uids.Begin();
   440 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   441 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   442 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   443 
   444 	TInt r = iSubSession->SendReceive(EFindNeqString, TIpcArgs(&pIdentifier, &aVal, &ptr));
   445 
   446 	if(r == KErrNone)
   447 		{
   448 		r = GetFindResult(uids, aFoundIds);
   449 		if (r==KErrNoMemory)
   450 			User::LeaveNoMemory();
   451 		}
   452 		
   453     CleanupStack::Pop();
   454 	
   455 	return r;
   456 	}
   457 
   458 //Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
   459 //operations valid in transactions.
   460 TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
   461 	const TDesC& aVal, RArray<TUint32>& aFoundIds)
   462 	{
   463     CleanupFailTransactionPushL();
   464 	aFoundIds.Reset();	
   465 	
   466 	TPtrC8 pVal((const TUint8*)aVal.Ptr(), aVal.Length()*2);
   467 	TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
   468 	TUint32* start = uids.Begin();
   469 	TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
   470 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   471 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   472 
   473 	TInt r = iSubSession->SendReceive(EFindNeqString, TIpcArgs(&pIdentifier, &pVal, &ptr));
   474 
   475 	if(r == KErrNone)
   476 		{
   477 		r = GetFindResult(uids, aFoundIds);
   478 		if (r==KErrNoMemory)
   479 			User::LeaveNoMemory();
   480 		}
   481 		
   482     CleanupStack::Pop();
   483 	
   484 	return r;
   485 	}
   486 
   487 /** Private helper function for all the Find~L functions.
   488 No need to call FailTransaction since all the methods that call this method calls
   489 FailTransaction prior to this method.
   490 @internalComponent
   491 */
   492 TInt CClientRepository::GetFindResult(const TFixedArray<TUint32, KCentRepFindWithLenghtBufSize>& aUids, RArray<TUint32>& aFoundIds)
   493 	{
   494 	iClientErr = KErrNone;	
   495 	const TUint32 numFound = aUids[0];
   496 	const TUint32 numInitial = numFound > KCentRepFindBufSize ? KCentRepFindBufSize : numFound;
   497 	const TUint32 numFinal = numFound > KCentRepFindBufSize ? numFound - KCentRepFindBufSize : 0;
   498 	
   499 	for(TUint32 i = 1; i <= numInitial; i++)
   500 		{
   501 		//initialise client error first
   502 		iClientErr=aFoundIds.Append(aUids[i]);
   503 		if (iClientErr!=KErrNone)
   504 			return iClientErr;		
   505 		}
   506 	
   507 	if(numFinal)
   508 		{
   509 		TAny* tempBuf = User::Alloc(numFinal * sizeof(TUint32));
   510 		if (tempBuf==NULL)
   511 			{
   512 			return KErrNoMemory;
   513 			}
   514 		TPtr8 p(static_cast<TUint8*>(tempBuf), numFinal * sizeof(TUint32));
   515 		TInt r = iSubSession->SendReceive(EGetFindResult, TIpcArgs(&p));
   516 		if (r == KErrNone)
   517 			{ 
   518 			for(TUint32 i = 0; i < numFinal; i++)
   519 				{
   520 				iClientErr=aFoundIds.Append(static_cast<const TUint32*>(tempBuf)[i]);
   521 				if (iClientErr!=KErrNone)
   522 					{
   523 					User::Free(tempBuf);
   524 					return iClientErr;
   525 					}
   526 				}
   527 			}
   528 		User::Free(tempBuf);
   529 		}		
   530 	return iClientErr;
   531 	}
   532 
   533 TInt CClientRepository::NotifyRequest(TUint32 aId, TRequestStatus& aStatus)
   534 	{
   535 	TInt r = iSubSession->SendReceive(ENotifyRequestCheck, TIpcArgs(aId));
   536 	if(r==KErrNone)
   537 		iSubSession->SendReceive(ENotifyRequest, TIpcArgs(aId), aStatus);
   538 	return r;
   539 	}
   540 
   541 TInt CClientRepository::NotifyCancel(TUint32 aId)
   542 	{
   543 	return iSubSession->SendReceive(ENotifyCancel, TIpcArgs(aId));
   544 	}
   545 
   546 TInt CClientRepository::NotifyCancelAll()
   547 	{
   548 	return iSubSession->SendReceive(ENotifyCancelAll);
   549 	}
   550 
   551 TInt CClientRepository::NotifyRequest(TUint32 aPartialId, TUint32 aIdMask,
   552 	TRequestStatus& aStatus)
   553 	{
   554 	iSubSession->SendReceive(EGroupNotifyRequest,
   555 		TIpcArgs(aPartialId, aIdMask), aStatus);
   556 	return KErrNone;
   557 	}
   558 
   559 TInt CClientRepository::NotifyCancel(TUint32 aPartialId, TUint32 aIdMask)
   560 	{
   561 	TKeyFilter keyIdentifier = {aPartialId, aIdMask};
   562 	TPckg<TKeyFilter> pIdentifier(keyIdentifier);
   563 	
   564 	return iSubSession->SendReceive(EGroupNotifyCancel, TIpcArgs(&pIdentifier));
   565 	}
   566 
   567 TInt CClientRepository::Reset()
   568 	{
   569 	return iSubSession->SendReceive(EResetAll);
   570 	}
   571 
   572 TInt CClientRepository::Reset(TUint32 aId)
   573 	{
   574 	return iSubSession->SendReceive(EReset, TIpcArgs(aId));
   575 	}
   576 
   577 TInt CClientRepository::StartTransaction(TTransactionMode aMode)
   578 	{
   579 	return iSubSession->SendReceive(ETransactionStart, TIpcArgs(aMode));
   580 	}
   581 
   582 void CClientRepository::StartTransaction(TTransactionMode aMode, TRequestStatus& aStatus)
   583 	{
   584 	iSubSession->SendReceive(ETransactionStart, TIpcArgs(aMode), aStatus);
   585 	}
   586 
   587 TInt CClientRepository::CommitTransaction(TUint32& aKeyInfo)
   588 	{
   589 	// set to KUnspecifiedKey in case failure happens before setting in server
   590 	aKeyInfo = KUnspecifiedKey;
   591 	TPckg<TUint32> p(aKeyInfo);
   592 	return iSubSession->SendReceive(ETransactionCommit, TIpcArgs(&p));
   593 	}
   594 
   595 void CClientRepository::CommitTransaction(TDes8& aKeyInfo, TRequestStatus& aStatus)
   596 	{
   597 	// set to KUnspecifiedKey in case failure happens before setting in server
   598 	aKeyInfo.Copy(TPckg<TUint32>(KUnspecifiedKey));
   599 	iSubSession->SendReceive(ETransactionCommit, TIpcArgs(&aKeyInfo), aStatus);
   600 	}
   601 	
   602 void CClientRepository::CancelTransaction()
   603 	{
   604     iSubSession->SendReceive(ETransactionCancel);
   605 	}
   606 
   607 static void CancelTransactionCleanupOperation(TAny* aRepository)
   608     {
   609     static_cast<CClientRepository*>(aRepository)->CancelTransaction();
   610     }
   611 
   612 // So CancelTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar
   613 void CClientRepository::CleanupCancelTransactionPushL()
   614     {
   615     CleanupStack::PushL(TCleanupItem(CancelTransactionCleanupOperation, this));
   616     }
   617     
   618 void CClientRepository::FailTransaction()
   619 	{
   620 	if (iClientErr==KErrNone)
   621 		iSubSession->SendReceive(ETransactionFail,TIpcArgs(KErrAbort));
   622 	else
   623 		iSubSession->SendReceive(ETransactionFail,TIpcArgs(iClientErr));
   624 	//reset the internal client code
   625 	iClientErr=KErrNone;
   626 	}
   627 	
   628 // So FailTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar
   629 static void FailTransactionCleanupOperation(TAny* aRepository)
   630     {
   631     static_cast<CClientRepository*>(aRepository)->FailTransaction();
   632     }
   633 	
   634 void CClientRepository::CleanupFailTransactionPushL()
   635 	{
   636 	CleanupStack::PushL(TCleanupItem(FailTransactionCleanupOperation, this));
   637 	}
   638 
   639 TInt CClientRepository::TransactionState()
   640 	{
   641 	TInt iValue;
   642 	
   643 	TPckg<TInt> p(iValue);
   644 	
   645 	iSubSession->SendReceive(ETransactionState, TIpcArgs(&p));
   646 	
   647 	return iValue;
   648 	}
   649 
   650 TInt RRepositorySubSession::Open(RRepositorySession* aSession,TInt aFunction,const TIpcArgs& aArgs)
   651 	{
   652 	iSession = aSession;
   653 	return(CreateSubSession(*aSession, aFunction, aArgs));
   654 	}
   655 	
   656 void RRepositorySubSession::Close()
   657 	{
   658 	RSubSessionBase::CloseSubSession(EClose);
   659 	}
   660 
   661 TInt RRepositorySubSession::SendReceive(TInt aFunction) const
   662 	{
   663 	return RSubSessionBase::SendReceive(aFunction);
   664 	}
   665 	
   666 TInt RRepositorySubSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs) const
   667 	{
   668 	return RSubSessionBase::SendReceive(aFunction, aArgs);
   669 	}
   670 	
   671 void RRepositorySubSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus) const
   672 	{
   673 	RSubSessionBase::SendReceive(aFunction, aArgs, aStatus);
   674 	}
   675 
   676 inline TInt RRepositorySession::IncrementSubSessionCounter()
   677 	{
   678 	return ++iSubSessionCounter;
   679 	}
   680 	
   681 RRepositorySession ::RRepositorySession()
   682 	:iSubSessionCounter(1)
   683 	{
   684 	}
   685 	
   686 inline TInt RRepositorySession::DecrementSubSessionCounter()
   687 	{
   688 	ASSERT(iSubSessionCounter > 0);
   689 	return --iSubSessionCounter;
   690 	}
   691 
   692 #if defined(__CENTREP_SERVER_PERFTEST__) || defined(__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__)
   693 TInt RRepositorySession::SendReceive(TInt aFunction) const
   694 	{
   695 	return RSessionBase::SendReceive(aFunction);
   696 	}
   697 
   698 TInt RRepositorySession::SendReceive(TInt aFunction,
   699 	const TIpcArgs& aArgs) const
   700 	{
   701 	return RSessionBase::SendReceive(aFunction, aArgs);
   702 	}
   703 
   704 void RRepositorySession::SendReceive(TInt aFunction, const TIpcArgs& aArgs,
   705 	TRequestStatus& aStatus) const
   706 	{
   707 	RSessionBase::SendReceive(aFunction, aArgs, aStatus);
   708 	}
   709 #endif
   710 
   711 LOCAL_C TInt StartServer();
   712 
   713 TInt RRepositorySession::Connect()
   714 	{
   715    	const TVersion KVersion(KServerMajorVersion, KServerMinorVersion,
   716    		KServerBuildVersion);
   717    	TInt retry = 2;
   718    	TInt err = KErrGeneral;
   719    	// Use unlimited message slots as we can call subscribe multiple times per
   720    	// session.
   721    	TInt numMessageSlots = -1; 
   722    	for(;;)
   723    		{
   724    		// Try to create a new session with the server.
   725    		err = CreateSession(KServerName, KVersion, numMessageSlots);
   726    		if((err != KErrNotFound) && (err != KErrServerTerminated))
   727    			break; //completed
   728    		// Server not running, try to start it.
   729    		if(--retry==0)
   730 			break; // Failed.
   731    		err = StartServer();
   732    		if((err != KErrNone) && (err != KErrAlreadyExists))
   733 			break;	// Launched server
   734    		}
   735    	return err;
   736 	}
   737 
   738 //
   739 // Start the server process or thread
   740 //
   741 LOCAL_C TInt StartServer()
   742 	{
   743 	const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
   744 	//
   745 	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
   746 	// launching of two such processes should be detected when the second one
   747 	// attempts to create the server object, failing with KErrAlreadyExists.
   748 	//
   749 	RProcess server;
   750 	TInt r=server.Create(KServerImg,KNullDesC,serverUid);
   751 
   752 	if (r!=KErrNone)
   753 		return r;
   754 	TRequestStatus stat;
   755 	server.Rendezvous(stat);
   756 	if (stat!=KRequestPending)
   757 		server.Kill(0);		// abort startup
   758 	else
   759 		server.Resume();	// logon OK - start the server
   760 	User::WaitForRequest(stat);		// wait for start or death
   761 	// we can't use the 'exit reason' if the server panicked as this
   762 	// is the panic 'reason' and may be '0' which cannot be distinguished
   763 	// from KErrNone
   764 	r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
   765 	server.Close();
   766 	return r;
   767 	}
   768