/* Conversion module for UTF-32.
   Copyright (C) 1999-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   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 <byteswap.h>
#include <dlfcn.h>
#include <gconv.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

/* This is the Byte Order Mark character (BOM).  */
#define BOM	0x0000feffu
/* And in the other byte order.  */
#define BOM_OE	0xfffe0000u


/* Definitions used in the body of the `gconv' function.  */
#define FROM_LOOP		from_utf32_loop
#define TO_LOOP			to_utf32_loop
#define DEFINE_INIT		0
#define DEFINE_FINI		0
#define MIN_NEEDED_FROM		4
#define MIN_NEEDED_TO		4
#define FROM_DIRECTION		(dir == from_utf32)
#define PREPARE_LOOP \
  enum direction dir = ((struct utf32_data *) step->__data)->dir;	      \
  enum variant var = ((struct utf32_data *) step->__data)->var;		      \
  int swap;								      \
  if (FROM_DIRECTION && var == UTF_32)					      \
    {									      \
      if (__builtin_expect (data->__invocation_counter == 0, 0))	      \
	{								      \
	  /* We have to find out which byte order the file is encoded in.  */ \
	  if (inptr + 4 > inend)					      \
	    return (inptr == inend					      \
		    ? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT);	      \
									      \
	  if (get32u (inptr) == BOM)					      \
	    /* Simply ignore the BOM character.  */			      \
	    *inptrp = inptr += 4;					      \
	  else if (get32u (inptr) == BOM_OE)				      \
	    {								      \
	      data->__flags |= __GCONV_SWAP;				      \
	      *inptrp = inptr += 4;					      \
	    }								      \
	}								      \
    }									      \
  else if (!FROM_DIRECTION && var == UTF_32 && !data->__internal_use	      \
	   && data->__invocation_counter == 0)				      \
    {									      \
      /* Emit the Byte Order Mark.  */					      \
      if (__builtin_expect (outbuf + 4 > outend, 0))			      \
	return __GCONV_FULL_OUTPUT;					      \
									      \
      put32u (outbuf, BOM);						      \
      outbuf += 4;							      \
    }									      \
  else if (__builtin_expect (data->__invocation_counter == 0, 0)	      \
	   && ((var == UTF_32LE && BYTE_ORDER == BIG_ENDIAN)		      \
	       || (var == UTF_32BE && BYTE_ORDER == LITTLE_ENDIAN)))	      \
    data->__flags |= __GCONV_SWAP;					      \
  swap = data->__flags & __GCONV_SWAP;
#define EXTRA_LOOP_ARGS		, var, swap


/* Direction of the transformation.  */
enum direction
{
  illegal_dir,
  to_utf32,
  from_utf32
};

enum variant
{
  illegal_var,
  UTF_32,
  UTF_32LE,
  UTF_32BE
};

struct utf32_data
{
  enum direction dir;
  enum variant var;
};


