/**********************************************************************
 * ti library's routine for filling in string data for node
 *
 * $Author: brlewis $
 * $Source: /mit/techinfodev/src/libti/RCS/setdata.c,v $
 * $Header: /mit/techinfodev/src/libti/RCS/setdata.c,v 0.2 1995/04/10 20:21:57 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: /mit/techinfodev/src/libti/RCS/setdata.c,v 0.2 1995/04/10 20:21:57 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 *nd, char *str, int idx)
 *
 * - returns error code
 **********************************************************************/

long
ti_setdata(nd, str, idx)
     ti_node *nd;
     char *str;
     int idx;
{
  int nchars, nmove=0, i, len, newstrlen, oldstrlen;
  char *toreplace;

  /* initialize nd_data if not yet allocated */
  if (!nd->nd_data)
    {
      if (!(nd->nd_data = NewArray(char, TI_OFFSETS+1)))
	{
	  *ti_context = '\0';
	  return((long) ENOMEM);
	}
      memset(nd->nd_data, 0, TI_OFFSETS+1);
      for (i=0; i<TI_OFFSETS; i++) nd->nd_off[i] = (u_char) (i+1);
    }

  /* initialize variables */
  if (idx == -1) toreplace = nd->nd_data;
  else toreplace = &(nd)->nd_data[(int)(nd)->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(nd->nd_data)+1;
  for (i=0; i<TI_OFFSETS; i++)
    {
      if (idx == i) nchars += newstrlen;
      else
	{
	  nchars += (len=strlen(&(nd)->nd_data[(int)(nd)->nd_off[i]])+1);
	  if (idx < i) nmove += len;
	}
      if (i == (TI_OFFSETS - 2) && nchars > 255)
	{
	  strncpy(ti_context, (&(nd)->nd_data[(int)(nd)->nd_off[i]]), 127);
	  return(TI_ERR_TOOMUCH);
	}
    }

  /* allocate more memory if necessary */
  if (newstrlen > oldstrlen)
    {
      TI_MEM(nd->nd_data = BiggerArray(char, nd->nd_data, nchars));
      /* since nd_data has been moved, toreplace must be recalculated */
      if (idx == -1) toreplace = nd->nd_data;
      else toreplace = &(nd)->nd_data[(int)(nd)->nd_off[idx]];
    }

  /* move old stuff if necessary */
  if (idx != TI_OFFSETS - 1)
    {
      memcpy(toreplace+newstrlen, toreplace+oldstrlen, nmove);
      for(i=idx+1; i< TI_OFFSETS; i++)
	  nd->nd_off[i] += newstrlen - oldstrlen;
    }

  /* copy the new stuff */
  memcpy(toreplace, str, newstrlen);
  return(0L);
}
