/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/

#include <Winsock2.h>
#include	<stdlib.h>
#include	<stdarg.h>
#include	<stdio.h>
#include	<io.h>

#include	"memory_debug.h"
#include	"stream.h"
#include	"task.h"


extern SEM stream_lock;
int max_fid = 3;
int now_open_files = 3;

int s_close_file();
int s_write_file();
int s_read_file();
int s_vprintf_file();
int s_vprintf_cr_file();
int s_flush_file();
int s_vscanf_file();


S_TABLE s_file_table = {
	'f',
	0,
	s_open_file_descripter,
	s_close_file,
	s_write_file,
	s_read_file,
	s_flush_file,
	s_proc_send_file,
	s_proc_recv_file
};

STREAM *
s_open_file(char * filename, int mode, int flags)
{
STREAM * ret;
char md[4];
	ret = d_alloc(sizeof(S_FILE),300);
	ret->h.tbl = &s_file_table;

	strcpy(md, "r+");
	if ( (mode & O_RDONLY) != 0 ) 
		strcpy(md, "r") ;
	if ( (mode & (O_RDWR|O_CREAT|O_TRUNC)) == (O_RDWR|O_CREAT|O_TRUNC) )
		strcpy(md, "w+") ;
	if ( mode & O_BINARY ) 
		strcat(md, "b") ;
	ret->file.fd = fopen(filename, md);
	
	if ( ret->file.fd == NULL ) {
		d_f_ree(ret);
		return 0;
	}
//printf("ret->file.fd := %08X\nfilename:=%s\n", ret->file.fd,filename);fflush(stdout);
	_s_open(ret, mode);
	lock_task(stream_lock);
	now_open_files ++;
	if ( ret->file.fid > max_fid )
		max_fid = ret->file.fid;
	unlock_task(stream_lock,"s_open_file");
	
	return ret;
}

int
s_close_file(STREAM * s)
{
	fclose(s->file.fd);
	now_open_files --;
	return 0;
}

int
s_write_file(STREAM * s, void * data, int len)
{
	return fwrite(data, 1, len, s->file.fd);
}

int
s_read_file(STREAM * s, void * data, int len)
{
	return fread(data, 1, len, s->file.fd);
}

int
s_flush_file(STREAM * s)
{
	return fflush(s->file.fd);
}

int
s_get_socketip(STREAM * s)
{

int ret;
int er;
int size;
struct sockaddr_in ss;
	if ( s->h.tbl != &s_file_table )
		return 0;
	size = sizeof(ss);
	er = getpeername(s->file.fid,(struct sockaddr*)&ss,&size);
	if ( er < 0 )
		return 0;
	ret = ntohl(ss.sin_addr.s_addr);
	return ret;

}

int
s_seek_file(STREAM * s,unsigned int offset,int where)
{
	if ( s->h.tbl != &s_file_table )
		return -1;
	fseek(s->file.fd, offset, where);
	return ftell(s->file.fd);
}
