Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/stdio/open_memstream.c')
-rw-r--r--newlib/libc/stdio/open_memstream.c329
1 files changed, 0 insertions, 329 deletions
diff --git a/newlib/libc/stdio/open_memstream.c b/newlib/libc/stdio/open_memstream.c
deleted file mode 100644
index 27ff5be9a..000000000
--- a/newlib/libc/stdio/open_memstream.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* Copyright (C) 2007 Eric Blake
- * Permission to use, copy, modify, and distribute this software
- * is freely granted, provided that this notice is preserved.
- */
-
-/*
-FUNCTION
-<<open_memstream>>---open a write stream around an arbitrary-length string
-
-INDEX
- open_memstream
-
-ANSI_SYNOPSIS
- #include <stdio.h>
- FILE *open_memstream(char **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
-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
-through following any call to <<fflush>> or <<fclose>>, set to the
-current address and usable size of the allocated string; although
-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>>.
-
-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
-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.
-
-RETURNS
-The return value is an open FILE pointer on success. On error,
-<<NULL>> is returned, and <<errno>> will be set to EINVAL if <[buf]>
-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.
-
-Supporting OS subroutines required: <<sbrk>>.
-*/
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/lock.h>
-#include "local.h"
-
-#ifndef __LARGE64_FILES
-# define OFF_T off_t
-#else
-# define OFF_T _off64_t
-#endif
-
-/* Describe details of an open memstream. */
-typedef struct memstream {
- void *storage; /* storage to free on close */
- char **pbuf; /* pointer to the current buffer */
- size_t *psize; /* pointer to the current size, smaller of pos or eof */
- 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 */
-} memstream;
-
-/* Write up to non-zero N bytes of BUF into the stream described by COOKIE,
- returning the number of bytes written or EOF on failure. */
-static _READ_WRITE_RETURN_TYPE
-_DEFUN(memwriter, (ptr, cookie, buf, n),
- struct _reent *ptr _AND
- void *cookie _AND
- const char *buf _AND
- int n)
-{
- memstream *c = (memstream *) cookie;
- char *cbuf = *c->pbuf;
-
- /* size_t is unsigned, but off_t is signed. Don't let stream get so
- big that user cannot do ftello. */
- if (sizeof (OFF_T) == sizeof (size_t) && (ssize_t) (c->pos + n) < 0)
- {
- ptr->_errno = EFBIG;
- return EOF;
- }
- /* Grow the buffer, if necessary. Choose a geometric growth factor
- to avoid quadratic realloc behavior, but use a rate less than
- (1+sqrt(5))/2 to accomodate malloc overhead. Overallocate, so
- that we can add a trailing \0 without reallocating. The new
- allocation should thus be max(prev_size*1.5, c->pos+n+1). */
- if (c->pos + n >= c->max)
- {
- size_t newsize = c->max * 3 / 2;
- if (newsize < c->pos + n + 1)
- newsize = c->pos + n + 1;
- cbuf = _realloc_r (ptr, cbuf, newsize);
- if (! cbuf)
- return EOF; /* errno already set to ENOMEM */
- *c->pbuf = cbuf;
- c->max = newsize;
- }
- /* If we have previously done a seek beyond eof, ensure all
- intermediate bytes are NUL. */
- if (c->pos > c->eof)
- memset (cbuf + c->eof, '\0', c->pos - c->eof);
- memcpy (cbuf + c->pos, buf, n);
- c->pos += n;
- /* If the user has previously written further, remember what the
- trailing NUL is overwriting. Otherwise, extend the stream. */
- if (c->pos > c->eof)
- c->eof = c->pos;
- else
- c->saved = cbuf[c->pos];
- cbuf[c->pos] = '\0';
- *c->psize = c->pos;
- return n;
-}
-
-/* Seek to position POS relative to WHENCE within stream described by
- COOKIE; return resulting position or fail with EOF. */
-static _fpos_t
-_DEFUN(memseeker, (ptr, cookie, pos, whence),
- struct _reent *ptr _AND
- void *cookie _AND
- _fpos_t pos _AND
- int whence)
-{
- memstream *c = (memstream *) cookie;
- OFF_T offset = (OFF_T) pos;
-
- if (whence == SEEK_CUR)
- offset += c->pos;
- else if (whence == SEEK_END)
- offset += c->eof;
- if (offset < 0)
- {
- ptr->_errno = EINVAL;
- offset = -1;
- }
- else if ((size_t) offset != offset)
- {
- ptr->_errno = ENOSPC;
- offset = -1;
- }
-#ifdef __LARGE64_FILES
- else if ((_fpos_t) offset != offset)
- {
- ptr->_errno = EOVERFLOW;
- offset = -1;
- }
-#endif /* __LARGE64_FILES */
- else
- {
- if (c->pos < c->eof)
- {
- (*c->pbuf)[c->pos] = c->saved;
- c->saved = '\0';
- }
- c->pos = offset;
- if (c->pos < c->eof)
- {
- c->saved = (*c->pbuf)[c->pos];
- (*c->pbuf)[c->pos] = '\0';
- *c->psize = c->pos;
- }
- else
- *c->psize = c->eof;
- }
- return (_fpos_t) offset;
-}
-
-/* Seek to position POS relative to WHENCE within stream described by
- COOKIE; return resulting position or fail with EOF. */
-#ifdef __LARGE64_FILES
-static _fpos64_t
-_DEFUN(memseeker64, (ptr, cookie, pos, whence),
- struct _reent *ptr _AND
- void *cookie _AND
- _fpos64_t pos _AND
- int whence)
-{
- _off64_t offset = (_off64_t) pos;
- memstream *c = (memstream *) cookie;
-
- if (whence == SEEK_CUR)
- offset += c->pos;
- else if (whence == SEEK_END)
- offset += c->eof;
- if (offset < 0)
- {
- ptr->_errno = EINVAL;
- offset = -1;
- }
- else if ((size_t) offset != offset)
- {
- ptr->_errno = ENOSPC;
- offset = -1;
- }
- else
- {
- if (c->pos < c->eof)
- {
- (*c->pbuf)[c->pos] = c->saved;
- c->saved = '\0';
- }
- c->pos = offset;
- if (c->pos < c->eof)
- {
- c->saved = (*c->pbuf)[c->pos];
- (*c->pbuf)[c->pos] = '\0';
- *c->psize = c->pos;
- }
- else
- *c->psize = c->eof;
- }
- return (_fpos64_t) offset;
-}
-#endif /* __LARGE64_FILES */
-
-/* Reclaim resources used by stream described by COOKIE. */
-static int
-_DEFUN(memcloser, (ptr, cookie),
- struct _reent *ptr _AND
- void *cookie)
-{
- memstream *c = (memstream *) cookie;
- char *buf;
-
- /* Be nice and try to reduce any unused memory. */
- buf = _realloc_r (ptr, *c->pbuf, *c->psize + 1);
- if (buf)
- *c->pbuf = buf;
- _free_r (ptr, c->storage);
- return 0;
-}
-
-/* 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),
- struct _reent *ptr _AND
- char **buf _AND
- size_t *size)
-{
- FILE *fp;
- memstream *c;
-
- if (!buf || !size)
- {
- ptr->_errno = EINVAL;
- return NULL;
- }
- if ((fp = __sfp (ptr)) == NULL)
- return NULL;
- if ((c = (memstream *) _malloc_r (ptr, sizeof *c)) == NULL)
- {
- __sfp_lock_acquire ();
- fp->_flags = 0; /* release */
-#ifndef __SINGLE_THREAD__
- __lock_close_recursive (fp->_lock);
-#endif
- __sfp_lock_release ();
- return NULL;
- }
- /* Use *size as a hint for initial sizing, but bound the initial
- malloc between 64 bytes (same as asprintf, to avoid frequent
- mallocs on small strings) and 64k bytes (to avoid overusing the
- heap if *size was garbage). */
- c->max = *size;
- if (c->max < 64)
- c->max = 64;
- else if (c->max > 64 * 1024)
- c->max = 64 * 1024;
- *size = 0;
- *buf = _malloc_r (ptr, c->max);
- if (!*buf)
- {
- __sfp_lock_acquire ();
- fp->_flags = 0; /* release */
-#ifndef __SINGLE_THREAD__
- __lock_close_recursive (fp->_lock);
-#endif
- __sfp_lock_release ();
- _free_r (ptr, c);
- return NULL;
- }
- **buf = '\0';
-
- c->storage = c;
- c->pbuf = buf;
- c->psize = size;
- c->eof = 0;
- c->saved = '\0';
-
- _flockfile (fp);
- fp->_file = -1;
- fp->_flags = __SWR;
- fp->_cookie = c;
- fp->_read = NULL;
- fp->_write = memwriter;
- fp->_seek = memseeker;
-#ifdef __LARGE64_FILES
- fp->_seek64 = memseeker64;
- fp->_flags |= __SL64;
-#endif
- fp->_close = memcloser;
- _funlockfile (fp);
- return fp;
-}
-
-#ifndef _REENT_ONLY
-FILE *
-_DEFUN(open_memstream, (buf, size),
- char **buf _AND
- size_t *size)
-{
- return _open_memstream_r (_REENT, buf, size);
-}
-#endif /* !_REENT_ONLY */