/***************************************************************************
 * Copyright 1995, Technion, Israel Institute of Technology
 * Electrical Eng, Software Lab.
 * Author:    Michael Veksler.
 ***************************************************************************
 * File:      dde_atom.c
 * Purpose :  atom functionality for DDE
 */
#ifdef CONFIG_IPC

#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "dde_atom.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "ldt.h"
#include "stddebug.h"
#include "debug.h"

typedef struct
{
	WORD        count;
	BYTE        str[1];
} AtomData, *AtomData_ptr;

#define EMPTY   0		   /* empty hash entry */
#define DELETED -1		   /* deleted hash entry */
#define MIN_STR_ATOM 0xfc00

/* OFS2AtomData_ptr: extract AtomData_ptr from ofs */
#define OFS2AtomData_ptr(ofs) ((AtomData*)((int)&main_block->block+(ofs)))

/* OFS2AtomStr: find the string of the atom */
#define OFS2AtomStr(ofs)      (OFS2AtomData_ptr(atom_ofs)->str)

/* offset of an atom according to index */
#define ATOM_OFS(idx) (main_block->atoms[idx])

/* rot_left: rotate (with wrap-around) */
static __inline__ int rot_left(unsigned var,int count)
{
  return (var<<count) | (var>> (sizeof(var)-count));
}
/* find the entry in the atom table for this string */
static int FindHash(LPCSTR str)	   /* ignore str case */
{
  int i,j;
  unsigned hash1,hash2;
  int deleted=-1;		   /* hash for deleted entry */
  int atom_ofs;

  /* get basic hash parameters */
  for (i= hash1= hash2= 0; str[i] ; i++) {
     hash1= rot_left(hash1,5) ^ toupper(str[i]);
     hash2= rot_left(hash2,4) ^ toupper(str[i]);
  }

  hash1%= DDE_ATOMS;
  atom_ofs=ATOM_OFS(hash1);
  switch (atom_ofs) {
    case EMPTY:			   /* empty atom entry */
      return hash1;		   
    case DELETED:		   /* deleted atom entry */
      deleted=hash1;
      break;
    default :			   /* non empty atom entry */
      if (  strcasecmp( OFS2AtomStr(atom_ofs) , str) == 0)
	 return hash1;		   /* found string in atom table */
  }
  hash2%= DDE_ATOMS-1 ;		   /* hash2=0..(DDE_ATOMS-2) */
  hash2++;			   /* hash2=1..(DDE_ATOMS-1) */

  /* make jumps in the hash table by hash2 steps */
  for (i=hash1+hash2 ; ; i+=hash2) {
     /* i wraps around into j */
     j=i-DDE_ATOMS;
     if (j >= 0)
	i=j;			   /* i wraps around */
     
     if (i==hash1) 
	/* here if covered all hash locations, and got back to beginning */
	return deleted;		   /* return first empty entry - if any */
     atom_ofs=ATOM_OFS(i);
     switch (atom_ofs) {
       case EMPTY:		   /* empty atom entry */
	 return i;		   
       case DELETED:		   /* deleted atom entry */
	 if (deleted < 0)
	    /* consider only the first deleted entry */
	    deleted= i;
	 break;
       default :		   /* nonempty atom entry */
	 if (  strcasecmp( OFS2AtomStr(atom_ofs) , str) == 0)
	    return i;	   /* found string in atom table */
     }
  }
}

void ATOM_GlobalInit(void)
{
  int i;
  
  for (i=0 ; i < DDE_ATOMS ; i++)
     ATOM_OFS(i)=EMPTY;
}

/***********************************************************************
 *           DDE_GlobalAddAtom
 */

/* important! don't forget to unlock semaphores before return */
ATOM DDE_GlobalAddAtom( SEGPTR name )
{
  int atom_idx;
  int atom_ofs;
  AtomData_ptr ptr;
  ATOM atom;
  char *str;

  /* First check for integer atom */

  if (!HIWORD(name)) return (ATOM)LOWORD(name);

  str = (char *)PTR_SEG_TO_LIN( name );
  if (str[0] == '#')
  {
     ATOM atom= (ATOM) atoi(&str[1]);
     return (atom<MIN_STR_ATOM) ? atom : 0;
  }

  dprintf_atom(stddeb,"GlobalAddAtom(\"%s\")\n",str);

  DDE_IPC_init();		/* will initialize only if needed */
  
  shm_write_wait(main_block->sem);

  atom_idx=FindHash(str);
  atom=(ATOM)0;

  /* use "return" only at the end so semaphore handling is done only once */
  if (atom_idx>=0) {
     /* unless table full and item not found */
     switch (atom_ofs= ATOM_OFS(atom_idx)) {
       case DELETED:
       case EMPTY:		   /* need to allocate new atom */
	 atom_ofs= shm_FragmentAlloc(&main_block->block,
				     strlen(str)+sizeof(AtomData));
	 if (atom_ofs==NIL)
	    break;		   /* no more memory (atom==0) */
	 ATOM_OFS(atom_idx)=atom_ofs;
	 ptr=OFS2AtomData_ptr(atom_ofs);
	 strcpy(ptr->str,str);
	 ptr->count=1;
	 atom=(ATOM)(atom_idx+MIN_STR_ATOM);
	 break;
       default :		   /* has to update existing atom */
	 OFS2AtomData_ptr(atom_ofs)->count++;
	 atom=(ATOM)(atom_idx+MIN_STR_ATOM);
     } /* end of switch */
  } /* end of if */
  shm_write_signal(main_block->sem);
  return atom;
}

