]> mj.ucw.cz Git - libucw.git/blob - ucw/fb-buffer.c
Tests: xtypes-test sets an explicit timezone
[libucw.git] / ucw / fb-buffer.c
1 /*
2  *      UCW Library -- Fast Buffered I/O on Static Buffers
3  *
4  *      (c) 2003--2006 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include <ucw/lib.h>
11 #include <ucw/fastbuf.h>
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 static int
17 fbbuf_refill(struct fastbuf *f)
18 {
19   f->bstop = f->bufend;
20   f->pos = f->bstop - f->buffer;
21   return f->bptr < f->bstop;
22 }
23
24 static int
25 fbbuf_seek(struct fastbuf *f, ucw_off_t pos, int whence)
26 {
27   /* Somebody might want to seek to the end of buffer, try to be nice to him. */
28   ucw_off_t len = f->bufend - f->buffer;
29   if (whence == SEEK_END)
30     pos += len;
31   if (pos < 0 || pos > len)
32     bthrow(f, "seek", "Seek out of range");
33   f->bstop = f->bptr = f->buffer + pos;
34   f->pos = pos;
35   return 1;
36 }
37
38 void
39 fbbuf_init_read(struct fastbuf *f, byte *buf, uint size, uint can_overwrite)
40 {
41   *f = (struct fastbuf) {
42     .buffer = buf,
43     .bptr = buf,
44     .bstop = buf + size,
45     .bufend = buf + size,
46     .name = "fbbuf-read",
47     .pos = size,
48     .refill = fbbuf_refill,
49     .seek = fbbuf_seek,
50     .can_overwrite_buffer = can_overwrite
51   };
52 }
53
54 static void
55 fbbuf_spout(struct fastbuf *f)
56 {
57   if (f->bptr >= f->bufend)
58     bthrow(f, "write", "fbbuf: buffer overflow on write");
59 }
60
61 void
62 fbbuf_init_write(struct fastbuf *f, byte *buf, uint size)
63 {
64   *f = (struct fastbuf) {
65     .buffer = buf,
66     .bstop = buf,
67     .bptr = buf,
68     .bufend = buf + size,
69     .name = "fbbuf-write",
70     .spout = fbbuf_spout,
71   };
72 }
73
74 #ifdef TEST
75
76 int main(int argc, char *argv[])
77 {
78   if (argc < 2)
79     {
80       fprintf(stderr, "You must specify a test (r, w, o)\n");
81       return 1;
82     }
83   switch (*argv[1])
84     {
85       case 'r':
86         {
87           struct fastbuf fb;
88           char *data = "Two\nlines\n";
89           fbbuf_init_read(&fb, data, strlen(data), 0);
90           char buffer[10];
91           while (bgets(&fb, buffer, 10))
92             puts(buffer);
93           bclose(&fb);
94           break;
95         }
96       case 'w':
97         {
98           struct fastbuf fb;
99           char buff[20];
100           fbbuf_init_write(&fb, buff, 20);
101           bputs(&fb, "Hello world\n");
102           bputc(&fb, 0);
103           fputs(buff, stdout);
104           break;
105         }
106       case 'o':
107         {
108           struct fastbuf fb;
109           char buff[4];
110           fbbuf_init_write(&fb, buff, 4);
111           bputs(&fb, "Hello");
112           bputc(&fb, 0);
113           fputs(buff, stdout);
114           break;
115         }
116     }
117   return 0;
118 }
119
120 #endif