/* Copyright (C) 1996-2018 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, see
   <http://www.gnu.org/licenses/>.  */

#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 (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;

  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)
