
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//         Reza Nekovei <reza@intcomm.net>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
 
// (c) COPYRIGHT URI/MIT 1994-1996,1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
//      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
//      reza            Reza Nekovei <reza@intcomm.net>

// To hold and managed a set of open Connect *'s. 
//
// jhrg 9/30/94

#include "Connections.h"
#include "debug.h"

using namespace std;

// private mfuncs

template <class T>
void
Connections<T>::init_array(int i)
{
    while (i--) {
	_free.push_back(i);
	_conns[i] = NULL;
    }
}

// public mfuncs

/** The constructor for the Connections object.

    @param i The maximum number of open Connect
    objects this Connections object can hold.  This number should
    not be bigger than the <tt>MAX_CONNECTIONS</tt> parameter in the
    Connections header file.
*/
template <class T>
Connections<T>::Connections(int i)
{
    _max_con = i;

    _conns = new T[i];

    while (i--) {
	DBG2(cerr << "Pushing " << i << " onto free list." << endl);
	_free.push_back(i);
	_conns[i] = NULL;
    }

    DBG2(cerr<< "Number of elements in Connections free list: "
	<< free_elements() << endl);
}

/** The specialized copy constructor. */
template <class T>
Connections<T>::Connections(const Connections<T> &cs)
{
    _max_con = cs._max_con;

    _conns = new T[_max_con];

    int i = _max_con;
    while (i--) {
        _free.push_back(cs._free[i]);
        _conns[i] = cs._conns[i];
    }
}
    
template <class T>
Connections<T>::~Connections()
{
    delete [] _conns; _conns = 0;
}

template <class T>
Connections<T> &
Connections<T>::operator=(const Connections<T> &rhs)
{
    if (this == &rhs)
	return *this;

    _max_con = rhs._max_con;

    _conns = new T[_max_con];

    int i = _max_con;
    while (i--) {
        _free.push_back(rhs._free[i]);
        _conns[i] = rhs._conns[i];
    }

    return *this;
}

/** @brief Reference a Connect object in a Connection collection.

    This operator is how you retrieve Connect objects from the
    Connection collection.

    @brief Reference a single Connect object from a set.
    @return This function returns a reference to an element of the
    Connections array.  It returns a reference so that this operator
    will work on both the left and right side of the assignment
    operator.
*/
template <class T>
T &
Connections<T>::operator[](int i)
{
    return _conns[i];
}

/** @brief Add a Connect object to the array. 

    @return The index of the newly added Connect object or -1 if the allocated
    space for the array is full.
    @param c The Connect object to add to the array.
*/
template <class T>
int
Connections<T>::add_connect(T c)
{
    if (_free.empty()) {
	cerr << "add_connect: too many connects, cannot add another" << endl;
	return -1;
    }

    int i = _free.back(); // pop the first element
    _free.pop_back();

    _conns[i] = c;
    
    DBG(cerr << "Bound object: " << c << " to Connections[" << i <<"]"
	<< endl);

    return i;
}


/** @brief Delete a Connect object from the array.

    Remove a connection from the array of managed conections. The caller is
    responsible for deleting the Connect * BEFORE calling this member
    function.

    @return void 
    @param i The integer index of the object to remove from the
    array. 
*/
template <class T>
void
Connections<T>::del_connect(int i)
{
    _free.push_back(i);
    _conns[i] = NULL;
}

/** @brief How many elements remain?
    @returns The number of elements in the free list. */
template <class T>
int
Connections<T>::free_elements()
{
    return _free.size();
}

