601 lines
17 KiB
C
601 lines
17 KiB
C
|
#define _FILE_OFFSET_BITS 64
|
||
|
#include <stdio.h>
|
||
|
#include "tlang.h"
|
||
|
|
||
|
int64_t _file_read(stream_t* strm,void* buff,int64_t len)
|
||
|
{
|
||
|
FILE* f = (FILE*)strm->ptr;
|
||
|
return fread(buff,1,(size_t)len,f);
|
||
|
}
|
||
|
void _file_write(stream_t* strm,void* buff,int64_t len)
|
||
|
{
|
||
|
FILE* f = (FILE*)strm->ptr;
|
||
|
fwrite(buff,1,(size_t)len,f);
|
||
|
}
|
||
|
int64_t _file_getpos(stream_t* strm)
|
||
|
{
|
||
|
return (int64_t)ftello((FILE*)strm->ptr);
|
||
|
}
|
||
|
void _file_setpos(stream_t* strm,int64_t nu)
|
||
|
{
|
||
|
|
||
|
fseeko((FILE*)strm->ptr,(off_t)nu,SEEK_SET);
|
||
|
}
|
||
|
void _file_free(stream_t* strm)
|
||
|
{
|
||
|
fclose((FILE*)strm->ptr);
|
||
|
}
|
||
|
int64_t _file_getlen(stream_t* strm)
|
||
|
{
|
||
|
fpos_t pos;
|
||
|
fgetpos((FILE*)strm->ptr,&pos);
|
||
|
fseeko((FILE*)strm->ptr,(off_t)0L,SEEK_END);
|
||
|
int64_t v=(int64_t)ftello((FILE*)strm->ptr);
|
||
|
fsetpos((FILE*)strm->ptr,&pos);
|
||
|
return v;
|
||
|
}
|
||
|
void _file_flush(stream_t* strm)
|
||
|
{
|
||
|
fflush((FILE*)strm->ptr);
|
||
|
}
|
||
|
stream_t* stream_create_file(FILE* f,stream_bool_t canread,stream_bool_t canwrite,stream_bool_t canseek)
|
||
|
{
|
||
|
return stream_create(f,_file_read,_file_write,_file_getpos,_file_getlen,_file_setpos,canread,canwrite,canseek,_file_free,_file_flush);
|
||
|
}
|
||
|
stream_t* stream_create(
|
||
|
void* ptr,
|
||
|
stream_read_t read,
|
||
|
stream_write_t write,
|
||
|
stream_get_t getpos,
|
||
|
stream_get_t getlength,
|
||
|
stream_set_t setpos,
|
||
|
stream_bool_t canread,
|
||
|
stream_bool_t canwrite,
|
||
|
stream_bool_t canseek,
|
||
|
stream_free_t free,
|
||
|
stream_free_t flush
|
||
|
)
|
||
|
{
|
||
|
stream_t* strm = (stream_t*)malloc(sizeof(stream_t));
|
||
|
strm->ptr = ptr;
|
||
|
strm->read = read;
|
||
|
strm->write =write;
|
||
|
strm->getpos = getpos;
|
||
|
strm->setpos = setpos;
|
||
|
strm->getlength = getlength;
|
||
|
strm->canread = canread;
|
||
|
strm->canwrite =canwrite;
|
||
|
strm->canseek = canseek;
|
||
|
strm->free = free;
|
||
|
strm->flush = flush;
|
||
|
strm->set_extra_methods = NULL;
|
||
|
return strm;
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
scope_t* s;
|
||
|
tobject_t* o;
|
||
|
bool closeStrm;
|
||
|
/* data */
|
||
|
} __toStrm;
|
||
|
|
||
|
int64_t __tobject_read(stream_t* strm,void* ptr,int64_t len)
|
||
|
{
|
||
|
uint8_t* pt = (uint8_t*)ptr;
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
tobject_t* r=tobject_create_array(_strm->s->rt,(int)len);
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"read"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"read")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
list_add(&g,r);
|
||
|
list_add(&g,tobject_number(_strm->s->rt,len));
|
||
|
tobject_t* fg=tobject_call(_strm->s,f,&g);
|
||
|
len = (int64_t)fg->data.number;
|
||
|
tobject_freeifzero(fg);
|
||
|
int i;
|
||
|
for(i=0;i<len;i++)
|
||
|
{
|
||
|
tobject_t* oe = r->data.list.items[i];
|
||
|
if(oe->type == tnumber)
|
||
|
{
|
||
|
pt[i] = (uint8_t)oe->data.number;
|
||
|
}
|
||
|
}
|
||
|
list_free(&g);
|
||
|
return len;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
void __tobject_write(stream_t* strm,void* ptr,int64_t len)
|
||
|
{
|
||
|
uint8_t* pt = (uint8_t*)ptr;
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
tobject_t* r=tobject_create_array(_strm->s->rt,0);
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"write"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"write")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
list_add(&g,r);
|
||
|
list_add(&g,tobject_number(_strm->s->rt,len));
|
||
|
|
||
|
int i;
|
||
|
for(i=0;i<len;i++)
|
||
|
{
|
||
|
list_add(&r->data.list,tobject_number(_strm->s->rt,(double)pt[i]));
|
||
|
|
||
|
}
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
int64_t __tobject_getlength(stream_t* strm)
|
||
|
{
|
||
|
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"getlength"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"getlength")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
double r = j->data.number;
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
return (int64_t)r;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
bool __tobject_canread(stream_t* strm)
|
||
|
{
|
||
|
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"canread"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"canread")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
bool r = tobject_tobool(j);
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
return r;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool __tobject_canseek(stream_t* strm)
|
||
|
{
|
||
|
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"canseek"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"canseek")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
bool r = tobject_tobool(j);
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
return r;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
bool __tobject_canwrite(stream_t* strm)
|
||
|
{
|
||
|
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"canwrite"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"canwrite")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
bool r = tobject_tobool(j);
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
return r;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
void __tobject_flush(stream_t* strm)
|
||
|
{
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"flush"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"flush")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
int64_t __tobject_getpos(stream_t* strm)
|
||
|
{
|
||
|
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"getposition"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"getposition")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
double r = j->data.number;
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
return (int64_t)r;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
void __tobject_setpos(stream_t* strm,int64_t len)
|
||
|
{
|
||
|
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"setposition"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"setposition")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
list_add(&g,tobject_number(_strm->s->rt,(double)len));
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
void __tobject_strm_free(stream_t* strm)
|
||
|
{
|
||
|
__toStrm* _strm= (__toStrm*)strm->ptr;
|
||
|
_strm->o->count--;
|
||
|
if(_strm->o->count <= 0 || _strm->closeStrm)
|
||
|
{
|
||
|
_strm->o->count=1;
|
||
|
if(_strm->o->type == tdict && dict_haskey(_strm->o->data.dict,"close"))
|
||
|
{
|
||
|
tobject_t* f = dict_getkvp(_strm->o->data.dict,"close")->value;
|
||
|
list_tobject_t g;
|
||
|
list_create(_strm->s->rt,&g,0);
|
||
|
|
||
|
|
||
|
tobject_t* j=tobject_call(_strm->s,f,&g);
|
||
|
|
||
|
tobject_freeifzero(j);
|
||
|
list_free(&g);
|
||
|
}
|
||
|
tobject_rmref(_strm->o);
|
||
|
}
|
||
|
free(_strm);
|
||
|
}
|
||
|
stream_t* tobject_tostream(scope_t* s,tobject_t* obj,bool closeStream)
|
||
|
{
|
||
|
__toStrm* strm = (__toStrm*)malloc(sizeof(__toStrm));
|
||
|
strm->s=s;
|
||
|
strm->o = obj;
|
||
|
strm->o->count++;
|
||
|
strm->closeStrm = closeStream;
|
||
|
return stream_create(strm,__tobject_read,__tobject_write,__tobject_getpos,__tobject_getlength,__tobject_setpos,__tobject_canread,__tobject_canwrite,__tobject_canseek,__tobject_strm_free,__tobject_flush);
|
||
|
}
|
||
|
tobject_t* __write_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(!strm->canwrite(strm) || strm->write == NULL) return tobject_number(rt,0);
|
||
|
if(obj->length >= 2)
|
||
|
{
|
||
|
tobject_t* array = obj->items[0];
|
||
|
int len = 0;
|
||
|
int offset=0;
|
||
|
if(obj->items[1]->type == tnumber)
|
||
|
{
|
||
|
len = (int)obj->items[1]->data.number;
|
||
|
if(obj->length >= 3 && obj->items[2]->type == tnumber)
|
||
|
{
|
||
|
offset = (int)obj->items[2]->data.number;
|
||
|
}
|
||
|
|
||
|
int a = array->data.list.length-offset;
|
||
|
int totalRead = len;
|
||
|
if(a < totalRead)
|
||
|
{
|
||
|
totalRead = a;
|
||
|
}
|
||
|
uint8_t* buffer = (uint8_t*)malloc(totalRead);
|
||
|
int i;
|
||
|
for(i=0;i<totalRead;i++)
|
||
|
{
|
||
|
tobject_t* o = array->data.list.items[offset+i];
|
||
|
if(o->type == tnumber)
|
||
|
{
|
||
|
buffer[i] = (uint8_t)o->data.number;
|
||
|
}
|
||
|
else if(o->type == tchar)
|
||
|
{
|
||
|
buffer[i] = (uint8_t)o->data.chr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
strm->write(strm,buffer,totalRead);
|
||
|
|
||
|
|
||
|
free(buffer);
|
||
|
return tobject_number(rt,totalRead);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
return tobject_number(rt,0);
|
||
|
}
|
||
|
tobject_t* __read_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(!strm->canread(strm) || strm->read == NULL) return tobject_number(rt,0);
|
||
|
if(obj->length >= 2)
|
||
|
{
|
||
|
tobject_t* array = obj->items[0];
|
||
|
int len = 0;
|
||
|
int offset=0;
|
||
|
if(obj->items[1]->type == tnumber)
|
||
|
{
|
||
|
len = (int)obj->items[1]->data.number;
|
||
|
if(obj->length >= 3 && obj->items[2]->type == tnumber)
|
||
|
{
|
||
|
offset = (int)obj->items[2]->data.number;
|
||
|
}
|
||
|
|
||
|
int a = array->data.list.length-offset;
|
||
|
int totalRead = len;
|
||
|
if(a < totalRead)
|
||
|
{
|
||
|
totalRead = a;
|
||
|
}
|
||
|
uint8_t* buffer = (uint8_t*)malloc(totalRead);
|
||
|
totalRead=strm->read(strm,buffer,totalRead);
|
||
|
int i;
|
||
|
for(i = 0;i<totalRead;i++)
|
||
|
{
|
||
|
list_set(&array->data.list,i+offset,tobject_number(rt,buffer[i]));
|
||
|
}
|
||
|
free(buffer);
|
||
|
return tobject_number(rt,totalRead);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
return tobject_number(rt,0);
|
||
|
}
|
||
|
tobject_t* __set_pos(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(strm->setpos == NULL || obj->length == 0 || obj->items[0]->type != tnumber) return tobject_basic(rt,tnull);
|
||
|
strm->setpos(strm,(int64_t)obj->items[0]->data.number);
|
||
|
return tobject_basic(rt,tnull);
|
||
|
}
|
||
|
tobject_t* __get_pos(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(strm->getpos == NULL) return tobject_number(rt,0);
|
||
|
return tobject_number(rt,strm->getpos(strm));
|
||
|
}
|
||
|
tobject_t* __get_len(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(strm->getlength == NULL) return tobject_number(rt,0);
|
||
|
return tobject_number(rt,strm->getlength(strm));
|
||
|
}
|
||
|
tobject_t* __can_read_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(strm->canread == NULL) return tobject_bool(rt,false);
|
||
|
return tobject_bool(rt,strm->canread(strm));
|
||
|
}
|
||
|
tobject_t* __can_write_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(strm->canwrite == NULL) return tobject_bool(rt,false);
|
||
|
return tobject_bool(rt,strm->canwrite(strm));
|
||
|
}
|
||
|
tobject_t* __can_seek_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(strm->canseek == NULL) return tobject_bool(rt,false);
|
||
|
return tobject_bool(rt,strm->canseek(strm));
|
||
|
}
|
||
|
tobject_t* __read_byte(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
if(!strm->canread(strm) || strm->read == NULL) return tobject_number(rt,-1);
|
||
|
uint8_t r[1];
|
||
|
int r2=strm->read(strm,r,1);
|
||
|
return tobject_number(rt,r2 == 1 ? r[0] : -1);
|
||
|
}
|
||
|
tobject_t* __close_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
stream_free(strm);
|
||
|
return tobject_basic(rt,tundef);
|
||
|
}
|
||
|
tobject_t* __flush_func(runtime_t* rt,void* ptr,list_tobject_t* obj)
|
||
|
{
|
||
|
stream_t* strm=(stream_t*)ptr;
|
||
|
stream_flush(strm);
|
||
|
return tobject_basic(rt,tundef);
|
||
|
}
|
||
|
tobject_t* tobject_fromstream(runtime_t* rt,stream_t* strm)
|
||
|
{
|
||
|
tobject_t* _strm = tobject_create(rt);
|
||
|
_strm->type = tdict;
|
||
|
_strm->data.dict=dict_create();
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"read",rt,strm,__read_func,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"write",rt,strm,__write_func,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"setposition",rt,strm,__set_pos,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getposition",rt,strm,__get_pos,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getlength",rt,strm,__get_len,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getcount",rt,strm,__get_len,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"readbyte",rt,strm,__read_byte,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getnextbyte",rt,strm,__read_byte,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getcanread",rt,strm,__can_read_func,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getcanwrite",rt,strm,__can_write_func,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"getcanseek",rt,strm,__can_seek_func,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"close",rt,strm,__close_func,NULL);
|
||
|
runtime_create_method_on_dict(_strm->data.dict,"flush",rt,strm,__flush_func,NULL);
|
||
|
if(strm->set_extra_methods != NULL)
|
||
|
{
|
||
|
strm->set_extra_methods(strm,_strm,rt,strm->set_extra_methods_data);
|
||
|
}
|
||
|
return _strm;
|
||
|
}
|
||
|
int64_t stream_read(stream_t* strm,void* buff,int64_t len)
|
||
|
{
|
||
|
if(strm->read != NULL)
|
||
|
strm->read(strm,buff,len);
|
||
|
return 0;
|
||
|
}
|
||
|
void stream_write(stream_t* strm,void* buffer,int64_t len)
|
||
|
{
|
||
|
if(strm->write != NULL)
|
||
|
strm->write(strm,buffer,len);
|
||
|
}
|
||
|
int64_t stream_getpos(stream_t* strm)
|
||
|
{
|
||
|
if(strm->getpos == NULL) return 0;
|
||
|
return strm->getpos(strm);
|
||
|
}
|
||
|
void stream_flush(stream_t* strm)
|
||
|
{
|
||
|
if(strm->flush != NULL)
|
||
|
strm->flush(strm);
|
||
|
}
|
||
|
int64_t stream_getlength(stream_t* strm)
|
||
|
{
|
||
|
if(strm->getpos == NULL) return 0;
|
||
|
return strm->getlength(strm);
|
||
|
}
|
||
|
void stream_setpos(stream_t* strm,int64_t pos)
|
||
|
{
|
||
|
if(strm->setpos != NULL)
|
||
|
strm->setpos(strm,pos);
|
||
|
}
|
||
|
bool stream_canread(stream_t* strm)
|
||
|
{
|
||
|
if(strm->canread != NULL)
|
||
|
return strm->canread(strm);
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
bool stream_canwrite(stream_t* strm)
|
||
|
{
|
||
|
if(strm->canwrite != NULL)
|
||
|
return strm->canwrite(strm);
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
bool stream_canseek(stream_t* strm)
|
||
|
{
|
||
|
if(strm->canseek != NULL)
|
||
|
return strm->canseek(strm);
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
stream_t* stream_stdin()
|
||
|
{
|
||
|
stream_t* strm=stream_create_file(stdin,stream_true,stream_false,stream_false);
|
||
|
strm->free=NULL;
|
||
|
return strm;
|
||
|
}
|
||
|
stream_t* stream_stdout()
|
||
|
{
|
||
|
stream_t* strm=stream_create_file(stdout,stream_false,stream_true,stream_false);
|
||
|
strm->free=NULL;
|
||
|
return strm;
|
||
|
}
|
||
|
stream_t* stream_stderr()
|
||
|
{
|
||
|
stream_t* strm=stream_create_file(stderr,stream_false,stream_true,stream_false);
|
||
|
strm->free=NULL;
|
||
|
return strm;
|
||
|
}
|
||
|
void stream_free(stream_t* strm)
|
||
|
{
|
||
|
if(strm->free != NULL)
|
||
|
strm->free(strm);
|
||
|
free(strm);
|
||
|
}
|
||
|
|
||
|
bool stream_true(stream_t* strm)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool stream_false(stream_t* stream)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
stream_t* stream_file_create(string_t* str)
|
||
|
{
|
||
|
char* fname=string_dupp(str);
|
||
|
FILE* f=fopen(fname,"wb");
|
||
|
free(fname);
|
||
|
return stream_create_file(f,stream_false,stream_true,stream_true);
|
||
|
|
||
|
}
|
||
|
stream_t* stream_file_openread(string_t* str)
|
||
|
{
|
||
|
char* fname=string_dupp(str);
|
||
|
FILE* f=fopen(fname,"rb");
|
||
|
free(fname);
|
||
|
return stream_create_file(f,stream_true,stream_false,stream_true);
|
||
|
|
||
|
}
|
||
|
stream_t* stream_file_openreadwrite(string_t* str)
|
||
|
{
|
||
|
char* fname=string_dupp(str);
|
||
|
FILE* f=fopen(fname,"r+b");
|
||
|
free(fname);
|
||
|
return stream_create_file(f,stream_true,stream_true,stream_true);
|
||
|
|
||
|
}
|
||
|
stream_t* stream_file_readappend(string_t* str)
|
||
|
{
|
||
|
char* fname=string_dupp(str);
|
||
|
FILE* f=fopen(fname,"a+b");
|
||
|
free(fname);
|
||
|
return stream_create_file(f,stream_true,stream_true,stream_true);
|
||
|
|
||
|
}
|
||
|
stream_t* stream_file_append(string_t* str)
|
||
|
{
|
||
|
char* fname=string_dupp(str);
|
||
|
FILE* f=fopen(fname,"ab");
|
||
|
free(fname);
|
||
|
return stream_create_file(f,stream_false,stream_true,stream_false);
|
||
|
|
||
|
}
|