/***************************************************************************
 * 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 "dde_atom.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "ldt.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(atom)

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;
  }

  TRACE("(\"%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;
  
  TRACE("(\"%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:
      WARN("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;

  TRACE("(%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;
  }
  TRACE("(\"%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) {
     WARN("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 */