// $Log: Connections.cc,v $
// Revision 1.1  2008/07/25 20:43:24  jma
// Overhaul of code to be compatible with libdap 3.7.
// All references of "dods" changed to "dap" including the name of the library.
// Changed to GPL license. New configure scripts.
//
// Revision 1.2  2005/06/03 16:38:30  jimg
// Added instrumentation using to find bugs found while working on bug 773.
//
// Revision 1.1  2005/03/05 00:19:08  jimg
// Added
//
// Revision 1.25  2004/07/07 21:08:47  jimg
// Merged with release-3-4-8FCS
//
// Revision 1.22.2.2  2004/07/02 20:41:51  jimg
// Removed (commented) the pragma interface/implementation lines. See
// the ChangeLog for more details. This fixes a build problem on HP/UX.
//
// Revision 1.24  2004/02/19 19:42:52  jimg
// Merged with release-3-4-2FCS and resolved conflicts.
//
// Revision 1.22.2.1  2004/02/11 22:26:46  jimg
// Changed all calls to delete so that whenever we use 'delete x' or
// 'delete[] x' the code also sets 'x' to null. This ensures that if a
// pointer is deleted more than once (e.g., when an exception is thrown,
// the method that throws may clean up and then the catching method may
// also clean up) the second, ..., call to delete gets a null pointer
// instead of one that points to already deleted memory.
//
// Revision 1.23  2003/12/08 18:02:29  edavis
// Merge release-3-4 into trunk
//
// Revision 1.22  2003/04/22 19:40:27  jimg
// Merged with 3.3.1.
//
// Revision 1.21  2003/02/21 00:14:24  jimg
// Repaired copyright.
//
// Revision 1.20.2.1  2003/02/21 00:10:07  jimg
// Repaired copyright.
//
// Revision 1.20  2003/01/23 00:22:24  jimg
// Updated the copyright notice; this implementation of the DAP is
// copyrighted by OPeNDAP, Inc.
//
// Revision 1.19  2003/01/10 19:46:40  jimg
// Merged with code tagged release-3-2-10 on the release-3-2 branch. In many
// cases files were added on that branch (so they appear on the trunk for
// the first time).
//
// Revision 1.15.4.5  2002/09/13 16:08:10  jimg
// Fixed a problem with the Pix/IteratorAdapter code and pop_back(). IteratorAdapter
// uses vectpr<> and its pop_back does not return the value poped.
//
// Revision 1.15.4.4  2002/09/05 22:52:54  pwest
// Replaced the GNU data structures SLList and DLList with the STL container
// class vector<>. To maintain use of Pix, changed the Pix.h header file to
// redefine Pix to be an IteratorAdapter. Usage remains the same and all code
// outside of the DAP should compile and link with no problems. Added methods
// to the different classes where Pix is used to include methods to use STL
// iterators. Replaced the use of Pix within the DAP to use iterators instead.
// Updated comments for documentation, updated the test suites, and added some
// unit tests. Updated the Makefile to remove GNU/SLList and GNU/DLList.
//
// Revision 1.15.4.3  2002/08/08 06:54:56  jimg
// Changes for thread-safety. In many cases I found ugly places at the
// tops of files while looking for globals, et c., and I fixed them up
// (hopefully making them easier to read, ...). Only the files RCReader.cc
// and usage.cc actually use pthreads synchronization functions. In other
// cases I removed static objects where they were used for supposed
// improvements in efficiency which had never actually been verifiied (and
// which looked dubious).
//
// Revision 1.18  2002/06/18 15:36:24  tom
// Moved comments and edited to accommodate doxygen documentation-generator.
//
// Revision 1.17  2002/06/03 22:21:15  jimg
// Merged with release-3-2-9
//
// Revision 1.15.4.2  2001/12/26 05:54:27  rmorris
// Make code go through the VC++ compiler.  Trivial change.
//
// Revision 1.16  2001/08/24 17:46:22  jimg
// Resolved conflicts from the merge of release 3.2.6
//
// Revision 1.15.4.1  2001/07/28 01:10:42  jimg
// Some of the numeric type classes did not have copy ctors or operator=.
// I added those where they were needed.
// In every place where delete (or delete []) was called, I set the pointer
// just deleted to zero. Thus if for some reason delete is called again
// before new memory is allocated there won't be a mysterious crash. This is
// just good form when using delete.
// I added calls to www2id and id2www where appropriate. The DAP now handles
// making sure that names are escaped and unescaped as needed. Connect is
// set to handle CEs that contain names as they are in the dataset (see the
// comments/Log there). Servers should not handle escaping or unescaping
// characters on their own.
//
// Revision 1.15  2000/09/22 02:17:19  jimg
// Rearranged source files so that the CVS logs appear at the end rather than
// the start. Also made the ifdef guard symbols use the same naming scheme and
// wrapped headers included in other headers in those guard symbols (to cut
// down on extraneous file processing - See Lakos).
//
// Revision 1.14  2000/08/02 22:46:48  jimg
// Merged 3.1.8
//
// Revision 1.12.6.2  2000/08/02 20:58:26  jimg
// Included the header config_dap.h in this file. config_dap.h has been
// removed from all of the DAP header files.
//
// Revision 1.13  1999/09/03 22:07:44  jimg
// Merged changes from release-3-1-1
//
// Revision 1.12.6.1  1999/08/28 06:43:04  jimg
// Fixed the implementation/interface pragmas and misc comments
//
// Revision 1.12  1999/05/04 19:47:20  jimg
// Fixed copyright statements. Removed more of the GNU classes.
//
// Revision 1.11  1999/04/29 03:04:52  jimg
// Merged ferret changes
//
// Revision 1.10.6.1  1999/04/14 22:33:46  jimg
// Removed assert() in del_connect() method. It is OK for the _conns[i] to be
// NULL when this method is called.
//
// Revision 1.10  1999/03/18 01:05:58  jimg
// Removed the assertion that checked the _conns member when operator[] was
// used. This was failing when people called close API calls (e.g., nc_close())
// more than once for a single file descriptor.
//
// Revision 1.9  1996/09/19 16:16:09  jimg
// Added some comments. Removed config_dap.h.
//
// Revision 1.8  1996/06/08 00:19:44  jimg
// Added config_dap.h in place of config_netio.h
//
// Revision 1.7  1996/05/31 23:29:31  jimg
// Updated copyright notice.
//
// Revision 1.6  1996/05/22 18:05:06  jimg
// Merged files from the old netio directory into the dap directory.
// Removed the errmsg library from the software.
//
// Revision 1.5  1995/07/09 21:20:46  jimg
// Fixed date in copyright (it now reads `Copyright 1995 ...').
//
// Revision 1.4  1995/07/09  21:14:47  jimg
// Added copyright.
//
// Revision 1.3  1995/05/22  20:43:56  jimg
// Added #include "config_netio.h"
//
// Revision 1.2  1995/04/17  03:21:45  jimg
// Added debug.h and some debugging code.
//
// Revision 1.1  1995/01/10  16:23:05  jimg
// Created new `common code' library for the net I/O stuff.
//
// Revision 1.2  1994/11/18  21:12:19  reza
// Changed it to a template class for derived classes of the Connect
//
// Revision 1.1  1994/10/05  18:02:10  jimg
// First version of the connection management classes.
// This commit also includes early versions of the test code.
//

