/**********************************************************************
 
	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.

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


#define STREAM_LIB

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

extern SEM stream_lock;
extern STREAM ** recv_streams;
extern int recv_streams_len;
extern S_TABLE * stream_table_list;


S_TABLE *
_search_type(char type)
{
S_TABLE * ret;
	ret = stream_table_list;
	for ( ; ret ; ret = ret->next )
		if ( ret->type == type )
			return ret;
	return 0;
}


void
proc_recv_stream(char *map_name){
char error_msg[256];
char event_name[256];
HANDLE map_file;
char *shared_memory;
PROC_SEND_CHUNK *chunk;
char *pointer;
S_TABLE *tbl;
HANDLE stream_receive_event;
char *message_on_receive=0;
int i;

	recv_streams_len = 0;
	/* open shared memory */
	map_file = OpenFileMapping(FILE_MAP_READ, FALSE, map_name);
	if(map_file==NULL){
		sprintf(error_msg, "error open file mapping cause:%d", GetLastError());
		er_panic(error_msg);
	}
	
	shared_memory = (char *)MapViewOfFile(map_file, FILE_MAP_READ, 0, 0, 0);
	if(shared_memory==NULL){
		sprintf(error_msg, "erro open MapViewOfFile cause:%s", GetLastError());
		er_panic(error_msg);
	}
	
	pointer = shared_memory;
	chunk = (PROC_SEND_CHUNK *)pointer;
	
	/* get stream count */
	for(recv_streams_len=0;chunk->header.type!='t'; chunk=(PROC_SEND_CHUNK *)pointer){
		if(chunk->header.type!='m'){/* type=='m' is message chunk, so skip*/
			++recv_streams_len;
		}
		pointer+=chunk->header.size;
	}
	/* WIN_SERVER_DEBUG */
	printf("proc_recv_stream: stream_count=%d\n", recv_streams_len);

	/* load streams */
	lock_task(stream_lock);
	recv_streams = (STREAM**)d_alloc(sizeof(STREAM*)*(recv_streams_len+1));
	i=0;
	pointer = shared_memory;
	chunk = (PROC_SEND_CHUNK *)pointer;
	for(;chunk->header.type!='t'; chunk=(PROC_SEND_CHUNK *)pointer){
		if(chunk->header.type=='m'){
			PROC_SEND_MESSAGE *msg = (PROC_SEND_MESSAGE *)chunk;
			message_on_receive = d_alloc(strlen(msg->message_on_receive)+1);
			strcpy(message_on_receive, msg->message_on_receive);
			printf("proc_recv_stream: message_on_receive = %s\n", message_on_receive);
		}
		else{
			tbl = _search_type(chunk->header.type);
			if(tbl==0){
				sprintf(error_msg, "table not found. type=%c", chunk->header.type);
				er_panic(error_msg);
			}

			/* WIN_SERVER_DEBUG */
			printf("proc_recv_stream: tbl->proc_recv tbl->type='%c'\n", tbl->type);
			
			recv_streams[i] = tbl->proc_recv(tbl, chunk);
			if(recv_streams[i] == NULL){
				er_panic("proc_recv_stream tbl->proc_recv error");
			}
		}
		pointer+=chunk->header.size;
	}
	unlock_task(stream_lock,"proc_recv_stream");
	
	UnmapViewOfFile(shared_memory);
	CloseHandle(map_file);
	
	/* report finish loading to parent process */
	meke_proc_send_event_name(event_name, map_name);
	stream_receive_event = OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
	if(stream_receive_event==NULL){
		er_panic("can't open stream_receive_event.");
	}
	SetEvent(stream_receive_event);
	CloseHandle(stream_receive_event);
	

	if(message_on_receive&&message_on_receive[0]!=0){
		for(i=0;i<recv_streams_len;++i){
			s_write(recv_streams[i], message_on_receive, strlen(message_on_receive));
		}
		d_f_ree(message_on_receive);
	}
}


/*
void
proc_recv_stream(char * msg)
{
PROC_RECV pr;
int i;

	printf("proc_recv is ...  %s\n" ,msg);
	fflush(stdout);

	lock_task(stream_lock);

	recv_streams = d_alloc(sizeof(STREAM*));
	i = 0;

	pr.ptr = msg+1;
	pr.fidp = 3;
	for ( ; *pr.ptr ; ) {
		if ( *pr.ptr == '[' )
			break;
		pr.tbl = _search_type(*pr.ptr);
		if ( pr.tbl == 0 ) {
			recv_streams[i++] = 0;
			pr.ptr ++;
		}
		else	recv_streams[i++] = (*pr.tbl->proc_recv)(&pr);
		recv_streams = d_re_alloc(
			recv_streams,
			sizeof(STREAM*)*(i+1));
	}
	recv_streams[i] = 0;
	recv_streams_len = i;
	unlock_task(stream_lock,"proc_recv_stream");
	if ( *pr.ptr == '[' )
		write_msg(pr.ptr);
}

*/