* libc/stdio/open_memstream.c: Add open_wmemstream to doumentation.
(struct memstream): Add wide element. Change saved to a union to take char and wchar_t values. (memwriter): Accommodate wide-oriented oeprations. (memseeker): Ditto. (memseeker64): Ditto. (memcloser): Ditto. (internal_open_memstream_r): New static function. Take functionality from former _open_memstream_r and handle additional "wide" parameter. (_open_memstream_r): Just call internal_open_memstream_r with wide==-1 from here. (_open_wmemstream_r): New function. (open_wmemstream): Ditto. * libc/include/wchar.h (open_wmemstream): Declare. (_open_wmemstream_r): Declare.
This commit is contained in:
parent
c6b9747e04
commit
84e851fd64
|
@ -1,3 +1,21 @@
|
|||
2009-02-18 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* libc/stdio/open_memstream.c: Add open_wmemstream to doumentation.
|
||||
(struct memstream): Add wide element.
|
||||
Change saved to a union to take char and wchar_t values.
|
||||
(memwriter): Accommodate wide-oriented oeprations.
|
||||
(memseeker): Ditto.
|
||||
(memseeker64): Ditto.
|
||||
(memcloser): Ditto.
|
||||
(internal_open_memstream_r): New static function. Take functionality
|
||||
from former _open_memstream_r and handle additional "wide" parameter.
|
||||
(_open_memstream_r): Just call internal_open_memstream_r with wide==-1
|
||||
from here.
|
||||
(_open_wmemstream_r): New function.
|
||||
(open_wmemstream): Ditto.
|
||||
* libc/include/wchar.h (open_wmemstream): Declare.
|
||||
(_open_wmemstream_r): Declare.
|
||||
|
||||
2009-02-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* libc/stdio/fputwc.c: Fix typo in man page info.
|
||||
|
|
|
@ -118,6 +118,9 @@ wint_t _EXFUN(_putwc_r, (struct _reent *, wchar_t, __FILE *));
|
|||
wint_t _EXFUN(_putwchar_r, (struct _reent *, wchar_t));
|
||||
wint_t _EXFUN (_ungetwc_r, (struct _reent *, wint_t wc, __FILE *));
|
||||
|
||||
__FILE *_EXFUN (open_wmemstream, (wchar_t **, size_t *));
|
||||
__FILE *_EXFUN (_open_wmemstream_r, (struct _reent *, wchar_t **, size_t *));
|
||||
|
||||
#define getwc(fp) fgetwc(fp)
|
||||
#define putwc(wc,fp) fputwc((wc), (fp))
|
||||
#ifndef _REENT_ONLY
|
||||
|
|
|
@ -5,19 +5,25 @@
|
|||
|
||||
/*
|
||||
FUNCTION
|
||||
<<open_memstream>>---open a write stream around an arbitrary-length string
|
||||
<<open_memstream>>, <<open_wmemstream>>---open a write stream around an arbitrary-length string
|
||||
|
||||
INDEX
|
||||
open_memstream
|
||||
INDEX
|
||||
open_wmemstream
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdio.h>
|
||||
FILE *open_memstream(char **restrict <[buf]>,
|
||||
size_t *restrict <[size]>);
|
||||
|
||||
#include <wchar.h>
|
||||
FILE *open_wmemstream(wchar_t **restrict <[buf]>,
|
||||
size_t *restrict <[size]>);
|
||||
|
||||
DESCRIPTION
|
||||
<<open_memstream>> creates a seekable <<FILE>> stream that wraps an
|
||||
arbitrary-length buffer, created as if by <<malloc>>. The current
|
||||
<<open_memstream>> creates a seekable, byte-oriented <<FILE>> stream that
|
||||
wraps an arbitrary-length buffer, created as if by <<malloc>>. The current
|
||||
contents of *<[buf]> are ignored; this implementation uses *<[size]>
|
||||
as a hint of the maximum size expected, but does not fail if the hint
|
||||
was wrong. The parameters <[buf]> and <[size]> are later stored
|
||||
|
@ -27,6 +33,10 @@ after fflush, the pointer is only valid until another stream operation
|
|||
that results in a write. Behavior is undefined if the user alters
|
||||
either *<[buf]> or *<[size]> prior to <<fclose>>.
|
||||
|
||||
<<open_wmemstream>> is like <<open_memstream>> just with the associated
|
||||
stream being wide-oriented. The size set in <[size]> in subsequent
|
||||
operations is the number of wide characters.
|
||||
|
||||
The stream is write-only, since the user can directly read *<[buf]>
|
||||
after a flush; see <<fmemopen>> for a way to wrap a string with a
|
||||
readable stream. The user is responsible for calling <<free>> on
|
||||
|
@ -34,10 +44,10 @@ the final *<[buf]> after <<fclose>>.
|
|||
|
||||
Any time the stream is flushed, a NUL byte is written at the current
|
||||
position (but is not counted in the buffer length), so that the string
|
||||
is always NUL-terminated after at most *<[size]> bytes. However, data
|
||||
previously written beyond the current stream offset is not lost, and
|
||||
the NUL byte written during a flush is restored to its previous value
|
||||
when seeking elsewhere in the string.
|
||||
is always NUL-terminated after at most *<[size]> bytes (or wide characters
|
||||
in case of <<open_wmemstream>>). However, data previously written beyond
|
||||
the current stream offset is not lost, and the NUL value written during a
|
||||
flush is restored to its previous value when seeking elsewhere in the string.
|
||||
|
||||
RETURNS
|
||||
The return value is an open FILE pointer on success. On error,
|
||||
|
@ -46,12 +56,13 @@ or <[size]> is NULL, ENOMEM if memory could not be allocated, or
|
|||
EMFILE if too many streams are already open.
|
||||
|
||||
PORTABILITY
|
||||
This function is being added to POSIX 200x, but is not in POSIX 2001.
|
||||
POSIX.1-2008
|
||||
|
||||
Supporting OS subroutines required: <<sbrk>>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/lock.h>
|
||||
|
@ -71,7 +82,11 @@ typedef struct memstream {
|
|||
size_t pos; /* current position */
|
||||
size_t eof; /* current file size */
|
||||
size_t max; /* current malloc buffer size, always > eof */
|
||||
char saved; /* saved character that lived at *psize before NUL */
|
||||
union {
|
||||
char c;
|
||||
wchar_t w;
|
||||
} saved; /* saved character that lived at *psize before NUL */
|
||||
int8_t wide; /* wide-oriented (>0) or byte-oriented (<0) */
|
||||
} memstream;
|
||||
|
||||
/* Write up to non-zero N bytes of BUF into the stream described by COOKIE,
|
||||
|
@ -119,10 +134,12 @@ _DEFUN(memwriter, (ptr, cookie, buf, n),
|
|||
trailing NUL is overwriting. Otherwise, extend the stream. */
|
||||
if (c->pos > c->eof)
|
||||
c->eof = c->pos;
|
||||
else if (c->wide > 0)
|
||||
c->saved.w = *(wchar_t *)(cbuf + c->pos);
|
||||
else
|
||||
c->saved = cbuf[c->pos];
|
||||
c->saved.c = cbuf[c->pos];
|
||||
cbuf[c->pos] = '\0';
|
||||
*c->psize = c->pos;
|
||||
*c->psize = (c->wide > 0) ? c->pos / sizeof (wchar_t) : c->pos;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -163,16 +180,30 @@ _DEFUN(memseeker, (ptr, cookie, pos, whence),
|
|||
{
|
||||
if (c->pos < c->eof)
|
||||
{
|
||||
(*c->pbuf)[c->pos] = c->saved;
|
||||
c->saved = '\0';
|
||||
if (c->wide > 0)
|
||||
*(wchar_t *)((*c->pbuf) + c->pos) = c->saved.w;
|
||||
else
|
||||
(*c->pbuf)[c->pos] = c->saved.c;
|
||||
c->saved.w = L'\0';
|
||||
}
|
||||
c->pos = offset;
|
||||
if (c->pos < c->eof)
|
||||
{
|
||||
c->saved = (*c->pbuf)[c->pos];
|
||||
(*c->pbuf)[c->pos] = '\0';
|
||||
*c->psize = c->pos;
|
||||
if (c->wide > 0)
|
||||
{
|
||||
c->saved.w = *(wchar_t *)((*c->pbuf) + c->pos);
|
||||
*(wchar_t *)((*c->pbuf) + c->pos) = L'\0';
|
||||
*c->psize = c->pos / sizeof (wchar_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
c->saved.c = (*c->pbuf)[c->pos];
|
||||
(*c->pbuf)[c->pos] = '\0';
|
||||
*c->psize = c->pos;
|
||||
}
|
||||
}
|
||||
else if (c->wide > 0)
|
||||
*c->psize = c->eof / sizeof (wchar_t);
|
||||
else
|
||||
*c->psize = c->eof;
|
||||
}
|
||||
|
@ -210,16 +241,30 @@ _DEFUN(memseeker64, (ptr, cookie, pos, whence),
|
|||
{
|
||||
if (c->pos < c->eof)
|
||||
{
|
||||
(*c->pbuf)[c->pos] = c->saved;
|
||||
c->saved = '\0';
|
||||
if (c->wide > 0)
|
||||
*(wchar_t *)((*c->pbuf) + c->pos) = c->saved.w;
|
||||
else
|
||||
(*c->pbuf)[c->pos] = c->saved.c;
|
||||
c->saved.w = L'\0';
|
||||
}
|
||||
c->pos = offset;
|
||||
if (c->pos < c->eof)
|
||||
{
|
||||
c->saved = (*c->pbuf)[c->pos];
|
||||
(*c->pbuf)[c->pos] = '\0';
|
||||
*c->psize = c->pos;
|
||||
if (c->wide > 0)
|
||||
{
|
||||
c->saved.w = *(wchar_t *)((*c->pbuf) + c->pos);
|
||||
*(wchar_t *)((*c->pbuf) + c->pos) = L'\0';
|
||||
*c->psize = c->pos / sizeof (wchar_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
c->saved.c = (*c->pbuf)[c->pos];
|
||||
(*c->pbuf)[c->pos] = '\0';
|
||||
*c->psize = c->pos;
|
||||
}
|
||||
}
|
||||
else if (c->wide > 0)
|
||||
*c->psize = c->eof / sizeof (wchar_t);
|
||||
else
|
||||
*c->psize = c->eof;
|
||||
}
|
||||
|
@ -237,7 +282,9 @@ _DEFUN(memcloser, (ptr, cookie),
|
|||
char *buf;
|
||||
|
||||
/* Be nice and try to reduce any unused memory. */
|
||||
buf = _realloc_r (ptr, *c->pbuf, *c->psize + 1);
|
||||
buf = _realloc_r (ptr, *c->pbuf,
|
||||
c->wide > 0 ? (*c->psize + 1) * sizeof (wchar_t)
|
||||
: *c->psize + 1);
|
||||
if (buf)
|
||||
*c->pbuf = buf;
|
||||
_free_r (ptr, c->storage);
|
||||
|
@ -246,11 +293,12 @@ _DEFUN(memcloser, (ptr, cookie),
|
|||
|
||||
/* Open a memstream that tracks a dynamic buffer in BUF and SIZE.
|
||||
Return the new stream, or fail with NULL. */
|
||||
FILE *
|
||||
_DEFUN(_open_memstream_r, (ptr, buf, size),
|
||||
static FILE *
|
||||
_DEFUN(internal_open_memstream_r, (ptr, buf, size, wide),
|
||||
struct _reent *ptr _AND
|
||||
char **buf _AND
|
||||
size_t *size)
|
||||
size_t *size _AND
|
||||
int wide)
|
||||
{
|
||||
FILE *fp;
|
||||
memstream *c;
|
||||
|
@ -300,7 +348,8 @@ _DEFUN(_open_memstream_r, (ptr, buf, size),
|
|||
c->pbuf = buf;
|
||||
c->psize = size;
|
||||
c->eof = 0;
|
||||
c->saved = '\0';
|
||||
c->saved.w = L'\0';
|
||||
c->wide = (int8_t) wide;
|
||||
|
||||
_flockfile (fp);
|
||||
fp->_file = -1;
|
||||
|
@ -314,10 +363,29 @@ _DEFUN(_open_memstream_r, (ptr, buf, size),
|
|||
fp->_flags |= __SL64;
|
||||
#endif
|
||||
fp->_close = memcloser;
|
||||
ORIENT (fp, wide);
|
||||
_funlockfile (fp);
|
||||
return fp;
|
||||
}
|
||||
|
||||
FILE *
|
||||
_DEFUN(_open_memstream_r, (ptr, buf, size),
|
||||
struct _reent *ptr _AND
|
||||
char **buf _AND
|
||||
size_t *size)
|
||||
{
|
||||
internal_open_memstream_r (ptr, buf, size, -1);
|
||||
}
|
||||
|
||||
FILE *
|
||||
_DEFUN(_open_wmemstream_r, (ptr, buf, size),
|
||||
struct _reent *ptr _AND
|
||||
wchar_t **buf _AND
|
||||
size_t *size)
|
||||
{
|
||||
internal_open_memstream_r (ptr, buf, size, 1);
|
||||
}
|
||||
|
||||
#ifndef _REENT_ONLY
|
||||
FILE *
|
||||
_DEFUN(open_memstream, (buf, size),
|
||||
|
@ -326,4 +394,12 @@ _DEFUN(open_memstream, (buf, size),
|
|||
{
|
||||
return _open_memstream_r (_REENT, buf, size);
|
||||
}
|
||||
|
||||
FILE *
|
||||
_DEFUN(open_wmemstream, (buf, size),
|
||||
wchar_t **buf _AND
|
||||
size_t *size)
|
||||
{
|
||||
return _open_wmemstream_r (_REENT, buf, size);
|
||||
}
|
||||
#endif /* !_REENT_ONLY */
|
||||
|
|
Loading…
Reference in New Issue