]>
code.delx.au - pulseaudio/blob - polyp/ioline.c
4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
35 #define BUFFER_LIMIT (64*1024)
36 #define READ_SIZE (1024)
39 struct pa_iochannel
*io
;
43 size_t wbuf_length
, wbuf_index
, wbuf_valid_length
;
46 size_t rbuf_length
, rbuf_index
, rbuf_valid_length
;
48 void (*callback
)(struct pa_ioline
*io
, const char *s
, void *userdata
);
52 static void io_callback(struct pa_iochannel
*io
, void *userdata
);
53 static int do_write(struct pa_ioline
*l
);
55 struct pa_ioline
* pa_ioline_new(struct pa_iochannel
*io
) {
59 l
= pa_xmalloc(sizeof(struct pa_ioline
));
64 l
->wbuf_length
= l
->wbuf_index
= l
->wbuf_valid_length
= 0;
67 l
->rbuf_length
= l
->rbuf_index
= l
->rbuf_valid_length
= 0;
72 pa_iochannel_set_callback(io
, io_callback
, l
);
77 void pa_ioline_free(struct pa_ioline
*l
) {
79 pa_iochannel_free(l
->io
);
85 void pa_ioline_puts(struct pa_ioline
*l
, const char *c
) {
90 if (len
> BUFFER_LIMIT
- l
->wbuf_valid_length
)
91 len
= BUFFER_LIMIT
- l
->wbuf_valid_length
;
96 if (len
> l
->wbuf_length
- l
->wbuf_valid_length
) {
97 size_t n
= l
->wbuf_valid_length
+len
;
98 char *new = pa_xmalloc(n
);
100 memcpy(new, l
->wbuf
+l
->wbuf_index
, l
->wbuf_valid_length
);
106 } else if (len
> l
->wbuf_length
- l
->wbuf_valid_length
- l
->wbuf_index
) {
107 memmove(l
->wbuf
, l
->wbuf
+l
->wbuf_index
, l
->wbuf_valid_length
);
111 memcpy(l
->wbuf
+l
->wbuf_index
+l
->wbuf_valid_length
, c
, len
);
112 l
->wbuf_valid_length
+= len
;
117 void pa_ioline_set_callback(struct pa_ioline
*l
, void (*callback
)(struct pa_ioline
*io
, const char *s
, void *userdata
), void *userdata
) {
118 assert(l
&& callback
);
119 l
->callback
= callback
;
120 l
->userdata
= userdata
;
123 static int do_read(struct pa_ioline
*l
) {
129 if (!pa_iochannel_is_readable(l
->io
))
132 len
= l
->rbuf_length
- l
->rbuf_index
- l
->rbuf_valid_length
;
134 if (len
< READ_SIZE
) {
135 size_t n
= l
->rbuf_valid_length
+READ_SIZE
;
137 if (n
>= BUFFER_LIMIT
)
140 if (l
->rbuf_length
>= n
) {
141 if (l
->rbuf_valid_length
)
142 memmove(l
->rbuf
, l
->rbuf
+l
->rbuf_index
, l
->rbuf_valid_length
);
144 char *new = pa_xmalloc(n
);
145 if (l
->rbuf_valid_length
)
146 memcpy(new, l
->rbuf
+l
->rbuf_index
, l
->rbuf_valid_length
);
155 len
= l
->rbuf_length
- l
->rbuf_index
- l
->rbuf_valid_length
;
157 if ((r
= pa_iochannel_read(l
->io
, l
->rbuf
+l
->rbuf_index
+l
->rbuf_valid_length
, len
)) <= 0)
160 e
= memchr(l
->rbuf
+l
->rbuf_index
+l
->rbuf_valid_length
, '\n', r
);
161 l
->rbuf_valid_length
+= r
;
163 if (!e
&&l
->rbuf_valid_length
>= BUFFER_LIMIT
)
164 e
= l
->rbuf
+BUFFER_LIMIT
-1;
171 p
= l
->rbuf
+l
->rbuf_index
;
174 l
->rbuf_index
+= m
+1;
175 l
->rbuf_valid_length
-= m
+1;
177 if (l
->rbuf_valid_length
== 0)
181 l
->callback(l
, p
, l
->userdata
);
187 static int do_write(struct pa_ioline
*l
) {
191 if (!l
->wbuf_valid_length
|| !pa_iochannel_is_writable(l
->io
))
194 if ((r
= pa_iochannel_write(l
->io
, l
->wbuf
+l
->wbuf_index
, l
->wbuf_valid_length
)) < 0)
197 l
->wbuf_valid_length
-= r
;
198 if (l
->wbuf_valid_length
== 0)
204 static void io_callback(struct pa_iochannel
*io
, void *userdata
) {
205 struct pa_ioline
*l
= userdata
;
208 if (!l
->dead
&& do_write(l
) < 0)
211 if (!l
->dead
&& do_read(l
) < 0)
219 l
->callback(l
, NULL
, l
->userdata
);