landmarks/locationlandmarks/server/src/EPos_CPosLmDbManEventHandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 27 Apr 2010 17:05:00 +0300
branchRCL_3
changeset 10 d6e4203b7ebe
parent 0 667063e416a2
permissions -rw-r--r--
Revision: 201015 Kit: 201017

/*
* Copyright (c) 2005 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: class to handle event notification to subscribers.
*
*
*/


// INCLUDE FILES
#include "EPos_CPosLmDbManEventHandler.h"
#include "EPos_LandmarksServerPanics.h"
#include "EPos_PosLmServerCommon.h"
#include "EPos_LmServerGlobal.h"

// CONSTANTS
const TInt KEventQueueMaxSize = 5;
const TInt KArrayGranularity = 6;

// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CPosLmDbManEventHandler::CPosLmDbManEventHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CPosLmDbManEventHandler::CPosLmDbManEventHandler()
    {
    }

// -----------------------------------------------------------------------------
// CPosLmDbManEventHandler::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::ConstructL()
    {
    iUriArray = new (ELeave) CDesCArrayFlat(KArrayGranularity);
    }

// Two-phased constructor.
CPosLmDbManEventHandler* CPosLmDbManEventHandler::NewL()
    {
    CPosLmDbManEventHandler* self = new (ELeave) CPosLmDbManEventHandler();
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

// Destructor
CPosLmDbManEventHandler::~CPosLmDbManEventHandler()
    {
    CompleteAnyOutStandingRequest(KErrCancel);
    iEventQueue.Close();
    delete iUriArray;
    delete iLastUri;
    }

// -----------------------------------------------------------------------------
// CPosLmEventHandler::ServerUriFromLastEvent
//
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::ServerUriFromLastEvent(
    const RMessagePtr2& aMessage)
    {
    if (!iLastUri || iLastUri->Length() == 0)
        {
        LmServerGlobal::Complete(aMessage, KErrNotFound);
        }
    else
        {
        LmServerGlobal::Write(aMessage, KPosLmServerUriArg, *iLastUri);
        LmServerGlobal::Complete(aMessage, KErrNone);
        }
    delete iLastUri;
    iLastUri = NULL;
    }

// -----------------------------------------------------------------------------
// CPosLmDbManEventHandler::HandleRequestForEventL
//
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::HandleRequestForEventL(
    const RMessagePtr2& aMessage)
    {
    // check that descriptor parameters are OK so that server
    // won't panic when trying to write.
    TPckgBuf<TPosLmDatabaseEvent> event;
    TPckgBuf<TInt> length;
    TInt eventMaxLength = aMessage.GetDesMaxLength(KPosLmServerDbManEventArg);
    TInt lengthMaxLength = aMessage.GetDesMaxLength(KPosLmServerUriLengthArg);
    if (eventMaxLength  != event.Length() ||
        lengthMaxLength != length.Length())
        {
        PanicClient(aMessage, EPosUnableToReadOrWriteDataToClient);
        return;
        }

    if (iEventQueue.Count() > 0)
        {
        // Send the first event in the queue to the client.
        WriteEventAndComplete(aMessage);
        }
    else
         {
        // No events in queue. Put the message on hold.
        if (!iHoldingMessage.IsNull())
            {
            PanicClient(aMessage,
                EPosEventNotifierAlreadyHasOutstandingRequest);
            }
        else
            {
            iHoldingMessage = aMessage;
            }
        }
    }

// -----------------------------------------------------------------------------
// CPosLmDbManEventHandler::HandleIncomingEventL
//
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::HandleIncomingEventL(
    TPosLmDatabaseEvent aEvent,
    const TDesC& aUri)
    {
    if (iEventQueue.Count() == KEventQueueMaxSize)
        {
        iEventQueue.Reset();
        iUriArray->Reset();
        aEvent.iEventType = EPosLmDbUnknownEvent;
        AddToEventQueueL(aEvent, KNullDesC);
        }
    else
        {
        AddToEventQueueL(aEvent, aUri);
        }

    if (!iHoldingMessage.IsNull())
        {
        // There is a message on hold. Send response immediately.
        WriteEventAndComplete(iHoldingMessage);
        }
    }

// -----------------------------------------------------------------------------
// CPosLmDbManEventHandler::CompleteAnyOutStandingRequest
//
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::CompleteAnyOutStandingRequest(
    TInt aError)
    {
    LmServerGlobal::Complete(iHoldingMessage, aError);
    }

// -----------------------------------------------------------------------------
// CPosLmDbManEventHandler::WriteEventAndComplete
//
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::WriteEventAndComplete(
    const RMessagePtr2& aMessage)
    {
    HBufC* tmpBuf = iUriArray->MdcaPoint(0).Alloc();
    if (!tmpBuf)
        {
        LmServerGlobal::Complete(aMessage, KErrNoMemory);
        }
    else
        {
        iUriArray->Delete(0);
        iUriArray->Compress();
        delete iLastUri;
        iLastUri = tmpBuf;

        TPckgBuf<TPosLmDatabaseEvent> event(iEventQueue[0]);
        TPckgBuf<TInt> length(iLastUri->Length());
        if (LmServerGlobal::Write(aMessage, KPosLmServerEventArg, event)
            == KErrNone &&
            LmServerGlobal::Write(aMessage, KPosLmServerUriLengthArg, length)
            == KErrNone)
            {
            LmServerGlobal::Complete(aMessage, KErrNone);
            }
        iEventQueue.Remove(0);
        }
    }

// -----------------------------------------------------------------------------
// CPosLmEventHandler::AddToEventQueueL
//
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CPosLmDbManEventHandler::AddToEventQueueL(
    TPosLmDatabaseEvent aEvent,
    const TDesC& aUri)
    {
    TInt index = KErrNotFound;
    if (aEvent.iEventType == EPosLmDbNewDefaultDbLocation)
        {
        index = iEventQueue.Find(aEvent);
        }

    iUriArray->AppendL(aUri);
    TInt err = iEventQueue.Append(aEvent);

    if (err != KErrNone)
        {
        iUriArray->Delete(iUriArray->Count() - 1);
        User::Leave(err);
        }
    else if (index != KErrNotFound)
        {
        iEventQueue.Remove(index);
        iUriArray->Delete(index);
        }
    }

// End of File