aboutsummaryrefslogtreecommitdiff
path: root/libio/strops.c
diff options
context:
space:
mode:
Diffstat (limited to 'libio/strops.c')
-rw-r--r--libio/strops.c119
1 files changed, 62 insertions, 57 deletions
diff --git a/libio/strops.c b/libio/strops.c
index 464063322d..8a6c56d055 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -26,7 +26,31 @@ the executable file might be covered by the GNU General Public License. */
#include "libioP.h"
#include <string.h>
-#define LEN(fp) (((_IO_strfile*)(fp))->_s._len)
+#if 0
+/* The following definitions are for exposition only.
+ They map the terminlogy used in the ANSI/ISO C++ draft standard
+ to the implementation. */
+
+/* allocated: set when a dynamic array object has been allocated, and
+ hence should be freed by the destructor for the strstreambuf object. */
+#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
+
+/* constant: set when the array object has const elements,
+ so the output sequence cannot be written. */
+#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
+
+/* alsize: the suggested minimum size for a dynamic array object. */
+#define ALSIZE(FP) ??? /* not stored */
+
+/* palloc: points to the function to call to allocate a dynamic array object.*/
+#define PALLOC(FP) \
+ ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
+
+/* pfree: points to the function to call to free a dynamic array object. */
+#define PFREE(FP) \
+ ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
+
+#endif
#ifdef TODO
/* An "unbounded buffer" is when a buffer is supplied, but with no
@@ -44,27 +68,17 @@ DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
{
/* If size is negative 'the characters are assumed to
continue indefinitely.' This is kind of messy ... */
-#if 1
int s;
size = 512;
- /* Try increasing powers of 2, as long as we don't wrap around.
- This can lose in pathological cases (ptr near the end
- of the address space). A better solution might be to
- adjust the size on underflow/overflow. FIXME. */
- for ( ; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+ /* Try increasing powers of 2, as long as we don't wrap around. */
+ for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
size = s;
- size = s;
-#else
- /* The following semi-portable kludge assumes that
- sizeof(unsigned long) == sizeof(char*). Hence,
- (unsigned long)(-1) should be the largest possible address. */
- unsigned long highest = (unsigned long)(-1);
- /* Pointers are signed on some brain-damaged systems, in
- which case we divide by two to get the maximum signed address. */
- if ((char*)highest < ptr)
- highest >>= 1;
- size = (char*)highest - ptr;
-#endif
+ /* Try increasing size as much as we can without wrapping around. */
+ for (s = size >> 1; s > 0; s >>= 1)
+ {
+ if (ptr + size + s > ptr)
+ size += s;
+ }
}
_IO_setb(fp, ptr, ptr+size, 0);
@@ -83,7 +97,6 @@ DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
fp->_IO_write_end = ptr;
fp->_IO_read_end = ptr+size;
}
- LEN(fp) = size;
/* A null _allocate_buffer function flags the strfile as being static. */
(((_IO_strfile*)(fp))->_s._allocate_buffer) = (_IO_alloc_type)0;
}
@@ -101,34 +114,25 @@ DEFUN(_IO_str_overflow, (fp, c),
register _IO_FILE* fp AND int c)
{
int flush_only = c == EOF;
- _IO_size_t pos = fp->_IO_write_ptr - fp->_IO_write_base;
- _IO_size_t get_pos = fp->_IO_read_ptr - fp->_IO_read_base;
+ _IO_size_t pos;
if (fp->_flags & _IO_NO_WRITES)
return flush_only ? 0 : EOF;
- if (pos > LEN(fp)) LEN(fp) = pos;
if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
{
- pos = get_pos;
fp->_flags |= _IO_CURRENTLY_PUTTING;
- get_pos = LEN(fp);
+ fp->_IO_write_ptr = fp->_IO_read_ptr;
+ fp->_IO_read_ptr = fp->_IO_read_end;
}
- if (pos >= (_IO_size_t) (_IO_blen(fp) + flush_only))
+ pos = fp->_IO_write_ptr - fp->_IO_write_base;
+ if (pos >= _IO_blen(fp) + flush_only)
{
if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
- {
-#ifdef TODO
- if (indefinite size)
- {
- fp->_IO_buf_end += 512;
- }
- else
-#endif
- return EOF;
- }
+ return EOF;
else
{
char *new_buf;
- _IO_size_t new_size = 2 * _IO_blen(fp);
+ char *old_buf = fp->_IO_buf_base;
+ _IO_size_t new_size = 2 * _IO_blen(fp) + 100;
new_buf
= (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
if (new_buf == NULL)
@@ -136,31 +140,32 @@ DEFUN(_IO_str_overflow, (fp, c),
/* __ferror(fp) = 1; */
return EOF;
}
- memcpy(new_buf, fp->_IO_buf_base, _IO_blen(fp));
-#if 0
- if (lenp == &LEN(fp)) /* use '\0'-filling */
- memset(new_buf + pos, 0, blen() - pos);
-#endif
if (fp->_IO_buf_base)
{
+ memcpy(new_buf, old_buf, _IO_blen(fp));
(*((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
/* Make sure _IO_setb won't try to delete _IO_buf_base. */
fp->_IO_buf_base = NULL;
}
+#if 0
+ if (lenp == &LEN(fp)) /* use '\0'-filling */
+ memset(new_buf + pos, 0, blen() - pos);
+#endif
_IO_setb(fp, new_buf, new_buf + new_size, 1);
+ fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
+ fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
+ fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
+ fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
+
fp->_IO_write_base = new_buf;
+ fp->_IO_write_end = fp->_IO_buf_end;
}
- fp->_IO_write_end = fp->_IO_buf_end;
}
- fp->_IO_write_ptr = fp->_IO_buf_base + pos;
-
- fp->_IO_read_base = fp->_IO_buf_base;
- fp->_IO_read_ptr = fp->_IO_buf_base + get_pos;
- fp->_IO_read_end = fp->_IO_buf_base + LEN(fp);
-
if (!flush_only)
*fp->_IO_write_ptr++ = (unsigned char) c;
+ if (fp->_IO_write_ptr > fp->_IO_read_end)
+ fp->_IO_read_end = fp->_IO_write_ptr;
return c;
}
@@ -168,28 +173,29 @@ int
DEFUN(_IO_str_underflow, (fp),
register _IO_FILE* fp)
{
- _IO_size_t ppos = fp->_IO_write_ptr - fp->_IO_write_base;
- if (ppos > LEN(fp)) LEN(fp) = ppos;
+ if (fp->_IO_write_ptr > fp->_IO_read_end)
+ fp->_IO_read_end = fp->_IO_write_ptr;
if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
{
fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ fp->_IO_read_ptr = fp->_IO_write_ptr;
fp->_IO_write_ptr = fp->_IO_write_end;
}
- fp->_IO_read_end = fp->_IO_read_base + LEN(fp);
if (fp->_IO_read_ptr < fp->_IO_read_end)
return *fp->_IO_read_ptr;
else
return EOF;
}
+/* The size of the valid part of the buffer. */
+
_IO_ssize_t
DEFUN(_IO_str_count, (fp),
register _IO_FILE *fp)
{
- _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
- if (put_len < (_IO_ssize_t) LEN(fp))
- put_len = LEN(fp);
- return put_len;
+ return (fp->_IO_write_ptr > fp->_IO_read_end ? fp->_IO_write_ptr
+ : fp->_IO_read_end)
+ - fp->_IO_read_base;
}
_IO_pos_t
@@ -236,7 +242,6 @@ DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
}
if (offset < 0 || (_IO_ssize_t)offset > cur_size)
return EOF;
- LEN(fp) = cur_size;
fp->_IO_write_ptr = fp->_IO_write_base + offset;
new_pos = offset;
}