release
[hcoop/zz_old/debian/djbdns.git] / buffer_put.c
1 #include "buffer.h"
2 #include "str.h"
3 #include "byte.h"
4 #include "error.h"
5
6 static int allwrite(int (*op)(),int fd,const char *buf,unsigned int len)
7 {
8 int w;
9
10 while (len) {
11 w = op(fd,buf,len);
12 if (w == -1) {
13 if (errno == error_intr) continue;
14 return -1; /* note that some data may have been written */
15 }
16 if (w == 0) ; /* luser's fault */
17 buf += w;
18 len -= w;
19 }
20 return 0;
21 }
22
23 int buffer_flush(buffer *s)
24 {
25 int p;
26
27 p = s->p;
28 if (!p) return 0;
29 s->p = 0;
30 return allwrite(s->op,s->fd,s->x,p);
31 }
32
33 int buffer_putalign(buffer *s,const char *buf,unsigned int len)
34 {
35 unsigned int n;
36
37 while (len > (n = s->n - s->p)) {
38 byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n;
39 if (buffer_flush(s) == -1) return -1;
40 }
41 /* now len <= s->n - s->p */
42 byte_copy(s->x + s->p,len,buf);
43 s->p += len;
44 return 0;
45 }
46
47 int buffer_put(buffer *s,const char *buf,unsigned int len)
48 {
49 unsigned int n;
50
51 n = s->n;
52 if (len > n - s->p) {
53 if (buffer_flush(s) == -1) return -1;
54 /* now s->p == 0 */
55 if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE;
56 while (len > s->n) {
57 if (n > len) n = len;
58 if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
59 buf += n;
60 len -= n;
61 }
62 }
63 /* now len <= s->n - s->p */
64 byte_copy(s->x + s->p,len,buf);
65 s->p += len;
66 return 0;
67 }
68
69 int buffer_putflush(buffer *s,const char *buf,unsigned int len)
70 {
71 if (buffer_flush(s) == -1) return -1;
72 return allwrite(s->op,s->fd,buf,len);
73 }
74
75 int buffer_putsalign(buffer *s,const char *buf)
76 {
77 return buffer_putalign(s,buf,str_len(buf));
78 }
79
80 int buffer_puts(buffer *s,const char *buf)
81 {
82 return buffer_put(s,buf,str_len(buf));
83 }
84
85 int buffer_putsflush(buffer *s,const char *buf)
86 {
87 return buffer_putflush(s,buf,str_len(buf));
88 }