Update.
[glibc.git] / libio / strops.c
blobd679a0de63be56bc2d43e05abe76e28de556de42
1 /* Copyright (C) 1993, 1997-2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
28 #include "strfile.h"
29 #include "libioP.h"
30 #include <string.h>
31 #include <stdio_ext.h>
33 #if 0
34 /* The following definitions are for exposition only.
35 They map the terminology used in the ANSI/ISO C++ draft standard
36 to the implementation. */
38 /* allocated: set when a dynamic array object has been allocated, and
39 hence should be freed by the destructor for the strstreambuf object. */
40 #define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
42 /* constant: set when the array object has const elements,
43 so the output sequence cannot be written. */
44 #define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
46 /* alsize: the suggested minimum size for a dynamic array object. */
47 #define ALSIZE(FP) ??? /* not stored */
49 /* palloc: points to the function to call to allocate a dynamic array object.*/
50 #define PALLOC(FP) \
51 ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
53 /* pfree: points to the function to call to free a dynamic array object. */
54 #define PFREE(FP) \
55 ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
57 #endif
59 #ifdef TODO
60 /* An "unbounded buffer" is when a buffer is supplied, but with no
61 specified length. An example is the buffer argument to sprintf.
63 #endif
65 void
66 _IO_str_init_static (sf, ptr, size, pstart)
67 _IO_strfile *sf;
68 char *ptr;
69 int size;
70 char *pstart;
72 _IO_FILE *fp = &sf->_sbf._f;
74 if (size == 0)
75 size = strlen (ptr);
76 else if (size < 0)
78 /* If size is negative 'the characters are assumed to
79 continue indefinitely.' This is kind of messy ... */
80 int s;
81 size = 512;
82 /* Try increasing powers of 2, as long as we don't wrap around. */
83 for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
84 size = s;
85 /* Try increasing size as much as we can without wrapping around. */
86 for (s = size >> 1; s > 0; s >>= 1)
88 if (ptr + size + s > ptr)
89 size += s;
92 _IO_setb (fp, ptr, ptr + size, 0);
94 fp->_IO_write_base = ptr;
95 fp->_IO_read_base = ptr;
96 fp->_IO_read_ptr = ptr;
97 if (pstart)
99 fp->_IO_write_ptr = pstart;
100 fp->_IO_write_end = ptr + size;
101 fp->_IO_read_end = pstart;
103 else
105 fp->_IO_write_ptr = ptr;
106 fp->_IO_write_end = ptr;
107 fp->_IO_read_end = ptr+size;
109 /* A null _allocate_buffer function flags the strfile as being static. */
110 sf->_s._allocate_buffer = (_IO_alloc_type) 0;
113 void
114 _IO_str_init_readonly (sf, ptr, size)
115 _IO_strfile *sf;
116 const char *ptr;
117 int size;
119 _IO_str_init_static (sf, (char *) ptr, size, NULL);
120 sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
124 _IO_str_overflow (fp, c)
125 _IO_FILE *fp;
126 int c;
128 int flush_only = c == EOF;
129 _IO_size_t pos;
130 if (fp->_flags & _IO_NO_WRITES)
131 return flush_only ? 0 : EOF;
132 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
134 fp->_flags |= _IO_CURRENTLY_PUTTING;
135 fp->_IO_write_ptr = fp->_IO_read_ptr;
136 fp->_IO_read_ptr = fp->_IO_read_end;
138 pos = fp->_IO_write_ptr - fp->_IO_write_base;
139 if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
141 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
142 return EOF;
143 else
145 char *new_buf;
146 char *old_buf = fp->_IO_buf_base;
147 _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
148 new_buf
149 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
150 if (new_buf == NULL)
152 /* __ferror(fp) = 1; */
153 return EOF;
155 if (old_buf)
157 memcpy (new_buf, old_buf, _IO_blen (fp));
158 (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
159 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
160 fp->_IO_buf_base = NULL;
162 #if 0
163 if (lenp == &LEN(fp)) /* use '\0'-filling */
164 memset (new_buf + pos, 0, blen() - pos);
165 #endif
166 _IO_setb (fp, new_buf, new_buf + new_size, 1);
167 fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
168 fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
169 fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
170 fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
172 fp->_IO_write_base = new_buf;
173 fp->_IO_write_end = fp->_IO_buf_end;
177 if (!flush_only)
178 *fp->_IO_write_ptr++ = (unsigned char) c;
179 if (fp->_IO_write_ptr > fp->_IO_read_end)
180 fp->_IO_read_end = fp->_IO_write_ptr;
181 return c;
185 _IO_str_underflow (fp)
186 _IO_FILE *fp;
188 if (fp->_IO_write_ptr > fp->_IO_read_end)
189 fp->_IO_read_end = fp->_IO_write_ptr;
190 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
192 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
193 fp->_IO_read_ptr = fp->_IO_write_ptr;
194 fp->_IO_write_ptr = fp->_IO_write_end;
196 if (fp->_IO_read_ptr < fp->_IO_read_end)
197 return *((unsigned char *) fp->_IO_read_ptr);
198 else
199 return EOF;
202 /* The size of the valid part of the buffer. */
204 _IO_ssize_t
205 _IO_str_count (fp)
206 _IO_FILE *fp;
208 return ((fp->_IO_write_ptr > fp->_IO_read_end
209 ? fp->_IO_write_ptr : fp->_IO_read_end)
210 - fp->_IO_read_base);
213 _IO_off64_t
214 _IO_str_seekoff (fp, offset, dir, mode)
215 _IO_FILE *fp;
216 _IO_off64_t offset;
217 int dir;
218 int mode;
220 _IO_off64_t new_pos;
222 if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
223 mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
225 if (mode == 0)
227 /* Don't move any pointers. But there is no clear indication what
228 mode FP is in. Let's guess. */
229 if (fp->_IO_file_flags & _IO_NO_WRITES)
230 new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
231 else
232 new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
234 else
236 _IO_ssize_t cur_size = _IO_str_count(fp);
237 new_pos = EOF;
239 /* Move the get pointer, if requested. */
240 if (mode & _IOS_INPUT)
242 switch (dir)
244 case _IO_seek_end:
245 offset += cur_size;
246 break;
247 case _IO_seek_cur:
248 offset += fp->_IO_read_ptr - fp->_IO_read_base;
249 break;
250 default: /* case _IO_seek_set: */
251 break;
253 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
254 return EOF;
255 fp->_IO_read_ptr = fp->_IO_read_base + offset;
256 fp->_IO_read_end = fp->_IO_read_base + cur_size;
257 new_pos = offset;
260 /* Move the put pointer, if requested. */
261 if (mode & _IOS_OUTPUT)
263 switch (dir)
265 case _IO_seek_end:
266 offset += cur_size;
267 break;
268 case _IO_seek_cur:
269 offset += fp->_IO_write_ptr - fp->_IO_write_base;
270 break;
271 default: /* case _IO_seek_set: */
272 break;
274 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
275 return EOF;
276 fp->_IO_write_ptr = fp->_IO_write_base + offset;
277 new_pos = offset;
280 return new_pos;
284 _IO_str_pbackfail (fp, c)
285 _IO_FILE *fp;
286 int c;
288 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
289 return EOF;
290 return _IO_default_pbackfail (fp, c);
293 void
294 _IO_str_finish (fp, dummy)
295 _IO_FILE *fp;
296 int dummy;
298 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
299 (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
300 fp->_IO_buf_base = NULL;
302 _IO_default_finish (fp, 0);
305 struct _IO_jump_t _IO_str_jumps =
307 JUMP_INIT_DUMMY,
308 JUMP_INIT(finish, _IO_str_finish),
309 JUMP_INIT(overflow, _IO_str_overflow),
310 JUMP_INIT(underflow, _IO_str_underflow),
311 JUMP_INIT(uflow, _IO_default_uflow),
312 JUMP_INIT(pbackfail, _IO_str_pbackfail),
313 JUMP_INIT(xsputn, _IO_default_xsputn),
314 JUMP_INIT(xsgetn, _IO_default_xsgetn),
315 JUMP_INIT(seekoff, _IO_str_seekoff),
316 JUMP_INIT(seekpos, _IO_default_seekpos),
317 JUMP_INIT(setbuf, _IO_default_setbuf),
318 JUMP_INIT(sync, _IO_default_sync),
319 JUMP_INIT(doallocate, _IO_default_doallocate),
320 JUMP_INIT(read, _IO_default_read),
321 JUMP_INIT(write, _IO_default_write),
322 JUMP_INIT(seek, _IO_default_seek),
323 JUMP_INIT(close, _IO_default_close),
324 JUMP_INIT(stat, _IO_default_stat),
325 JUMP_INIT(showmanyc, _IO_default_showmanyc),
326 JUMP_INIT(imbue, _IO_default_imbue)