/*
 * $Id: jexc_java_io.c,v 1.7 2000/09/28 04:33:28 msato Exp $
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */

#include "jexc.h"
#include "jexc_runtime.h"
#include "jexc_sys_class.h"
#include <sys/stat.h>

/* 
 * Reader
 */
#define JEXC_EOF (-1)

/* method <init> (Ljava/lang/String;)V  	Io_FileReader_INIT */
DEFINE_C_METHOD(Io_FileReader_INIT)
{
    DECL_C_METHOD_VAR;
    jexc_string *sp;
    FILE *filep;
    sp = (jexc_string *)fp[1];
    if((filep = fopen(sp->op->str,"r")) == NULL){
	jexc_throw(jexc_new_object(jexc_find_class("java/io/FileNotFoundException")));
    }
    VAR0(fp[0])=(jexc_word)jexc_alloc_opaque(sizeof(struct jexc_io_stream));
    VAR0_OPAQUE(struct jexc_io_stream *,fp[0])->fp = filep;
}

/* method <init> (Ljava/io/Reader;I)V	Io_BufferedReader_INIT */
DEFINE_C_METHOD(Io_BufferedReader_INIT)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
}

/* method <init> (Ljava/io/InputStream;)V Io_InputStreamReader_INIT */
DEFINE_C_METHOD(Io_InputStreamReader_INIT)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
}

DEFINE_C_METHOD(Io_Reader_close)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fclose(p->fp);
}

/* method read ([C)I			Io_FileReader_read */
DEFINE_C_METHOD(Io_Reader_read)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    jexc_iarray *ap;
    jexc_char *cp;
    char c;
    int i;

    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    ap = (jexc_iarray *)fp[1];
    cp = (jexc_char *)ap->base;
    if(feof(p->fp)||ferror(p->fp)) i = -1;
    else {
	for(i = 0; i < ap->length; i++){
	    if(fread(&c,1,1,p->fp) != 1) break;
	    *cp++ = (((int)c)&0xFF);
	}
    }
    RETURN_C_METHOD_INT(i);
}

/* method read ()I			Io_FileReader_read1 */
DEFINE_C_METHOD(Io_Reader_read1)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    char c;
    jexc_int i;

    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    if(feof(p->fp)||ferror(p->fp)) i = JEXC_EOF;
    else {
	if(fread(&c,1,1,p->fp) != 1) i =  JEXC_EOF;
	else i = (((int)c)&0xFF);
    }
    RETURN_C_METHOD_INT(i);
}

DEFINE_C_METHOD(Io_Reader_readLine)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    char buf[200];
    int len;
    jexc_word x;
    
    GC_OFF;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    if(fgets(buf,200,p->fp) == NULL){
	RETURN_C_METHOD(NULL);
    }
    len = strlen(buf);
    x = (jexc_word)jexc_new_string_n(buf,len-1);
    GC_ON;
    RETURN_C_METHOD(x);
}


/* 
 *  PrintWriter, BufferedWriter, FileWriter, OutputStreamWriter, Writer
 *   -- Writer is abstract class
 *   -- all share the same implementation
 */

void Io_PrintStream_INIT() 
{ jexc_error("cannot create java/io/PrintStream"); }

/* method <init> (Ljava/io/OutputStream;)V	Io_PrintWriter_INIT1 */
DEFINE_C_METHOD(Io_PrintWriter_INIT1)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
}

/* method <init> (Ljava/io/Writer;)V		Io_PrintWriter_INIT2 */
DEFINE_C_METHOD(Io_PrintWriter_INIT2)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
}

/* method <init> (Ljava/io/OutputStream;Z)V	Io_PrintWriter_INIT3 */
DEFINE_C_METHOD(Io_PrintWriter_INIT3)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
    /* ingore flush_flag */
}

DEFINE_C_METHOD(Io_PrintWriter_INIT4)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
    /* ingore flush_flag */
}

/* method <init> (Ljava/io/Writer;I)V		Io_BufferedWriter_INIT */
DEFINE_C_METHOD(Io_BufferedWriter_INIT)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
    /* don't care buffered */
}

