--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendar/client/src/calclient.cpp Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,2319 @@
+// Copyright (c) 1997-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 "calclient.h"
+
+#include <s32mem.h>
+
+#include "agmallocator.h"
+#include "agmattachment.h"
+#include "agmentry.h"
+#include "agmtlsproxy.h"
+#include "agmtzrules.h"
+#include "agmrptdef.h"
+#include "agmcategory.h"
+#include "agmcontent.h"
+#include "agmserv.h"
+#include "agssignal.h"
+#include "calattachmentmanagerimpl.h"
+#include "calinstance.h"
+#include "calentryimpl.h"
+#include "agmsortcriteria.h"
+#include "calsessionimpl.h"
+#include "calcalendarinfoimpl.h"
+#include "agmfilechangenotification.h"
+
+const TUint KDefaultMessageSlots = 3;
+
+_LIT(KAgendaMutex, "AgnMutex");
+
+//
+// RAgendaServ
+//
+void RAgendaServ::AddSessionL(const CCalSessionImpl& aSession, TInt& aSessionId)
+ {
+ __ASSERT_DEBUG(FindSession(aSession) == -1, User::Invariant());
+ iCalSessions.AppendL(&aSession);
+ aSessionId = ++iLastSessionId;
+ }
+
+TBool RAgendaServ::RemoveSession(const CCalSessionImpl& aSession)
+ {
+ TInt pos = FindSession(aSession);
+ if (pos != KErrNotFound)
+ {
+ iCalSessions.Remove(pos);
+ }
+ return (iCalSessions.Count()>0)?ETrue:EFalse;
+ }
+
+TInt RAgendaServ::FindSession(const CCalSessionImpl& aSession)
+ {
+ const TInt count = iCalSessions.Count();
+ for(TInt ii=0; ii<count; ++ii)
+ {
+ if(&aSession == iCalSessions[ii])
+ {
+ return ii;
+ }
+ }
+ return -1;
+ }
+
+void RAgendaServ::IncreaseRef()
+ {
+ iReferenceCount++;
+ }
+
+TInt RAgendaServ::DecreaseRef()
+ {
+ iReferenceCount--;
+ __ASSERT_ALWAYS( iReferenceCount >= 0, User::Invariant());
+ return iReferenceCount;
+ }
+
+RAgendaServ* RAgendaServ::NewL()
+/** Constructs a new RAgendaServ, initialising all member data to NULL.
+
+@return A pointer to the client interface to the agenda server. */
+ {
+ RAgendaServ* self = new (ELeave) RAgendaServ();
+
+ TRAPD(err, self->ConstructL());
+ if(err != KErrNone)
+ {
+ delete self;
+ User::Leave(err);
+ }
+
+ return self;
+ }
+
+ // not derived from CBase, so have to set member data to NULL
+RAgendaServ::RAgendaServ()
+ : RSessionBase(), iBuffer(NULL),iLastSessionId(0)
+ {
+ }
+
+void RAgendaServ::ConstructL()
+ {
+ iReferenceCount = 0;
+ iSimpleEntryAllocator = 0;
+ iSimpleEntryAllocator = new (ELeave) CAgnSimpleEntryAllocator;
+ CAgnTlsProxy::CreateL(CAgnTlsProxy::TAgnTlsTzRulesType_Client);
+ iBuffer = CBufFlat::NewL(KInitialBufferSize);
+ iBuffer->ExpandL(0, KInitialBufferSize);
+ }
+
+RAgendaServ::~RAgendaServ()
+/** The destructor frees all resources owned by the server, prior to its destruction. */
+ {
+ __ASSERT_ALWAYS( iReferenceCount == 0, User::Invariant());
+ delete iBuffer;
+ CAgnTlsProxy::Release(NULL);
+ delete iSimpleEntryAllocator;
+ iCalSessions.Close();
+ }
+
+// Connect to the server
+
+//
+// CAgnServer
+//
+
+// Static function to create a new thread or process, depending upon the
+// variant. For marm builds, the AGSVEXE.EXE program is run, which
+// creates the server objects in a new process
+
+TInt RAgendaServ::StartServer()
+ {
+ TRequestStatus stat;
+ TAgnSignal signal(stat);
+
+
+ RProcess server;
+ // Locate the server on all drives (Y-A, then Z)
+
+ TInt ret = server.Create(KAgendaServerExe, signal.Command(), EOwnerThread);
+ if (ret!=KErrNone)
+ {
+ return ret;
+ }
+ server.SetPriority(EPriorityForeground);
+
+ server.Rendezvous(stat);
+
+ if (stat!=KRequestPending)
+ {
+ server.Kill(0); // abort startup
+ }
+ else
+ {
+ server.Resume(); // logon OK - start the server
+ }
+
+
+ User::WaitForRequest(stat);
+ server.Close();
+ return stat.Int();
+ }
+
+TInt RAgendaServ::Connect()
+/** Connects the client process to the agenda server.
+
+This function must be called before the server can be used.
+
+@return An error code. KErrNone if successful. */
+ {
+ RMutex mutex;
+ TInt ret = mutex.CreateGlobal(KAgendaMutex);
+ if(ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ return ret;
+ }
+ ret = mutex.OpenGlobal(KAgendaMutex);
+ if (ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ return ret;
+ }
+ mutex.Wait();
+ TInt r = DoConnect();
+ if (r==KErrNotFound || r==KErrServerTerminated)
+ {
+ r=StartServer();
+ if(r==KErrNone || r==KErrAlreadyExists)
+ {
+ r=DoConnect();
+ }
+ }
+ mutex.Signal();
+ mutex.Close();
+ return r;
+ }
+
+TInt RAgendaServ::DoConnect()
+ {
+ return CreateSession(KAgendaServerName,Version(), KDefaultMessageSlots);
+ }
+
+
+// Return the client side version no.
+TVersion RAgendaServ::Version() const
+ {
+ return (TVersion(KAgnServerMajorVersion,KAgnServerMinorVersion,KAgnServerBuildVersion));
+ }
+
+
+
+//
+// Server Utility Functions
+
+void RAgendaServ::Panic(TAgnClientPanic aPanic) const
+ {
+ _LIT(KAgendaClient,"AgendaClient");
+ User::Panic(KAgendaClient, aPanic);
+ }
+
+/**
+Checks the size of the incoming buffer, and if it is larger
+than the size of the buffer already defined, allocates enough
+space in aBuffer, and transfers the data from the server
+
+@capability ReadUserData
+*/
+CBufFlat* RAgendaServ::CreateTransmitBufferL(TInt aBufferSize) const
+ {
+ CBufFlat* buffer = NULL;
+
+ if (aBufferSize > KInitialBufferSize)
+ {
+ // Create a buffer with granularity of aBufferSize
+ buffer = CBufFlat::NewL(aBufferSize);
+ CleanupStack::PushL(buffer);
+
+ // Extends the size of the bufferr by the required size
+ buffer->ExpandL(0,aBufferSize);
+
+ // Transfer the data from the server
+ TPtr8 bufptr = buffer->Ptr(0);
+ TIpcArgs args(&bufptr);
+ User::LeaveIfError(SendReceive(ETransmitBuffer,args));
+ CleanupStack::Pop(buffer);
+ }
+ return buffer;
+ }
+
+
+void RAgendaServ::ExternalizeFilterL(const TAgnFilter& aFilter, RWriteStream& aStream) const
+ {
+ aFilter.ExternalizeL(aStream);
+ }
+
+
+CAgnSimpleEntry* RAgendaServ::InternalizeSimpleEntryL(RReadStream& aStream) const
+ {
+ CCalEntry::TType entryType = static_cast<CCalEntry::TType>( aStream.ReadUint32L() );
+
+ CAgnSimpleEntry* entry = iSimpleEntryAllocator->CreateSimpleEntryL(entryType);
+ //to cleanup CAgnSortEntry pointer, if a leave happens during internalize.
+ TCleanSimpleEntry simpleEntryCleanupItem(*entry, *iSimpleEntryAllocator);
+ CleanupStack::PushL(TCleanupItem(TCleanSimpleEntry::DestroySimpleEntry,&simpleEntryCleanupItem));
+ entry->InternalizeL(aStream, ETrue);
+ CleanupStack::Pop(&simpleEntryCleanupItem);
+
+ return ( entry );
+ }
+
+/**
+@capability None
+*/
+void RAgendaServ::OpenAgendaL(const CCalSessionImpl& aSession, const TDesC& aFileName, CalCommon::TCalFileVersionSupport& aStatus, TInt64& aFileId, TCalCollectionId& aCallectionId)
+ {
+ CBufFlat* streamBuffer = CBufFlat::NewL(aFileName.Size()+ sizeof(TUint8));
+ CleanupStack::PushL(streamBuffer);
+ RBufWriteStream bufStream;
+ bufStream.Open(*streamBuffer);
+ CleanupClosePushL(bufStream);
+ bufStream << aFileName;
+ bufStream.WriteInt32L(aSession.SessionId());
+ CleanupStack::PopAndDestroy(&bufStream);
+ TPtr8 readPtr = streamBuffer->Ptr(0);
+ TPckgBuf<CalCommon::TCalFileVersionSupport> statusPckg(aStatus);
+ TPckgBuf<TInt64> fileId(aFileId);
+ TPckgBuf<TCalCollectionId> shortFileId(aCallectionId);
+ TIpcArgs args(&readPtr, &statusPckg, &fileId, &shortFileId);
+ TInt err = SendReceive(EOpenAgenda,args);
+ CleanupStack::PopAndDestroy(streamBuffer);
+ if(err != KErrAlreadyExists)
+ {
+ aStatus = statusPckg();
+ User::LeaveIfError(err);
+ aFileId = fileId();
+ aCallectionId = shortFileId();
+ }
+ }
+
+void RAgendaServ::WaitUntilLoadedL(TCalCollectionId aCallectionId)
+ {
+ TIpcArgs args(0, aCallectionId);//0 argument means not to report the progess
+ TRequestStatus status = KRequestPending;
+ SendReceive(EStartBuildIndex, args, status);
+ User::WaitForRequest(status);
+ User::LeaveIfError(status.Int());
+ }
+
+/**
+Closes the file that is open in the current agenda server session.
+@capability None
+*/
+void RAgendaServ::CloseAgenda(TInt aSessionId)
+ {
+ TIpcArgs args(aSessionId);
+ SendReceive(ECloseAgenda, args);
+ }
+
+/**
+Fetches a complete entry from the server
+@capability ReadUserData
+*/
+CAgnEntry* RAgendaServ::FetchEntryL(TAgnEntryId& aId, TInt64 aFileId) const
+ {
+ TPckg<TAgnEntryId> entryId(aId);
+ TPckgBuf<TInt> size;
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ if (aId.IsNullId())
+ {
+ return NULL;
+ }
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&ptr, &entryId, &size, &fileId);
+ User::LeaveIfError(SendReceive(EFetchEntry,args));
+
+ return ReadEntryFromServerSessionL(size());
+ }
+
+/** Fetches a complete entry from the server
+@capability ReadUserData
+*/
+CAgnEntry* RAgendaServ::FetchEntryL(TCalLocalUid aId, TInt64 aFileId) const
+ {
+ TPckg<TCalLocalUid> entryId(aId);
+ TPckgBuf<TInt> size;
+ TPtr8 ptr = iBuffer->Ptr(0);
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&ptr, &entryId, &size, &fileId);
+ User::LeaveIfError(SendReceive(EFetchEntryByUID,args));
+ return ReadEntryFromServerSessionL(size());
+ }
+
+
+/* Internalize agenda entry from buffer
+
+@capability ReadUserData
+@param aBufferSize size of buffer
+@return agenda entry internalized from buffer
+*/
+CAgnEntry* RAgendaServ::ReadEntryFromServerSessionL(TInt aBufferSize) const
+ {
+ if (aBufferSize==0) // if size = 0, there entry has already been deleted
+ {
+ return NULL;
+ }
+
+ RBufReadStream readStream;
+ // Create a transfer buffer, and set where to read the data from
+ CBufFlat* buffer = CreateTransmitBufferL(aBufferSize);
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ CAgnEntry* entry = CreateEntryFromBufferStreamL(readStream);
+ readStream.Close();
+ CleanupStack::PopAndDestroy(buffer);
+
+ return entry;
+ }
+
+CAgnEntry* RAgendaServ::CreateEntryFromBufferStreamL(RReadStream& aReadStream) const
+ {
+ CCalEntry::TType entryType = (CCalEntry::TType)aReadStream.ReadUint32L();
+
+ CAgnEntry* entry = CAgnEntry::NewL(entryType);
+ CleanupStack::PushL(entry);
+ entry->InternalizeFromBufferL(aReadStream);
+ CleanupStack::Pop(entry);
+ return entry;
+ }
+
+/**
+Get a lite entry from the server
+(Lite-entries are just time information, with no text, etc)
+@capability ReadUserData
+*/
+CAgnSimpleEntry* RAgendaServ::GetSimpleEntryL(const TAgnEntryId& aId, TCalCollectionId aCallectionId) const
+ {
+ TPckgBuf<TInt> size;
+
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ if (aId.IsNullId())
+ {
+ return NULL;
+ }
+ CBufFlat* streamBuffer = CBufFlat::NewL(sizeof(TAgnInstance));
+ CleanupStack::PushL(streamBuffer);
+ RBufWriteStream bufStream;
+ bufStream.Open(*streamBuffer);
+ CleanupClosePushL(bufStream);
+
+ bufStream << aId;
+ CleanupStack::PopAndDestroy(&bufStream);
+ TPtr8 readPtr = streamBuffer->Ptr(0);
+ TIpcArgs args(&ptr, &readPtr, &size, aCallectionId);
+ User::LeaveIfError(SendReceive(EFetchSimpleEntry,args));
+ CleanupStack::PopAndDestroy(streamBuffer);
+ if (size() == 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ RBufReadStream readStream;
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ CleanupStack::PushL(buffer);
+
+ CAgnSimpleEntry* entry = NULL;
+
+ if (readStream.ReadUint8L())
+ {
+ entry = InternalizeSimpleEntryL(readStream);
+ entry->SetCollectionId(aCallectionId);
+ }
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+
+ // Don't leave here for a NULL entry could be a race with an entry delete
+ return entry;
+ }
+
+/**
+Get a lite entry from the server
+(Lite-entries are just time information, with no text, etc)
+@capability ReadUserData
+*/
+CAgnSimpleEntry* RAgendaServ::GetSimpleEntryL(TCalCollectionId aCallectionId, TUint32 aId) const
+ {
+// TPckg<TAgnEntryId> entryId(aId);
+ TPckgBuf<TInt> size;
+
+ TPtr8 ptr = iBuffer->Ptr(0);
+ if (aId == 0)
+ {
+ return NULL;
+ }
+ CBufFlat* streamBuffer = CBufFlat::NewL(sizeof(TUint8)+sizeof(TUint32));
+ CleanupStack::PushL(streamBuffer);
+ RBufWriteStream bufStream;
+ bufStream.Open(*streamBuffer);
+ CleanupClosePushL(bufStream);
+
+ bufStream << aId;
+ CleanupStack::PopAndDestroy(&bufStream);
+ TPtr8 readPtr = streamBuffer->Ptr(0);
+ TIpcArgs args(&ptr, &readPtr, &size, aCallectionId);
+ User::LeaveIfError(SendReceive(EFetchSimpleEntryByUID,args));
+ CleanupStack::PopAndDestroy(streamBuffer);
+ if (size() == 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ RBufReadStream readStream;
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ CleanupStack::PushL(buffer);
+
+ CAgnSimpleEntry* entry = NULL;
+
+ if (readStream.ReadUint8L())
+ {
+ entry = InternalizeSimpleEntryL(readStream);
+ entry->SetCollectionId(aCallectionId);
+ }
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+
+ // Don't leave here for a NULL entry could be a race with an entry delete
+ return entry;
+ }
+
+/** Get an array of lite entries from the server
+
+On return the instance ids and lite entries will have corresponding indices in the arrays
+(Lite-entries are just time information, with no text, etc)
+
+@param aIds The instance ids of the lite entries to fetch
+@param aLiteEntries on return will contain the fetched lite entries.
+
+@capability ReadUserData
+*/
+void RAgendaServ::GetSimpleEntryL(const RArray<TAgnInstance>& aEntryIds, RPointerArray<CAgnSimpleEntry>& aLiteEntries) const
+ {
+ // only fetches KMaxNumToFetch at a time from the server
+ const TInt KMaxNumToFetch(32);
+ const TInt KBufferSize = (KMaxNumToFetch + 1) * sizeof(TUint32); // enough room to write KNumToFetch entries plus a count
+
+ const TInt KEntryIdCount(aEntryIds.Count());
+ for (TInt entriesFetchedSoFar(0) ; entriesFetchedSoFar < KEntryIdCount ;)
+ {
+ CBufFlat* instanceIdBuffer = CBufFlat::NewL(KBufferSize);
+ CleanupStack::PushL(instanceIdBuffer);
+ RBufWriteStream bufStream;
+ bufStream.Open(*instanceIdBuffer);
+
+ // Externalize up to KMaxNumToFetch instance ids
+ // KNumToFetch will be the total number of fetched TAgnLiteEntrys fetched this time
+ const TInt KNumToFetch = ((KEntryIdCount - entriesFetchedSoFar) < KMaxNumToFetch) ? KEntryIdCount : entriesFetchedSoFar + KMaxNumToFetch;
+ bufStream.WriteUint32L(KNumToFetch - entriesFetchedSoFar);
+ for (; entriesFetchedSoFar < KNumToFetch ; ++entriesFetchedSoFar)
+ {
+ bufStream << aEntryIds[entriesFetchedSoFar];
+ }
+
+ bufStream.CommitL();
+ bufStream.Close();
+ TPtr8 entryIds = instanceIdBuffer->Ptr(0);
+
+ TPckgBuf<TInt> size;
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ // call the server
+ TIpcArgs args(&ptr, &entryIds, &size);
+ User::LeaveIfError(SendReceive(EFetchSimpleEntries, args));
+
+ // open the read stream
+ RBufReadStream readStream;
+ CBufFlat* liteEntryBuffer = CreateTransmitBufferL(size());
+ if (liteEntryBuffer)
+ {
+ readStream.Open(*liteEntryBuffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(liteEntryBuffer);
+
+ // Read the lite entries from the buffer
+ const TCalCollectionId KLiteEntryCount(readStream.ReadUint8L());
+ for (TInt i(0) ; i < KLiteEntryCount ; ++i)
+ {
+ if (readStream.ReadUint8L())
+ {
+ CAgnSimpleEntry* ptr = InternalizeSimpleEntryL(readStream);
+ ptr->SetCollectionId(readStream.ReadUint8L());
+ TInt err = aLiteEntries.Append(ptr);
+ if (err != KErrNone)
+ {
+ iSimpleEntryAllocator->Delete(ptr);
+ User::Leave(err);
+ }
+ }
+ }
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(liteEntryBuffer);
+ CleanupStack::PopAndDestroy(instanceIdBuffer);
+ }
+ }
+
+/** Get an array of lite entries from the server
+
+On return the instance ids and lite entries will have corresponding indices in the arrays
+(Lite-entries are just time information, with no text, etc)
+
+@param aUid The UID of the lite entries to fetch
+@param aLiteEntries on return will contain the fetched lite entries.
+
+@capability ReadUserData
+*/
+void RAgendaServ::FetchSimpleEntriesByGuidL(const TDesC8& aUid, RPointerArray<CAgnSimpleEntry>& aLiteEntries, RArray<TInt> aFileIds) const
+ {
+ const TInt countFile = aFileIds.Count();
+ const TInt lenUid = aUid.Length();
+
+ CBufFlat* inBuffer = CBufFlat::NewL(sizeof(countFile*8) + lenUid);
+ CleanupStack::PushL(inBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*inBuffer);
+ bufStream.WriteInt16L(lenUid);
+ bufStream.WriteL(aUid, lenUid);
+ bufStream.WriteInt16L(countFile);
+ for(TInt ii=0; ii<countFile;++ii)
+ {
+ bufStream.WriteUint8L(aFileIds[ii]);
+ }
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = inBuffer->Ptr(0);
+
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+ TIpcArgs args(&ptr, &size, ¶msPtr);
+ User::LeaveIfError(SendReceive(EFetchSimpleEntriesByGuid, args));
+ CleanupStack::PopAndDestroy(inBuffer);
+ // open the read stream
+ RBufReadStream readStream;
+ CBufFlat* liteEntryBuffer = CreateTransmitBufferL(size());
+ if (liteEntryBuffer)
+ {
+ readStream.Open(*liteEntryBuffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(liteEntryBuffer);
+
+ // Read the lite entries from the buffer
+ const TUint32 KLiteEntryCount(readStream.ReadUint32L());
+ for (TInt i(0) ; i < KLiteEntryCount ; ++i)
+ {
+ CAgnSimpleEntry* ptr = InternalizeSimpleEntryL(readStream);
+ ptr->SetCollectionId(readStream.ReadUint8L());
+ TInt err = aLiteEntries.Append(ptr);
+ if (err != KErrNone)
+ {
+ iSimpleEntryAllocator->Delete(ptr);
+ User::Leave(err);
+ }
+ }
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(liteEntryBuffer);
+ }
+
+/** Updates an existing entry on the server
+@param aEntry
+@param aTodoPosition
+@capability WriteUserData
+@capability ReadUserData
+@leave
+@internalComponent
+*/
+void RAgendaServ::UpdateEntryL(CAgnEntry& aEntry, TBool aDeleteChildren, TCalCollectionId aCallectionId)
+ {
+ /*
+ Check that either (or both) the instance or the unique id of the entry
+ passed is not null, otherwise, the update will not occur because the server
+ will not know which of its entries it should update.
+ */
+ __ASSERT_ALWAYS( !(aEntry.EntryId().IsNullId() && aEntry.LocalUid() == 0 && aCallectionId == NULL), User::Leave(KErrNotFound));
+
+ aEntry.VerifyBeforeStoreL();
+
+ RBufWriteStream bufStream;
+
+ bufStream.Open(*iBuffer);
+
+ bufStream.WriteUint32L(aEntry.Type());
+ bufStream.WriteUint8L(aDeleteChildren);
+
+ // Set regardless.
+ aEntry.SetLastModifiedDate();
+
+ // Externalize the entry details to the buffer
+ // Any rich text components will be stored in the textStream buffer
+ aEntry.ExternalizeToBufferL(bufStream);
+ bufStream.CommitL();
+ bufStream.Close();
+
+ // Get the sizes of the buffers
+ TInt size(iBuffer->Size());
+
+ // Get the pointer of the buffers
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ // The entry id
+ TPckgBuf<TAgnEntryId> entryId;
+ TIpcArgs args(size, &ptr, &entryId, aCallectionId);
+
+ User::LeaveIfError(SendReceive(EUpdateEntry, args));
+ aEntry.SetEntryId(entryId());
+ }
+
+/**
+Add a new enty to the server
+@capability WriteUserData
+@capability ReadUserData
+*/
+TAgnEntryId RAgendaServ::AddEntryL(CAgnEntry& aEntry, TInt64 aFileId)
+ {
+ aEntry.VerifyBeforeStoreL();
+
+ RBufWriteStream bufStream;
+
+ bufStream.Open(*iBuffer);
+
+ bufStream.WriteUint32L(aEntry.Type());
+
+ aEntry.ExternalizeToBufferL(bufStream);
+
+ bufStream.CommitL();
+ bufStream.Close();
+
+ // Get the sizes of the buffers
+ TInt size = iBuffer->Size();
+
+ // Get the pointer of the buffers
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ // The entry Id and unique Id
+ TPckgBuf<TAgnEntryParameters> entryParams;
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(size, &ptr, &entryParams, &fileId);
+
+ User::LeaveIfError(SendReceive(EAddEntry, args));
+
+ aEntry.SetEntryId(entryParams().iEntryId);
+ aEntry.SetLocalUid(entryParams().iLocalId);
+ if (entryParams().iRecurrenceId != Time::NullTTime())
+ {
+ TAgnCalendarTime agnRecId;
+ if (aEntry.TimeMode() == MAgnCalendarTimeMode::EFloating)
+ {
+ agnRecId.SetFloatingL(entryParams().iRecurrenceId);
+ }
+ else
+ {
+ agnRecId.SetLocalL(entryParams().iRecurrenceId);
+ }
+ aEntry.UpdateRecurrenceIdL(agnRecId);
+ }
+ aEntry.SetLastModifiedDateUtc(entryParams().iLastModifiedDateUtc);
+ if (aEntry.TimeMode() != MAgnCalendarTimeMode::EFloating && aEntry.RptDef() != NULL )
+ {
+ CAgnTzRules* tzRules = aEntry.RptDef()->AgnTzRules();
+ if(tzRules != NULL)
+ {
+ tzRules->SetTzZoneStreamId(entryParams().iTzStreamId);
+ tzRules->SetSystemTzRule(entryParams().iSystemTzRule);
+ }
+ }
+
+
+ SendFileAttachmentHandlesL(aEntry, aFileId);
+
+ return entryParams().iEntryId;
+ }
+
+/**
+For all attachments on this entry, find out whether they are file attachments.
+If it contains a file handle, then it must be transferred to the server through a separate IPC call (TransferFileHandleToServerL).
+If it contains binary data, then a file handle must be fetched from the server, to which the binary data
+will be written directly (WriteBinaryDataToNewAttachmentFileL).
+*/
+void RAgendaServ::SendFileAttachmentHandlesL(CAgnEntry& aEntry, TInt64 aFileId)
+ {
+ const TInt KAttachmentCount = aEntry.AttachmentCount();
+ for (TUint32 i = 0; i < KAttachmentCount; i++)
+ {
+ CAgnAttachment& attach = aEntry.Attachment(i);
+ if (attach.Type() == CCalContent::EDispositionInline)
+ {
+ // This is a file attachment
+ CAgnAttachmentFile* fileAttach = static_cast<CAgnAttachmentFile*>(&attach);
+ if (fileAttach->IsFileHandleSet())
+ {
+ // This is a file attachment with a file handle
+ TransferFileHandleToServerL(aEntry.LocalUid(), i, *fileAttach, aFileId);
+ }
+ else if (fileAttach->Uid() == 0 && fileAttach->Content().Length() > 0)
+ {
+ // This is a new file attachment (uid==0) with binary data
+ WriteBinaryDataToNewAttachmentFileL(aEntry, i, aFileId);
+ }
+ }
+ }
+ }
+
+/**
+Store a new attachment with a file handle. The file handle is transferred to the Calendar server, which moves the file to
+the Calendar store.
+On the server-side, this will also update the entry containing this attachment with the new attachment metadata.
+@capability WriteUserData
+*/
+void RAgendaServ::TransferFileHandleToServerL(TCalLocalUid aLocalUid, TInt aAttachmentIndex, CAgnAttachmentFile& aFileAttachment, TInt64 aFileId)
+ {
+ TAttachmentData attachData;
+ attachData.iLocalUid = aLocalUid;
+ attachData.iAttachmentIndex = aAttachmentIndex;
+ TPckg<TCalAttachmentUid> attachUid(0);
+
+ CBufFlat* paramsBuffer = CBufFlat::NewL(sizeof(TInt64) + sizeof(TAttachmentData));
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ bufStream.WriteUint32L(attachData.iLocalUid);
+ bufStream.WriteInt16L(attachData.iAttachmentIndex);
+ bufStream << aFileId;
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+ TIpcArgs args(¶msPtr, &attachUid);
+ // Detach file handle from attachment, if TransferToServer or SendReceive(ETransferAttachmentFileToServer) fail,
+ // then the fileHandle must not be deleted.
+ RFile& fileHandle = const_cast<RFile&>(aFileAttachment.FileHandle());
+ CleanupClosePushL(fileHandle);
+
+ // note that the following line will panic if the RFs that contains
+ // this file handle is not shared by calling RFs::ShareProtected()
+ User::LeaveIfError(aFileAttachment.FileHandle().TransferToServer(args, KTransferAttachmentToSrvFsArgIndex, KTransferAttachmentToSrvFileArgIndex));
+ User::LeaveIfError(SendReceive(ETransferAttachmentFileToServer, args));//replace the file in the same drive
+ CleanupStack::PopAndDestroy(&fileHandle);
+ if(attachUid() == 0)
+ {//When the Drive is different from the default one, the server adopt the handle and will move the attachment file after the file handle is closed.
+ User::LeaveIfError(SendReceive(EMoveFileToServer, args));
+ }
+ CleanupStack::PopAndDestroy(paramsBuffer);
+ aFileAttachment.SetHasFileHandle(EFalse);
+ aFileAttachment.SetUid(attachUid());
+ }
+
+/**
+Store a new attachment from binary data. A new file handle is created on the Calendar server, and this is transferred
+to the client side so that the binary data can be written directly.
+On the server-side, this will also update the entry containing this attachment with the new attachment metadata.
+@capability WriteUserData
+*/
+void RAgendaServ::WriteBinaryDataToNewAttachmentFileL(CAgnEntry& aEntry, TInt aAttachmentIndex, TInt64 aFileId)
+ {
+ CAgnAttachmentFile* attachment = static_cast<CAgnAttachmentFile*>(&aEntry.Attachment(aAttachmentIndex));
+
+ // package up data required to identify this attachment on server side.
+ TAttachmentData data;
+ data.iLocalUid = aEntry.LocalUid();
+ data.iAttachmentIndex = aAttachmentIndex;
+ if (attachment->FileName().Length() > 0)
+ {
+ data.iDrive = attachment->FileName().Left(1);
+ }
+ else
+ {
+ data.iDrive = KNullDesC;
+ }
+
+ TPckg<TAttachmentData> pckgData(data);
+ TPckg<TInt> pckgSubSessionHandle(0); // initialise
+ TPckgBuf<TInt64> fileId(aFileId);
+
+ TIpcArgs args(&pckgData, &pckgSubSessionHandle, &fileId);
+
+ TInt dataSize = attachment->Content().Length();
+ args.Set(3, dataSize);
+
+ // call server side to create new file and update entry
+ const TInt KSessionHandle = SendReceive(ETransferFileToClientToWrite, args);
+ User::LeaveIfError(KSessionHandle);
+
+ // fetch file handle and write binary data to it
+ RFile newFileHandle;
+ CleanupClosePushL(newFileHandle);
+ User::LeaveIfError(newFileHandle.AdoptFromServer(KSessionHandle, pckgSubSessionHandle()));
+ User::LeaveIfError(newFileHandle.Write(attachment->Content()));
+ CleanupStack::PopAndDestroy(&newFileHandle); // newFileHandle.Close();
+ }
+
+/**
+Fetch file handle for a file attachment.
+@capability ReadUserData
+*/
+void RAgendaServ::FetchFileHandleL(RFile& aFileHandle, TCalAttachmentUid aAttachmentUid, TInt64 aFileId)
+ {
+ TPckg<TInt> pckgSubSessionHandle(0); // initialise
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(aAttachmentUid, &pckgSubSessionHandle, &fileId);
+
+ TInt sessionHandle = SendReceive(ETransferAttachmentFileToClient, args);
+ User::LeaveIfError(sessionHandle);
+ User::LeaveIfError(aFileHandle.AdoptFromServer(sessionHandle, pckgSubSessionHandle()));
+ }
+
+/**
+Fetch all file attachments in the order specified and add them to the iterator.
+@capability ReadUserData
+*/
+void RAgendaServ::FetchAttachmentsL(CCalAttachmentIteratorImpl& aIteratorImpl, CCalAttachmentManager::TSortOrder aSortOrder, TInt64 aFileId)
+ {
+ TPtr8 bufptr = iBuffer->Ptr(0);
+ TPckg<TInt> size(0);
+ TPckgBuf<TInt64> fileId(aFileId);
+ // make server request
+ TIpcArgs args(&bufptr, &size, aSortOrder, &fileId);
+ User::LeaveIfError(SendReceive(EFetchSortedAttachments, args));
+
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ CleanupStack::PushL(buffer);
+ // internalize array from readStream
+ const TInt KCount = readStream.ReadUint32L();
+
+ TCalAttachmentUid attachUid;
+ for (TInt i = 0; i < KCount; ++i)
+ {
+ readStream >> attachUid;
+ aIteratorImpl.AppendL(attachUid);
+ }
+
+ readStream.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+/**
+Fetch local UIDs of all entries that reference the attachment specified.
+@capability ReadUserData
+*/
+void RAgendaServ::EntriesReferencingFileAttachmentL(RArray<TCalLocalUid>& aUids, const CAgnAttachment& aAttachment, TInt64 aFileId)
+ {
+ if (aAttachment.Uid() && aAttachment.Type() == CCalContent::EDispositionInline)
+ {
+ TPtr8 bufptr = iBuffer->Ptr(0);
+ TPckg<TInt> size(0);
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&bufptr, &size, aAttachment.Uid(), &fileId);
+ User::LeaveIfError(SendReceive(EEntriesWithAttachment, args));
+
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ // internalize local UIDs from readStream
+ const TInt KCount = readStream.ReadUint32L();
+ TCalLocalUid id;
+ for (TInt i = 0; i < KCount; ++i)
+ {
+ readStream >> id;
+ aUids.AppendL(id);
+ }
+
+ readStream.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ }
+ }
+
+/**
+Fetch an attachment by its attachment UID. Note attachment UIDs are not exposed to clients, and are just used internally.
+@capability ReadUserData
+*/
+CAgnAttachment* RAgendaServ::FetchAttachmentByIdL(TCalAttachmentUid aAttachUid, TInt64 aFileId)
+ {
+ if (aAttachUid == 0)
+ {
+ return NULL;
+ }
+
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&ptr, &size, aAttachUid, &fileId);
+ User::LeaveIfError(SendReceive(EFetchAttachmentById, args));
+
+ if (size() == 0) // if size = 0, there entry has already been deleted
+ {
+ return NULL;
+ }
+
+ RBufReadStream readStream;
+ // Create a transfer buffer, and set where to read the data from
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ CAgnAttachment* attachment = AttachmentFactory::NewAttachmentL(readStream);
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+ return attachment;
+ }
+
+/** Finds previous instances in the calendar store
+
+@param aParams The filter settings to use when fidning the previous instances
+@param aInstances The previous instances. Note that the instances will be inserted at the begining of the array
+
+@capability ReadUserData
+*/
+void RAgendaServ::PreviousInstancesL(const RArray<TInt64> aFileIds, CArrayFix<TAgnInstance>& aInstances, TFindInstanceParams& aParams) const
+ {
+ const TInt count = aFileIds.Count();
+ CBufFlat* paramsBuffer = CBufFlat::NewL(sizeof(TFindInstanceParams) + count*64);
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ aParams.ExternalizeL(bufStream);
+ bufStream.WriteInt16L(count);
+ for(TInt ii=0; ii<count;++ii)
+ {
+ bufStream << aFileIds[ii];
+ }
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+ TInt paramsSize = paramsBuffer->Size();
+
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TIpcArgs args(&ptr, &size, ¶msPtr, paramsSize);
+
+ User::LeaveIfError(SendReceive(EPreviousInstances, args));
+
+ CleanupStack::PopAndDestroy(paramsBuffer);
+
+ RBufReadStream readStream;
+ CleanupClosePushL(readStream);
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ CleanupStack::PushL(buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ const TInt KCount(readStream.ReadUint32L());
+
+ for (TInt i(0) ; i < KCount; ++i)
+ {
+ TAgnInstance instance;
+ readStream >> instance;
+ aInstances.InsertL(i,instance);
+ }
+
+ if (buffer)
+ {
+ CleanupStack::PopAndDestroy(buffer);
+ }
+ CleanupStack::PopAndDestroy(&readStream);
+ }
+
+/** Finds the next instances in the calendar store
+
+@param aParams The filter settings to use when finding the next instances
+@param aInstances The next instances. Note that the instances will be appended to the end of the array
+
+@capability ReadUserData
+*/
+void RAgendaServ::NextInstancesL(const RArray<TInt64> aFileIds, CArrayFix<TAgnInstance>& aInstances, const TFindInstanceParams& aParams) const
+ {
+ // Write the find instance setting out to the buffer
+
+ CBufFlat* paramsBuffer = CBufFlat::NewL(sizeof(TFindInstanceParams));
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ aParams.ExternalizeL(bufStream);
+ bufStream.WriteInt16L(aFileIds.Count());
+ for(TInt ii=0; ii<aFileIds.Count();++ii)
+ {
+ bufStream << aFileIds[ii];
+ }
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TIpcArgs args(&ptr, &size, ¶msPtr);
+
+ User::LeaveIfError(SendReceive(ENextInstances, args));
+
+ CleanupStack::PopAndDestroy(paramsBuffer);
+
+ RBufReadStream readStream;
+ CleanupClosePushL(readStream);
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ CleanupStack::PushL(buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ const TInt KCount(readStream.ReadUint32L());
+
+ for (TInt i(0) ; i < KCount; ++i)
+ {
+ TAgnInstance instance;
+ readStream >> instance;
+ aInstances.AppendL(instance);
+ }
+
+ if (buffer)
+ {
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+ CleanupStack::PopAndDestroy(&readStream);
+ }
+
+// Entry Iterator Calls
+
+/**
+Creates an iterator for iterating though all the entries in the file.
+
+This may be used for activities such as merging or finding. The function returns
+EFalse if no entries are available. If any entries are available, the iterator
+is set to the first one.
+
+Although this API does not have a trailing L it can leave
+
+@capability None
+@return ETrue if there are entries in the file. EFalse if there are none.
+*/
+TBool RAgendaServ::CreateEntryIteratorL(TInt64 aFileId)
+ {
+ // Creates a server side entry iterator
+ TPckgBuf<TInt64> fileId(aFileId);
+ TPckgBuf<TBool> ok;
+ TIpcArgs args(&fileId, &ok);
+ User::LeaveIfError(SendReceive(ECreateEntryIterator,args));
+ return ok();
+ }
+
+/**
+Moves the entry iterator to the next entry.
+
+Returns EFalse if no more entries exist.
+
+Although this API does not have a trailing L it can leave
+
+@capability None
+@return ETrue if there is are more entries. EFalse if there are no more entries.
+*/
+TBool RAgendaServ::EntryIteratorNextL(TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TPckgBuf<TBool> ok;
+ TIpcArgs args(&fileId, &ok);
+ User::LeaveIfError(SendReceive(EEntryIteratorNext,args));
+ return ok();
+ }
+
+/**
+Retrieves the ID for the entry at the current iterator position.
+
+The ID can be used to retrieve the entry using CAgnEntryModel::FetchEntryL().
+
+@capability None
+@return The ID for the entry at the current iterator position
+*/
+CAgnEntry* RAgendaServ::FetchEntryByIteratorL(TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+
+ TPckgBuf<TInt> size;
+ TPtr8 ptr = iBuffer->Ptr(0);
+ TIpcArgs args(&ptr, &size, &fileId);
+ User::LeaveIfError(SendReceive(EEntryIteratorPosition,args));
+
+ return ReadEntryFromServerSessionL(size());
+ }
+
+/**
+Place the uids of entries that have a last changed data greater than aDate and which meet the selection
+criteria specified in aFilter into the aUids array.
+@capability None
+*/
+void RAgendaServ::GetEntryUidsSinceDateL(RArray<TCalLocalUid>& aUids, const TTime& aTime, TInt64 aFileId)
+ {
+ // package up filter size and filter
+ TPckgBuf<TTime> time(aTime);
+
+ TPtr8 bufptr = iBuffer->Ptr(0);
+ TPckg<TInt> size(0);
+ TPckgBuf<TInt64> fileId(aFileId);
+ // make server request
+ TIpcArgs args(&bufptr, &size, &time, &fileId);
+ User::LeaveIfError(SendReceive(EGetEntryUidsSinceDate, args));
+
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ // internalize carrayfix from readStream
+ const TInt KCount = readStream.ReadUint32L();
+ TCalLocalUid id;
+ for (TInt i = 0; i < KCount; i++)
+ {
+ readStream >> id;
+ aUids.AppendL(id);
+ }
+
+ readStream.Close();
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+/**
+Restore the notes text from the server
+@capability ReadUserData
+*/
+HBufC* RAgendaServ::RestoreTextL(TStreamId aId, TInt64 aFileId)
+ {
+ __ASSERT_ALWAYS( (aId != KNullStreamId), Panic(EStreamIdError));
+
+ TPckgBuf<TInt> size(0);
+ TPckg<TStreamId> textId(aId);
+
+ TPtr8 ptr(iBuffer->Ptr(0));
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&ptr, &textId, &size, &fileId);
+ User::LeaveIfError(SendReceive(ERestoreText, args ));
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ TInt textLength = readStream.ReadUint32L();
+ HBufC* text = HBufC::NewL(readStream, textLength);
+
+ CleanupStack::PopAndDestroy(buffer);
+ return text;
+ }
+
+/**
+@capability ReadUserData
+*/
+CAgnContent* RAgendaServ::RestoreAlarmActionL(TStreamId aId, TInt64 aFileId)
+ {
+ __ASSERT_ALWAYS( (aId != KNullStreamId), Panic(EStreamIdError));
+
+ TPckgBuf<TInt> size(0);
+ TPckg<TStreamId> id(aId);
+ TPckgBuf<TInt64> fileId(aFileId);
+
+ TPtr8 ptr(iBuffer->Ptr(0));
+ TIpcArgs args(&ptr, &id, &size, &fileId);
+ User::LeaveIfError(SendReceive(ERestoreAlarmAction, args ));
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ CAgnContent* alarmAction = new (ELeave) CAgnContent;
+ CleanupStack::PushL(alarmAction);
+ readStream >> *alarmAction;
+ CleanupStack::Pop(alarmAction);
+
+ CleanupStack::PopAndDestroy(buffer);
+
+ return alarmAction;
+ }
+
+
+/**
+Gets the number of allocated cells in the server space, debug only.
+@capability None
+*/
+TInt RAgendaServ::_DebugRequestAllocatedCellsL()
+ {
+ TPckg<TInt> numCells(0);
+ TIpcArgs args(&numCells);
+ User::LeaveIfError(SendReceive(EAgnResourceCount, args));
+ return numCells();
+ }
+
+/**
+Gets the number of allocated cells in the server space, debug only.
+@capability None
+*/
+TInt RAgendaServ::_DebugRequestAllocatedHeapSizeL()
+ {
+ TPckg<TInt> heapSize(0);
+ TIpcArgs args(&heapSize);
+ User::LeaveIfError(SendReceive(EAgnHeapSizeCount, args));
+ return heapSize();
+ }
+
+
+/**
+Set heap allocation failure according the arguments, debug only.
+@param aHeapAllocationFailureFlag heap allocation failure flags (RAllocator::TAllocFail)
+@param aCount Fail at allocation number aCount
+@capability None
+*/
+void RAgendaServ::_DebugSetHeapFailL(TInt aHeapAllocationFailureFlag, TInt aCount)
+ {
+ TIpcArgs args(aHeapAllocationFailureFlag, aCount);
+ User::LeaveIfError(SendReceive(EAgnSetHeapFailure, args));
+ }
+
+//
+// Category access
+//
+//
+
+/**
+Start building the Indexes asynchronously.
+*/
+void RAgendaServ::StartBuildIndex(TBool aNeedProgressReport, TRequestStatus& aStatus, TCalCollectionId aCallectionId)
+ {
+ TIpcArgs args(aNeedProgressReport, aCallectionId);
+ SendReceive(EStartBuildIndex, args, aStatus);
+ }
+
+
+/**
+Start tidying by ToDo list asynchronously.
+@capability WriteUserData
+@capability ReadUserData
+*/
+void RAgendaServ::StartTidyByDateL(TBool aReportProgress, TRequestStatus& aStatus,
+ const TAgnFilter& aFilter,
+ const TTime& aTodaysDate,
+ const CalCommon::TCalTimeRange& aCalTimeRange,
+ TCalCollectionId aCallectionId)
+ {
+ // Externalize parameters
+ RBufWriteStream bufStream;
+ bufStream.Open(*iBuffer);
+ aFilter.ExternalizeL(bufStream);
+ TPckgBuf<TTime> timePckgBuf;
+ timePckgBuf = aTodaysDate;
+ bufStream.WriteL(timePckgBuf);
+ timePckgBuf = aCalTimeRange.StartTime().TimeLocalL();
+ bufStream.WriteL(timePckgBuf);
+ timePckgBuf = aCalTimeRange.EndTime().TimeLocalL();
+ bufStream.WriteL(timePckgBuf);
+ bufStream.CommitL();
+ bufStream.Close();
+ TPtr8 parameterPtr = iBuffer->Ptr(0);
+
+ // Pass the parameters to the agenda model server but don't start the
+ // tidy operation.
+ TIpcArgs args(¶meterPtr, aCallectionId);
+ SendReceive(ETidyByDateReadParams, args);
+
+ // Start the tidy operation and notify us asynchronously when it is
+ // complete
+ TIpcArgs args1(aReportProgress, aCallectionId);
+ SendReceive(ETidyByDateStart, args1, aStatus);
+ }
+
+void RAgendaServ::RequestProgress(TRequestStatus& aStatus, TCalCollectionId aCallectionId)
+ {
+ TIpcArgs args(aCallectionId);
+ SendReceive(ERequestProgress, args, aStatus);
+ }
+/**
+returns the number of categories in the category list
+@capability None
+*/
+TInt RAgendaServ::CategoryCountL(TInt64 aFileId)
+ {
+ TPckgBuf<TInt> count;
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&count, &fileId);
+ User::LeaveIfError(SendReceive(EGetCategoryListCount, args));
+
+ return count();
+ }
+
+/**
+returns a category created from the category at aIndex in the category list
+@capability ReadUserData
+@param aIndex, this is the index of the category in the category list
+*/
+CAgnCategory* RAgendaServ::CategoryL(TInt aIndex, TInt64 aFileId)
+ {
+ TPtr8 ptr(iBuffer->Ptr(0));
+ TPckgBuf<TInt> size;
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&ptr, aIndex, &size, &fileId);
+ User::LeaveIfError(SendReceive(EGetCategoryListItem, args));
+
+ RBufReadStream readStream;
+ // Create a transfer buffer, and set where to read the data from
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ CAgnCategory* category = CAgnCategory::NewL(readStream);
+ CleanupStack::PopAndDestroy(buffer);
+
+ return category;
+ }
+
+/**
+adds a category to the list
+@capability WriteUserData
+@param aName, this is the name of the new category that we want to add to the category list
+*/
+void RAgendaServ::AddCategoryToListL(const TDesC& aName, TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&aName, &fileId);
+ User::LeaveIfError(SendReceive(EAddCategoryToList, args));
+ }
+
+/**
+package up step size and category
+@capability None
+*/
+void RAgendaServ::FilterCategoryL(CArrayFixSeg<TAgnEntryId>& aEntries, TInt64 aFileId)
+ {
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr(iBuffer->Ptr(0));
+ TPckgBuf<TInt64> fileId(aFileId);
+
+ TIpcArgs args(&ptr, &size, &fileId);
+ User::LeaveIfError(SendReceive(ECategoryFilter, args));
+
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ const TInt numberEntries = readStream.ReadInt16L();
+ for(TInt a = 0; a < numberEntries; ++a)
+ {
+ TAgnEntryId entry;
+ entry.InternalizeL(readStream);
+ aEntries.AppendL(entry);
+ }
+
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::StartCategoryTaskL(TBool aReportProgress, TRequestStatus& aStatus, const CAgnCategory& aCategory, CCalAsyncTaskManager::TAsyncAction aTask, TCalCollectionId aCallectionId)
+ {
+ // Create a write stream for this buffer
+ RBufWriteStream bufStream;
+ bufStream.Open(*iBuffer);
+ CleanupClosePushL(bufStream);
+ aCategory.ExternalizeL(bufStream);
+
+ bufStream.CommitL();
+ CleanupStack::Pop(&bufStream);
+ TPtr8 ptr(iBuffer->Ptr(0));
+ TIpcArgs args(&ptr, iBuffer->Size(), aTask, aCallectionId);
+ User::LeaveIfError(SendReceive(ECategoryStart, args));
+ TIpcArgs args1(aReportProgress, aTask, aCallectionId);
+ SendReceive(ECategoryStartAsyn, args1, aStatus);
+ }
+
+
+void RAgendaServ::FilterCategorySynchronouslyL(const CAgnCategory& aCategory, TCalCollectionId aCallectionId)
+ {
+ RBufWriteStream bufStream;
+ bufStream.Open(*iBuffer);
+ CleanupClosePushL(bufStream);
+ aCategory.ExternalizeL(bufStream);
+
+ bufStream.CommitL();
+ CleanupStack::Pop(&bufStream);
+
+ TPtr8 ptr(iBuffer->Ptr(0));
+ TIpcArgs args(&ptr, iBuffer->Size(), CCalAsyncTaskManager::EFilterCategory, aCallectionId);
+ User::LeaveIfError(SendReceive(ECategoryStart, args));
+ TRequestStatus status = KRequestPending;
+ TIpcArgs args1(EFalse, CCalAsyncTaskManager::EFilterCategory, aCallectionId);
+ SendReceive(ECategoryStartAsyn, args1, status);
+ User::WaitForRequest(status);
+ User::LeaveIfError(status.Int());
+ }
+
+/**
+@capability None
+*/
+void RAgendaServ::CancelTask(TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&fileId);
+ SendReceive(ECancelTask, args);
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::CreateAgendaFileL(const TDesC& aFileName)
+ {
+ TIpcArgs args(&aFileName);
+ User::LeaveIfError(SendReceive(ECreateAgendaFile,args));
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::DeleteAgendaFileL(const TDesC& aFileName, TInt aSessionId)
+ {
+ TIpcArgs args(&aFileName,aSessionId);
+ User::LeaveIfError(SendReceive(EDeleteAgendaFile,args));
+ }
+
+CDesCArray* RAgendaServ::ListAgendaFilesL()
+ {
+ // Get a list of file names held by the server
+ // currently setup extractor
+ // Argumnents: 0 : Data buffer
+ // 1 : Size of buffer
+
+ //create the buffer
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TPckgBuf<TInt> size(0);
+ TIpcArgs args(&ptr, &size);
+ User::LeaveIfError(SendReceive(EGetListFileNames,args));
+ RBufReadStream readStream;
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ const TInt count = readStream.ReadUint8L();
+ CDesCArray* fileNames=NULL;
+ if(count!=0)
+ {
+ fileNames = new(ELeave) CDesCArrayFlat(count);
+ CleanupStack::PushL(fileNames);
+ for (TInt i=0; i<count; ++i)
+ {
+ TFileName fileName;
+ TInt length=readStream.ReadInt8L();
+ readStream.ReadL(fileName,length);
+ fileNames->AppendL(fileName);
+ }
+
+ CleanupStack::Pop(fileNames);
+ }
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+ return fileNames;
+ }
+
+TBool RAgendaServ::AgendaFileExistsL(const TDesC& aFileName)
+ {
+ TPckgBuf<TBool> isFileThere;
+ TIpcArgs args(&isFileThere,&aFileName);
+ User::LeaveIfError(SendReceive(EAgendaFileExists,args));
+ return isFileThere();
+ }
+
+TInt RAgendaServ::SetUpdateAlarm(TBool aUpdateAlarm, TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(aUpdateAlarm, &fileId);
+ return SendReceive(ESetUpdateAlarm,args);
+ }
+
+void RAgendaServ::SetEnablePubSubNotificationsL(TBool aEnablePubSubNotification, TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(aEnablePubSubNotification, &fileId);
+ User::LeaveIfError(SendReceive(ESetEnablePubSubNotification,args));
+ }
+
+void RAgendaServ::SetChangeNotificationParametersL(MCalChangeCallBack2::TChangeEntryType aEntryType, TBool aIncludeUndatedTodos, TTime aFilterStartTimeUtc, TTime aFilterEndTimeUtc, TInt64 aFileId)
+ {
+ CBufFlat* paramsBuffer = CBufFlat::NewL(sizeof(TInt64) + sizeof(TBool) + sizeof(MCalChangeCallBack2::TChangeEntryType));
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ bufStream.WriteInt16L(aEntryType);
+ bufStream.WriteInt16L(aIncludeUndatedTodos);
+ bufStream << aFileId;
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+
+ TPckg<TTime> start(aFilterStartTimeUtc);
+ TPckg<TTime> end(aFilterEndTimeUtc);
+ TIpcArgs args(&start, &end, ¶msPtr);
+ User::LeaveIfError(SendReceive(ERequestChangeNotificationParameters, args));
+ CleanupStack::PopAndDestroy(paramsBuffer);
+ }
+
+void RAgendaServ::RequestChangeNotification(TRequestStatus& aStatus, TInt aSessionId, TUint8 aNotificationType)
+ {
+ TIpcArgs args(aSessionId, aNotificationType);
+ SendReceive(ERequestChangeNotification, args, aStatus);
+ }
+
+void RAgendaServ::CancelChangeNotification(TInt aSessionId, TUint8 aNotificationType)
+ {
+ TIpcArgs args(aSessionId, aNotificationType);
+ SendReceive(ECancelChangeNotification, args);
+ }
+
+// Prevent notification of changes made to the agenda model from this
+// client from being broadcast to other clients.
+void RAgendaServ::DisableChangeBroadcast(TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&fileId);
+ SendReceive(EDisableChangeBroadcast, args);
+ }
+
+// Allow notification of changes made to the agenda model from this
+// client from being broadcast to other clients.
+void RAgendaServ::EnableChangeBroadcast(TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&fileId);
+ SendReceive(EEnableChangeBroadcast, args);
+ }
+
+void RAgendaServ::GetFileChangesSinceLastNotificationL(RPointerArray<CAgnFileChangeInfo>& aCalFileChangeInfo, TInt aSessionId)
+ {
+ TPtr8 ptr = iBuffer->Ptr(0);
+ TPckgBuf<TInt> size(0);
+ TIpcArgs args(&ptr, &size, aSessionId);
+ User::LeaveIfError(SendReceive(EGetFileChangesSinceLastNotification,args));
+ RBufReadStream readStream;
+ CleanupClosePushL(readStream);
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+ const TInt count = readStream.ReadInt32L();
+ aCalFileChangeInfo.ReserveL(aCalFileChangeInfo.Count() + count);
+ for (TInt ii = 0; ii < count; ++ii)
+ {
+ CAgnFileChangeInfo* info = CAgnFileChangeInfo::NewL(readStream);
+ aCalFileChangeInfo.Append(info);
+ }
+
+ CleanupStack::PopAndDestroy(buffer);
+ CleanupStack::PopAndDestroy(&readStream);
+ }
+
+/**
+@capability ReadUserData
+*/
+void RAgendaServ::GetChangesSinceLastNotificationL(RArray<TCalChangeEntry>& aChangeItems, TCalCollectionId aCollectionId, TCalFileId& aFileId )
+ {
+ TPckgBuf<TCalFileId> fileId(aFileId);
+ TPtr8 ptr = iBuffer->Ptr(0);
+ TPckgBuf<TInt> size(0);
+ TIpcArgs args(&ptr, &size, aCollectionId, &fileId);
+ User::LeaveIfError(SendReceive(EGetChangesSinceLastNotification,args));
+ RBufReadStream readStream;
+ aFileId = fileId();
+ const TInt KBufferSize = size();
+ CBufFlat* buffer = CreateTransmitBufferL(KBufferSize);
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ CleanupStack::PushL(buffer);
+
+ // The buffer contains a number of change item (6 bytes in size) and nothing else.
+ // Check that the buffer is divisible by the size of a change item.
+ const TInt KSizeOfChangeItem = 6;
+ if (KBufferSize % KSizeOfChangeItem == 0)
+ {
+ const TInt KItems = KBufferSize / KSizeOfChangeItem;
+
+ TCalChangeEntry changeItem;
+ for (TInt count=0; count < KItems; count++)
+ {
+ changeItem.iEntryId = readStream.ReadUint32L();
+ changeItem.iChangeType = (MCalChangeCallBack2::TChangeType)readStream.ReadUint8L();
+ CCalEntry::TType type = static_cast<CCalEntry::TType>(readStream.ReadUint8L());
+ if (changeItem.iChangeType == MCalChangeCallBack2::EChangeUndefined)
+ {
+ changeItem.iEntryType = MCalChangeCallBack2::EChangeEntryAll;
+ }
+ else
+ {
+ if (type == CCalEntry::ETodo)
+ {
+ changeItem.iEntryType = MCalChangeCallBack2::EChangeEntryTodo;
+ }
+ else
+ {
+ changeItem.iEntryType = MCalChangeCallBack2::EChangeEntryEvent;
+ }
+ }
+ aChangeItems.AppendL(changeItem);
+ }
+ }
+ else
+ {
+ // If the buffer is corrupt, return a dummy item to say that something has changed
+ TCalChangeEntry changeItem;
+ changeItem.iEntryId = 0;
+ changeItem.iChangeType = MCalChangeCallBack2::EChangeUndefined;
+ changeItem.iEntryType = MCalChangeCallBack2::EChangeEntryAll;
+ aChangeItems.AppendL(changeItem);
+ }
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+/**
+@capability ReadUserData
+*/
+HBufC8* RAgendaServ::GetPropertyValueL(const TDesC& aFilename, TStreamId aStreamId) const
+ {
+ TPtr8 bufptr = iBuffer->Ptr(0);
+ TPckg<TInt> size(0);
+ TPckgC<TStreamId> streamId(aStreamId);
+
+ // make server request
+ TIpcArgs args(&bufptr, &size, &aFilename, &streamId);
+
+ User::LeaveIfError(SendReceive(EGetPropertyValue, args));
+
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ // internalize calendar info from readStream
+ HBufC8* value = HBufC8::NewL(readStream, KMaxTInt);
+
+ readStream.Close();
+ CleanupStack::PopAndDestroy(buffer);
+
+ return value;
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::SetCalendarInfoL(const TDesC& aFilename, const CCalCalendarInfoImpl& aCalendarInfoImpl) const
+ {
+ CBufFlat* paramsBuffer = CBufFlat::NewL(100);
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ aCalendarInfoImpl.IpcExternalizeL(bufStream);
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+
+ TIpcArgs args(&aFilename, ¶msPtr);
+ TInt error = SendReceive(ESetCalendarInfo, args);
+ User::LeaveIfError(error);
+ CleanupStack::PopAndDestroy(paramsBuffer);
+ }
+
+/**
+@capability ReadUserData
+*/
+CCalCalendarInfoImpl* RAgendaServ::GetCalendarInfoLC(const TDesC& aFilename, CCalSessionImpl& aSessionImpl) const
+ {
+ TPtr8 bufptr = iBuffer->Ptr(0);
+ TPckg<TInt> size(0);
+
+ // make server request
+ TIpcArgs args(&bufptr, &size, &aFilename);
+
+ User::LeaveIfError(SendReceive(EGetCalendarInfo, args));
+
+ RBufReadStream readStream;
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ // internalize calendar info from readStream
+ CCalCalendarInfoImpl* info(CCalCalendarInfoImpl::NewL(aSessionImpl));
+ CleanupStack::PushL(info);
+ info->IpcInternalizeL(readStream);
+
+ readStream.Close();
+ CleanupStack::Pop(info);
+ CleanupStack::PopAndDestroy(buffer);
+ CleanupStack::PushL(info);
+ return info;
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::DeleteEntryL(TAgnEntryId aEntryId, TCalCollectionId aCallectionId)
+ {
+ TPckg<TAgnEntryId> entryId(aEntryId);
+ TIpcArgs args(&entryId, aCallectionId);
+ User::LeaveIfError(SendReceive(EDeleteEntry,args));
+ }
+
+/**
+@capability ReadUserData
+*/
+void RAgendaServ::FetchEntryByGuidL(const TDesC8& aGuid, RPointerArray<CAgnEntry>& aList, TInt64 aFileId) const
+ {
+ // Get all entries which have the same GUID
+ // currently setup extractor
+ // Argumnents: 0 : Data buffer
+ // 1 : Size of buffer
+ // 2 : GUID
+
+ //create the buffer
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TPckgBuf<TInt> size(0);
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&ptr, &size, &aGuid, &fileId);
+ User::LeaveIfError(SendReceive(EFetchEntryByGuid,args));
+ RBufReadStream readStream;
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+ CleanupStack::PushL(buffer);
+
+ const TInt KCount = readStream.ReadUint32L();
+
+ for (TInt i = 0; i < KCount; ++i)
+ {
+ CAgnEntry* entry = CreateEntryFromBufferStreamL(readStream);
+ CleanupStack::PushL(entry);
+ aList.AppendL(entry);
+ CleanupStack::Pop(entry);
+ }
+
+ readStream.Close();
+
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::DeleteEntryL(const RArray<TCalLocalUid>& aIds, TCalCollectionId aCallectionId)
+ {
+ // Create a write stream for this buffer
+ RBufWriteStream writeStream;
+ writeStream.Open(*iBuffer);
+ const TInt KCount = aIds.Count();
+ writeStream.WriteUint32L(KCount);
+ for (TInt ii = 0; ii < KCount; ++ii)
+ {
+ writeStream.WriteUint32L(aIds[ii]);
+ }
+
+ writeStream.CommitL();
+ writeStream.Close();
+
+ TInt size(iBuffer->Size());
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TIpcArgs args(size, &ptr, aCallectionId);
+ User::LeaveIfError(SendReceive(EDeleteEntriesByLocalUid,args));
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::DeleteEntryByGuidL(const TDesC8& aGuid, TBool aCommitAndNotify, TInt64 aFileId)
+ {
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&aGuid, aCommitAndNotify, &fileId);
+ User::LeaveIfError(SendReceive(EDeleteEntryByGuid, args));
+ }
+
+/**
+@capability ReadUserData
+*/
+void RAgendaServ::FindInstancesL(RArray<TInt64>& aFileIds, CArrayFix<TAgnInstance>& aMatchedInstanceList, const TFindInstanceParams& aParams)
+ {
+ // Write the find instance setting out to the buffer
+ CBufFlat* paramsBuffer = CBufFlat::NewL(sizeof(TFindInstanceParams));
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ aParams.ExternalizeL(bufStream);
+ bufStream.WriteInt16L(aFileIds.Count());
+ for(TInt ii=0; ii<aFileIds.Count();++ii)
+ {
+ bufStream << aFileIds[ii];
+ }
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TIpcArgs args(&ptr, &size, ¶msPtr);
+ User::LeaveIfError(SendReceive(EFindInstances,args));
+
+ CleanupStack::PopAndDestroy(paramsBuffer);
+
+ RBufReadStream readStream;
+
+ CBufFlat* buffer = CreateTransmitBufferL(size());
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ if (buffer)
+ {
+ CleanupStack::PushL(buffer);
+ }
+
+ TInt items = readStream.ReadUint32L();
+
+ for (TInt count=0; count<items; count++)
+ {
+ TAgnInstance aInstance;
+ readStream >> aInstance;
+
+ aMatchedInstanceList.AppendL(aInstance);
+ }
+
+ readStream.Close();
+
+ if (buffer)
+ {
+ CleanupStack::PopAndDestroy(buffer);
+ }
+ }
+
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::CommitL(TCalCollectionId aCallectionId)
+ {
+ TIpcArgs args(aCallectionId);
+ User::LeaveIfError(SendReceive(ECommit, args));
+ }
+/**
+@capability WriteUserData
+*/
+void RAgendaServ::Rollback(TCalCollectionId aCallectionId)
+ {
+ TIpcArgs args(aCallectionId);
+ SendReceive(ERollback, args);
+ }
+/** Get the last modified time for tz rules from time zone server
+ It is called when the client getting the last modified date for an entry since the
+ last modified time of an entry is not updated when tz database is updated.
+@capability none
+*/
+TTime RAgendaServ::TzRulesLastModifiedDateL(TInt64 aFileId)
+ {
+ TPckgBuf<TTime> time;
+ TPckgBuf<TInt64> fileId(aFileId);
+ TIpcArgs args(&time, &fileId);
+ User::LeaveIfError(SendReceive(ETzDbChangedTime, args));
+ return time();
+ }
+
+#ifdef SYMBIAN_CALENDAR_ENHANCEDSEARCHANDSORT
+/**
+ * Create instance iterator with given find instance settings and sort
+ * criteria
+@capability ReadUserData
+*/
+TInt RAgendaServ::CreateInstanceIteratorL(const TFindInstanceParams& aFindParams, const CCalSortCriteria& aSortCriteria, RArray<TInt64>& aFileIds)
+ {
+ //Store find instance parameter into buffer
+ CBufFlat* paramsBuffer = CBufFlat::NewL(sizeof(TFindInstanceParams));
+ CleanupStack::PushL(paramsBuffer);
+ RBufWriteStream bufStream;
+ CleanupClosePushL(bufStream);
+ bufStream.Open(*paramsBuffer);
+ aFindParams.ExternalizeL(bufStream);
+ bufStream.CommitL();
+ CleanupStack::PopAndDestroy(&bufStream);
+
+ TPtr8 paramsPtr = paramsBuffer->Ptr(0);
+
+ //Store sort criteria into buffer
+ RBufWriteStream sortCriteriaBufStream;
+ sortCriteriaBufStream.Open(*iBuffer);
+ CleanupClosePushL(sortCriteriaBufStream);
+ aSortCriteria.SortCriteria().ExternalizeL(sortCriteriaBufStream);
+ sortCriteriaBufStream.WriteInt16L(aFileIds.Count());
+ const TInt count = aFileIds.Count();
+ for(TInt ii=0; ii<count; ++ii)
+ {
+ sortCriteriaBufStream << aFileIds[ii];
+ }
+
+ sortCriteriaBufStream.CommitL();
+ CleanupStack::PopAndDestroy(&sortCriteriaBufStream);
+
+ // Get the sizes of the buffers
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TPckgBuf<TInt> iteratorId(KErrNotFound);
+ TIpcArgs args(¶msPtr, &ptr, &iteratorId);
+
+ User::LeaveIfError(SendReceive(EInstanceIteratorCreate, args));
+
+ CleanupStack::PopAndDestroy(paramsBuffer);
+
+ return iteratorId();
+ }
+#endif
+
+/**
+ * Destroy instance iterator with specified iterator id
+@capability ReadUserData
+*/
+void RAgendaServ::DestroyInstanceIterator(TInt aIteratorId)
+ {
+ TIpcArgs args(aIteratorId);
+
+ //It's not neccessary/possible to check if the operation complete successfully
+ //because the function may be called at application exiting time.
+ Send(EInstanceIteratorDestroy, args);
+ }
+
+/**
+ * Fetch the available instances start from specified index
+@capability ReadUserData
+*/
+void RAgendaServ::InstanceIteratorNextL(TInt aIteratorId, CArrayFix<TAgnInstance>& aInstances, TInt aIndex) const
+ {
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TIpcArgs args(&ptr, &size, aIteratorId, aIndex);
+ User::LeaveIfError(SendReceive(EInstanceIteratorNext, args));
+
+ LoadingInstancesFromBufferL(aInstances, size());
+ }
+
+/**
+ * Fetch the previous instances which index are before given index
+@capability ReadUserData
+*/
+void RAgendaServ::InstanceIteratorPreviousL(TInt aIteratorId, CArrayFix<TAgnInstance>& aInstances, TInt aIndex) const
+ {
+ TPckgBuf<TInt> size(0);
+ TPtr8 ptr = iBuffer->Ptr(0);
+
+ TIpcArgs args(&ptr, &size, aIteratorId, aIndex);
+ User::LeaveIfError(SendReceive(EInstanceIteratorPrevious, args));
+
+ LoadingInstancesFromBufferL(aInstances, size());
+ }
+
+void RAgendaServ::LoadingInstancesFromBufferL(CArrayFix<TAgnInstance>& aInstances, TInt aBufSize) const
+ {
+ RBufReadStream readStream;
+ CleanupClosePushL(readStream);
+
+ CBufFlat* buffer = CreateTransmitBufferL(aBufSize);
+ if (buffer)
+ {
+ readStream.Open(*buffer);
+ CleanupStack::PushL(buffer);
+ }
+ else
+ {
+ readStream.Open(*iBuffer);
+ }
+
+ const TInt KCount(readStream.ReadUint32L());
+
+ for (TInt i(0) ; i < KCount; ++i)
+ {
+ TAgnInstance instanceId;
+ instanceId.InternalizeL(readStream);
+ aInstances.AppendL(instanceId);
+ }
+
+ if (buffer)
+ {
+ CleanupStack::PopAndDestroy(buffer);
+ }
+
+ CleanupStack::PopAndDestroy(&readStream);
+ }
+
+/**
+ * Get the number of instances stored in an iterator
+@capability ReadUserData
+*/
+TInt RAgendaServ::InstanceIteratorCountL(TInt aIteratorId) const
+ {
+ TPckgBuf<TInt> count(0);
+ TIpcArgs args(aIteratorId, &count);
+ User::LeaveIfError(SendReceive(EInstanceIteratorCount, args));
+ return count();
+ }
+
+/**
+ * Find the index of the given instance in the iterator.
+@capability ReadUserData
+*/
+TInt RAgendaServ::InstanceIteratorLocateIndexL(TInt aIteratorId, TAgnInstance& aInstanceId)
+ {
+ TPckgBuf<TInt> index(0);
+ TPckg<TAgnInstance> instanceId(aInstanceId);
+ TIpcArgs args(aIteratorId, &instanceId, &index);
+ User::LeaveIfError(SendReceive(EInstanceIteratorLocateIndex, args));
+ return index();
+ }
+
+void RAgendaServ::DeleteSimpleEntry(CAgnSimpleEntry* aSimpleEntry)
+/** Deletes a sort entry from the sort entry allocator (a specialised memory handler
+for sort entry objects).
+
+A sort entry is an entry in an agenda index. The function frees the sort entry object
+and puts it on the free list.
+
+@param aSimpleEntry Pointer to the simple entry to delete. */
+ {
+ iSimpleEntryAllocator->Delete(aSimpleEntry);
+ }
+
+CAgnSimpleEntry* RAgendaServ::CreateDumySimpleEntryL()
+ {
+ return iSimpleEntryAllocator->CreateSimpleEntryL(CCalEntry::EAppt);
+ }
+
+CAgnSimpleEntryAllocator& RAgendaServ::SimpleEntryAllocator() const
+ {
+ return *iSimpleEntryAllocator;
+ }
+
+/**
+@capability none
+*/
+void RAgendaServ::__dbgClearTzClientCacheL(TBool aRestartCaching)
+ {
+ CAgnTlsProxy* agntlsproxy = CAgnTlsProxy::CreateL(CAgnTlsProxy::TAgnTlsTzRulesType_Client);
+ agntlsproxy->__dbgClearTzClientCacheL(aRestartCaching);
+ CAgnTlsProxy::Release(agntlsproxy);
+ }
+
+
+//Cleanup Callback function which deletes CAgnSortEntry * using CAgnSorEntryAllocator.
+void TCleanSimpleEntry::DestroySimpleEntry(TAny* aPtr)
+ {
+ TCleanSimpleEntry* cleanSimpleEntry = static_cast<TCleanSimpleEntry*> (aPtr);
+ cleanSimpleEntry->GetSimpleEntryAllocator().Delete(cleanSimpleEntry->GetSimpleEntry());
+ }
+
+TCleanSimpleEntry::TCleanSimpleEntry(CAgnSimpleEntry& aSimpleEntry, CAgnSimpleEntryAllocator& aAlloc)
+ : iSimpleEntry(aSimpleEntry),iAlloc(aAlloc)
+ {
+ }
+
+CAgnSimpleEntry* TCleanSimpleEntry::GetSimpleEntry()
+ {
+ return &iSimpleEntry;
+ }
+
+CAgnSimpleEntryAllocator& TCleanSimpleEntry::GetSimpleEntryAllocator()
+ {
+ return iAlloc;
+ }
+
+