//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / OVOPS++
//
//File: conduit.cpp
//
//Version: $Revision: 1.46 $
//
//State: $State: Exp $
//
//Date: $Date: 1999/03/09 10:04:24 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
// 
//Authors:
//      Pasi Nummisalo
//      Juhana Räsänen
//      Timo Pärnänen
//	Vesa-Matti Puro
//
//Description:
//      See corresponding header file.   
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//      
//Licence:
//     
//
//History:
//
//
 
#include "protocol.h"
#include "debug.h"

pfConduit :: pfConduit(pfProtocol *implementation_)
    : _implementation(implementation_)
{
    if ((implementation_ != 0) && (implementation_->noReference() == true))
    {
        debugCreate(implementation_);
    }
    incRefCount();
    return;
}

pfConduit :: pfConduit(const pfConduit &other_)
    : _implementation(other_._implementation)
{
    incRefCount();
    return;
}

pfConduit :: ~pfConduit(void)
{
    decRefCount();
    return;
}

//
//Functions: operators
//
//Description:
//    Define equal and not equal logical operators
//    and assignment operator
//

const pfConduit &pfConduit :: operator = (const pfConduit &other_)
{
    if (this != &other_) // if not x = x situation
    {
        // Decrease refcount at old implementation
        decRefCount();
        _implementation = other_._implementation;
        // Increase refcount at new implementation
        incRefCount();
    }
    return *this;
}

int pfConduit :: operator == (const pfConduit &other_) const
{
    int result = _implementation == other_._implementation;
    return result; 
}

int pfConduit :: operator != (const pfConduit &other_) const
{
    int result = _implementation != other_._implementation;
    return result; 
}  

//
//Function: clone
//
//Description:
//    Implements clone method for conduit.
//

pfConduit pfConduit :: clone(void) const
{
    pfProtocol *newImplementation = 0;
    if (_implementation != 0) 
    {
        newImplementation = _implementation->cloneImplementation();        
    }
    pfConduit result(newImplementation);
    return result; 
}

//
//Functions: set and get methods
//
//Description:
//    See pfProtocol. 
//

void pfConduit :: setId(pfId id_)
{
    if (_implementation != 0)
    {
        _implementation->setId(id_); 
    }
    return;
}

pfId pfConduit :: getId(void) const
{
    int result = 0;    
    if (_implementation != 0)
    {
        result = _implementation->getId(); 
    }
    return result;
}

void pfConduit :: setKey(pfKey key_)
{
    if (_implementation != 0)
    {
        _implementation->setKey(key_); 
    }
    return;
}

pfKey pfConduit :: getKey(void) const
{
    pfKey result = 0;
    if (_implementation != 0)
    {
        result = _implementation->getKey();
    }
    return result;
}

//
//Functions: accept method
//
//Description:
//    See pfProtocol. 
//

void pfConduit :: accept(pfTransporter *transporter_)
    throw(pfNullPointerException)
{
    if (transporter_ == 0)
    {
        throw pfNullPointerException(PF_EX_INFO);
    }
    if (_implementation != 0)
    {
        _implementation->accept(transporter_);
    }
    else
    {
        if (transporter_->acceptAsynchronous() == true)
        {
            delete transporter_;
        }
    }
    return;
}

//
//Functions: connect methods
//
//Description:
//    See pfProtocol.
//

void pfConduit :: connectToA(pfConduit &conduit_)
{
    if (_implementation != 0)
    {
        _implementation->connectToA(conduit_);
    }
    return;
}

void pfConduit :: connectToB(pfConduit &conduit_)
{
    if (_implementation != 0)
    {   
        _implementation->connectToB(conduit_);
    }
    return;
}

//
//Function: disconnect
//
//Description:
//    See pfProtocol.
//

void pfConduit :: disconnect(void)
{
    if (_implementation != 0)
    {
        _implementation->disconnect();
    }
    return;
}

//
//Function: methods for reference counter
//
//Description:
//    See pfProtocol.
//

void pfConduit :: incRefCount(void) 
{
    if (_implementation != 0)
    {
        _implementation->incRefCount();
    }
    return;
}

void pfConduit :: decRefCount(void)
{
    if (_implementation != 0)
    {
        _implementation->decRefCount();
        if (_implementation->noReference() != 0)
        {
            debugDelete(_implementation);
            delete _implementation;
            _implementation = 0;
        }
    }
    return;
}

//
//Function: setTraceOn
//
//Description:
//    See pfProtocol.
//

void pfConduit :: setTraceOn(void)
{
    if (_implementation != 0)
    {
        _implementation->setTraceOn();
    }
    return;
}

//
//Function: getName
//
//Description:
//    Return name of implementation class from rtti
//

string pfConduit :: getName(void) const
{
    string name;
    if (_implementation != 0)
    {
        name = pfDebug::getProtocolName(_implementation);
    }
    return name;
}

//
//Function: getAdderess
//
//Description:
//    Return address of implementation as long
//

long pfConduit :: getAddress(void) const
{
    return (long)_implementation;
}