/* method <init> (Ljava/io/OutputStream;)V  	Io_OutputStreamWriter_INIT */
DEFINE_C_METHOD(Io_OutputStreamWriter_INIT)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = VAR0(fp[1]);
}

/* method <init> (Ljava/lang/String;)V		Io_FileWriter_INIT */
DEFINE_C_METHOD(Io_FileWriter_INIT)
{
    DECL_C_METHOD_VAR;
    jexc_string *sp;
    FILE *filep;
    sp = (jexc_string *)fp[1];
    if((filep = fopen(sp->op->str,"w")) == NULL){
	jexc_throw(jexc_new_object(jexc_find_class("java/io/IOException")));
    }
    VAR0(fp[0])=(jexc_word)jexc_alloc_opaque(sizeof(struct jexc_io_stream));
    VAR0_OPAQUE(struct jexc_io_stream *,fp[0])->fp = filep;
}

/* method println (Ljava/lang/Object;)V		Io_PrintWriter_println_L */
DEFINE_C_METHOD(Io_PrintWriter_println_L)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    jexc_word *sp0;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    sp0 = fp+1;
    (*(fp[1]->class->methods[JEXC_TOSTRING_METHOD]))(&sp0); /* call toString */
    fprintf(p->fp,"%s\n",((jexc_string *)fp[1])->op->str);
}

/* method println (Ljava/lang/String;)V */
DEFINE_C_METHOD(Io_PrintWriter_println_String)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fprintf(p->fp,"%s\n",((jexc_string *)fp[1])->op->str);
}

DEFINE_C_METHOD(Io_PrintWriter_print_String)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fprintf(p->fp,"%s",((jexc_string *)fp[1])->op->str);
}

/* method println (I)V	 Io_PrintWriter_println_I */
DEFINE_C_METHOD(Io_PrintWriter_println_I)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fprintf(p->fp,"%d\n",(jexc_int)((_omAddrInt_t)fp[1]));
}

/* method print (I)V	 Io_PrintWriter_print_I */
DEFINE_C_METHOD(Io_PrintWriter_print_I)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fprintf(p->fp,"%d",(jexc_int)((_omAddrInt_t)fp[1]));
}

DEFINE_C_METHOD(Io_PrintWriter_print_C)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fprintf(p->fp,"%c",(jexc_int)((_omAddrInt_t)fp[1]));
}

DEFINE_C_METHOD(Io_PrintWriter_print_D)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    jexc_any tmp;
    char buf[100];
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    tmp.HL.low = (jexc_int)((_omAddrInt_t)fp[1]);
    tmp.HL.high = (jexc_int)((_omAddrInt_t)fp[2]);
    float_toString(buf,tmp.d);
    fprintf(p->fp,"%s",buf);
}

DEFINE_C_METHOD(Io_PrintWriter_println)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fputc('\n',p->fp);
}

DEFINE_C_METHOD(Io_PrintWriter_flush)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fflush(p->fp);
}

DEFINE_C_METHOD(Io_Writer_close)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    fclose(p->fp);
}

/* method write (I)V				Io_PrintWriter_write */
DEFINE_C_METHOD(Io_PrintWriter_write)
{
    DECL_C_METHOD_VAR;
    struct jexc_io_stream *p;
    char c;
    p = VAR0_OPAQUE(struct jexc_io_stream *,fp[0]);
    c = (jexc_int)((_omAddrInt_t)fp[1]);
    fwrite(&c,1,1,p->fp);
}

/* method <init> (Ljava/lang/String;)V		Io_File_INIT */
DEFINE_C_METHOD(Io_File_INIT)
{
    DECL_C_METHOD_VAR;
    VAR0(fp[0]) = fp[1];
}

/* method exists ()Z				Io_File_exist */
DEFINE_C_METHOD(Io_File_exist)
{
    DECL_C_METHOD_VAR;
    jexc_string *sp;
    struct stat buf;
    int r;
    sp = (jexc_string *)VAR0(fp[0]);
    r = stat(sp->op->str,&buf);
    RETURN_C_METHOD_INT(r == 0);
}





