/**********************************************************************
 
	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;
#ifndef _SOCKLEN_T
typedef size_t socklen_t;
#endif

int s_close_socket();
int s_write_socket();
int s_read_socket();
int s_vprintf_socket();
int s_vprintf_cr_socket();
int s_flush_socket();
int s_vscanf_socket();

S_TABLE s_socket_table = {
	's',
	0,
	0,
	s_close_socket,
	s_write_socket,
	s_read_socket,
	s_flush_socket,
	0,
	0
};

int
s_close_socket(STREAM * s)
{
	shutdown(s->_socket.fid, 2);
	closesocket(s->_socket.fid);
	s->_socket.fid = INVALID_SOCKET;
	return 0;
}

int
s_write_socket(STREAM * s, void * data, int len)
{
	int nResult;
	long timeout = 12;
	
	do{
		FD_SET fd = {{1}, {s->_socket.fid}};
		TIMEVAL tv = {timeout, 0};
		nResult = select(0, NULL, &fd, NULL, &tv);
	}while(nResult == 0);
	if(nResult == SOCKET_ERROR){
		return -1;
	}
	return send(s->_socket.fid, data, len, 0);
}

int
s_read_socket(STREAM * s, void * data, int len)
{
	int nResult;
	long timeout = 12;
	
	do{
		FD_SET fd = {{1}, {s->_socket.fid}};
		TIMEVAL tv = {timeout, 0};
		nResult = select(0, &fd, NULL, NULL, &tv);
	}while(nResult==0);
	if(nResult == SOCKET_ERROR) {
		return -1;
	}
	return recv(s->_socket.fid, data, len, 0);
}


/*
int
s_vprintf_socket(STREAM * s, char * string)
{
	send(s->_socket.fid, string, strlen(string), 0);
	return strlen(string);
}

int
s_vprintf_cr_socket(STREAM * s, char * string)
{
char * ptr;
	lock_task(stream_lock);
	for ( ptr = string ; *ptr ; ptr ++ )
		if ( *ptr == '\n' || *ptr == '\r' )
			s->h.cr_cnt ++;
	unlock_task(stream_lock, "s_vprintf_cr_file");
	send(s->_socket.fid, string,strlen(string), 0);
	return strlen(string);
}
*/

int
s_flush_socket(STREAM * s)
{
	return 0;
}
/*
S_FILE __s_std[3] = {
	{	{	&s_file_table,
			O_RDONLY
		},
		stdin
	},
	{	{	&s_file_table,
			O_WRONLY
		},
		stdout
	},
	{	{	&s_file_table,
			O_WRONLY
		},
		stderr
	}
};
*/
int
s_get_socketip(STREAM * s)
{
int ret;
int er;
socklen_t size;
struct sockaddr_in ss;
	if ( s->h.tbl != &s_file_table )
		return 0;
	size = sizeof(ss);
	er = getpeername(s->_socket.fid,(struct sockaddr*)&ss,&size);
	if ( er < 0 )
		return 0;
	ret = ntohl(ss.sin_addr.s_addr);
	return ret;
}
