1 #include "stdio_impl.h"
17 unsigned char buf
[UNGET
+BUFSIZ
], buf2
[];
20 static off_t
mseek(FILE *f
, off_t off
, int whence
)
23 struct cookie
*c
= f
->cookie
;
29 base
= (size_t [3]){0, c
->pos
, c
->len
}[whence
];
30 if (off
< -base
|| off
> (ssize_t
)c
->size
-base
) goto fail
;
31 return c
->pos
= base
+off
;
34 static size_t mread(FILE *f
, unsigned char *buf
, size_t len
)
36 struct cookie
*c
= f
->cookie
;
37 size_t rem
= c
->len
- c
->pos
;
38 if (c
->pos
> c
->len
) rem
= 0;
43 memcpy(buf
, c
->buf
+c
->pos
, len
);
46 if (rem
> f
->buf_size
) rem
= f
->buf_size
;
48 f
->rend
= f
->buf
+ rem
;
49 memcpy(f
->rpos
, c
->buf
+c
->pos
, rem
);
54 static size_t mwrite(FILE *f
, const unsigned char *buf
, size_t len
)
56 struct cookie
*c
= f
->cookie
;
58 size_t len2
= f
->wpos
- f
->wbase
;
61 if (mwrite(f
, f
->wpos
, len2
) < len2
) return 0;
63 if (c
->mode
== 'a') c
->pos
= c
->len
;
64 rem
= c
->size
- c
->pos
;
65 if (len
> rem
) len
= rem
;
66 memcpy(c
->buf
+c
->pos
, buf
, len
);
68 if (c
->pos
> c
->len
) {
70 if (c
->len
< c
->size
) c
->buf
[c
->len
] = 0;
71 else if ((f
->flags
&F_NORD
) && c
->size
) c
->buf
[c
->size
-1] = 0;
76 static int mclose(FILE *m
)
81 FILE *fmemopen(void *restrict buf
, size_t size
, const char *restrict mode
)
84 int plus
= !!strchr(mode
, '+');
86 if (!size
|| !strchr("rwa", *mode
)) {
91 if (!buf
&& size
> PTRDIFF_MAX
) {
96 f
= malloc(sizeof *f
+ (buf
?0:size
));
98 memset(&f
->f
, 0, sizeof f
->f
);
102 f
->f
.buf
= f
->buf
+ UNGET
;
103 f
->f
.buf_size
= sizeof f
->buf
- UNGET
;
106 memset(buf
, 0, size
);
109 memset(&f
->c
, 0, sizeof f
->c
);
114 if (!plus
) f
->f
.flags
= (*mode
== 'r') ? F_NOWR
: F_NORD
;
115 if (*mode
== 'r') f
->c
.len
= size
;
116 else if (*mode
== 'a') f
->c
.len
= f
->c
.pos
= strnlen(buf
, size
);
117 else if (plus
) *f
->c
.buf
= 0;
124 if (!libc
.threaded
) f
->f
.lock
= -1;
126 return __ofl_add(&f
->f
);