1 #include "stdio_impl.h"
25 static off_t
wms_seek(FILE *f
, off_t off
, int whence
)
28 struct cookie
*c
= f
->cookie
;
34 base
= (size_t [3]){0, c
->pos
, c
->len
}[whence
];
35 if (off
< -base
|| off
> SSIZE_MAX
/4-base
) goto fail
;
36 memset(&c
->mbs
, 0, sizeof c
->mbs
);
37 return c
->pos
= base
+off
;
40 static size_t wms_write(FILE *f
, const unsigned char *buf
, size_t len
)
42 struct cookie
*c
= f
->cookie
;
43 size_t len2
= f
->wpos
- f
->wbase
;
47 if (wms_write(f
, f
->wbase
, len2
) < len2
) return 0;
49 if (len
+ c
->pos
>= c
->space
) {
50 len2
= 2*c
->space
+1 | c
->pos
+len
+1;
51 if (len2
> SSIZE_MAX
/4) return 0;
52 newbuf
= realloc(c
->buf
, len2
*4);
53 if (!newbuf
) return 0;
54 *c
->bufp
= c
->buf
= newbuf
;
55 memset(c
->buf
+ c
->space
, 0, 4*(len2
- c
->space
));
59 len2
= mbsnrtowcs(c
->buf
+c
->pos
, (void *)&buf
, len
, c
->space
-c
->pos
, &c
->mbs
);
60 if (len2
== -1) return 0;
62 if (c
->pos
>= c
->len
) c
->len
= c
->pos
;
67 static int wms_close(FILE *f
)
72 FILE *open_wmemstream(wchar_t **bufp
, size_t *sizep
)
77 if (!(f
=malloc(sizeof *f
))) return 0;
78 if (!(buf
=malloc(sizeof *buf
))) {
82 memset(&f
->f
, 0, sizeof f
->f
);
83 memset(&f
->c
, 0, sizeof f
->c
);
88 f
->c
.pos
= f
->c
.len
= f
->c
.space
= *sizep
= 0;
89 f
->c
.buf
= *bufp
= buf
;
97 f
->f
.write
= wms_write
;
99 f
->f
.close
= wms_close
;
101 if (!libc
.threaded
) f
->f
.lock
= -1;
105 return __ofl_add(&f
->f
);