summaryrefslogtreecommitdiff
path: root/libio
diff options
context:
space:
mode:
Diffstat (limited to 'libio')
-rw-r--r--libio/libio.h3
-rw-r--r--libio/strfile.h4
-rw-r--r--libio/strops.c119
3 files changed, 66 insertions, 60 deletions
diff --git a/libio/libio.h b/libio/libio.h
index 0cd6b39c24..7dd47db9fa 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -303,6 +303,9 @@ extern int _IO_vfprintf __P((_IO_FILE*, const char*, _IO_va_list));
extern _IO_ssize_t _IO_padn __P((_IO_FILE *, int, _IO_ssize_t));
extern _IO_size_t _IO_sgetn __P((_IO_FILE *, void*, _IO_size_t));
+extern _IO_fpos_t _IO_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P((_IO_FILE*, _IO_fpos_t, int));
+
extern void _IO_free_backup_area __P((_IO_FILE*));
#ifdef __cplusplus
diff --git a/libio/strfile.h b/libio/strfile.h
index 55783bb5c1..4934a06e3c 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (C) 1993 Free Software Foundation
This file is part of the GNU IO Library. This library is free
@@ -32,8 +32,6 @@ typedef void (*_IO_free_type) __P((void*));
struct _IO_str_fields
{
- /* The current length is max(_len, _IO_write_ptr-_IO_write_base). */
- _IO_size_t _len;
_IO_alloc_type _allocate_buffer;
_IO_free_type _free_buffer;
};
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;
}