//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / OVOPS++
//
//File: messenge.cpp
//
//Version: $Revision: 1.33 $
//
//State: $State: Exp $
//
//Date: $Date: 1999/03/08 11:05:15 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
// 
//Authors:
//      Timo Kokkonen
//      Timo Pärnänen
//      Juhana Räsänen
//      Pasi Nummisalo
//
//Description:
//      See corresponding header file.
//
//Copyright:     
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//      
//Licence:
//     
//
//History:
//
//

#include "messenge.h"
#include "error.h"	// includes debug.h

pfMessenger::SerialNumber pfMessenger :: _nextSerialNumber = 0;

pfMessenger :: pfMessenger(void)
    : pfStorage(),
      _serialNumber(0),
      _refCount(0),
      _sequenceNumber(0)
{
    _serialNumber = getNextSerialNumber();
    return;
}

pfMessenger ::pfMessenger(const pfMessenger &other_)
    : pfStorage(other_),
      _serialNumber(0),
      _refCount(0),
      _sequenceNumber(other_._sequenceNumber) // ++TODO++ should be own SN
{
    _serialNumber = getNextSerialNumber();
    return;
}

pfMessenger :: ~pfMessenger(void)
{
    return;
}

//
//Functions: reference count methods
//
//Description:
//   Methods to increase, decrease and to check the if there are
//   references to this object.
//   Used in pfMsgTransporter destructor to prevent
//   messenger destruction, if it has been buffered in protocol.
//

void pfMessenger :: incRefCount(void)
{
//    debugUser("pfMessenger :: incRefCount");
    ++_refCount;
    if (_refCount == 0)
    {
        debugUser("pfMessenger::incRefCount: reference count reached max value");
        THROW_TEMPORARY_FAILURE;
    }
    return;
}

void pfMessenger :: decRefCount(void)
{
//   debugUser("pfMessenger :: decRefCount");
    --_refCount;
    if (_refCount < 0)
    {
        debugUser("pfMessenger::incRefCount: reference count under zero");
        THROW_TEMPORARY_FAILURE;
    }
    return;
}

bool pfMessenger :: isReference(void) const
{
    bool result = _refCount == 0 ? false : true;
    return result;
}

pfMessenger::SerialNumber pfMessenger :: getSerialNumber(void) const
{
    return _serialNumber;
}

//   
//Function: getSerialNumber
//
//Description:
//      Returns SerialNumber for transporters and messengers.
//

pfMessenger::SerialNumber pfMessenger :: getNextSerialNumber(void)
{
    SerialNumber result = _nextSerialNumber;
    ++_nextSerialNumber;
    return result;
}

//
//Function: getSequenceNumber
//
//Description:
//   Messenger has a default implementation of sequence numbers to support
//   buffering. Default is to set every messenger's sequence number to 0.
//

pfUlong pfMessenger :: getSequenceNumber(void) const
{
    return _sequenceNumber;
}

void pfMessenger :: setSequenceNumber(pfUlong sequenceNumber_)
{
    _sequenceNumber = sequenceNumber_;
    return;
}

pfKey pfMessenger :: getDispatchKey(string &keyName_) const
{
    pfKey key = getInteger(keyName_);
    return key;
}

//
//Function: apply
//
//Description:
//    Default action to apply method
//
//

void pfMessenger :: apply(pfState *, pfProtocol *)
{
    return;
}

//
//Function: clone
//
//Description:
//    Returns pointer to new messenger created by using copy constructor
//

pfMessenger *pfMessenger :: clone(void)
{
    pfMessenger *newMessenger = new pfMessenger(*this);
    return newMessenger;
}