/***********************************************************************
 *           DDE_GlobalDeleteAtom
 */

ATOM DDE_GlobalDeleteAtom( ATOM atom )
{
  int atom_idx;
  int atom_ofs;
  AtomData_ptr atom_ptr;
  ATOM retval=(ATOM) 0;
  
  dprintf_atom(stddeb,"GlobalDeleteAtom(\"%d\")\n",(int)atom);
  atom_idx=(int)atom - MIN_STR_ATOM;
  
  if (atom_idx < 0 )
     return 0;

  DDE_IPC_init();	   /* will initialize only if needed */

  shm_write_wait(main_block->sem);
  /* return used only once from here on -- for semaphore simplicity */
  switch (atom_ofs=ATOM_OFS(atom_idx)) {
    case DELETED:
    case EMPTY:
      fprintf(stderr,"trying to free unallocated atom %d\n", atom);
      retval=atom;
      break;
    default :
      atom_ptr=OFS2AtomData_ptr(atom_ofs);
      if ( --atom_ptr->count == 0) {
	 shm_FragmentFree(&main_block->block,atom_ofs);
	 ATOM_OFS(atom_idx)=DELETED;
      }
  }
  
  shm_write_signal(main_block->sem);
  return retval;
}

/***********************************************************************
 *           DDE_GlobalFindAtom
 */
ATOM DDE_GlobalFindAtom( SEGPTR name )
{
  int atom_idx;
  int atom_ofs;
  char *str;

  dprintf_atom(stddeb,"GlobalFindAtom(%08lx)\n", name );

  /* First check for integer atom */

  if (!HIWORD(name)) return (ATOM)LOWORD(name);

  str = (char *)PTR_SEG_TO_LIN( name );
  if (str[0] == '#')
  {
     ATOM atom= (ATOM) atoi(&str[1]);
     return (atom<MIN_STR_ATOM) ? atom : 0;
  }
  dprintf_atom(stddeb,"GlobalFindAtom(\"%s\")\n",str);

  DDE_IPC_init();		/* will initialize only if needed */

  shm_read_wait(main_block->sem);
  atom_idx=FindHash(str);
  if (atom_idx>=0)		   
     atom_ofs=ATOM_OFS(atom_idx);  /* is it free ? */
  else
     atom_ofs=EMPTY;
  shm_read_signal(main_block->sem);

  if (atom_ofs==EMPTY || atom_ofs==DELETED)
     return 0;
  else
     return (ATOM)(atom_idx+MIN_STR_ATOM);
}

/***********************************************************************
 *           DDE_GlobalGetAtomName
 */
WORD DDE_GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
{
  int atom_idx, atom_ofs;
  int size;
  /* temporary buffer to hold maximum "#65535\0" */
  char str_num[7];
  
  if (count<2)			   /* no sense to go on */
     return 0;
  atom_idx=(int)atom - MIN_STR_ATOM;
  
  if (atom_idx < 0) {		   /* word atom */
     /* use wine convention... */
     sprintf(str_num,"#%d%n",(int)atom,&size);
     if (size+1>count) {	   /* overflow ? */
	/* truncate the string */
	size=count-1;
	str_num[size]='\0';
     }
     strcpy(buffer,str_num);
     return size;
  }

  DDE_IPC_init();		/* will initialize only if needed */

  /* string atom */
  shm_read_wait(main_block->sem);
  atom_ofs=ATOM_OFS(atom_idx);
  if (atom_ofs==EMPTY || atom_ofs==DELETED) {
     fprintf(stderr,"GlobalGetAtomName: illegal atom=%d\n",(int)atom);
     size=0;
  } else {			   /* non empty entry */
     /* string length will be at most count-1, find actual size */
     sprintf(buffer,"%.*s%n",count-1, OFS2AtomStr(atom_ofs), &size);
  }
  shm_read_signal(main_block->sem);
  return size;
}

#endif  /* CONFIG_IPC */
