--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/centralrepository/cenrepcli/clirep.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,768 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "clirep.h"
+#include <e32math.h>
+#include "srvparams.h"
+#include "srvreqs.h"
+
+using namespace NCentralRepositoryConstants;
+
+RRepositorySession* CClientRepository::Session()
+ {
+ return static_cast<RRepositorySession*>(Dll::Tls());
+ }
+
+CClientRepository* CClientRepository::NewLC(TUid aRepositoryUid)
+ {
+ CClientRepository* rep = new(ELeave) CClientRepository();
+ CleanupStack::PushL(rep);
+ rep->ConstructL(aRepositoryUid);
+ return rep;
+ }
+
+void CClientRepository::ConstructL(TUid aRepositoryUid)
+ {
+ RRepositorySession* session = Session();
+
+ if(session == NULL)
+ {
+ session = new (ELeave) RRepositorySession();
+ CleanupStack::PushL(session);
+ User::LeaveIfError(Dll::SetTls(session));
+ CleanupStack::Pop(session);
+ User::LeaveIfError(session->Connect());
+ }
+ else
+ {
+ session->IncrementSubSessionCounter();
+ }
+
+ iSubSession = new (ELeave) RRepositorySubSession();
+ User::LeaveIfError(iSubSession->Open(session, EInitialise, TIpcArgs(aRepositoryUid.iUid)));
+ }
+
+CClientRepository::CClientRepository()
+ {
+ }
+
+CClientRepository::~CClientRepository()
+ {
+ if(iSubSession)
+ {
+ iSubSession->Close();
+ delete iSubSession;
+ }
+ RRepositorySession* session = Session();
+ if(session && session->DecrementSubSessionCounter() == 0)
+ {
+ //The last subSesssion is closed. Time to close the session.
+ session->Close();
+ delete session;
+ Dll::FreeTls();
+ //SetSession(NULL);
+ }
+ }
+
+TInt CClientRepository::Create(TUint32 aId, TInt aVal)
+ {
+ return iSubSession->SendReceive(ECreateInt, TIpcArgs(aId, aVal));
+ }
+
+TInt CClientRepository::Create(TUint32 aId, const TReal& aVal)
+ {
+ TPckg<TReal> p(aVal);
+ return iSubSession->SendReceive(ECreateReal, TIpcArgs(aId, &p));
+ }
+
+TInt CClientRepository::Create(TUint32 aId, const TDesC8& aVal)
+ {
+ return iSubSession->SendReceive(ECreateString, TIpcArgs(aId, &aVal));
+ }
+
+TInt CClientRepository::Create(TUint32 aId, const TDesC16& aVal)
+ {
+ TPtrC8 ptr8((const TUint8*)aVal.Ptr(), aVal.Size());
+ return iSubSession->SendReceive(ECreateString, TIpcArgs(aId, &ptr8));
+ }
+
+TInt CClientRepository::Delete(TUint32 aId)
+ {
+ return iSubSession->SendReceive(EDelete, TIpcArgs(aId));
+ }
+
+TInt CClientRepository::Delete(TUint32 aPartialKey, TUint32 aMask, TUint32 &aErrorKey)
+ {
+ aErrorKey = KUnspecifiedKey; // set in case not filled by server
+ TPckg<TUint32> p(aErrorKey);
+ return iSubSession->SendReceive(EDeleteRange, TIpcArgs(aPartialKey, aMask, &p));
+ }
+
+TInt CClientRepository::Get(TUint32 aId, TInt& aVal)
+ {
+ TPckg<TInt> p(aVal);
+ return iSubSession->SendReceive(EGetInt, TIpcArgs(aId, &p));
+ }
+
+TInt CClientRepository::Set(TUint32 aId, TInt aVal)
+ {
+ return iSubSession->SendReceive(ESetInt, TIpcArgs(aId, aVal));
+ }
+
+TInt CClientRepository::Get(TUint32 aId, TReal& aVal)
+ {
+ TPckg<TReal> p(aVal);
+ return iSubSession->SendReceive(EGetReal, TIpcArgs(aId, &p));
+ }
+
+TInt CClientRepository::Set(TUint32 aId, const TReal& aVal)
+ {
+ TPckg<TReal> p(aVal);
+ return iSubSession->SendReceive(ESetReal, TIpcArgs(aId, &p));
+ }
+
+TInt CClientRepository::Get(TUint32 aId, TDes8& aVal)
+ {
+ TPckg<TInt> p(aVal.MaxLength());
+ return iSubSession->SendReceive(EGetString, TIpcArgs(aId, &aVal, &p));
+ }
+
+TInt CClientRepository::Get(TUint32 aId, TDes8& aVal, TInt& aActualLen)
+ {
+ aActualLen = aVal.MaxLength();
+ TPckg<TInt> p(aActualLen);
+ return iSubSession->SendReceive(EGetString, TIpcArgs(aId, &aVal, &p));
+ }
+
+TInt CClientRepository::Set(TUint32 aId, const TDesC8& aVal)
+ {
+ return iSubSession->SendReceive(ESetString, TIpcArgs(aId, &aVal));
+ }
+
+TInt CClientRepository::Get(TUint32 aId, TDes& aVal)
+ {
+ TPtr8 ptr8((TUint8*)aVal.Ptr(), 0, aVal.MaxSize());
+
+ TPckg<TInt> p(ptr8.MaxLength());
+
+ TInt r = iSubSession->SendReceive(EGetString, TIpcArgs(aId, &ptr8, &p));
+
+ if(r==KErrNone || r==KErrOverflow)
+ {
+ TInt len = ptr8.Length();
+ // note the following handles the case where client is getting an odd-length 8-bit
+ // descriptor into 16-bit aVal. Round up length and ensure the extra byte is zero.
+ if(len&1)
+ {
+ ptr8.SetLength(len+1); // set the length before trying to write the value
+ ptr8[len] = 0;
+ }
+ aVal.SetLength((len + 1)/2);
+ }
+
+ return r;
+ }
+
+TInt CClientRepository::Get(TUint32 aId, TDes& aVal, TInt& aActualLen)
+ {
+ TPtr8 ptr8((TUint8*)aVal.Ptr(), 0, aVal.MaxSize());
+
+ aActualLen = ptr8.MaxLength();
+ TPckg<TInt> p(aActualLen);
+
+ TInt r = iSubSession->SendReceive(EGetString, TIpcArgs(aId, &ptr8, &p));
+
+ if(r==KErrNone || r==KErrOverflow)
+ {
+ TInt len = ptr8.Length();
+ // note the following handles the case where client is getting an odd-length 8-bit
+ // descriptor into 16-bit aVal. Round up length and ensure the extra byte is zero.
+ if(len&1)
+ {
+ ptr8.SetLength(len+1); // set the length before trying to write the value
+ ptr8[len] = 0;
+ }
+ aVal.SetLength((len + 1)/2);
+ aActualLen = ((aActualLen + 1)/2);
+ }
+
+ return r;
+ }
+
+TInt CClientRepository::Set(TUint32 aId, const TDesC& aVal)
+ {
+ TPtrC8 ptr8((const TUint8*)aVal.Ptr(), aVal.Size());
+ return iSubSession->SendReceive(ESetString, TIpcArgs(aId, &ptr8));
+ }
+
+TInt CClientRepository::GetMeta(TUint32 aId, TUint32& aMeta)
+ {
+ TPckg<TUint32> p(aMeta);
+ return iSubSession->SendReceive(EGetMeta, TIpcArgs(aId, &p));
+ }
+
+TInt CClientRepository::Move(TUint32 aSourcePartialId, TUint32 aTargetPartialId,
+ TUint32 aIdMask, TUint32 &aErrorId)
+ {
+ aErrorId = KUnspecifiedKey; // set in case not filled by server
+ TPckg<TUint32> p(aErrorId);
+ TKeyFilter srcKeyIdentifier = {aSourcePartialId, aIdMask};
+ TKeyFilter tgtKeyIdentifier = {aTargetPartialId, aIdMask};
+ TPckg<TKeyFilter> pSrc(srcKeyIdentifier);
+ TPckg<TKeyFilter> pTrg(tgtKeyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EMove, TIpcArgs(&pSrc, &pTrg, &p));
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindL(TUint32 aPartialId, TUint32 aIdMask,
+ RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFind, TIpcArgs(&pIdentifier, 0, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask, TInt aVal,
+ RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindEqInt, TIpcArgs(&pIdentifier, aVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask,
+ const TReal& aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TPckg<TReal> pVal(aVal);
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindEqReal, TIpcArgs(&pIdentifier, &pVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask,
+ const TDesC8& aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindEqString, TIpcArgs(&pIdentifier, &aVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindEqL(TUint32 aPartialId, TUint32 aIdMask,
+ const TDesC& aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TPtrC8 pVal((const TUint8*)aVal.Ptr(), aVal.Length()*2);
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindEqString, TIpcArgs(&pIdentifier, &pVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
+ TInt aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindNeqInt, TIpcArgs(&pIdentifier, aVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
+ const TReal& aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TPckg<TReal> pVal(aVal);
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindNeqReal, TIpcArgs(&pIdentifier, &pVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
+ const TDesC8& aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindNeqString, TIpcArgs(&pIdentifier, &aVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+//Calls FailTransaction if it Leaves. This is the pattern for all client-side failure of
+//operations valid in transactions.
+TInt CClientRepository::FindNeqL(TUint32 aPartialId, TUint32 aIdMask,
+ const TDesC& aVal, RArray<TUint32>& aFoundIds)
+ {
+ CleanupFailTransactionPushL();
+ aFoundIds.Reset();
+
+ TPtrC8 pVal((const TUint8*)aVal.Ptr(), aVal.Length()*2);
+ TFixedArray<TUint32, KCentRepFindWithLenghtBufSize> uids;
+ TUint32* start = uids.Begin();
+ TPtr8 ptr(reinterpret_cast<TUint8*>(start), uids.Count() * uids.Length());
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ TInt r = iSubSession->SendReceive(EFindNeqString, TIpcArgs(&pIdentifier, &pVal, &ptr));
+
+ if(r == KErrNone)
+ {
+ r = GetFindResult(uids, aFoundIds);
+ if (r==KErrNoMemory)
+ User::LeaveNoMemory();
+ }
+
+ CleanupStack::Pop();
+
+ return r;
+ }
+
+/** Private helper function for all the Find~L functions.
+No need to call FailTransaction since all the methods that call this method calls
+FailTransaction prior to this method.
+@internalComponent
+*/
+TInt CClientRepository::GetFindResult(const TFixedArray<TUint32, KCentRepFindWithLenghtBufSize>& aUids, RArray<TUint32>& aFoundIds)
+ {
+ iClientErr = KErrNone;
+ const TUint32 numFound = aUids[0];
+ const TUint32 numInitial = numFound > KCentRepFindBufSize ? KCentRepFindBufSize : numFound;
+ const TUint32 numFinal = numFound > KCentRepFindBufSize ? numFound - KCentRepFindBufSize : 0;
+
+ for(TUint32 i = 1; i <= numInitial; i++)
+ {
+ //initialise client error first
+ iClientErr=aFoundIds.Append(aUids[i]);
+ if (iClientErr!=KErrNone)
+ return iClientErr;
+ }
+
+ if(numFinal)
+ {
+ TAny* tempBuf = User::Alloc(numFinal * sizeof(TUint32));
+ if (tempBuf==NULL)
+ {
+ return KErrNoMemory;
+ }
+ TPtr8 p(static_cast<TUint8*>(tempBuf), numFinal * sizeof(TUint32));
+ TInt r = iSubSession->SendReceive(EGetFindResult, TIpcArgs(&p));
+ if (r == KErrNone)
+ {
+ for(TUint32 i = 0; i < numFinal; i++)
+ {
+ iClientErr=aFoundIds.Append(static_cast<const TUint32*>(tempBuf)[i]);
+ if (iClientErr!=KErrNone)
+ {
+ User::Free(tempBuf);
+ return iClientErr;
+ }
+ }
+ }
+ User::Free(tempBuf);
+ }
+ return iClientErr;
+ }
+
+TInt CClientRepository::NotifyRequest(TUint32 aId, TRequestStatus& aStatus)
+ {
+ TInt r = iSubSession->SendReceive(ENotifyRequestCheck, TIpcArgs(aId));
+ if(r==KErrNone)
+ iSubSession->SendReceive(ENotifyRequest, TIpcArgs(aId), aStatus);
+ return r;
+ }
+
+TInt CClientRepository::NotifyCancel(TUint32 aId)
+ {
+ return iSubSession->SendReceive(ENotifyCancel, TIpcArgs(aId));
+ }
+
+TInt CClientRepository::NotifyCancelAll()
+ {
+ return iSubSession->SendReceive(ENotifyCancelAll);
+ }
+
+TInt CClientRepository::NotifyRequest(TUint32 aPartialId, TUint32 aIdMask,
+ TRequestStatus& aStatus)
+ {
+ iSubSession->SendReceive(EGroupNotifyRequest,
+ TIpcArgs(aPartialId, aIdMask), aStatus);
+ return KErrNone;
+ }
+
+TInt CClientRepository::NotifyCancel(TUint32 aPartialId, TUint32 aIdMask)
+ {
+ TKeyFilter keyIdentifier = {aPartialId, aIdMask};
+ TPckg<TKeyFilter> pIdentifier(keyIdentifier);
+
+ return iSubSession->SendReceive(EGroupNotifyCancel, TIpcArgs(&pIdentifier));
+ }
+
+TInt CClientRepository::Reset()
+ {
+ return iSubSession->SendReceive(EResetAll);
+ }
+
+TInt CClientRepository::Reset(TUint32 aId)
+ {
+ return iSubSession->SendReceive(EReset, TIpcArgs(aId));
+ }
+
+TInt CClientRepository::StartTransaction(TTransactionMode aMode)
+ {
+ return iSubSession->SendReceive(ETransactionStart, TIpcArgs(aMode));
+ }
+
+void CClientRepository::StartTransaction(TTransactionMode aMode, TRequestStatus& aStatus)
+ {
+ iSubSession->SendReceive(ETransactionStart, TIpcArgs(aMode), aStatus);
+ }
+
+TInt CClientRepository::CommitTransaction(TUint32& aKeyInfo)
+ {
+ // set to KUnspecifiedKey in case failure happens before setting in server
+ aKeyInfo = KUnspecifiedKey;
+ TPckg<TUint32> p(aKeyInfo);
+ return iSubSession->SendReceive(ETransactionCommit, TIpcArgs(&p));
+ }
+
+void CClientRepository::CommitTransaction(TDes8& aKeyInfo, TRequestStatus& aStatus)
+ {
+ // set to KUnspecifiedKey in case failure happens before setting in server
+ aKeyInfo.Copy(TPckg<TUint32>(KUnspecifiedKey));
+ iSubSession->SendReceive(ETransactionCommit, TIpcArgs(&aKeyInfo), aStatus);
+ }
+
+void CClientRepository::CancelTransaction()
+ {
+ iSubSession->SendReceive(ETransactionCancel);
+ }
+
+static void CancelTransactionCleanupOperation(TAny* aRepository)
+ {
+ static_cast<CClientRepository*>(aRepository)->CancelTransaction();
+ }
+
+// So CancelTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar
+void CClientRepository::CleanupCancelTransactionPushL()
+ {
+ CleanupStack::PushL(TCleanupItem(CancelTransactionCleanupOperation, this));
+ }
+
+void CClientRepository::FailTransaction()
+ {
+ if (iClientErr==KErrNone)
+ iSubSession->SendReceive(ETransactionFail,TIpcArgs(KErrAbort));
+ else
+ iSubSession->SendReceive(ETransactionFail,TIpcArgs(iClientErr));
+ //reset the internal client code
+ iClientErr=KErrNone;
+ }
+
+// So FailTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar
+static void FailTransactionCleanupOperation(TAny* aRepository)
+ {
+ static_cast<CClientRepository*>(aRepository)->FailTransaction();
+ }
+
+void CClientRepository::CleanupFailTransactionPushL()
+ {
+ CleanupStack::PushL(TCleanupItem(FailTransactionCleanupOperation, this));
+ }
+
+TInt CClientRepository::TransactionState()
+ {
+ TInt iValue;
+
+ TPckg<TInt> p(iValue);
+
+ iSubSession->SendReceive(ETransactionState, TIpcArgs(&p));
+
+ return iValue;
+ }
+
+TInt RRepositorySubSession::Open(RRepositorySession* aSession,TInt aFunction,const TIpcArgs& aArgs)
+ {
+ iSession = aSession;
+ return(CreateSubSession(*aSession, aFunction, aArgs));
+ }
+
+void RRepositorySubSession::Close()
+ {
+ RSubSessionBase::CloseSubSession(EClose);
+ }
+
+TInt RRepositorySubSession::SendReceive(TInt aFunction) const
+ {
+ return RSubSessionBase::SendReceive(aFunction);
+ }
+
+TInt RRepositorySubSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs) const
+ {
+ return RSubSessionBase::SendReceive(aFunction, aArgs);
+ }
+
+void RRepositorySubSession::SendReceive(TInt aFunction, const TIpcArgs& aArgs, TRequestStatus& aStatus) const
+ {
+ RSubSessionBase::SendReceive(aFunction, aArgs, aStatus);
+ }
+
+inline TInt RRepositorySession::IncrementSubSessionCounter()
+ {
+ return ++iSubSessionCounter;
+ }
+
+RRepositorySession ::RRepositorySession()
+ :iSubSessionCounter(1)
+ {
+ }
+
+inline TInt RRepositorySession::DecrementSubSessionCounter()
+ {
+ ASSERT(iSubSessionCounter > 0);
+ return --iSubSessionCounter;
+ }
+
+#if defined(__CENTREP_SERVER_PERFTEST__) || defined(__CENTREP_SERVER_MEMTEST__) || defined(__CENTREP_SERVER_CACHETEST__)
+TInt RRepositorySession::SendReceive(TInt aFunction) const
+ {
+ return RSessionBase::SendReceive(aFunction);
+ }
+
+TInt RRepositorySession::SendReceive(TInt aFunction,
+ const TIpcArgs& aArgs) const
+ {
+ return RSessionBase::SendReceive(aFunction, aArgs);
+ }
+
+void RRepositorySession::SendReceive(TInt aFunction, const TIpcArgs& aArgs,
+ TRequestStatus& aStatus) const
+ {
+ RSessionBase::SendReceive(aFunction, aArgs, aStatus);
+ }
+#endif
+
+LOCAL_C TInt StartServer();
+
+TInt RRepositorySession::Connect()
+ {
+ const TVersion KVersion(KServerMajorVersion, KServerMinorVersion,
+ KServerBuildVersion);
+ TInt retry = 2;
+ TInt err = KErrGeneral;
+ // Use unlimited message slots as we can call subscribe multiple times per
+ // session.
+ TInt numMessageSlots = -1;
+ for(;;)
+ {
+ // Try to create a new session with the server.
+ err = CreateSession(KServerName, KVersion, numMessageSlots);
+ if((err != KErrNotFound) && (err != KErrServerTerminated))
+ break; //completed
+ // Server not running, try to start it.
+ if(--retry==0)
+ break; // Failed.
+ err = StartServer();
+ if((err != KErrNone) && (err != KErrAlreadyExists))
+ break; // Launched server
+ }
+ return err;
+ }
+
+//
+// Start the server process or thread
+//
+LOCAL_C TInt StartServer()
+ {
+ const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
+ //
+ // EPOC and EKA2 is easy, we just create a new server process. Simultaneous
+ // launching of two such processes should be detected when the second one
+ // attempts to create the server object, failing with KErrAlreadyExists.
+ //
+ RProcess server;
+ TInt r=server.Create(KServerImg,KNullDesC,serverUid);
+
+ if (r!=KErrNone)
+ return r;
+ TRequestStatus stat;
+ server.Rendezvous(stat);
+ if (stat!=KRequestPending)
+ server.Kill(0); // abort startup
+ else
+ server.Resume(); // logon OK - start the server
+ User::WaitForRequest(stat); // wait for start or death
+ // we can't use the 'exit reason' if the server panicked as this
+ // is the panic 'reason' and may be '0' which cannot be distinguished
+ // from KErrNone
+ r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
+ server.Close();
+ return r;
+ }
+