#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <wchar.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>

#define RAIZ_NOME "dados-utf8"
#define SUFIXO    ".txt"
#define RES_NOME "-res"

void abrir_arquivos (int *in, int *out);

int main ()
{
  int input, output;

  /* Note the use of MB_LEN_MAX.
     MB_CUR_MAX cannot portably be used here.  */
  char buffer[BUFSIZ + MB_LEN_MAX];
  mbstate_t state;
  int filled = 0;
  int eof = 0;

  abrir_arquivos(&input, &output);

  /* Initialize the state.  */
  memset (&state, '\0', sizeof (state));
  
  while (!eof)
    {
      ssize_t nread;
      ssize_t nwrite;
      char *inp = buffer;
      wchar_t outbuf[BUFSIZ];
      wchar_t *outp = outbuf;
      
      /* Fill up the buffer from the input file.  */
      nread = read (input, buffer + filled, BUFSIZ);
      if (nread < 0)
	{
	  perror ("read");
	  return 0;
	}
      /* If we reach end of file, make a note to read no more. */
      if (nread == 0)
	eof = 1;
      
      /* filled is now the number of bytes in buffer. */
      filled += nread;
      
      /* Convert those bytes to wide characters--as many as we can. */
      while (1)
	{
	  size_t thislen = mbrtowc (outp, inp, filled, &state);
	  /* Stop converting at invalid character;
	     this can mean we have read just the first part
	     of a valid character.  */
	  if (thislen == (size_t) -1)
	    break;
	  /* We want to handle embedded NUL bytes
	     but the return value is 0.  Correct this.  */
	  if (thislen == 0)
	    thislen = 1;
	  /* Advance past this character. */
	  inp += thislen;
	  filled -= thislen;
	  ++outp;
	}
      
      /* Write the wide characters we just made.  */
      nwrite = write (output, outbuf,
		      (outp - outbuf) * sizeof (wchar_t));
      if (nwrite < 0)
	{
	  perror ("write");
	  return 0;
	}
      
      /* See if we have a real invalid character. */
      if ((eof && filled > 0) || filled >= MB_CUR_MAX)
	{
	  error (0, 0, "invalid multibyte character");
	  return 0;
	}
      
      /* If any characters must be carried forward,
	 put them at the beginning of buffer. */
      if (filled > 0)
	memmove (buffer, inp, filled);
    }

  close(input);
  close(output);
  return 1;
}

void abrir_arquivos(int *in, int *out)
{
  char *arq;

  arq = strdup(RAIZ_NOME);
  arq = realloc (arq, strlen(RAIZ_NOME)+strlen(SUFIXO)+strlen(RES_NOME)+1);

  *in  = open( strcat(arq,SUFIXO), O_RDONLY );

  arq[strlen(RAIZ_NOME)] = '\0';
  *out = open( strcat( strcat(arq,RES_NOME), SUFIXO), O_WRONLY|O_TRUNC|O_CREAT);
}
