diff options
author | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2007-05-21 11:59:11 +0000 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2007-05-21 11:59:11 +0000 |
commit | 4f8e3ce7232c4f84814973b82b8143ab1f54f327 (patch) | |
tree | e2116b163b96216bd5be8b6e6a9457579b1f04b7 | |
parent | 7dd7209d1c0f4d3a3d1ece0b3a4f9460477a14ba (diff) |
added fz's [freadln] and [fwriteln]
svn path=/trunk/externals/zexy/; revision=7703
-rw-r--r-- | src/freadln.c | 221 | ||||
-rw-r--r-- | src/fwriteln.c | 160 | ||||
-rw-r--r-- | src/z_zexy.c | 2 | ||||
-rw-r--r-- | src/z_zexy.h | 2 |
4 files changed, 385 insertions, 0 deletions
diff --git a/src/freadln.c b/src/freadln.c new file mode 100644 index 0000000..fea9181 --- /dev/null +++ b/src/freadln.c @@ -0,0 +1,221 @@ + +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) Franz Zotter + * + * 2105:forum::für::umläute:2007 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <fcntl.h> + +#ifdef __WIN32__ +# include <io.h> +#else +# include <sys/types.h> +# include <unistd.h> +#endif + +#define MIN_FREADLN_LENGTH 10 + +/* freadln: reads messages continuously from the lines of + * a file that doesn't necessarily need to fit + * into the RAM of your system + * + * Franz Zotter zotter@iem.at, 2007 + * Institute of Electronic Music and Acoustics + * + */ + +static t_class *freadln_class; + +typedef struct freadln +{ + t_object x_ob; + FILE *x_file; + char *x_filename; + char *x_textbuf; + int x_textbuf_length; + t_outlet *x_message_outlet; + t_outlet *x_readybang_outlet; +} t_freadln; + + +static void freadln_close (t_freadln *x) +{ + if(x->x_file) + fclose(x->x_file); + x->x_file=0; + if(x->x_filename) + freebytes(x->x_filename, sizeof(char)*MAXPDSTRING); + x->x_filename=0; + if(x->x_textbuf) + freebytes(x->x_textbuf, sizeof(char)*x->x_textbuf_length); + x->x_textbuf=0; + x->x_textbuf_length=0; +} + +static void freadln_open (t_freadln *x, t_symbol *s, t_symbol*type) +{ + char filenamebuf[MAXPDSTRING], *filenamebufptr; + int fd; + freadln_close(x); + + if(type!=gensym("cr")) { + pd_error(x, "currently only 'cr' type files are implemented!"); + return; + } + + // directory, filename, extension, dirresult, nameresult, unsigned int size, int bin + if ((fd=open_via_path("",s->s_name,"", filenamebuf, &filenamebufptr, MAXPDSTRING,0))==-1) { + pd_error(x, "failed to open %128s", filenamebuf); + close(fd); + return; + } + close(fd); + if (!(x->x_file=fopen(filenamebuf, "r"))) { + pd_error(x, "failed to open %128s",filenamebuf); + return; + } + if (!(x->x_filename=(char*)getbytes(sizeof(char)*strlen(filenamebuf)))) { + pd_error(x, "out of memory"); + freadln_close(x); + return; + } + strcpy(x->x_filename,filenamebuf); + if (!(x->x_textbuf = (char *) getbytes (MIN_FREADLN_LENGTH * sizeof(char)))) { + pd_error(x, "out of memory"); + freadln_close(x); + return; + } + x->x_textbuf_length=MIN_FREADLN_LENGTH; +} + +static int enlarge_cstr_if_required(const char **c_str, int *len, const int desired_min_length) +{ + if ((!(*c_str))||*len==0) { + *c_str = (char*) calloc (1,sizeof(char)); + return 1; + } + if (len[0]<desired_min_length) { + do { + len[0]<<=1; + } while ((len[0]<desired_min_length)&&(len[0]!=0)); + freebytes((char*)*c_str, sizeof(char)*len[0]); + if (!(*c_str=(char*)calloc(len[0],sizeof(char)))) + len[0]=0; + } + return len[0]; +} + +static int cstr_char_pos(const char *c_str, const char c) +{ + int cnt=1; + if (c_str) { + do { + if (*c_str==c) + return cnt; + cnt++; + } while (*c_str++!='\0'); + } + return -1; +} + +static void freadln_readline (t_freadln *x) +{ + int min_length=(x->x_textbuf_length < 1)?1:x->x_textbuf_length; + int ret_pos=0; + t_binbuf *bbuf; + t_atom *abuf; + int abuf_length; + t_symbol *s; + + if (!x->x_file) { + pd_error(x, "no file opened for reading"); + return; + } + + do { + if (ret_pos==-1) { + min_length++; + fseek(x->x_file,-(long)(x->x_textbuf_length-1),SEEK_CUR); + } + if (!enlarge_cstr_if_required((const char**) &x->x_textbuf, &x->x_textbuf_length, min_length)) { + pd_error(x, "out of memory"); + x->x_textbuf_length=0; + freadln_close(x); + return; + } + if (!(fgets(x->x_textbuf, x->x_textbuf_length, x->x_file))) { + freadln_close(x); + outlet_bang(x->x_readybang_outlet); + return; + } + } while ((ret_pos=cstr_char_pos(x->x_textbuf,'\n'))==-1); + x->x_textbuf[ret_pos-1]='\0'; + //post("analyzing \"%s\"",x->x_textbuf); + if (!(bbuf=binbuf_new())) { + pd_error(x, "out of memory"); + freadln_close(x); + return; + } + binbuf_text(bbuf, x->x_textbuf, ret_pos-1); + abuf = binbuf_getvec(bbuf); + abuf_length = binbuf_getnatom(bbuf); + if (abuf_length>0) { + if (abuf->a_type==A_SYMBOL) { + outlet_anything(x->x_message_outlet, atom_getsymbol(abuf), abuf_length-1, abuf+1); + } + else { + outlet_list(x->x_message_outlet, gensym("list"), abuf_length, abuf); + } + } + else { + outlet_list(x->x_message_outlet, atom_getsymbol(abuf), 0, abuf); + } + // NOTE: the following line might be a problem in recursions + // and could be performed before to outlet_* as well, + // but(!) atom buffer abuf must be copied if doing so. + binbuf_free(bbuf); + +} +static void freadln_free (t_freadln *x) +{ + freadln_close(x); + outlet_free (x->x_message_outlet); + outlet_free (x->x_readybang_outlet); +} + +static void *freadln_new(void) +{ + t_freadln *x = (t_freadln *)pd_new(freadln_class); + x->x_message_outlet = outlet_new(&x->x_ob, &s_list); + x->x_readybang_outlet = outlet_new(&x->x_ob, &s_bang); + x->x_filename=0; + x->x_file=0; + x->x_textbuf=0; + return (void *)x; +} + +void freadln_setup(void) +{ + freadln_class = class_new(gensym("freadln"), (t_newmethod)freadln_new, + (t_method) freadln_free, sizeof(t_freadln), 0, 0); + class_addmethod(freadln_class, (t_method)freadln_open, gensym("open"), A_SYMBOL, A_DEFSYM, 0); + class_addmethod(freadln_class, (t_method)freadln_close, gensym("close"), A_NULL, 0); + class_addbang(freadln_class, (t_method)freadln_readline); +} + diff --git a/src/fwriteln.c b/src/fwriteln.c new file mode 100644 index 0000000..ad7a2f3 --- /dev/null +++ b/src/fwriteln.c @@ -0,0 +1,160 @@ +#include "m_pd.h" +#include <stdio.h> +#include <string.h> + +/* fwriteln: writes messages continuously into a file that + * doesn't necessarily need to fit into the RAM of your system + * + * Franz Zotter zotter@iem.at, 2007 + * Institute of Electronic Music and Acoustics + * + * parts of this externals were copied from Iohannes zmoelnig's + * iemmatrix + */ + +static t_class *fwriteln_class; + +typedef struct fwriteln +{ + t_object x_ob; + FILE *x_file; + char *x_filename; + char *x_textbuf; +} t_fwriteln; + + +static void fwriteln_close (t_fwriteln *x) +{ + if(x->x_file) + fclose(x->x_file); + x->x_file=0; + if(x->x_filename) + freebytes(x->x_filename, sizeof(char)*MAXPDSTRING); + x->x_filename=0; + if(x->x_textbuf) + freebytes(x->x_textbuf, sizeof(char)*MAXPDSTRING); + x->x_textbuf=0; +} + +static void fwriteln_open (t_fwriteln *x, t_symbol *s, t_symbol*type) +{ + char filename[MAXPDSTRING]; + sys_bashfilename (s->s_name, filename); + filename[MAXPDSTRING-1]=0; + fwriteln_close (x); + + if(0==type || type!=gensym("cr")) { + pd_error(x, "unknown type '%s'", (type)?type->s_name:""); + return; + } + + if (!(x->x_file=fopen(filename, "w"))) { + pd_error(x, "failed to open %128s",filename); + return; + } + x->x_filename=(char*)getbytes(sizeof(char)*strlen(filename)); + strcpy(x->x_filename,filename); + x->x_textbuf = (char *) getbytes (MAXPDSTRING * sizeof(char)); +} + +static void fwriteln_write (t_fwriteln *x, t_symbol *s, int argc, t_atom *argv) +{ + int length=0; + char *text=x->x_textbuf; + if (x->x_file) { + if ((s!=gensym("list"))||(argv->a_type==A_SYMBOL)) { + snprintf(text,MAXPDSTRING,"%s ", s->s_name); + text[MAXPDSTRING-1]=0; + length=strlen(text); + if (fwrite(text, length*sizeof(char),1,x->x_file) < 1) { + pd_error(x, "failed to write %128s",x->x_filename); + freebytes (text, MAXPDSTRING * sizeof(char)); + fwriteln_close(x); + return; + } + } + while (argc--) + { + switch (argv->a_type) { + case A_FLOAT: + snprintf(text,MAXPDSTRING,"%.16g ", atom_getfloat(argv)); + text[MAXPDSTRING-1]=0; + length=strlen(text); + if (fwrite(text, length*sizeof(char),1,x->x_file) < 1) { + pd_error(x, "failed to write %128s",x->x_filename); + freebytes (text, MAXPDSTRING * sizeof(char)); + fwriteln_close(x); + return; + } + break; + case A_SYMBOL: + snprintf(text,MAXPDSTRING,"%s ", atom_getsymbol(argv)->s_name); + text[MAXPDSTRING-1]=0; + length=strlen(text); + if (fwrite(text, length*sizeof(char),1,x->x_file) < 1) { + pd_error(x, "failed to write %128s",x->x_filename); + freebytes (text, MAXPDSTRING * sizeof(char)); + fwriteln_close(x); + return; + } + break; + case A_COMMA: + snprintf(text,MAXPDSTRING,", "); + length=strlen(text); + if (fwrite(text, length*sizeof(char),1,x->x_file) < 1) { + pd_error(x, "failed to write %128s",x->x_filename); + freebytes (text, MAXPDSTRING * sizeof(char)); + fwriteln_close(x); + return; + } + break; + case A_SEMI: + snprintf(text,MAXPDSTRING,"; "); + length=strlen(text); + if (fwrite(text, length*sizeof(char),1,x->x_file) < 1) { + pd_error(x, "failed to write %128s",x->x_filename); + freebytes (text, MAXPDSTRING * sizeof(char)); + fwriteln_close(x); + return; + } + break; + } + argv++; + } + + snprintf(text,MAXPDSTRING,"\n"); + length=strlen(text); + if (fwrite(text, length*sizeof(char),1,x->x_file) < 1) { + pd_error(x, "failed to write %128s",x->x_filename); + freebytes (text, MAXPDSTRING * sizeof(char)); + fwriteln_close(x); + return; + } + } + else { + pd_error(x, "no file opened for writing"); + } +} +static void fwriteln_free (t_fwriteln *x) +{ + fwriteln_close(x); +} + +static void *fwriteln_new(void) +{ + t_fwriteln *x = (t_fwriteln *)pd_new(fwriteln_class); + x->x_filename=0; + x->x_file=0; + x->x_textbuf=0; + return (void *)x; +} + +void fwriteln_setup(void) +{ + fwriteln_class = class_new(gensym("fwriteln"), (t_newmethod)fwriteln_new, + (t_method) fwriteln_free, sizeof(t_fwriteln), 0, 0); + class_addmethod(fwriteln_class, (t_method)fwriteln_open, gensym("open"), A_SYMBOL, A_DEFSYM, 0); + class_addmethod(fwriteln_class, (t_method)fwriteln_close, gensym("close"), A_NULL, 0); + class_addanything(fwriteln_class, (t_method)fwriteln_write); +} + diff --git a/src/z_zexy.c b/src/z_zexy.c index 258949f..92e0aa3 100644 --- a/src/z_zexy.c +++ b/src/z_zexy.c @@ -29,6 +29,8 @@ void z_zexy_setup(void) drip_setup(); /* drip */ envrms_tilde_setup(); /* envrms~ */ fifop_setup(); /* fifop */ + freadln_setup(); /* freadln */ + fwriteln_setup(); /* fwriteln */ glue_setup(); /* glue */ index_setup(); /* index */ length_setup(); /* length */ diff --git a/src/z_zexy.h b/src/z_zexy.h index 2a50ef5..0c9b2cf 100644 --- a/src/z_zexy.h +++ b/src/z_zexy.h @@ -27,6 +27,8 @@ void dirac_tilde_setup(void); /* dirac~ */ void drip_setup(void); /* drip */ void envrms_tilde_setup(void); /* envrms~ */ void fifop_setup(void); /* fifop */ +void freadln_setup(void); /* freadln */ +void fwriteln_setup(void); /* fwriteln */ void glue_setup(void); /* glue */ void index_setup(void); /* index */ void length_setup(void); /* length */ |