/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* This file is distributed subject to a Software License Agreement found
* in the file LICENSE that is included with this distribution. 
\*************************************************************************/

/*
 * $Log: not supported by cvs2svn $
 * Revision 1.3  2001/01/16 22:33:26  soliday
 * BLT is no longer required to build this extension.
 *
 * Revision 1.2  2001/01/15 22:16:59  soliday
 * Merged some of the changes from caTCL.
 *
 * Revision 1.1  1999/06/10 19:36:05  soliday
 * Moved to oag tree.
 *
 * Revision 1.2  1999/06/08 20:00:47  soliday
 * Removed compiler warnings under Linux.
 *
 * Revision 1.1.1.1  1996/05/07 19:08:38  saunders
 * Imported Files
 *
 *
 *-------------------------------------------------------------------
 * The following is the revision history while in OAG CVS Repository
 *-------------------------------------------------------------------
 * Revision 1.6  1996/04/22  15:58:01  saunders
 * 1. Fixed bug in "pv stat" which causes core dump when unlinked or
 *    partially linked tcl var is given.
 *
 * Revision 1.5  1996/04/19 20:10:00  saunders
 * 1. Added "pv unlink" command.
 * 2. Repaired a number of bugs in existing link command. Now permits
 *    multiple linkw on same pv, and behaves better if IOC goes down/up.
 * 3. Changed link command so that ca flushes are done in groups, not
 *    on a channel by channel basis. The only loss is in the specificity
 *    of the error messages when a connect fails.
 * 4. Tcl var is now initialized with pv value upon completion of the link.
 * 5. Removed length limitation on tcl var names supplied to pv commands.
 * 6. Removed repeated free/malloc's when DBR_STRING and DBR_ENUM gets
 *    are performed.
 *
 * Revision 1.4  1996/04/18 20:32:15  saunders
 * 1. Add drvh/drvl options to "pv info" command.
 * 2. Change tclCaHash.c to use Tcl supplied hash table library.
 * 3. Removed more unneeded indirection and variables in structs.
 *
 * Revision 1.3  1996/04/16 14:54:00  saunders
 * 1. Removed unneeded indirection in pv_exists() function.
 * 2. Removed unused vars in chandata struct.
 * 3. Removed doubleValue() function, replacing with copyCaTypeToTclType().
 *    Collapsed redundant code around doubleValue() function.
 * 4. Renamed eventCount to secondMonEvent, and fixed usage of it.
 * 5. Changed updateInterpVar technique, yielding 25% performance improvement,
 *    and less memory fragmentation.
 *
 * Revision 1.2  1996/04/11 19:18:33  saunders
 * 1. Periodic pend_io time from .001 to 1e-9, resulting in poll.
 * 2. Use search_and_connect, not build_and_connect ca call.
 * 3. Removed ca_pend_io calls at end of async functions.
 * 4. Remove redundant call to ca_change_connection_event in updateChCtrl.
 * 5. Removed switch statement from howManyBytes (should be macro).
 * 6. Changed byte-by-byte copies to use memcpy instead.
 * 7. Removed some mixed use of ca_field_type() and iType.
 * 8. Removed redundant clause in if-then-else.
 * 9. Removed hardcoded pend_io timeouts. Use #define now.
 * 10. Removed unused calls to system time().
 * 11. Uppercased and lowercased stuff to follow conventions.
 *
 * Revision 1.1  1996/04/04 23:16:25  saunders
 * Renamed library files, ANSI-fied and reformatted code. Renamed external
 * function names to begin with tclCa library name.
 * */

#include <tclCa.h>
#include <stdlib.h>

static Tcl_HashTable tclCaLinkHash;

void pv_hash_init() {
  Tcl_InitHashTable(&tclCaLinkHash, TCL_STRING_KEYS);
}

/****************************************************************
 * find 's' in the hash table, if not found allocate space for it 
****************************************************************/
ITEM *pv_search(char *s) {
  CHANDATA *pchandata;
  ITEM *try;
  int newEntry;
  Tcl_HashEntry *entryPtr;

  entryPtr = Tcl_CreateHashEntry(&tclCaLinkHash, s, &newEntry);

  if (newEntry) {
    try = (ITEM *)calloc(1,sizeof(ITEM));
    if (try == NULL)
      return NULL;
    pchandata = (CHANDATA *)calloc(1,sizeof(CHANDATA));
    if (pchandata == NULL) {
      free(try);
      return NULL;
    }
    try->tclname = (char *)malloc(strlen(s)+1);
#if defined(USE_BLT)
    try->vecname = NULL;
#endif
    pchandata->castate = NewConnection;
    try->pchandata = pchandata;
    strcpy(try->tclname,s);
    Tcl_SetHashValue(entryPtr, try);
    return try;

  } else {
    try = (ITEM *)Tcl_GetHashValue(entryPtr);
    return try;
  }
}

/****************************************************************
 * find 's' in the hash table
****************************************************************/
ITEM *pv_exists(char *s) {
  ITEM *try;
  Tcl_HashEntry *entryPtr;
  
  entryPtr = Tcl_FindHashEntry(&tclCaLinkHash, s);
  if (entryPtr == NULL) {
    return NULL;
  } else {
    try = (ITEM *)Tcl_GetHashValue(entryPtr);
    return try;
  }
}

void pv_delete(char *s) {
  Tcl_HashEntry *entryPtr;

  entryPtr = Tcl_FindHashEntry(&tclCaLinkHash, s);
  if (entryPtr == NULL) {
    return;
  } else {
    Tcl_DeleteHashEntry(entryPtr);
    return;
  }
}


