/* Agent Tcl
   Bob Gray
   29 January 1997

   agentAgentId.h

   This file defines the class AgentId.

   Copyright (c) 1995-1997, Robert S. Gray Dartmouth College

   See the file "agent.terms" for information on usage and redistribution
   of this file and for a DISCLAIMER OF ALL WARRANTIES.
*/

#ifndef _AGENT_AGENT_ID_H
#define _AGENT_AGENT_ID_H

#ifndef NO_PRAGMAS
#pragma interface
#endif

#ifndef _PLAT_PORTING_H
#include "platPorting.h"		// UNKNOWN_IP
#endif
#ifndef _PLAT_SIZES_H
#include "platSizes.h"             	// UINT_32
#endif
#ifndef _SUPP_DSTRING_H
#include "suppDString.h"            	// DynamicString class
#endif
#ifndef _TRUEFALSE_H
#include "truefalse.h"            	// BOOLEAN 
#endif

/*
 * forward declarations
 */

class DynamicBuffer;

/*
 * An agent identification
 */

class AgentId
{
    friend class AgentIdPacker;		
    friend class AgentIdUnpacker;

    DynamicString m_serverName; 	// server name
    UINT_32 m_serverIp; 		// server IP address
    DynamicString m_name;		// agent name
    UINT_32 m_id;			// agent numeric id

public:

	// constructors

    AgentId (void):
	m_serverName (),
	m_serverIp (UNKNOWN_IP),
	m_name (),
	m_id (0)
    {
	// empty
    }
   
    AgentId (const AgentId &agentId):
	m_serverName (agentId.m_serverName),
	m_serverIp (agentId.m_serverIp),
	m_name (agentId.m_name),
	m_id (agentId.m_id)
    {
	// empty
    }
   
    AgentId (const DynamicString &serverName, UINT_32 serverIp, const DynamicString &name, UINT_32 id):
	m_serverName (serverName),
	m_serverIp (serverIp),
	m_name (name),
	m_id (id)
    {
	// empty
    }

	// assignment operator

    AgentId& operator= (const AgentId& agentId) {

	if (this != &agentId) {
	    m_serverName = agentId.m_serverName;
	    m_serverIp   = agentId.m_serverIp;
	    m_name	 = agentId.m_name;
	    m_id	 = agentId.m_id;
	}

	return (*this);
    }

	// destructor

   ~AgentId () {
	// empty
    }

	// get and set operations

    DynamicString getServerName (void) const {
	return (m_serverName);
    }

    UINT_32 getServerIp (void) const {
	return (m_serverIp);
    }

    DynamicString getName (void) const {
	return (m_name);
    }

    UINT_32 getId (void) const {
	return (m_id);
    }

    void setServerName (const DynamicString &serverName) {
	m_serverName = serverName;
    }

    void setServerIp (UINT_32 serverIp) {
	m_serverIp = serverIp;
    }

    void setName (const DynamicString &name) {
	m_name = name; 
    }

    void setId (UINT_32 id) {
	m_id = id;
    }

	// empty out the agent identification 

    void empty (void) {
	m_serverName = DynamicString ();
	m_serverIp   = UNKNOWN_IP;
	m_name	     = DynamicString ();
	m_id	     = 0;
    }

	// see if the agent identification is empty 

    BOOLEAN isEmpty (void) {
	return (m_serverName.isEmpty() && m_name.isEmpty() && m_serverIp == UNKNOWN_IP && m_id == 0) ? e_TRUE : e_FALSE;
    }
};

/*
 * Iterators that pack and unpack an AgentId -- we use iterators since
 * eventually we want to be able to pack the AgentId in fixed-size chunks
 * so that we can overlap the packing and transmission process
 */

class AgentIdPacker
{
    AgentId &m_agentId;    // AgentId that we are packing into a byte stream

public:

	// constructor

    AgentIdPacker (AgentId &agentId):
	m_agentId (agentId)
    {
	// empty
    }
	
	// get the packed size of the AgentId

    UINT_32 getPackedSize (void);

	// pack the AgentId into the buffer

    char *pack (char *buffer);
};

class AgentIdUnpacker
{
    AgentId &m_agentId;

public:

	// constructor and destructor

    AgentIdUnpacker (AgentId &agentId):
	m_agentId (agentId)
    {
	// empty
    }

	// unpack from a buffer

    char *unpack (char *buffer, char *endBuffer);
};

#endif
