//
// Copyright (C) 1999-2002 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

#include <WScom.h>
#include <WStcpcom.h>
#include <x11/WSDunixFile.h>
#include <stdio.h>
#include <fcntl.h>

WSMFclassInit(WSDunixFile,WSDfile);

WSDfile* _unix_fp_chandler(){
  return new WSDunixFile;
}

void WSGFinitializeUnixFile(){
    WSDfile::setCreateInstanceHandler((void*)_unix_fp_chandler);
}

class _unix_fp_init {
  public: _unix_fp_init(){
    WSDfile::setCreateInstanceHandler((void*)_unix_fp_chandler);
  };
};
_unix_fp_init  _unix_fp_init_execute;

WSDunixFile::WSDunixFile(){
  _fp = NULL;
  _mfp = NULL;
}

WSDunixFile::~WSDunixFile(){
  close();
}

long WSDunixFile::open(char* name,char* mode){
  _file_name.setString(name);
  _file_name.delHeadSpace();
  char* fn = _file_name.getString();
  if (!strncmp("http://",fn,7)){
    char*  pbuf = NULL;
    char*  ctype = NULL;
    long  size = 0;
    long  ishtml = 0;
    WSGFloadRemoteFile(fn,&pbuf,&ctype,&size,&ishtml,1);
    if (pbuf != NULL){
      if (_mfp == NULL){
        _mfp = new WSCmfile();
      }
      _mfp->open(pbuf,size);
      delete pbuf;
      return WS_NO_ERR;
    }
    return WS_ERR;
  }
  _fp = fopen(name,mode);
  if (_fp != NULL){
    return WS_NO_ERR;
  }else{
    if (!strcmp("r+",mode)){
      _fp = fopen(name,"a");
    }
    if (_fp != NULL){
      return WS_NO_ERR;
    }
    return WS_ERR;
  }
}

long WSDunixFile::close(){
  if (_fp != NULL){
    fclose(_fp);
    _fp = NULL;
  }
  if (_mfp != NULL){
    delete _mfp;
    _mfp = NULL;
  }
  return WS_NO_ERR;
}
long WSDunixFile::read(void* buf,long len){
  if (_mfp != NULL){
    return _mfp->read(buf,len);
  }
  if (_fp == NULL){
    return 0;
  }
  return fread(buf,1,len,_fp);
}
long WSDunixFile::write(void* buf,long len){
  if (_mfp != NULL){
    return _mfp->write(buf,len);
  }
  if (_fp == NULL){
    return 0;
  }
  return fwrite(buf,1,len,_fp);
}
WSCbool WSDunixFile::eof(){
  if (_mfp != NULL){
    return _mfp->eof();
  }
  if (_fp == NULL){
    return 0;
  }
  if (feof(_fp) != False){
    return True;
  }
  return False;
}

long WSDunixFile::seekSet(){
  return seek(0);
}
long WSDunixFile::seekEnd(){
  if (_mfp != NULL){
    _mfp->seekEnd();
    return WS_NO_ERR;
  }
  if (_fp == NULL){
    return 0;
  }
  fseek(_fp,0,SEEK_END);
  return WS_NO_ERR;
}
long WSDunixFile::seek(long addr){
  if (_mfp != NULL){
    return _mfp->seek(addr);
  }
  if (_fp == NULL){
//fprintf(stderr,"Error: WSDunixFDB::seek error file=NULL\n");
    return 0;
  }
  fseek(_fp,addr,SEEK_SET);
  return WS_NO_ERR;
}
long WSDunixFile::getSize(){
  if (_mfp != NULL){
    return _mfp->getSize();
  }
  if (_fp == NULL){
//fprintf(stderr,"Error: WSDunixFDB::getSize error file=NULL\n");
    return 0;
  }
  long pos = ftell(_fp);
  fseek(_fp,0,SEEK_END);
  long ret = ftell(_fp);
  fseek(_fp,pos,SEEK_SET);
  return ret;
}
long WSDunixFile::tell(){
  if (_mfp != NULL){
    return _mfp->tell();
  }
  if (_fp == NULL){
    return 0;
  }
  return ftell(_fp);
}