extern int gconv_init (struct __gconv_step *step);
int
gconv_init (struct __gconv_step *step)
{
  /* Determine which direction.  */
  struct utf32_data *new_data;
  enum direction dir = illegal_dir;
  enum variant var = illegal_var;
  int result;

  if (__strcasecmp (step->__from_name, "UTF-32//") == 0)
    {
      dir = from_utf32;
      var = UTF_32;
    }
  else if (__strcasecmp (step->__to_name, "UTF-32//") == 0)
    {
      dir = to_utf32;
      var = UTF_32;
    }
  else if (__strcasecmp (step->__from_name, "UTF-32BE//") == 0)
    {
      dir = from_utf32;
      var = UTF_32BE;
    }
  else if (__strcasecmp (step->__to_name, "UTF-32BE//") == 0)
    {
      dir = to_utf32;
      var = UTF_32BE;
    }
  else if (__strcasecmp (step->__from_name, "UTF-32LE//") == 0)
    {
      dir = from_utf32;
      var = UTF_32LE;
    }
  else if (__strcasecmp (step->__to_name, "UTF-32LE//") == 0)
    {
      dir = to_utf32;
      var = UTF_32LE;
    }

  result = __GCONV_NOCONV;
  if (__builtin_expect (dir, to_utf32) != illegal_dir)
    {
      new_data = (struct utf32_data *) malloc (sizeof (struct utf32_data));

      result = __GCONV_NOMEM;
      if (new_data != NULL)
	{
	  new_data->dir = dir;
	  new_data->var = var;
	  step->__data = new_data;

	  if (dir == from_utf32)
	    {
	      step->__min_needed_from = MIN_NEEDED_FROM;
	      step->__max_needed_from = MIN_NEEDED_FROM;
	      step->__min_needed_to = MIN_NEEDED_TO;
	      step->__max_needed_to = MIN_NEEDED_TO;
	    }
	  else
	    {
	      step->__min_needed_from = MIN_NEEDED_TO;
	      step->__max_needed_from = MIN_NEEDED_TO;
	      step->__min_needed_to = MIN_NEEDED_FROM;
	      step->__max_needed_to = MIN_NEEDED_FROM;
	    }

	  step->__stateful = 0;

	  result = __GCONV_OK;
	}
    }

  return result;
}


extern void gconv_end (struct __gconv_step *data);
void
gconv_end (struct __gconv_step *data)
{
  free (data->__data);
}


/* Convert from the internal (UCS4-like) format to UTF-32.  */
#define MIN_NEEDED_INPUT	MIN_NEEDED_TO
#define MIN_NEEDED_OUTPUT	MIN_NEEDED_FROM
#define LOOPFCT			TO_LOOP
#define BODY \
  {									      \
    uint32_t c = get32 (inptr);						      \
									      \
    if (__builtin_expect (c >= 0x110000, 0))				      \
      {									      \
	STANDARD_TO_LOOP_ERR_HANDLER (4);				      \
      }									      \
    else if (__builtin_expect (c >= 0xd800 && c < 0xe000, 0))		      \
      {									      \
	/* Surrogate characters in UCS-4 input are not valid.		      \
	   We must catch this.  If we let surrogates pass through,	      \
	   attackers could make a security hole exploit by		      \
	   generating "irregular UTF-32" sequences.  */			      \
	result = __GCONV_ILLEGAL_INPUT;					      \
	if (! ignore_errors_p ())					      \
	  break;							      \
	inptr += 4;							      \
	++*irreversible;						      \
	continue;							      \
      }									      \
									      \
    if (swap)								      \
      c = bswap_32 (c);							      \
    put32 (outptr, c);							      \
									      \
    outptr += 4;							      \
    inptr += 4;								      \
  }
#define LOOP_NEED_FLAGS
#define EXTRA_LOOP_DECLS \
	, enum variant var, int swap
#include <iconv/loop.c>


/* Convert from UTF-32 to the internal (UCS4-like) format.  */
#define MIN_NEEDED_INPUT	MIN_NEEDED_FROM
#define MIN_NEEDED_OUTPUT	MIN_NEEDED_TO
#define LOOPFCT			FROM_LOOP
#define BODY \
  {									      \
    uint32_t u1 = get32 (inptr);					      \
									      \
    if (swap)								      \
      u1 = bswap_32 (u1);						      \
									      \
    if (__builtin_expect (u1 >= 0x110000, 0))				      \
      {									      \
	/* This is illegal.  */						      \
	STANDARD_FROM_LOOP_ERR_HANDLER (4);				      \
      }									      \
									      \
    put32 (outptr, u1);							      \
    inptr += 4;								      \
    outptr += 4;							      \
  }
#define LOOP_NEED_FLAGS
#define EXTRA_LOOP_DECLS \
	, enum variant var, int swap
#include <iconv/loop.c>


/* Now define the toplevel functions.  */
#include <iconv/skeleton.c>
