/***************************************************************************
 * 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 (lstrcmpi16( 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 (lstrcmpi16( 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 */
