/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* gzfile.c --- file open/read/write/close functions with gzipped file support */

/* $Id: gzfile.c,v 1.3 2002/09/11 22:01:50 ri Exp $ */

/* multiple open is not allowed */

#include <sent/stddefs.h>
#include <errno.h>

#ifdef HAVE_ZLIB
/* use zlib functions */
#include <zlib.h>
/* current implementatin casts gzFile to FILE, it's dangerous.. */
FILE *
fopen_readfile(char *filename)
{
  gzFile gp;
  gp = gzopen(filename, "rb");
  if (gp == NULL) perror("fopen_readfile");
  return(gp);
}
int
fclose_readfile(FILE *fp)
{
  if (gzclose((gzFile)fp) < 0) perror("fclose_readfile");
  return 0;
}
size_t
myfread(void *ptr, size_t size, size_t n, FILE *fp)
{
  int cnt;
  cnt = gzread((gzFile)fp, (voidp)ptr, (unsigned)size * n);
  if (cnt < 0) perror("myfread");
  return(cnt / size);
}

#else  /* ~HAVE_ZLIB */

/* use external "gzip" via pipe */
/* can read only one file at a time */

static boolean isopen = FALSE;
static FILE *zcat_pipe = NULL;

/* is the file is .gz file? (determine by file name..) */
static boolean
is_zcatfile(filename)
     char *filename;
{
  int len;

  len = strlen(filename);
  if (strmatch(".Z", &filename[len - 2])) {
    return TRUE;
  } else {
    if (strmatch(".z", &filename[len - 2]) || strmatch(".gz", &filename[len - 3])) {
#ifdef ZCAT
      return TRUE;
#else
      j_error("Error: cannot read \".gz\" or \".z\" file without \"gunzip\"\n");
#endif
    } else {
      return FALSE;
    }
  }
}

/* open file for read: both gzipped and not is supported */
/* return value: file pointer (NULL on error) */
FILE *
fopen_readfile(char *filename)
{
  FILE *fp;
  char cmd[1024];

  if (isopen) {		/* already open */
    j_printerr("fopen_readfile: previously opened file is not closed yet.\n");
    return NULL;
  }
    
  if (is_zcatfile(filename)) {	/* open compressed file */
    strcpy(cmd, ZCAT);
    strcat(cmd," ");
    if (strlen(cmd) + strlen(filename) + 1 > sizeof(cmd)) {
      j_printerr("fopen_readfile: cmd len exceeded\n");
      return NULL;
    }
    strcat(cmd, filename);
    zcat_pipe = popen(cmd, "r");
    if (zcat_pipe == NULL) {
      perror("fopen_readfile");
      return NULL;
    }
    fp = zcat_pipe;
  } else {			/* open uncompressed file */
    fp = fopen(filename, "r");
    if (fp == NULL) {		/* error */
      perror("fopen_readfile");
      return NULL;
    }
    zcat_pipe = NULL;
  }
  
  isopen = TRUE;
  return (fp);
}

/* close file previously opend by fopen_readfile() */
int				/* return value: 0=success,-1=failure */
fclose_readfile(FILE *fp)
{
  if (!isopen) {		/* not opened yet */
    return -1;
  }
  
  if (zcat_pipe != NULL) {	/* pipe opened fp */
    if (fp != zcat_pipe) {
      j_printerr("fp is not opened by fopen_readfile()\n");
      return -1;
    }
    pclose(zcat_pipe);
    zcat_pipe = NULL;
  } else  {			/* normal opened fp */
    fclose(fp);
  }
  
  isopen = FALSE;
  return 0;
}

size_t
myfread(void *ptr, size_t size, size_t n, FILE *fp)
{
  return(fread(ptr, size, n, fp));
}

#endif /* ~HAVE_ZLIB */

/* open file for write (no compress) */
FILE *
fopen_writefile(char *filename)
{
  FILE *fp;

  fp = fopen(filename, "wb");
  if (fp == NULL) {		/* error */
    perror("fopen_writefile");
  }
  return (fp);
}

/* close file previously opened by open_writefile() */
int				/* return value: 0=success, -1=failure */
fclose_writefile(FILE *fp)
{
  fclose(fp);
  return 0;
}

size_t
myfwrite(void *ptr, size_t size, size_t n, FILE *fp)
{
  return(fwrite(ptr, size, n, fp));
}
