/*
** mg_vec_buf.c for  in 
** 
** Made by vianney rancurel
** Login   <vianney@epita.fr>
** 
** Started on  Wed Aug 25 16:25:59 1999 vianney rancurel
** Last update Thu Oct 28 20:15:29 1999 
*/
#include "mg.h"

/* adds a buffer to a vector of buffers.
   Note that it's a t_buf structure which is stored.
   Returns 0 if OK. Might return various errors */
int		vec_buf_add(vec,buf,len)
t_vec		*vec;
char		*buf;
int		len;
{
  t_buf		*b;
  t_status	status;

  if ((b = vec->alloc_proc(sizeof (t_buf),
			   vec->comment,
			   "vec_buf_add:b",
			   &status)) == NULL)
    return (status);
  if ((b->buf = vec->alloc_proc(len,
				vec->comment,
				"vec_buf_add:buf",
				&status)) == NULL)
    {
      vec->free_proc(b,
		     vec->comment,
		     "vec_buf_add:b");
      return (status);
    }
  bcopy(buf,b->buf,len);
  b->len = len;
  if ((status = vec_add(vec,b)) != 0)
    {
      vec->free_proc(b->buf,
		     vec->comment,
		     "vec_buf_add:buf");
      vec->free_proc(b,
		     vec->comment,
		     "vec_buf_add:b");
      return (status);
    }
  return (0);
}

/* transforms a vector of buffers to a string.
   If a buffer contains a zero it will affects the result (logical!).
   Returns a new string or NULL if there was a problem (status is then filled)
   */
char		*vec_buf_str(vec,status)
t_vec		*vec;
t_status	*status;	
{
  int		total_len;
  size_t	size;
  char		*str;
  int		offset;

  total_len = 0;
  VEC_FOR(vec,t_buf *b)
    {
      total_len += b->len;
    }
  VEC_ENDFOR;
  size = (total_len + 1) * sizeof (char);
  if ((str = vec->alloc_proc(size,
			     vec->comment,
			     "vec_buf_str:str",
			     status)) == NULL)
    return (NULL);
  offset = 0;
  VEC_FOR(vec,t_buf *b)
    {
      bcopy(b->buf,str + offset,b->len);
      offset += b->len;
    }
  VEC_ENDFOR;
  str[offset] = 0;
  return (str);
}

/* destroys all buffers contained in the vector but not the structure.
   The vector is then empty and reusable. */
VOID_FUNC	vec_buf_destroy(vec)
t_vec		*vec;
{
  VEC_FOR(vec,t_buf *b)
    {
      vec->free_proc(b->buf,
		     vec->comment,
		     "*:buf");
      vec->free_proc(b,
		     vec->comment,
		     "*:b");
    }
  VEC_ENDFOR;
  vec_destroy(vec);
}

/* destroys all buffers contained in the vector and the structure */
VOID_FUNC	vec_buf_delete(vec)
t_vec		*vec;
{
  vec_buf_destroy(vec);
  vec_delete(vec);
}	

#ifdef DEBUG
/* writes out all buffers to file descriptor 2.
   This is a debug function. */
VOID_FUNC	vec_buf_show(vec)
t_vec		*vec;
{
  VEC_FOR(vec,t_buf *b)
    {
      printf("%p %d\n",b->buf,b->len);
      write(2,b->buf,b->len);
    }
  VEC_ENDFOR;
}
#endif
