/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the w64 mingw-runtime package.
 * No warranty is given; refer to the file DISCLAIMER within this package.
 */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "mb_wc_common.h"
#include <wchar.h>
#include <stdlib.h>
#include <errno.h>
#include <windows.h>

static int 
__mbrtowc_cp (wchar_t * __restrict__ pwc, const char * __restrict__ s,
	      size_t n, mbstate_t* __restrict__ ps,
	      const unsigned int cp, const unsigned int mb_max) 
{
  union {
    mbstate_t val;
    char mbcs[4];
  }  shift_state;


  /* Do the prelim checks */
  if (s == NULL)
    return 0;

  if (n == 0)
    /* The standard doesn't mention this case explicitly. Tell
       caller that the conversion from a non-null s is incomplete. */
    return -2;

  /* Save the current shift state, in case we need it in DBCS case.  */
  shift_state.val = *ps;
  *ps = 0;

  if (!*s)
    {
      *pwc = 0;
      return 0;
    }
 
  if (mb_max > 1)
    {
      if (shift_state.mbcs[0] != 0)
	{
	  /* Complete the mb char with the trailing byte.  */
          shift_state.mbcs[1] = *s;  /* the second byte */
          if (MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS,
				  shift_state.mbcs, 2, pwc, 1)
		 == 0)
	    {
	      /* An invalid trailing byte */	 
	      errno = EILSEQ;
	      return -1;
	    }
          return 2;
        }
      else if (IsDBCSLeadByteEx (cp, *s))
        {
          /* If told to translate one byte, just save the leadbyte
             in *ps.  */
	  if (n < 2)
	    {
	      ((char*) ps)[0] = *s; 
	      return -2;
	    }
          /* Else translate the first two bytes  */  
          else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS,
					s, 2, pwc, 1)
		    == 0)
	    {
	      errno = EILSEQ;
	      return -1;
	    }
          return 2;
        }
    }

  /* Fall through to single byte char  */ 
  if (cp == 0)
      *pwc = (wchar_t)(unsigned char)*s;
 
  else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, s, 1, pwc, 1)
	    == 0)
    {
      errno = EILSEQ;
      return  -1;
    }
  return 1;
}

size_t
mbrtowc (wchar_t * __restrict__ pwc, const char * __restrict__ s,
	 size_t n, mbstate_t* __restrict__ ps)
{
  static mbstate_t internal_mbstate = 0;
  wchar_t  byte_bucket = 0;
  wchar_t* dst = pwc ? pwc : &byte_bucket;

  return (size_t) __mbrtowc_cp (dst, s, n, ps ? ps : &internal_mbstate,
				get_codepage(), MB_CUR_MAX);
}


size_t
mbsrtowcs (wchar_t* __restrict__ dst,  const char ** __restrict__ src,
	   size_t len, mbstate_t* __restrict__ ps)
{
  int ret =0 ;
  size_t n = 0;
  static mbstate_t internal_mbstate = 0;
  mbstate_t* internal_ps = ps ? ps : &internal_mbstate;
  const unsigned int cp = get_codepage();
  const unsigned int mb_max = MB_CUR_MAX;

  if ( src == NULL || *src == NULL )	/* undefined behavior */
    return 0;

  if (dst != NULL)
    {
      while (n < len
	     && (ret = __mbrtowc_cp(dst, *src, len - n,
				    internal_ps, cp, mb_max))
		  > 0)
	{
	  ++dst;
   	  *src += ret;
          n += ret;
        }

      if (n < len && ret == 0)
        *src = (char *)NULL;
    }
  
  else
    {
      wchar_t byte_bucket = 0;
      while (n < len
	     && (ret = __mbrtowc_cp (&byte_bucket, *src, mb_max,
				     internal_ps, cp, mb_max))
		  > 0)
	{
          *src += ret;
          n += ret;
        }
    }
  return n;
}

size_t
mbrlen (const char * __restrict__ s, size_t n,
	mbstate_t * __restrict__ ps)
{
  static mbstate_t s_mbstate = 0;
  wchar_t byte_bucket = 0;
  return __mbrtowc_cp (&byte_bucket, s, n, (ps) ? ps : &s_mbstate,
		       get_codepage(), MB_CUR_MAX);
}
