]> pd.if.org Git - pdclib/blob - functions/stdio/fread.c
Merged PDPCLIB and Therx code.
[pdclib] / functions / stdio / fread.c
1 // ----------------------------------------------------------------------------
2 // $Id$
3 // ----------------------------------------------------------------------------
4 // Public Domain C Library - http://pdclib.sourceforge.net
5 // This code is Public Domain. Use, modify, and redistribute at will.
6 // ----------------------------------------------------------------------------
7
8 size_t fread( void * restrict ptr, size_t size, size_t nelem, FILE * restrict stream ) { /* TODO */ };
9
10 /* PDPC code - unreviewed, verbatim.
11 Read the note in fopen.c.
12 {
13     size_t toread;
14     size_t elemRead;
15     size_t actualRead;
16 #ifdef __OS2__
17     APIRET rc;
18     ULONG tempRead;
19 #endif
20 #ifdef __MSDOS__
21     int errind;
22     size_t tempRead;
23 #endif
24
25     if (nmemb == 1)
26     {
27         toread = size;
28     }
29     else if (size == 1)
30     {
31         toread = nmemb;
32     }
33     else
34     {
35         toread = size * nmemb;
36     }
37     if (toread < stream->szfbuf)
38     {
39         stream->quickBin = 0;
40     }
41     if (!stream->quickBin)
42     {
43         if (stream->textMode)
44         {
45             freadSlowT(ptr, stream, toread, &actualRead);
46         }
47         else
48         {
49             if (toread <= (stream->endbuf - stream->upto))
50             {
51                 memcpy(ptr, stream->upto, toread);
52                 actualRead = toread;
53                 stream->upto += toread;
54             }
55             else
56             {
57                 freadSlowB(ptr, stream, toread, &actualRead);
58             }
59         }
60         if (nmemb == 1)
61         {
62             if (actualRead == size)
63             {
64                 elemRead = 1;
65             }
66             else
67             {
68                 elemRead = 0;
69             }
70         }
71         else if (size == 1)
72         {
73             elemRead = actualRead;
74         }
75         else
76         {
77             elemRead = actualRead / size;
78         }
79         return (elemRead);
80     }
81     else
82     {
83 #ifdef __OS2__
84         rc = DosRead(stream->hfile, ptr, toread, &tempRead);
85         if (rc != 0)
86         {
87             actualRead = 0;
88             stream->errorInd = 1;
89             errno = rc;
90         }
91         else
92         {
93             actualRead = tempRead;
94         }
95 #endif
96 #ifdef __MSDOS__
97         tempRead = __read(stream->hfile, ptr, toread, &errind);
98         if (errind)
99         {
100             errno = tempRead;
101             actualRead = 0;
102             stream->errorInd = 1;
103         }
104         else
105         {
106             actualRead = tempRead;
107         }
108 #endif
109         if (nmemb == 1)
110         {
111             if (actualRead == size)
112             {
113                 elemRead = 1;
114             }
115             else
116             {
117                 elemRead = 0;
118                 stream->eofInd = 1;
119             }
120         }
121         else if (size == 1)
122         {
123             elemRead = actualRead;
124             if (nmemb != actualRead)
125             {
126                 stream->eofInd = 1;
127             }
128         }
129         else
130         {
131             elemRead = actualRead / size;
132             if (toread != actualRead)
133             {
134                 stream->eofInd = 1;
135             }
136         }
137         stream->bufStartR += actualRead;
138         return (elemRead);
139     }
140 }
141
142
143 /*
144 while toread has not been satisfied
145 {
146     scan stuff out of buffer, replenishing buffer as required
147 }
148 */
149
150 static void freadSlowT(void *ptr,
151                        FILE *stream,
152                        size_t toread,
153                        size_t *actualRead)
154 {
155     int finReading = 0;
156     size_t avail;
157     size_t need;
158     char *p;
159     size_t got;
160 #ifdef __OS2__
161     ULONG tempRead;
162     APIRET rc;
163 #endif
164 #ifdef __MSDOS__
165     size_t tempRead;
166     int errind;
167 #endif
168
169     *actualRead = 0;
170     while (!finReading)
171     {
172         if (stream->upto == stream->endbuf)
173         {
174             stream->bufStartR += (stream->upto - stream->fbuf);
175 #ifdef __OS2__
176             rc = DosRead(stream->hfile,
177                          stream->fbuf,
178                          stream->szfbuf,
179                          &tempRead);
180             if (rc != 0)
181             {
182                 tempRead = 0;
183                 stream->errorInd = 1;
184                 errno = rc;
185             }
186 #endif
187 #ifdef __MSDOS__
188             tempRead = __read(stream->hfile,
189                               stream->fbuf,
190                               stream->szfbuf,
191                               &errind);
192             if (errind)
193             {
194                 errno = tempRead;
195                 tempRead = 0;
196                 stream->errorInd = 1;
197             }
198 #endif
199             if (tempRead == 0)
200             {
201                 stream->eofInd = 1;
202                 break;
203             }
204             stream->endbuf = stream->fbuf + tempRead;
205             *stream->endbuf = '\n';
206             stream->upto = stream->fbuf;
207         }
208         avail = (size_t)(stream->endbuf - stream->upto) + 1;
209         need = toread - *actualRead;
210         p = memchr(stream->upto, '\n', avail);
211         got = (size_t)(p - stream->upto);
212         if (need < got)
213         {
214             memcpy((char *)ptr + *actualRead, stream->upto, need);
215             stream->upto += need;
216             *actualRead += need;
217         }
218         else
219         {
220             memcpy((char *)ptr + *actualRead, stream->upto, got);
221             stream->upto += got;
222             *actualRead += got;
223             if (p != stream->endbuf)
224             {
225                 if (*(stream->upto - 1) == '\r')
226                 {
227                     *((char *)ptr + *actualRead - 1) = '\n';
228                 }
229                 else
230                 {
231                     *((char *)ptr + *actualRead) = '\n';
232                     *actualRead += 1;
233                 }
234                 stream->upto++;
235             }
236             else
237             {
238                 if (*(stream->upto - 1) == '\r')
239                 {
240                     *actualRead -= 1;
241                 }
242             }
243         }
244         if (*actualRead == toread)
245         {
246             finReading = 1;
247         }
248     }
249     return;
250 }
251
252 static void freadSlowB(void *ptr,
253                        FILE *stream,
254                        size_t toread,
255                        size_t *actualRead)
256 {
257     size_t avail;
258 #ifdef __OS2__
259     ULONG tempRead;
260     APIRET rc;
261 #endif
262 #ifdef __MSDOS__
263     size_t tempRead;
264     int errind;
265 #endif
266
267     avail = (size_t)(stream->endbuf - stream->upto);
268     memcpy(ptr, stream->upto, avail);
269     *actualRead = avail;
270     stream->bufStartR += (stream->endbuf - stream->fbuf);
271     if (toread >= stream->szfbuf)
272     {
273         stream->upto = stream->endbuf;
274         stream->quickBin = 1;
275 #ifdef __OS2__
276         rc = DosRead(stream->hfile,
277                      (char *)ptr + *actualRead,
278                      toread - *actualRead,
279                      &tempRead);
280         if (rc != 0)
281         {
282             tempRead = 0;
283             stream->errorInd = 1;
284             errno = rc;
285         }
286 #endif
287 #ifdef __MSDOS__
288         tempRead = __read(stream->hfile,
289                           (char *)ptr + *actualRead,
290                           toread - *actualRead,
291                           &errind);
292         if (errind)
293         {
294             errno = tempRead;
295             tempRead = 0;
296             stream->errorInd = 1;
297         }
298 #endif
299         else if (tempRead != (toread - *actualRead))
300         {
301             stream->eofInd = 1;
302         }
303         *actualRead += tempRead;
304         stream->bufStartR += tempRead;
305     }
306     else
307     {
308         size_t left;
309
310         stream->upto = stream->fbuf;
311 #ifdef __OS2__
312         rc = DosRead(stream->hfile,
313                      stream->fbuf,
314                      stream->szfbuf,
315                      &tempRead);
316         left = toread - *actualRead;
317         if (rc != 0)
318         {
319             tempRead = 0;
320             stream->errorInd = 1;
321             errno = rc;
322         }
323 #endif
324 #ifdef __MSDOS__
325         tempRead = __read(stream->hfile,
326                           stream->fbuf,
327                           stream->szfbuf,
328                           &errind);
329         left = toread - *actualRead;
330         if (errind)
331         {
332             errno = tempRead;
333             tempRead = 0;
334             stream->errorInd = 1;
335         }
336 #endif
337         else if (tempRead < left)
338         {
339             stream->eofInd = 1;
340         }
341         stream->endbuf = stream->fbuf + tempRead;
342         *stream->endbuf = '\n';
343         avail = (size_t)(stream->endbuf - stream->upto);
344         if (avail > left)
345         {
346             avail = left;
347         }
348         memcpy((char *)ptr + *actualRead,
349                stream->upto,
350                avail);
351         stream->upto += avail;
352         *actualRead += avail;
353     }
354     return;
355 }
356 #endif
357 */