]> mj.ucw.cz Git - libucw.git/blob - lib/fastbuf.c
Moved #include <getopt.h> to conf.h.
[libucw.git] / lib / fastbuf.c
1 /*
2  *      Sherlock Library -- Fast Buffered I/O
3  *
4  *      (c) 1997--2000 Martin Mares <mj@ucw.cz>
5  */
6
7 #include "lib/lib.h"
8 #include "lib/fastbuf.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 void bclose(struct fastbuf *f)
14 {
15   bflush(f);
16   f->close(f);
17   xfree(f);
18 }
19
20 void bflush(struct fastbuf *f)
21 {
22   if (f->bptr != f->buffer)
23     {                                   /* Have something to flush */
24       if (f->bstop > f->buffer)         /* Read data? */
25         {
26           f->bptr = f->bstop = f->buffer;
27           f->pos = f->fdpos;
28         }
29       else                              /* Write data... */
30         f->spout(f);
31     }
32 }
33
34 inline void bsetpos(struct fastbuf *f, sh_off_t pos)
35 {
36   if (pos >= f->pos && (pos <= f->pos + (f->bptr - f->buffer) || pos <= f->pos + (f->bstop - f->buffer)))
37     f->bptr = f->buffer + (pos - f->pos);
38   else
39     {
40       bflush(f);
41       f->seek(f, pos, SEEK_SET);
42     }
43 }
44
45 void bseek(struct fastbuf *f, sh_off_t pos, int whence)
46 {
47   switch (whence)
48     {
49     case SEEK_SET:
50       return bsetpos(f, pos);
51     case SEEK_CUR:
52       return bsetpos(f, btell(f) + pos);
53     case SEEK_END:
54       bflush(f);
55       f->seek(f, pos, SEEK_END);
56       break;
57     default:
58       die("bseek: invalid whence=%d", whence);
59     }
60 }
61
62 int bgetc_slow(struct fastbuf *f)
63 {
64   if (f->bptr < f->bstop)
65     return *f->bptr++;
66   if (!f->refill(f))
67     return EOF;
68   return *f->bptr++;
69 }
70
71 int bpeekc_slow(struct fastbuf *f)
72 {
73   if (f->bptr < f->bstop)
74     return *f->bptr;
75   if (!f->refill(f))
76     return EOF;
77   return *f->bptr;
78 }
79
80 void bputc_slow(struct fastbuf *f, byte c)
81 {
82   if (f->bptr >= f->bufend)
83     f->spout(f);
84   *f->bptr++ = c;
85 }
86
87 word bgetw_slow(struct fastbuf *f)
88 {
89   word w = bgetc_slow(f);
90 #ifdef CPU_BIG_ENDIAN
91   return (w << 8) | bgetc_slow(f);
92 #else
93   return w | (bgetc_slow(f) << 8);
94 #endif
95 }
96
97 u32 bgetl_slow(struct fastbuf *f)
98 {
99   u32 l = bgetc_slow(f);
100 #ifdef CPU_BIG_ENDIAN
101   l = (l << 8) | bgetc_slow(f);
102   l = (l << 8) | bgetc_slow(f);
103   return (l << 8) | bgetc_slow(f);
104 #else
105   l = (bgetc_slow(f) << 8) | l;
106   l = (bgetc_slow(f) << 16) | l;
107   return (bgetc_slow(f) << 24) | l;
108 #endif
109 }
110
111 u64 bgetq_slow(struct fastbuf *f)
112 {
113   u32 l, h;
114 #ifdef CPU_BIG_ENDIAN
115   h = bgetl_slow(f);
116   l = bgetl_slow(f);
117 #else
118   l = bgetl_slow(f);
119   h = bgetl_slow(f);
120 #endif
121   return ((u64) h << 32) | l;
122 }
123
124 u64 bget5_slow(struct fastbuf *f)
125 {
126   u32 l, h;
127 #ifdef CPU_BIG_ENDIAN
128   h = bgetc_slow(f);
129   l = bgetl_slow(f);
130 #else
131   l = bgetl_slow(f);
132   h = bgetc_slow(f);
133 #endif
134   return ((u64) h << 32) | l;
135 }
136
137 void bputw_slow(struct fastbuf *f, word w)
138 {
139 #ifdef CPU_BIG_ENDIAN
140   bputc_slow(f, w >> 8);
141   bputc_slow(f, w);
142 #else
143   bputc_slow(f, w);
144   bputc_slow(f, w >> 8);
145 #endif
146 }
147
148 void bputl_slow(struct fastbuf *f, u32 l)
149 {
150 #ifdef CPU_BIG_ENDIAN
151   bputc_slow(f, l >> 24);
152   bputc_slow(f, l >> 16);
153   bputc_slow(f, l >> 8);
154   bputc_slow(f, l);
155 #else
156   bputc_slow(f, l);
157   bputc_slow(f, l >> 8);
158   bputc_slow(f, l >> 16);
159   bputc_slow(f, l >> 24);
160 #endif
161 }
162
163 void bputq_slow(struct fastbuf *f, u64 q)
164 {
165 #ifdef CPU_BIG_ENDIAN
166   bputl_slow(f, q >> 32);
167   bputl_slow(f, q);
168 #else
169   bputl_slow(f, q);
170   bputl_slow(f, q >> 32);
171 #endif
172 }
173
174 void bput5_slow(struct fastbuf *f, u64 o)
175 {
176   u32 hi = o >> 32;
177   u32 low = o;
178 #ifdef CPU_BIG_ENDIAN
179   bputc_slow(f, hi);
180   bputl_slow(f, low);
181 #else
182   bputl_slow(f, low);
183   bputc_slow(f, hi);
184 #endif
185 }
186
187 uns bread_slow(struct fastbuf *f, void *b, uns l)
188 {
189   uns total = 0;
190   while (l)
191     {
192       uns k = f->bstop - f->bptr;
193
194       if (!k)
195         {
196           f->refill(f);
197           k = f->bstop - f->bptr;
198           if (!k)
199             break;
200         }
201       if (k > l)
202         k = l;
203       memcpy(b, f->bptr, k);
204       f->bptr += k;
205       b = (byte *)b + k;
206       l -= k;
207       total += k;
208     }
209   return total;
210 }
211
212 void bwrite_slow(struct fastbuf *f, void *b, uns l)
213 {
214   while (l)
215     {
216       uns k = f->bufend - f->bptr;
217
218       if (!k)
219         {
220           f->spout(f);
221           k = f->bufend - f->bptr;
222         }
223       if (k > l)
224         k = l;
225       memcpy(f->bptr, b, k);
226       f->bptr += k;
227       b = (byte *)b + k;
228       l -= k;
229     }
230 }
231
232 byte *                                  /* Non-standard */
233 bgets(struct fastbuf *f, byte *b, uns l)
234 {
235   byte *e = b + l - 1;
236   int k;
237
238   k = bgetc(f);
239   if (k == EOF)
240     return NULL;
241   while (b < e)
242     {
243       if (k == '\n' || k == EOF)
244         {
245           *b = 0;
246           return b;
247         }
248       *b++ = k;
249       k = bgetc(f);
250     }
251   die("%s: Line too long", f->name);
252 }