/*
 *  DLC - Utility for dynamic loading of classes
 *  Copyright (C) 1999 Martin Reinecke
 *
 *  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.
 *
 *  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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  See the README file for more information.
 */

#include <dlfcn.h>

#include "dlc_server.h"
#include "dlc_maker_base.h"

//explicit
DLC_MAKER_BASE::DLC_MAKER_BASE (string Id)
  : Identity (Id)
  { DLC_Server.enter (Identity, this); }

DLC_MAKER_BASE::~DLC_MAKER_BASE ()
  { DLC_Server.remove (Identity); }


DLC_SERVER::~DLC_SERVER ()
  {
  for (DLLMap::iterator iter = DLLs.begin(); iter != DLLs.end(); iter++)
    {
    dlclose (iter->second);
    }
  }

bool DLC_SERVER::load (const string &name)
  {
  if (DLLs.find (name) != DLLs.end())
    {
    cout << "DLC_Server::load: library " << name
         << " already registered." << endl;
    return false;
    }
  void *tmp = dlopen (name.c_str(), RTLD_NOW);
  if (!tmp)
    {
    cout << "DLC_Server::load: library  " << name
         << " found, but could not open" << endl;
    return false;
    }
  DLLs[name] = tmp;
  return true;
  }

void DLC_SERVER::unload (const string &name)
  {
  DLLMap::iterator iter = DLLs.find (name);
  if (iter == DLLs.end())
    {
    cout << "DLC_Server::unload: library " << name
         << " not registered." << endl;
    return;
    }
  dlclose (iter->second);
  DLLs.erase(iter);
  }

DLC_BASE *DLC_SERVER::Get_Instance (const string &name)
  {
  ClassMap::const_iterator iter = Classes.find (name);
  if (iter == Classes.end()) return 0;
  return (iter->second)->Create();
  }

void DLC_SERVER::enter (const string &Id, const DLC_MAKER_BASE *const ptr)
  {
  if (Classes.find (Id) != Classes.end())
    {
    cout << "DLC_Server::enter: class "
         << Id << " already registered." << endl;
    return;
    }
  Classes[Id] = ptr;
  }

void DLC_SERVER::remove (const string &Id)
  {
  ClassMap::iterator iter = Classes.find (Id);
  if (iter == Classes.end())
    {
    cout << "DLC_Server::remove: class "
         << Id << "  not registered." << endl;
    return;
    }
  Classes.erase (iter);
  }

DLC_SERVER DLC_Server;
