]>
code.delx.au - pulseaudio/blob - src/ioline.c
13 #define BUFFER_LIMIT (64*1024)
14 #define READ_SIZE (1024)
17 struct pa_iochannel
*io
;
21 size_t wbuf_length
, wbuf_index
, wbuf_valid_length
;
24 size_t rbuf_length
, rbuf_index
, rbuf_valid_length
;
26 void (*callback
)(struct pa_ioline
*io
, const char *s
, void *userdata
);
30 static void io_callback(struct pa_iochannel
*io
, void *userdata
);
31 static int do_write(struct pa_ioline
*l
);
33 struct pa_ioline
* pa_ioline_new(struct pa_iochannel
*io
) {
37 l
= malloc(sizeof(struct pa_ioline
));
43 l
->wbuf_length
= l
->wbuf_index
= l
->wbuf_valid_length
= 0;
46 l
->rbuf_length
= l
->rbuf_index
= l
->rbuf_valid_length
= 0;
51 pa_iochannel_set_callback(io
, io_callback
, l
);
56 void pa_ioline_free(struct pa_ioline
*l
) {
58 pa_iochannel_free(l
->io
);
64 void pa_ioline_puts(struct pa_ioline
*l
, const char *c
) {
69 if (len
> BUFFER_LIMIT
- l
->wbuf_valid_length
)
70 len
= BUFFER_LIMIT
- l
->wbuf_valid_length
;
75 if (len
> l
->wbuf_length
- l
->wbuf_valid_length
) {
76 size_t n
= l
->wbuf_valid_length
+len
;
77 char *new = malloc(n
);
79 memcpy(new, l
->wbuf
+l
->wbuf_index
, l
->wbuf_valid_length
);
85 } else if (len
> l
->wbuf_length
- l
->wbuf_valid_length
- l
->wbuf_index
) {
86 memmove(l
->wbuf
, l
->wbuf
+l
->wbuf_index
, l
->wbuf_valid_length
);
90 memcpy(l
->wbuf
+l
->wbuf_index
+l
->wbuf_valid_length
, c
, len
);
91 l
->wbuf_valid_length
+= len
;
96 void pa_ioline_set_callback(struct pa_ioline
*l
, void (*callback
)(struct pa_ioline
*io
, const char *s
, void *userdata
), void *userdata
) {
97 assert(l
&& callback
);
98 l
->callback
= callback
;
99 l
->userdata
= userdata
;
102 static int do_read(struct pa_ioline
*l
) {
108 if (!pa_iochannel_is_readable(l
->io
))
111 len
= l
->rbuf_length
- l
->rbuf_index
- l
->rbuf_valid_length
;
113 if (len
< READ_SIZE
) {
114 size_t n
= l
->rbuf_valid_length
+READ_SIZE
;
116 if (n
>= BUFFER_LIMIT
)
119 if (l
->rbuf_length
>= n
) {
120 if (l
->rbuf_valid_length
)
121 memmove(l
->rbuf
, l
->rbuf
+l
->rbuf_index
, l
->rbuf_valid_length
);
123 char *new = malloc(n
);
124 if (l
->rbuf_valid_length
)
125 memcpy(new, l
->rbuf
+l
->rbuf_index
, l
->rbuf_valid_length
);
134 len
= l
->rbuf_length
- l
->rbuf_index
- l
->rbuf_valid_length
;
136 if ((r
= pa_iochannel_read(l
->io
, l
->rbuf
+l
->rbuf_index
+l
->rbuf_valid_length
, len
)) <= 0)
139 e
= memchr(l
->rbuf
+l
->rbuf_index
+l
->rbuf_valid_length
, '\n', r
);
140 l
->rbuf_valid_length
+= r
;
142 if (!e
&&l
->rbuf_valid_length
>= BUFFER_LIMIT
)
143 e
= l
->rbuf
+BUFFER_LIMIT
-1;
150 p
= l
->rbuf
+l
->rbuf_index
;
153 l
->rbuf_index
+= m
+1;
154 l
->rbuf_valid_length
-= m
+1;
156 if (l
->rbuf_valid_length
== 0)
160 l
->callback(l
, p
, l
->userdata
);
166 static int do_write(struct pa_ioline
*l
) {
170 if (!l
->wbuf_valid_length
|| !pa_iochannel_is_writable(l
->io
))
173 if ((r
= pa_iochannel_write(l
->io
, l
->wbuf
+l
->wbuf_index
, l
->wbuf_valid_length
)) < 0)
176 l
->wbuf_valid_length
-= r
;
177 if (l
->wbuf_valid_length
== 0)
183 static void io_callback(struct pa_iochannel
*io
, void *userdata
) {
184 struct pa_ioline
*l
= userdata
;
187 if (!l
->dead
&& do_write(l
) < 0)
190 if (!l
->dead
&& do_read(l
) < 0)
198 l
->callback(l
, NULL
, l
->userdata
);