Update.
[glibc.git] / libio / strops.c
blobed55c8e836d635bd833e8268a5ca7a431a8aac4b
1 /*
2 Copyright (C) 1993 Free Software Foundation
4 This file is part of the GNU IO Library. This library is free
5 software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING. If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does not cause
21 the resulting executable to be covered by the GNU General Public License.
22 This exception does not however invalidate any other reasons why
23 the executable file might be covered by the GNU General Public License. */
25 #include "strfile.h"
26 #include "libioP.h"
27 #include <string.h>
29 #if 0
30 /* The following definitions are for exposition only.
31 They map the terminology used in the ANSI/ISO C++ draft standard
32 to the implementation. */
34 /* allocated: set when a dynamic array object has been allocated, and
35 hence should be freed by the destructor for the strstreambuf object. */
36 #define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
38 /* constant: set when the array object has const elements,
39 so the output sequence cannot be written. */
40 #define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
42 /* alsize: the suggested minimum size for a dynamic array object. */
43 #define ALSIZE(FP) ??? /* not stored */
45 /* palloc: points to the function to call to allocate a dynamic array object.*/
46 #define PALLOC(FP) \
47 ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
49 /* pfree: points to the function to call to free a dynamic array object. */
50 #define PFREE(FP) \
51 ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
53 #endif
55 #ifdef TODO
56 /* An "unbounded buffer" is when a buffer is supplied, but with no
57 specified length. An example is the buffer argument to sprintf.
59 #endif
61 void
62 DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
63 _IO_FILE *fp AND char *ptr AND int size AND char *pstart)
65 if (size == 0)
66 size = strlen(ptr);
67 else if (size < 0)
69 /* If size is negative 'the characters are assumed to
70 continue indefinitely.' This is kind of messy ... */
71 int s;
72 size = 512;
73 /* Try increasing powers of 2, as long as we don't wrap around. */
74 for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
75 size = s;
76 /* Try increasing size as much as we can without wrapping around. */
77 for (s = size >> 1; s > 0; s >>= 1)
79 if (ptr + size + s > ptr)
80 size += s;
83 _IO_setb(fp, ptr, ptr+size, 0);
85 fp->_IO_write_base = ptr;
86 fp->_IO_read_base = ptr;
87 fp->_IO_read_ptr = ptr;
88 if (pstart)
90 fp->_IO_write_ptr = pstart;
91 fp->_IO_write_end = ptr + size;
92 fp->_IO_read_end = pstart;
94 else
96 fp->_IO_write_ptr = ptr;
97 fp->_IO_write_end = ptr;
98 fp->_IO_read_end = ptr+size;
100 /* A null _allocate_buffer function flags the strfile as being static. */
101 (((_IO_strfile*)(fp))->_s._allocate_buffer) = (_IO_alloc_type)0;
104 void
105 DEFUN(_IO_str_init_readonly, (fp, ptr, size),
106 _IO_FILE *fp AND const char *ptr AND int size)
108 _IO_str_init_static (fp, (char*)ptr, size, NULL);
109 fp->_IO_file_flags |= _IO_NO_WRITES;
113 DEFUN(_IO_str_overflow, (fp, c),
114 register _IO_FILE* fp AND int c)
116 int flush_only = c == EOF;
117 _IO_size_t pos;
118 if (fp->_flags & _IO_NO_WRITES)
119 return flush_only ? 0 : EOF;
120 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
122 fp->_flags |= _IO_CURRENTLY_PUTTING;
123 fp->_IO_write_ptr = fp->_IO_read_ptr;
124 fp->_IO_read_ptr = fp->_IO_read_end;
126 pos = fp->_IO_write_ptr - fp->_IO_write_base;
127 if (pos >= (_IO_size_t) (_IO_blen(fp) + flush_only))
129 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
130 return EOF;
131 else
133 char *new_buf;
134 char *old_buf = fp->_IO_buf_base;
135 _IO_size_t new_size = 2 * _IO_blen(fp) + 100;
136 new_buf
137 = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
138 if (new_buf == NULL)
140 /* __ferror(fp) = 1; */
141 return EOF;
143 if (fp->_IO_buf_base)
145 memcpy(new_buf, old_buf, _IO_blen(fp));
146 (*((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
147 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
148 fp->_IO_buf_base = NULL;
150 #if 0
151 if (lenp == &LEN(fp)) /* use '\0'-filling */
152 memset(new_buf + pos, 0, blen() - pos);
153 #endif
154 _IO_setb(fp, new_buf, new_buf + new_size, 1);
155 fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
156 fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
157 fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
158 fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
160 fp->_IO_write_base = new_buf;
161 fp->_IO_write_end = fp->_IO_buf_end;
165 if (!flush_only)
166 *fp->_IO_write_ptr++ = (unsigned char) c;
167 if (fp->_IO_write_ptr > fp->_IO_read_end)
168 fp->_IO_read_end = fp->_IO_write_ptr;
169 return c;
173 DEFUN(_IO_str_underflow, (fp),
174 register _IO_FILE* fp)
176 if (fp->_IO_write_ptr > fp->_IO_read_end)
177 fp->_IO_read_end = fp->_IO_write_ptr;
178 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
180 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
181 fp->_IO_read_ptr = fp->_IO_write_ptr;
182 fp->_IO_write_ptr = fp->_IO_write_end;
184 if (fp->_IO_read_ptr < fp->_IO_read_end)
185 return *fp->_IO_read_ptr;
186 else
187 return EOF;
190 /* The size of the valid part of the buffer. */
192 _IO_ssize_t
193 DEFUN(_IO_str_count, (fp),
194 register _IO_FILE *fp)
196 return (fp->_IO_write_end > fp->_IO_read_end ? fp->_IO_write_end
197 : fp->_IO_read_end)
198 - fp->_IO_read_base;
201 _IO_pos_t
202 DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
203 register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
205 _IO_pos_t new_pos;
207 if (mode == 0)
209 /* Don't move any pointers. But there is no clear indication what
210 mode FP is in. Let's guess. */
211 if (fp->_IO_file_flags & _IO_NO_WRITES)
212 new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
213 else
214 new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
216 else
218 _IO_ssize_t cur_size = _IO_str_count(fp);
219 new_pos = EOF;
221 /* Move the get pointer, if requested. */
222 if (mode & _IOS_INPUT)
224 switch (dir)
226 case _IO_seek_end:
227 offset += cur_size;
228 break;
229 case _IO_seek_cur:
230 offset += fp->_IO_read_ptr - fp->_IO_read_base;
231 break;
232 default: /* case _IO_seek_set: */
233 break;
235 if (offset < 0 || (_IO_ssize_t)offset > cur_size)
236 return EOF;
237 fp->_IO_read_ptr = fp->_IO_read_base + offset;
238 fp->_IO_read_end = fp->_IO_read_base + cur_size;
239 new_pos = offset;
242 /* Move the put pointer, if requested. */
243 if (mode & _IOS_OUTPUT)
245 switch (dir)
247 case _IO_seek_end:
248 offset += cur_size;
249 break;
250 case _IO_seek_cur:
251 offset += fp->_IO_write_ptr - fp->_IO_write_base;
252 break;
253 default: /* case _IO_seek_set: */
254 break;
256 if (offset < 0 || (_IO_ssize_t)offset > cur_size)
257 return EOF;
258 fp->_IO_write_ptr = fp->_IO_write_base + offset;
259 new_pos = offset;
262 return new_pos;
266 DEFUN(_IO_str_pbackfail, (fp, c),
267 register _IO_FILE *fp AND int c)
269 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
270 return EOF;
271 return _IO_default_pbackfail(fp, c);
274 void
275 DEFUN (_IO_str_finish, (fp, dummy),
276 register _IO_FILE* fp AND int dummy)
278 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
279 (((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
280 fp->_IO_buf_base = NULL;
282 _IO_default_finish(fp, 0);
285 struct _IO_jump_t _IO_str_jumps = {
286 JUMP_INIT_DUMMY,
287 JUMP_INIT(finish, _IO_str_finish),
288 JUMP_INIT(overflow, _IO_str_overflow),
289 JUMP_INIT(underflow, _IO_str_underflow),
290 JUMP_INIT(uflow, _IO_default_uflow),
291 JUMP_INIT(pbackfail, _IO_str_pbackfail),
292 JUMP_INIT(xsputn, _IO_default_xsputn),
293 JUMP_INIT(xsgetn, _IO_default_xsgetn),
294 JUMP_INIT(seekoff, _IO_str_seekoff),
295 JUMP_INIT(seekpos, _IO_default_seekpos),
296 JUMP_INIT(setbuf, _IO_default_setbuf),
297 JUMP_INIT(sync, _IO_default_sync),
298 JUMP_INIT(doallocate, _IO_default_doallocate),
299 JUMP_INIT(read, _IO_default_read),
300 JUMP_INIT(write, _IO_default_write),
301 JUMP_INIT(seek, _IO_default_seek),
302 JUMP_INIT(close, _IO_default_close),
303 JUMP_INIT(stat, _IO_default_stat)