/**
 * 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.
 */
#include "mb_wc_common.h"
#include <wchar.h>
#include <stdlib.h>
#include <errno.h>
#define WIN32_LEAN_AND_MEAN
#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_cp_from_locale(), 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_cp_from_locale();;
  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_cp_from_locale(), MB_CUR_MAX);
}
