/* $OpenXM: OpenXM_contrib2/asir2018/io/io_win_mini.c,v 1.1 2018/09/19 05:45:08 noro Exp $ */
#include "ca.h"
#include "parse.h"
#include "ox.h"
#include "wsio.h"
#include "signal.h"
#define ISIZ sizeof(int)
#define _NEWNODE(n) ((n)=(NODE)malloc(sizeof(struct oNODE)))
#define _NEWSTR(l) ((l)=(STRING)malloc(sizeof(struct oSTRING)),OID(l)=O_STR)
#define _NEWUSINT(u) ((u)=(USINT)malloc(sizeof(struct oUSINT)),OID(u)=O_USINT)
#define _NEWERR(e) ((e)=(ERR)malloc(sizeof(struct oERR)),OID(e)=O_ERR)
#define _NEWLIST(l) ((l)=(LIST)malloc(sizeof(struct oLIST)),OID(l)=O_LIST)
#define _MKSTR(u,b) (_NEWSTR(u),(u)->body=(unsigned)(b))
#define _MKUSINT(u,b) (_NEWUSINT(u),(u)->body=(unsigned)(b))
#define _MKERR(e,b) (_NEWERR(e),(e)->body=(Obj)(b))
#define _MKLIST(l,b) (_NEWLIST(l),(l)->body=(Obj)(b))
#define _MKNODE(a,b,c) \
(_NEWNODE(a),(a)->body=(pointer)b,NEXT(a)=(NODE)(c))
int ox_usr1_sent, ox_int_received, critical_when_signal;
unsigned int ox_serial;
int ox_flushing;
int ox_batch;
int ox_check=1;
int ox_exchange_mathcap=0;
int little_endian=1;
int terminate;
static int available_cmo[] = {
CMO_NULL, CMO_INT32, CMO_STRING,CMO_LIST,
CMO_ERROR, CMO_ERROR2, CMO_ZERO,
0
};
int ox_data_is_available(int s)
{
return FP_DATA_IS_AVAILABLE(iofp[s].in);
}
void wait_for_data(int s)
{
fd_set r;
int sock;
if ( !FP_DATA_IS_AVAILABLE(iofp[s].in) ) {
sock = iofp[s].in->fildes;
FD_ZERO(&r);
FD_SET((unsigned int)sock,&r);
select(0,&r,NULL,NULL,NULL);
}
}
void ox_send_data(int s,pointer p)
{
ERR err;
if ( !valid_as_cmo(p) )
return;
ox_write_int(s,OX_DATA);
ox_write_int(s,ox_serial++);
ox_write_cmo(s,p);
ox_flush_stream(s);
}
void ox_send_cmd(int s,int id)
{
ox_write_int(s,OX_COMMAND);
ox_write_int(s,ox_serial++);
ox_write_int(s,id);
ox_flush_stream(s);
}
void ox_send_sync(int s)
{
ox_write_int(s,OX_SYNC_BALL);
ox_write_int(s,ox_serial++);
ox_flush_stream(s);
}
unsigned int ox_recv(int s, int *id, Obj *p)
{
unsigned int cmd,serial;
USINT ui;
wait_for_data(s);
if ( terminate ) return -1;
ox_read_int(s,id);
ox_read_int(s,&serial);
switch ( *id ) {
case OX_COMMAND:
ox_read_int(s,&cmd);
_MKUSINT(ui,cmd);
*p = (Obj)ui;
break;
case OX_DATA:
ox_read_cmo(s,p);
break;
default:
*p = 0;
break;
}
return serial;
}
void ox_get_result(int s,Obj *rp)
{
int id;
Obj obj,r;
int level;
level = 0;
r = 0;
do {
ox_recv(s,&id,&obj);
if ( id == OX_COMMAND ) {
switch ( ((USINT)obj)->body ) {
case SM_beginBlock:
level++;
break;
case SM_endBlock:
level--;
}
} else
r = obj;
} while ( level );
*rp = r;
}
void ox_read_int(int s, int *n)
{
read_int((FILE *)iofp[s].in,n);
}
void ox_read_cmo(int s, Obj *rp)
{
read_cmo((FILE *)iofp[s].in,rp);
}
void ox_write_int(int s, int n)
{
write_int((FILE *)iofp[s].out,&n);
}
void ox_write_cmo(int s, Obj obj)
{
write_cmo((FILE *)iofp[s].out,obj);
}
void ox_flush_stream(int s)
{
if ( ox_batch )
return;
if ( _fileno(&iofp[s].out->fp) < 0 )
cflush(iofp[s].out);
else
fflush((FILE *)iofp[s].out);
}
void ox_flush_stream_force(int s)
{
if ( _fileno(&iofp[s].out->fp) < 0 )
cflush(iofp[s].out);
else
fflush((FILE *)iofp[s].out);
}
/* CMO I/O functions */
int valid_as_cmo(Obj obj)
{
NODE m;
if ( !obj )
return 1;
switch ( OID(obj) ) {
case O_STR: case O_ERR: case O_USINT:
return 1;
default:
return 0;
}
}
void write_cmo(FILE *s,Obj obj)
{
int r;
char errmsg[BUFSIZ];
if ( !obj ) {
r = CMO_NULL; write_int(s,&r);
return;
}
switch ( OID(obj) ) {
case O_STR:
write_cmo_string(s,(STRING)obj);
break;
case O_USINT:
write_cmo_uint(s,(USINT)obj);
break;
case O_LIST:
write_cmo_list(s,(LIST)obj);
break;
case O_ERR:
write_cmo_error(s,(ERR)obj);
break;
}
}
int cmo_tag(Obj obj,int *tag)
{
if ( !obj ) {
*tag = CMO_NULL;
return 1;
}
switch ( OID(obj) ) {
case O_STR:
*tag = CMO_STRING; break;
case O_USINT:
*tag = CMO_INT32; break;
case O_LIST:
*tag = CMO_LIST; break;
case O_ERR:
*tag = CMO_ERROR2; break;
default:
return 0;
}
return 1;
}
void write_cmo_uint(FILE *s,USINT ui)
{
unsigned int r;
r = CMO_INT32; write_int(s,&r);
r = ui->body; write_int(s,&r);
}
void write_cmo_string(FILE *s,STRING str)
{
int r;
int size;
char *p;
r = CMO_STRING; write_int(s,&r);
p = BDY(str);
size = p ? strlen(p) : 0;
write_int(s,&size);
if ( size )
write_string(s,p,size);
}
void write_cmo_list(FILE *s,LIST list)
{
NODE m;
int i,n,r;
for ( n = 0, m = BDY(list); m; m = NEXT(m), n++ );
r = CMO_LIST; write_int(s,&r);
write_int(s,&n);
for ( i = 0, m = BDY(list); i < n; i++, m = NEXT(m) )
write_cmo(s,BDY(m));
}
void write_cmo_error(FILE *s,ERR e)
{
int r;
r = CMO_ERROR2; write_int(s,&r);
write_cmo(s,BDY(e));
}
void read_cmo(FILE *s,Obj *rp)
{
int id;
STRING str;
LIST list;
USINT t;
Obj obj;
ERR e;
read_int(s,&id);
switch ( id ) {
/* level 0 objects */
case CMO_NULL:
*rp = 0;
break;
case CMO_INT32:
read_cmo_uint(s,&t); *rp = (Obj)t;
break;
case CMO_STRING:
loadstring(s,&str); *rp = (Obj)str;
break;
case CMO_LIST:
read_cmo_list(s,&list); *rp = (Obj)list;
break;
case CMO_ERROR:
_MKERR(e,0); *rp = (Obj)e;
break;
case CMO_ERROR2:
read_cmo(s,&obj); _MKERR(e,obj); *rp = (Obj)e;
break;
case CMO_ZERO:
*rp = 0;
break;
default:
_MKUSINT(t,id);
t->id = O_VOID;
*rp = (Obj)t;
break;
}
}
void read_cmo_uint(FILE *s,USINT *rp)
{
unsigned int body;
read_int(s,&body);
_MKUSINT(*rp,body);
}
void read_cmo_list(FILE *s,Obj *rp)
{
int len;
Obj *w;
int i;
NODE n0,n1;
LIST list;
read_int(s,&len);
w = (Obj *)ALLOCA(len*sizeof(Obj));
for ( i = 0; i < len; i++ )
read_cmo(s,&w[i]);
for ( i = len-1, n0 = 0; i >= 0; i-- ) {
_MKNODE(n1,w[i],n0); n0 = n1;
}
_MKLIST(list,n0);
*rp = (Obj)list;
}
void loadstring(FILE *s,STRING *p)
{
char *t;
loadstr(s,&t); _MKSTR(*p,t);
}
void loadstr(FILE *s,char **p)
{
int len;
char *t;
read_int(s,&len);
t = (char *)malloc(len+1);
if ( len ) read_string(s,t,len);
t[len] = 0;
*p = t;
}
/* low level buffered I/O functions */
int gen_fread (char *ptr,int size,int nitems,FILE *stream)
{
int n;
if ( _fileno(stream) < 0 )
n = cread(ptr,size,nitems,(STREAM *)stream);
else
n = fread(ptr,size,nitems,stream);
if ( !n )
return 0;
else
return n;
}
int gen_fwrite (char *ptr,int size,int nitems,FILE *stream)
{
if ( _fileno(stream) < 0 )
return cwrite(ptr,size,nitems,(STREAM *)stream);
else
return fwrite(ptr,size,nitems,stream);
}
void write_char(FILE *f,unsigned char *p)
{
gen_fwrite(p,sizeof(unsigned char),1,f);
}
void write_short(FILE *f,unsigned short *p)
{
gen_fwrite((char *)p,sizeof(unsigned short),1,f);
}
void write_int(FILE *f,unsigned int *p)
{
gen_fwrite((char *)p,sizeof(unsigned int),1,f);
}
void write_string(FILE *f,unsigned char *p,int l)
{
gen_fwrite(p,sizeof(unsigned char),l,f);
}
void read_char(FILE *f,unsigned char *p)
{
gen_fread((char *)p,sizeof(unsigned char),1,f);
}
void read_short(FILE *f,unsigned short *p)
{
gen_fread((char *)p,sizeof(unsigned short),1,f);
}
void read_int(FILE *f,unsigned int *p)
{
gen_fread((char *)p,sizeof(unsigned int),1,f);
}
void read_string(FILE *f,unsigned char *p,int l)
{
gen_fread((char *)p,sizeof(unsigned char),l,f);
}
/* dummy functions, alternative functions */
double get_current_time()
{
return GetTickCount()/1000.0;
}
void shutdown_all(){}