/*
*******************************************************************************
*
*   Copyright (C) 1998-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*
* File ufile.c
*
* Modification History:
*
*   Date        Name        Description
*   11/19/98    stephen	    Creation.
*   03/12/99    stephen     Modified for new C API.
*   12/01/99    weiv        ufille_fill_uchar_buffer modified to be able to use invariant conversion
*******************************************************************************
*/

#include <stdio.h>
#include "ustdio.h"
#include "ufile.h"
#include "cmemory.h"
#include "cstring.h"

#define MIN(a,b) (a < b ? a : b)
#define MAX(a,b) (a > b ? a : b)

UFILE*
u_finit(FileStream *f, const char *cp,
	UErrorCode *status)
{
  UFILE *result	= (UFILE*) uprv_malloc(sizeof(UFILE));
  if(result == 0) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return 0;
  }

  result->fFile 	= f;
  result->fOwnFile 	= FALSE;
  result->fUCPos 	= result->fUCBuffer;
  result->fUCLimit 	= result->fUCBuffer;
  
  if(cp == 0) {                     /* weiv: we're using the default converter*/
      result->fConverter = ucnv_open(0, status);
      if(U_FAILURE(*status) || result->fConverter == 0) {
        T_FileStream_close(result->fFile);
        uprv_free(result);
        return 0;
      }
  } else if (uprv_strlen(cp)>uprv_strlen("")) {    /*weiv: we're specifying the converter*/
      result->fConverter = ucnv_open(cp, status);
      if(U_FAILURE(*status) || result->fConverter == 0) {
        T_FileStream_close(result->fFile);
        uprv_free(result);
        return 0;
      }
  } else {                          /*weiv: we'll go for invariant converter */
      result->fConverter = NULL;
  }


  return result;
}

void
u_fclose(UFILE *file)
{
  if(file->fOwnFile)
    T_FileStream_close(file->fFile);

  ucnv_close(file->fConverter);
  uprv_free(file);
}

/* private function used for buffering input */
void
ufile_fill_uchar_buffer(UFILE *f,
			UErrorCode *status)
{
  const char		*mySource;
  const char		*mySourceEnd;
  UChar			*myTarget;
  int32_t		bufferSize;
  int32_t		maxCPBytes;
  int32_t		bytesRead;
  int32_t		availLength;
  int32_t		dataSize;

  if(U_FAILURE(*status)) return;

  /* shift the buffer if it isn't empty */
  dataSize = f->fUCLimit - f->fUCPos;
  if(dataSize != 0) {
    uprv_memmove(f->fUCBuffer, 
		f->fUCPos, 
		dataSize * sizeof(UChar));
  }
  
  /* record how much buffer space is available */
  availLength = UFILE_UCHARBUFFER_SIZE - dataSize;
  
  /* Determine the # of codepage bytes needed to fill our UChar buffer */
  maxCPBytes = availLength * (f->fConverter!=NULL?ucnv_getMaxCharSize(f->fConverter):1); /*weiv: Probably shoud #define it somewhere */
  
  /* Read in the data to convert */
  bytesRead = T_FileStream_read(f->fFile,f->fCharBuffer, 
		    MIN(maxCPBytes, UFILE_CHARBUFFER_SIZE));
  
  /* Set up conversion parameters */
  *status	= U_ZERO_ERROR;
  mySource   	= f->fCharBuffer;
  mySourceEnd 	= f->fCharBuffer + bytesRead;
  myTarget 	= f->fUCBuffer + dataSize;
  bufferSize	= UFILE_UCHARBUFFER_SIZE;

  if(f->fConverter != NULL) {   /*weiv: we have a good converter, so we'll just use it */
      /* Perform the conversion */
      ucnv_toUnicode(f->fConverter,
		     &myTarget, 
		     f->fUCBuffer + bufferSize,
		     &mySource,
		     mySourceEnd,
		     NULL,
		     TRUE,
		     status);
  } else {                      /*weiv: we couldn't obtain a converter, so we'll go with invariant conversion */
      u_charsToUChars(mySource, myTarget, bytesRead);
      myTarget += bytesRead;
  }
  
  /* update the pointers into our array */
  f->fUCPos	= f->fUCBuffer;
  f->fUCLimit 	= myTarget;
}
