2
/******************************************************
4
* zexy - implementation file
6
* copyleft (c) Franz Zotter
8
* 2105:forum::f�r::uml�ute:2007
10
* institute of electronic music and acoustics (iem)
12
******************************************************
14
* license: GNU General Public License v.2
16
******************************************************/
21
# define snprintf _snprintf
35
#define MIN_FREADLN_LENGTH 10
37
/* freadln: reads messages continuously from the lines of
38
* a file that doesn't necessarily need to fit
39
* into the RAM of your system
41
* Franz Zotter zotter@iem.at, 2007
42
* Institute of Electronic Music and Acoustics
46
static t_class *freadln_class;
48
typedef struct freadln
55
t_outlet *x_message_outlet;
56
t_outlet *x_readybang_outlet;
58
char linebreak_chr[3];
64
static void freadln_close (t_freadln *x)
70
freebytes(x->x_filename, sizeof(char)*MAXPDSTRING);
73
freebytes(x->x_textbuf, sizeof(char)*x->x_textbuf_length);
75
x->x_textbuf_length=0;
78
static void freadln_open (t_freadln *x, t_symbol *s, t_symbol*type)
80
char filenamebuf[MAXPDSTRING], *filenamebufptr;
81
char*dirname=canvas_getdir(x->x_canvas)->s_name;
87
if(type!=gensym("cr")) {
88
pd_error(x, "currently only 'cr' type files are implemented!");
92
if (type==gensym("cr"))
93
strcpy(x->linebreak_chr,"\n");
95
strcpy(x->linebreak_chr,";\n");
98
/* directory, filename, extension, dirresult, nameresult, unsigned int size, int bin */
99
if ((fd=open_via_path(dirname,
100
s->s_name,"", filenamebuf, &filenamebufptr, MAXPDSTRING,0)) < 0 ) {
101
pd_error(x, "%s: failed to open %s", s->s_name, filenamebuf);
105
len=strlen(filenamebuf);
106
if (!(x->x_filename=(char*)getbytes(sizeof(char)*(len+strlen(s->s_name)+2)))) {
107
pd_error(x, "out of memory");
111
strcpy(x->x_filename,filenamebuf);
112
strcpy(x->x_filename+len,"/");
113
strcpy(x->x_filename+len+1,s->s_name);
114
if (!(x->x_file=fopen(x->x_filename, "r"))) {
115
pd_error("freadln: failed to open %128s",filenamebuf);
118
if (!(x->x_textbuf = (char *) getbytes (MIN_FREADLN_LENGTH * sizeof(char)))) {
119
pd_error(x, "out of memory");
123
x->x_textbuf_length=MIN_FREADLN_LENGTH;
126
static int enlarge_cstr_if_required(const char **c_str, int *len, const int desired_min_length)
128
if ((!(*c_str))||*len==0) {
129
*c_str = (char*) calloc (1,sizeof(char));
132
if (len[0]<desired_min_length) {
135
} while ((len[0]<desired_min_length)&&(len[0]!=0));
136
freebytes((char*)*c_str, sizeof(char)*len[0]);
137
if (!(*c_str=(char*)calloc(len[0],sizeof(char))))
143
static int cstr_char_pos(const char *c_str, const char c)
151
} while (*c_str++!='\0');
156
static void freadln_done(t_freadln*x)
158
outlet_bang(x->x_readybang_outlet);
161
static void freadln_readline (t_freadln *x)
163
int min_length=(x->x_textbuf_length < 1)?1:x->x_textbuf_length;
172
pd_error(x, "no file opened for reading");
178
if (linebreak_pos==-1) {
180
fseek(x->x_file,-(long)(x->x_textbuf_length),SEEK_CUR);
182
if (!enlarge_cstr_if_required((const char**) &x->x_textbuf, &x->x_textbuf_length, min_length)) {
183
pd_error(x, "out of memory");
184
x->x_textbuf_length=0;
189
if (!(items_read=fread(x->x_textbuf,sizeof(char),x->x_textbuf_length,x->x_file))) {
194
x->x_textbuf[x->x_textbuf_length-1]=0;
195
} while (((linebreak_pos=cstr_char_pos(x->x_textbuf,x->linebreak_chr[0]))==-1) &&
196
!(items_read < x->x_textbuf_length));
198
if (linebreak_pos-1 < items_read - strlen(x->linebreak_chr)) {
199
rewind_after=items_read-linebreak_pos;
200
fseek(x->x_file,-(long)(rewind_after),SEEK_CUR);
202
if (linebreak_pos==-1)
203
linebreak_pos=items_read;
204
x->x_textbuf[linebreak_pos-1]='\0';
205
if (!(bbuf=binbuf_new())) {
206
pd_error(x, "out of memory");
211
binbuf_text(bbuf, x->x_textbuf, linebreak_pos-1);
212
abuf = binbuf_getvec(bbuf);
213
abuf_length = binbuf_getnatom(bbuf);
215
if (abuf->a_type==A_SYMBOL) {
216
outlet_anything(x->x_message_outlet, atom_getsymbol(abuf), abuf_length-1, abuf+1);
219
outlet_list(x->x_message_outlet, gensym("list"), abuf_length, abuf);
223
outlet_list(x->x_message_outlet, atom_getsymbol(abuf), 0, abuf);
225
/* NOTE: the following line might be a problem in recursions
226
* and could be performed before to outlet_* as well,
227
* but(!) atom buffer abuf must be copied if doing so.
231
static void freadln_free (t_freadln *x)
234
outlet_free (x->x_message_outlet);
235
outlet_free (x->x_readybang_outlet);
238
static void *freadln_new(void)
240
t_freadln *x = (t_freadln *)pd_new(freadln_class);
241
x->x_message_outlet = outlet_new(&x->x_ob, &s_list);
242
x->x_readybang_outlet = outlet_new(&x->x_ob, &s_bang);
246
x->x_canvas = canvas_getcurrent();
250
void freadln_setup(void)
252
freadln_class = class_new(gensym("freadln"), (t_newmethod)freadln_new,
253
(t_method) freadln_free, sizeof(t_freadln), 0, 0);
254
class_addmethod(freadln_class, (t_method)freadln_open, gensym("open"), A_SYMBOL, A_DEFSYM, 0);
255
class_addmethod(freadln_class, (t_method)freadln_close, gensym("close"), A_NULL, 0);
256
class_addbang(freadln_class, (t_method)freadln_readline);
258
zexy_register("freadln");