1 #include "stdio_impl.h"
10 size_t pos
, len
, size
;
18 unsigned char buf
[UNGET
+BUFSIZ
], buf2
[];
21 static off_t
mseek(FILE *f
, off_t off
, int whence
)
24 struct cookie
*c
= f
->cookie
;
30 base
= (size_t [3]){0, c
->pos
, c
->len
}[whence
];
31 if (off
< -base
|| off
> (ssize_t
)c
->size
-base
) goto fail
;
32 return c
->pos
= base
+off
;
35 static size_t mread(FILE *f
, unsigned char *buf
, size_t len
)
37 struct cookie
*c
= f
->cookie
;
38 size_t rem
= c
->len
- c
->pos
;
39 if (c
->pos
> c
->len
) rem
= 0;
44 memcpy(buf
, c
->buf
+c
->pos
, len
);
47 if (rem
> f
->buf_size
) rem
= f
->buf_size
;
49 f
->rend
= f
->buf
+ rem
;
50 memcpy(f
->rpos
, c
->buf
+c
->pos
, rem
);
55 static size_t mwrite(FILE *f
, const unsigned char *buf
, size_t len
)
57 struct cookie
*c
= f
->cookie
;
59 size_t len2
= f
->wpos
- f
->wbase
;
62 if (mwrite(f
, f
->wpos
, len2
) < len2
) return 0;
64 if (c
->mode
== 'a') c
->pos
= c
->len
;
65 rem
= c
->size
- c
->pos
;
66 if (len
> rem
) len
= rem
;
67 memcpy(c
->buf
+c
->pos
, buf
, len
);
69 if (c
->pos
> c
->len
) {
71 if (c
->len
< c
->size
) c
->buf
[c
->len
] = 0;
72 else if ((f
->flags
&F_NORD
) && c
->size
) c
->buf
[c
->size
-1] = 0;
77 static int mclose(FILE *m
)
82 FILE *fmemopen(void *restrict buf
, size_t size
, const char *restrict mode
)
85 int plus
= !!strchr(mode
, '+');
87 if (!strchr("rwa", *mode
)) {
92 if (!buf
&& size
> PTRDIFF_MAX
) {
97 f
= malloc(sizeof *f
+ (buf
?0:size
));
99 memset(f
, 0, offsetof(struct mem_FILE
, buf
));
103 f
->f
.buf
= f
->buf
+ UNGET
;
104 f
->f
.buf_size
= sizeof f
->buf
- UNGET
;
107 memset(buf
, 0, size
);
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
);