persistentstorage/centralrepository/cenrepcli/clirep.cpp
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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