1 #include "stdio_impl.h"
2 #include <string.h>
3 #ifndef __LITEOS__
4 #include "param_check.h"
5 #endif
6
7 #define MIN(a,b) ((a)<(b) ? (a) : (b))
8
__fill_buffer(FILE *f)9 int __fill_buffer(FILE *f)
10 {
11 int r = __toread(f);
12 if (r != 0) {
13 return r;
14 }
15
16 int k = f->readx(f, f->buf, f->buf_size);
17 if (k <= 0) {
18 f->flags |= (k == 0) ? F_EOF : F_ERR;
19 f->rpos = f->rend;
20 return k;
21 }
22
23 f->rpos = f->buf;
24 f->rend = f->rpos + k;
25
26 return 0;
27 }
28
fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)29 size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)
30 {
31 #ifndef __LITEOS__
32 PARAM_CHECK(f);
33 #endif
34 unsigned char *dest = destv;
35 size_t len = size * nmemb, l = len, k;
36 if (!size) {
37 nmemb = 0;
38 }
39
40 FLOCK(f);
41
42 /* allocate file buffer if needed */
43 if (__falloc_buf(f) < 0) {
44 f->flags |= F_ERR;
45 goto exit;
46 }
47
48 f->mode |= f->mode-1;
49
50 while (l > 0) {
51 if (f->rpos != f->rend) {
52 /* First exhaust the buffer. */
53 k = MIN(f->rend - f->rpos, l);
54 memcpy(dest, f->rpos, k);
55 f->rpos += k;
56 dest += k;
57 l -= k;
58 }
59 /* done */
60 if (l == 0) {
61 goto exit;
62 }
63 /* if user buffer is longer than file buffer,
64 * maybe buffer size is 0, non-buffer mode,
65 * read directly */
66 if (l > f->buf_size) {
67 break;
68 }
69
70 if (__fill_buffer(f)) {
71 goto exit;
72 }
73 }
74
75 /* Read the remainder directly */
76 for (; l; l-=k, dest+=k) {
77 k = f->readx(f, dest, l);
78 if (!k) {
79 break;
80 }
81 }
82
83 exit:
84 FUNLOCK(f);
85 return (len - l) / size;
86 }
87
88 weak_alias(fread, fread_unlocked);
89