/*
  reads input data
  Copyright (C) 1999  Martin Vogt

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Library General Public License as published by
  the Free Software Foundation.

  For more information look at the file COPYRIGHT in this package

 */



#include "fileInputStream.h"


FileInputStream::FileInputStream() {
  file=NULL;
  lopen=false;
  fileLen=0;
  abs_thread_mutex_init(&fileMut);
}


FileInputStream::~FileInputStream() {
  close();
  abs_thread_mutex_destroy(&fileMut);
}


int FileInputStream::open(const char* dest) {
  char* filename=NULL;

  close();
  if (dest == NULL) {
    return false;
  }
  setUrl(dest);
  if (strlen(dest) == 1) {
    if (strncmp(dest,"-",1)==0) {
      lockFile();
      file=::fdopen(0,"rb");
      unlockFile();
    }
  }
  // load out of current dir if no full path is given
  if (strlen(dest) > 1) {
    if ( (dest[0] != '/') &&
         (dest[0] != '.') ) {
      filename=new char[strlen(dest)+3];  // prefix with ./ plus zero at end
      filename[0]='.';
      filename[1]='/';
      memcpy(filename+2,dest,strlen(dest)+1); // copy with zero
    } else {
      filename=strdup(dest);
    }
  }
  lockFile();
  if (file == NULL) {
    file=fopen(filename,"rb");
  }
  fileLen=0;
  if (file == NULL) {
    cout << dest<<endl;
    perror("cannot open file");
  } else {
    lopen=true;
    struct stat fileStat;
    stat(filename,&fileStat);
    fileLen=(long)fileStat.st_size;
  }
  int back=(file!=NULL);
  unlockFile();
  delete filename;
  return back;
}


void FileInputStream::close() {
  if (isOpen()) {
    lockFile();
    ::fclose(file);
    file=NULL;
    lopen=false;
    unlockFile();
  }
}


int FileInputStream::isOpen() {
  return lopen;
}


int FileInputStream::eof() {
  if (isOpen()==false){
    return true;
  }
  int back=true;
  lockFile();
  if (file != NULL) {
    back=feof(file);
  }
  unlockFile();

  return back;
}


int FileInputStream::read(char* ptr,int size) {
  int bytesRead=-1;
  if (isOpen()) {
    if (size <= 0) {
      cout << "size is <= 0!"<<endl;
      return 0;
    }
    lockFile();
    if (file != NULL) {
      bytesRead=fread(ptr,1,size,file);
    }
    unlockFile();
  } else {
    cerr << "read on not open file want:"<<size<<endl;
    return 0;
  }
  if (bytesRead == 0){
    perror("zero bytes fread");
    bytesRead=0;
  }
  return bytesRead;
}


int FileInputStream::seek(long posInBytes) {
  int back=true;
  if (isOpen()==false) {
    return false;
  }
  lockFile();
  long pos=-1;
  if (file != NULL) {
    pos=fseek(file,posInBytes,SEEK_SET);
  }
  unlockFile();

  if (pos < 0) {
    perror("seek in setBytePos");
    back=false;
  }
  return back;
}


long FileInputStream::getByteLength() {
  return fileLen;
}


long FileInputStream::getBytePosition() {
  int back=0;
  if (isOpen()) {
    lockFile();
    if (file != NULL) {
      back=ftell(file);
    }
    unlockFile();
  }
  return back;
}



void FileInputStream::print() {
  printf("pos in file:%8x\n",(int)getBytePosition());
}


void FileInputStream::lockFile() {
  abs_thread_mutex_lock(&fileMut);
}



void FileInputStream::unlockFile() {
  abs_thread_mutex_unlock(&fileMut);
}

