/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iemlib2 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ #include "m_pd.h" #include "iemlib.h" #include #include #include #include /* ---------------------------- iem_pbank_csv ------------------------------- */ /* -- is a list storage and management object, can store an array of lists -- */ /* ------------------------------- as an csv file --------------------------- */ /* read and write method needs 2 symbols, 1. symbol is a filename, 2. symbol is a 3 character descriptor 1.char: 'b'...for blank as ITEM_SEPARATOR (" ") 1.char: 'c'...for comma as ITEM_SEPARATOR (",") 1.char: 's'...for semicolon as ITEM_SEPARATOR (";") 1.char: 't'...for tabulator as ITEM_SEPARATOR (" " = 0x09) 2.char: 'b'...for blank,return as END_OF_LINE (" \n") 2.char: 'r'...for return-only as END_OF_LINE ("\n") 2.char: 's'...for semicolon,return as END_OF_LINE (";\n") 3.char: 'l'...for linux RETURN (0x0A) 3.char: 'w'...for windows RETURN (0x0D,0x0A) 3.char: 'm'...for mac RETURN (0x0D) change: recall + offset + number */ static t_class *iem_pbank_csv_class; typedef struct _iem_pbank_csv { t_object x_obj; int x_nr_para; int x_nr_line; int x_line; t_atom *x_atbegmem; t_atom *x_atbegbuf; t_atom *x_atbegout; t_canvas *x_canvas; void *x_list_out; void *x_offset_list_out; } t_iem_pbank_csv; static void iem_pbank_csv_write(t_iem_pbank_csv *x, t_symbol *filename, t_symbol *format) { char completefilename[400], eol[4], sep, mode[4], string[200]; int size, p, l, nrl=x->x_nr_line, nrp=x->x_nr_para; int state, max=nrl*nrp, org_size, eollen; FILE *fh; t_atom *ap=x->x_atbegmem; char formattext[100]; strcpy(mode, "bsl"); /*blank-separator, semicolon-return-eol, linux_return*/ sep = ' '; eol[0] = ';'; eol[1] = 0x0a; eol[2] = 0; if(filename->s_name[0] == '/') { strcpy(completefilename, filename->s_name); } else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')|| (filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&& (filename->s_name[1] == ':')&&(filename->s_name[2] == '/')) { strcpy(completefilename, filename->s_name); } else { strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name); strcat(completefilename, "/"); strcat(completefilename, filename->s_name); } fh = fopen(completefilename,"wb"); if(!fh) { post("iem_pbank_csv_write: cannot create %s !!\n", completefilename); } else { if(strlen(format->s_name) >= 3) { for(p=0; p<3; p++) { if((format->s_name[p] >= 'A')&&(format->s_name[p] <= 'Z')) format->s_name[p] += 'a' - 'A'; } if((format->s_name[0] == 'b')||(format->s_name[0] == 'c')||(format->s_name[0] == 's')||(format->s_name[0] == 't')) mode[0] = format->s_name[0]; if((format->s_name[1] == 'b')||(format->s_name[1] == 'r')||(format->s_name[1] == 's')) mode[1] = format->s_name[1]; if((format->s_name[2] == 'l')||(format->s_name[2] == 'w')||(format->s_name[2] == 'm')) mode[2] = format->s_name[2]; } else post("iem_pbank_csv_write: use default format %s !!\n", mode); if(mode[0] == 'b') { sep = ' '; strcpy(formattext, "item-separator = BLANK; "); } else if(mode[0] == 'c') { sep = ','; strcpy(formattext, "item-separator = COMMA; "); } else if(mode[0] == 's') { sep = ';'; strcpy(formattext, "item-separator = SEMICOLON; "); } else if(mode[0] == 't') { sep = 0x09; strcpy(formattext, "item-separator = TABULATOR; "); } eollen = 1; if(mode[1] == 'b') { eol[0] = ' '; strcat(formattext, "end_of_line_terminator = BLANK-RETURN in "); } else if(mode[1] == 'r') { eollen = 0; strcat(formattext, "end_of_line_terminator = RETURN in "); } else if(mode[1] == 's') { eol[0] = ';'; strcat(formattext, "end_of_line_terminator = SEMICOLON-RETURN in "); } if(mode[2] == 'l') { eol[eollen++] = 0x0a; strcat(formattext, "LINUX-Format."); } else if(mode[2] == 'w') { eol[eollen++] = 0x0d; eol[eollen++] = 0x0a; strcat(formattext, "WINDOWS-Format."); } else if(mode[2] == 'm') { eol[eollen++] = 0x0d; strcat(formattext, "MACINTOSH-Format."); } eol[eollen] = 0; ap = x->x_atbegmem; for(l=0; la_w.w_float, sep); else if(IS_A_SYMBOL(ap, 0)) fprintf(fh, "%s%c", ap->a_w.w_symbol->s_name, sep); ap++; } if(IS_A_FLOAT(ap, 0)) fprintf(fh, "%g%s", ap->a_w.w_float, eol); else if(IS_A_SYMBOL(ap, 0)) fprintf(fh, "%s%s", ap->a_w.w_symbol->s_name, eol); ap++; } fclose(fh); post("iem_pbank_csv: wrote %d parameters x %d lines to file:\n%s\nwith following format:\n%s\n", nrp, nrl, completefilename, formattext); } } int iem_pbank_csv_text2atom(char *text, int text_size, t_atom **at_beg, int *nalloc, char sep, char eol) { char buf[MAXPDSTRING+1], *bufp, *ebuf = buf+MAXPDSTRING; const char *textp = text, *etext = text + text_size; int natom = 0; t_atom *ap = *at_beg; t_float f; while(1) { int type; if(textp == etext) break; if(*textp == eol) { SETSEMI(ap); textp++; } else if(*textp == sep) { SETCOMMA(ap); textp++; } else { char c; int flst = 0, slash = 0, lastslash = 0; int firstslash = (*textp == '\\'); bufp = buf; do { c = *bufp = *textp++; lastslash = slash; slash = (c == '\\'); if (flst >= 0) { int digit = (c >= '0' && c <= '9'), dot = (c == '.'), minus = (c == '-'), plusminus = (minus || (c == '+')), expon = (c == 'e' || c == 'E'); if (flst == 0) /* beginning */ { if (minus) flst = 1; else if (digit) flst = 2; else if (dot) flst = 3; else flst = -1; } else if (flst == 1) /* got minus */ { if (digit) flst = 2; else if (dot) flst = 3; else flst = -1; } else if (flst == 2) /* got digits */ { if (dot) flst = 4; else if (expon) flst = 6; else if (!digit) flst = -1; } else if (flst == 3) /* got '.' without digits */ { if (digit) flst = 5; else flst = -1; } else if (flst == 4) /* got '.' after digits */ { if (digit) flst = 5; else if (expon) flst = 6; else flst = -1; } else if (flst == 5) /* got digits after . */ { if (expon) flst = 6; else if (!digit) flst = -1; } else if (flst == 6) /* got 'e' */ { if (plusminus) flst = 7; else if (digit) flst = 8; else flst = -1; } else if (flst == 7) /* got plus or minus */ { if (digit) flst = 8; else flst = -1; } else if (flst == 8) /* got digits */ { if (!digit) flst = -1; } } if (!slash) bufp++; } while (textp != etext && bufp != ebuf && *textp != ' ' && (slash || (*textp != sep && *textp != eol))); *bufp = 0; if(*buf == '$' && buf[1] >= '0' && buf[1] <= '9' && !firstslash) { for (bufp = buf+2; *bufp; bufp++) if (*bufp < '0' || *bufp > '9') { SETDOLLSYM(ap, gensym(buf+1)); goto iem_pbank_csv_didit; } SETDOLLAR(ap, atoi(buf+1)); iem_pbank_csv_didit: ; } else { if(flst == 2 || flst == 4 || flst == 5 || flst == 8) { f = atof(buf); if((f < 1.0e-20)&&(f > -1.0e-20)) f = 0.0; SETFLOAT(ap, f); } else SETSYMBOL(ap, gensym(buf)); } } ap++; natom++; if(natom == *nalloc) { *at_beg = t_resizebytes(*at_beg, *nalloc * sizeof(t_atom), *nalloc * (2*sizeof(t_atom))); *nalloc = *nalloc * 2; ap = *at_beg + natom; } if(textp == etext) break; } return(natom); } /*static char myq(t_atom *a, int off) { char c='0'; if(IS_A_SEMI(a,off)) c = 's'; else if(IS_A_COMMA(a,off)) c = 'c'; else if(IS_A_FLOAT(a,off)) c = 'f'; else if(IS_A_SYMBOL(a,off)) c = 'y'; return(c); } */ static void iem_pbank_csv_read(t_iem_pbank_csv *x, t_symbol *filename, t_symbol *format) { char completefilename[400], eol[4], sep, mode[4], *txbuf1, *txbuf2, *txvec_src, *txvec_dst; int size, p, l, i, j, nrl=x->x_nr_line, nrp=x->x_nr_para, atlen=0; int txlen, txalloc, hat_alloc, max, eollen; FILE *fh; t_atom *ap, *hap, *at; char formattext[100]; strcpy(mode, "bsl"); /*blank-separator, semicolon-return-eol, linux_return*/ sep = ' '; eol[0] = ';'; eol[1] = 0x0a; eol[2] = 0; if(filename->s_name[0] == '/')/*make complete path + filename*/ { strcpy(completefilename, filename->s_name); } else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')|| (filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&& (filename->s_name[1] == ':')&&(filename->s_name[2] == '/')) { strcpy(completefilename, filename->s_name); } else { strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name); strcat(completefilename, "/"); strcat(completefilename, filename->s_name); } fh = fopen(completefilename,"rb"); if(!fh) { post("iem_pbank_csv_read: cannot open %s !!\n", completefilename); } else { if(strlen(format->s_name) >= 3) { for(p=0; p<3; p++) { if((format->s_name[p] >= 'A')&&(format->s_name[p] <= 'Z')) format->s_name[p] += 'a' - 'A'; } if((format->s_name[0] == 'b')||(format->s_name[0] == 'c')||(format->s_name[0] == 's')||(format->s_name[0] == 't')) mode[0] = format->s_name[0]; if((format->s_name[1] == 'b')||(format->s_name[1] == 'r')||(format->s_name[1] == 's')) mode[1] = format->s_name[1]; if((format->s_name[2] == 'l')||(format->s_name[2] == 'w')||(format->s_name[2] == 'm')) mode[2] = format->s_name[2]; } else post("iem_pbank_csv_read: use default format %s !!\n", mode); if(mode[0] == 'b') { sep = ' '; strcpy(formattext, "item-separator = BLANK; "); } else if(mode[0] == 'c') { sep = ','; strcpy(formattext, "item-separator = COMMA; "); } else if(mode[0] == 's') { sep = ';'; strcpy(formattext, "item-separator = SEMICOLON; "); } else if(mode[0] == 't') { sep = 0x09; strcpy(formattext, "item-separator = TABULATOR; "); } eollen = 1; if(mode[1] == 'b') { eol[0] = ' '; strcat(formattext, "end_of_line_terminator = BLANK-RETURN in "); } else if(mode[1] == 'r') { eollen = 0; strcat(formattext, "end_of_line_terminator = RETURN in "); } else if(mode[1] == 's') { eol[0] = ';'; strcat(formattext, "end_of_line_terminator = SEMICOLON-RETURN in "); } if(mode[2] == 'l') { eol[eollen++] = 0x0a; strcat(formattext, "LINUX-Format."); } else if(mode[2] == 'w') { eol[eollen++] = 0x0d; eol[eollen++] = 0x0a; strcat(formattext, "WINDOWS-Format."); } else if(mode[2] == 'm') { eol[eollen++] = 0x0d; strcat(formattext, "MACINTOSH-Format."); } eol[eollen] = 0; fseek(fh, 0, SEEK_END); txalloc = ftell(fh); fseek(fh,0,SEEK_SET); txbuf1 = (char *)getbytes(2 * txalloc * sizeof(char)); txbuf2 = (char *)getbytes(2 * txalloc * sizeof(char)); fread(txbuf1, sizeof(char), txalloc, fh); fclose(fh); txvec_src = txbuf1; txvec_dst = txbuf2; p = 0; for(l=0; l= 20) { post("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",myq(ap,0),myq(ap,1),myq(ap,2),myq(ap,3),myq(ap,4),myq(ap,5),myq(ap,6),myq(ap,7),myq(ap,8),myq(ap,9),myq(ap,10),myq(ap,11),myq(ap,12),myq(ap,13),myq(ap,14),myq(ap,15),myq(ap,16),myq(ap,17),myq(ap,18),myq(ap,19)); ap += 20; i -= 20; } */ at = x->x_atbegmem; for(l=0; lx_atbegmem; ap = hap; nrp++; i = 0; /* atom-counter */ j = 0; for(l=0; la_w.w_float); /*post("float");*/ p++; i++; at++; } else if(IS_A_SYMBOL(ap,0)) { SETSYMBOL(at, ap->a_w.w_symbol); /*post("sym");*/ p++; i++; at++; } else if(IS_A_SEMI(ap,0)) { /*post("semi");*/ for(; px_nr_para; t_atom *atbuf=x->x_atbegbuf, *atmem=x->x_atbegmem; t_atom *atout=x->x_atbegout; if(ac >= 2) nrp = atom_getintarg(1, ac, av); if(ac >= 1) beg = atom_getintarg(0, ac, av); if(beg < 0) beg = 0; else if(beg >= x->x_nr_para) beg = x->x_nr_para - 1; if(nrp < 0) nrp = 0; else if((beg+nrp) > x->x_nr_para) nrp = x->x_nr_para - beg; atmem += x->x_nr_para * x->x_line + beg; atbuf += beg; SETFLOAT(atout, (t_float)beg); atout++; for(i=0; ix_offset_list_out, &s_list, nrp+1, x->x_atbegout); outlet_list(x->x_list_out, &s_list, nrp, x->x_atbegout+1); } static void iem_pbank_csv_bang(t_iem_pbank_csv *x) { int i, nrp=x->x_nr_para; t_atom *atbuf=x->x_atbegbuf; t_atom *atout=x->x_atbegout; SETFLOAT(atout, 0.0f); atout++; for(i=0; ix_offset_list_out, &s_list, nrp+1, x->x_atbegout); outlet_list(x->x_list_out, &s_list, nrp, x->x_atbegout+1); } static void iem_pbank_csv_store(t_iem_pbank_csv *x, t_symbol *s, int ac, t_atom *av) { int i, beg=0, nrp=x->x_nr_para; t_atom *atbuf=x->x_atbegbuf, *atmem=x->x_atbegmem; if(ac >= 2) nrp = atom_getintarg(1, ac, av); if(ac >= 1) beg = atom_getintarg(0, ac, av); if(beg < 0) beg = 0; else if(beg >= x->x_nr_para) beg = x->x_nr_para - 1; if(nrp < 0) nrp = 0; else if((beg+nrp) > x->x_nr_para) nrp = x->x_nr_para - beg; atmem += x->x_nr_para * x->x_line; atmem += beg; atbuf += beg; for(i=0; i= 2) { int para_index = atom_getintarg(0, ac, av); if(para_index >= 0) { if((para_index+ac-1) <= x->x_nr_para) { int i; for(i=1; ix_atbegbuf[para_index] = av[i]; para_index++; } } } } } static void iem_pbank_csv_ft1(t_iem_pbank_csv *x, t_floatarg fline_nr) { int line = (int)fline_nr; if(line < 0) line = 0; else if(line >= x->x_nr_line) line = x->x_nr_line - 1; x->x_line = line; } static void iem_pbank_csv_free(t_iem_pbank_csv *x) { freebytes(x->x_atbegmem, x->x_nr_para * x->x_nr_line * sizeof(t_atom)); freebytes(x->x_atbegbuf, x->x_nr_para * sizeof(t_atom)); freebytes(x->x_atbegout, (x->x_nr_para+1) * sizeof(t_atom)); } static void *iem_pbank_csv_new(t_symbol *s, int ac, t_atom *av) { t_iem_pbank_csv *x = (t_iem_pbank_csv *)pd_new(iem_pbank_csv_class); int nrpp=0, nrp=10, nrl=10, p, l, i; t_atom *ap; if((ac >= 1) && IS_A_FLOAT(av,0)) nrp = atom_getintarg(0, ac, av); if((ac >= 2) && IS_A_FLOAT(av,1)) nrl = atom_getintarg(1, ac, av); if(nrp <= 0) nrp = 10; if(nrl <= 0) nrl = 10; x->x_line = 0; x->x_nr_para = nrp; x->x_nr_line = nrl; x->x_atbegmem = (t_atom *)getbytes(x->x_nr_para * x->x_nr_line * sizeof(t_atom)); x->x_atbegbuf = (t_atom *)getbytes(x->x_nr_para * sizeof(t_atom)); x->x_atbegout = (t_atom *)getbytes((x->x_nr_para+1) * sizeof(t_atom)); ap = x->x_atbegmem; for(l=0; lx_atbegbuf; for(p=0; px_list_out = outlet_new(&x->x_obj, &s_list); /*left out*/ x->x_offset_list_out = outlet_new(&x->x_obj, &s_list); /*right out*/ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); x->x_canvas = canvas_getcurrent(); return (x); } /* ---------------- global setup function -------------------- */ void iem_pbank_csv_setup(void ) { iem_pbank_csv_class = class_new(gensym("iem_pbank_csv"), (t_newmethod)iem_pbank_csv_new, (t_method)iem_pbank_csv_free, sizeof(t_iem_pbank_csv), 0, A_GIMME, 0); class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_recall, gensym("recall"), A_GIMME, 0); class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_store, gensym("store"), A_GIMME, 0); class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_read, gensym("read"), A_SYMBOL, A_DEFSYM, 0); class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_write, gensym("write"), A_SYMBOL, A_DEFSYM, 0); class_addlist(iem_pbank_csv_class, iem_pbank_csv_list); class_addbang(iem_pbank_csv_class, iem_pbank_csv_bang); class_addmethod(iem_pbank_csv_class, (t_method)iem_pbank_csv_ft1, gensym("ft1"), A_FLOAT, 0); class_sethelpsymbol(iem_pbank_csv_class, gensym("iemhelp/help-iem_pbank_csv")); }