/* Copyright (C) 1996-2000, 2002, 2003, 2005 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@gnu.org>, 1996.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <assert.h>
#include <dlfcn.h>
#include <errno.h>
#include <gconv.h>
#include <wchar.h>
#include <wcsmbsload.h>

#include <sysdep.h>

#ifndef EILSEQ
# define EILSEQ EINVAL
#endif


/* This is the private state used if PS is NULL.  */
static mbstate_t state;

/* This is a non-standard function but it is very useful in the
   implementation of stdio because we have to deal with unterminated
   buffers.  At most NWC wide character will be converted.  */
size_t
__wcsnrtombs (dst, src, nwc, len, ps)
     char *dst;
     const wchar_t **src;
     size_t nwc;
     size_t len;
     mbstate_t *ps;
{
  struct __gconv_step_data data;
  const wchar_t *srcend;
  int status;
  size_t result;
  struct __gconv_step *tomb;
  const struct gconv_fcts *fcts;

  /* Tell where we want the result.  */
  data.__invocation_counter = 0;
  data.__internal_use = 1;
  data.__flags = __GCONV_IS_LAST;
  data.__statep = ps ?: &state;
  data.__trans = NULL;

  if (nwc == 0)
    return 0;
  srcend = *src + __wcsnlen (*src, nwc - 1) + 1;

  /* Get the conversion functions.  */
  fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));

  /* Get the structure with the function pointers.  */
  tomb = fcts->tomb;
  __gconv_fct fct = tomb->__fct;
#ifdef PTR_DEMANGLE
  if (tomb->__shlib_handle != NULL)
    PTR_DEMANGLE (fct);
#endif

  /* We have to handle DST == NULL special.  */
  if (dst == NULL)
    {
      mbstate_t temp_state;
      unsigned char buf[256];		/* Just an arbitrary value.  */
      const unsigned char *inbuf = (const unsigned char *) *src;
      size_t dummy;

      temp_state = *data.__statep;
      data.__statep = &temp_state;

      result = 0;
      data.__outbufend = buf + sizeof (buf);

      do
	{
	  data.__outbuf = buf;

	  status = DL_CALL_FCT (fct, (tomb, &data, &inbuf,
				      (const unsigned char *) srcend, NULL,
				      &dummy, 0, 1));

	  /* Count the number of bytes.  */
	  result += data.__outbuf - buf;
	}
      while (status == __GCONV_FULL_OUTPUT);

      if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT)
	  && data.__outbuf[-1] == '\0')
	/* Don't count the NUL character in.  */
	--result;
    }
  else
    {
      /* This code is based on the safe assumption that all internal
	 multi-byte encodings use the NUL byte only to mark the end
	 of the string.  */
      size_t dummy;

      data.__outbuf = (unsigned char *) dst;
      data.__outbufend = (unsigned char *) dst + len;

      status = DL_CALL_FCT (fct, (tomb, &data, (const unsigned char **) src,
				  (const unsigned char *) srcend, NULL,
				  &dummy, 0, 1));

      /* Count the number of bytes.  */
      result = data.__outbuf - (unsigned char *) dst;

      /* We have to determine whether the last character converted
	 is the NUL character.  */
      if ((status == __GCONV_OK || status == __GCONV_EMPTY_INPUT)
	  && data.__outbuf[-1] == '\0')
	{
	  assert (data.__outbuf != (unsigned char *) dst);
	  assert (__mbsinit (data.__statep));
	  *src = NULL;
	  --result;
	}
    }

  /* There must not be any problems with the conversion but illegal input
     characters.  */
  assert (status == __GCONV_OK || status == __GCONV_EMPTY_INPUT
	  || status == __GCONV_ILLEGAL_INPUT
	  || status == __GCONV_INCOMPLETE_INPUT
	  || status == __GCONV_FULL_OUTPUT);

  if (status != __GCONV_OK && status != __GCONV_FULL_OUTPUT
      && status != __GCONV_EMPTY_INPUT)
    {
      result = (size_t) -1;
      __set_errno (EILSEQ);
    }

  return result;
}
weak_alias (__wcsnrtombs, wcsnrtombs)
