/**********************************************************************
 * ti library's routine for filling in string data for node
 *
 * $Author: brlewis $
 * $Source: /afs/net.mit.edu/project/net_dev/brlewis/src/lib/RCS/ti_setdata.c,v $
 * $Header: /afs/net.mit.edu/project/net_dev/brlewis/src/lib/RCS/ti_setdata.c,v 0.1 92/03/12 15:27:55 brlewis Exp $
 *
 * Copyright 1991 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 **********************************************************************/

#include <mit-copyright.h>

#ifndef lint
static char rcsid_ti_setdata_c[] = "$Header: /afs/net.mit.edu/project/net_dev/brlewis/src/lib/RCS/ti_setdata.c,v 0.1 92/03/12 15:27:55 brlewis Exp $";
#endif /* lint */

#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <ti/memory.h>
#include <ti/ti.h>

/**********************************************************************
 * ti_setdata(ti_node_H hnode, LPSTR str, int idx)
 *
 * - returns error code
 **********************************************************************/

/* jms 7/13/92 -- windows-izing begun */

/* !!! lots of work. */

long
ti_setdata(hnode, str, idx)
     ti_node_H hnode;
     LPSTR str;
     int idx;
{
  int nchars, nmove=0, i, len, newstrlen, oldstrlen;
  ti_node_LP lpnode = NULL;
  char *toreplace;

  lpnode = (ti_node_LP)TI_DEREFERENCE(hnode);

  /* initialize nd_data if not yet allocated */
  if (!lpnode->nd_data)
    {
      if (!(lpnode->nd_data = NewArray(char, TI_OFFSETS+1)))
	{
	  *ti_context = '\0';
	  CLEANUP_AND_RETURN((long) ENOMEM)
	}
      bzero(lpnode->nd_data, TI_OFFSETS+1);
      for (i=0; i<TI_OFFSETS; i++) lpnode->nd_off[i] = (u_char) (i+1);
    }

  /* initialize variables */
  if (idx == -1) toreplace = lpnode->nd_data;
  else toreplace = &(lpnode)->nd_data[(int)(lpnode)->nd_off[idx]];
  oldstrlen = strlen(toreplace)+1;
  newstrlen = strlen(str)+1;

  /* make sure there's not too much data to do u_char offsets */
  if (idx == -1) nchars = newstrlen;
  else nchars = strlen(lpnode->nd_data)+1;
  for (i=0; i<TI_OFFSETS; i++)
    {
      if (idx == i) nchars += newstrlen;
      else
	{
	  nchars += (len=strlen(&(lpnode)->nd_data[(int)(lpnode)->nd_off[i]])+1);
	  if (idx < i) nmove += len;
	}
      if (i == (TI_OFFSETS - 2) && nchars > 255)
	{
	  strncpy(ti_context, (&(lpnode)->nd_data[(int)(lpnode)->nd_off[i]]), 127);
	  CLEANUP_AND_RETURN(TI_ERR_TOOMUCH)
	}
    }

  /* allocate more memory if necessary */
  if (newstrlen > oldstrlen)
    {
      TI_MEM(lpnode->nd_data = BiggerArray(char, lpnode->nd_data, nchars));
      /* since nd_data has been moved, toreplace must be recalculated */
      if (idx == -1) toreplace = lpnode->nd_data;
      else toreplace = &(lpnode)->nd_data[(int)(lpnode)->nd_off[idx]];
    }

  /* move old stuff if necessary */
  if (idx != TI_OFFSETS - 1)
    {
      bcopy(toreplace+oldstrlen, toreplace+newstrlen, nmove);
      for(i=idx+1; i< TI_OFFSETS; i++)
	  lpnode->nd_off[i] += newstrlen - oldstrlen;
    }

  /* copy the new stuff */
  bcopy(str, toreplace, newstrlen);
  CLEANUP_AND_RETURN(0L)

CLEANUP:
  TI_REMOVE_DEREFERENCE(hnode, lpnode);
  return (code);
}

