// -*- c++ -*-
//------------------------------------------------------------------------------
//                           Address.h
//------------------------------------------------------------------------------
//  Copyright (C) 1997  Vladislav Grinchenko <vladg@erols.com>
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Library General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
#ifndef ADDRESS_H
#define ADDRESS_H

#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>		// addresses handling
#include <sys/un.h>
#include <string.h>
#include <errno.h>

#include "assa/Logger.h"
#include "assa/Assert.h"

namespace ASSA {

typedef struct sockaddr SA;	// stolen from R.Stevens
typedef struct sockaddr_in SA_IN;	
typedef struct sockaddr_un SA_UN;	

/** @file Address.h 

   Address is an abstraction for INET or UNIX-domain address data type.
*/

class Address {
public:
	/** State bits */
	enum addr_state_t { 
		goodbit=0,				/**< good state */
		badbit=1				/**< bad state */
	};
	typedef int addrstate;

private:
	unsigned char m_state;

public:
	/// Constructor.
	Address () : m_state (Address::goodbit) { trace("Address::Address");	}

	/// Destructor.
	virtual ~Address() {}

	/** Valid address is constructed
	    @return true if valid address, false otherwise
	 */
	bool good() const { return m_state == 0; }

	/** Indicates whether there was error during address
	    construction process i.e. host or port lookup 
	    failure or invalid format used.
	    @return true if invalid address, false otherwise
	 */
	bool bad() const { return m_state & Address::badbit; }

	/** Conversion to void * (or bool) for testing where bool
	    is required (in conditional statements).
	    @return true if valid address; false otherwise
	 */
	operator void* () const { return (void*) good (); }

	/** Alias to bad ().
	    @return true if invaid address; false otherwise.
	*/
	bool operator! () const { return bad (); }
	
	/// Return length of the underlying address structure

	virtual const int getLength() const = 0;

	/// Retrieve pointer to the address structure
	virtual SA* getAddress() const = 0;
	
	/// Dump object state to the log file.
	virtual void dump () 
		{ 	
			trace("Address");
			DL((TRACE,"state   - %s\n", good () ? "good" : "bad"));
		}

protected:
	/** Set state of the Address object
	 *  @param flag_ new state
	 */
	void setstate (addrstate flag_) { m_state |= flag_; }
};

} // end namespace ASSA

#endif /* ADDRESS_H */
