aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2007-05-21 11:59:11 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2007-05-21 11:59:11 +0000
commit4f8e3ce7232c4f84814973b82b8143ab1f54f327 (patch)
treee2116b163b96216bd5be8b6e6a9457579b1f04b7
parent7dd7209d1c0f4d3a3d1ece0b3a4f9460477a14ba (diff)
added fz's [freadln] and [fwriteln]
svn path=/trunk/externals/zexy/; revision=7703
-rw-r--r--src/freadln.c221
-rw-r--r--src/fwriteln.c160
-rw-r--r--src/z_zexy.c2
-rw-r--r--src/z_zexy.h2
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 */