Update.
[glibc.git] / libio / strops.c
blobd95f33c2e95aaf44ecc0801c59ad1d2b8163a1ec
1 /* Copyright (C) 1993, 1997-2000, 2001, 2002 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 INTUSE(_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;
112 INTDEF(_IO_str_init_static)
114 void
115 _IO_str_init_readonly (sf, ptr, size)
116 _IO_strfile *sf;
117 const char *ptr;
118 int size;
120 INTUSE(_IO_str_init_static) (sf, (char *) ptr, size, NULL);
121 sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
125 _IO_str_overflow (fp, c)
126 _IO_FILE *fp;
127 int c;
129 int flush_only = c == EOF;
130 _IO_size_t pos;
131 if (fp->_flags & _IO_NO_WRITES)
132 return flush_only ? 0 : EOF;
133 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
135 fp->_flags |= _IO_CURRENTLY_PUTTING;
136 fp->_IO_write_ptr = fp->_IO_read_ptr;
137 fp->_IO_read_ptr = fp->_IO_read_end;
139 pos = fp->_IO_write_ptr - fp->_IO_write_base;
140 if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
142 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
143 return EOF;
144 else
146 char *new_buf;
147 char *old_buf = fp->_IO_buf_base;
148 _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
149 new_buf
150 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
151 if (new_buf == NULL)
153 /* __ferror(fp) = 1; */
154 return EOF;
156 if (old_buf)
158 memcpy (new_buf, old_buf, _IO_blen (fp));
159 (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
160 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
161 fp->_IO_buf_base = NULL;
163 #if 0
164 if (lenp == &LEN(fp)) /* use '\0'-filling */
165 memset (new_buf + pos, 0, blen() - pos);
166 #endif
167 INTUSE(_IO_setb) (fp, new_buf, new_buf + new_size, 1);
168 fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
169 fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
170 fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
171 fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
173 fp->_IO_write_base = new_buf;
174 fp->_IO_write_end = fp->_IO_buf_end;
178 if (!flush_only)
179 *fp->_IO_write_ptr++ = (unsigned char) c;
180 if (fp->_IO_write_ptr > fp->_IO_read_end)
181 fp->_IO_read_end = fp->_IO_write_ptr;
182 return c;
184 INTDEF(_IO_str_overflow)
187 _IO_str_underflow (fp)
188 _IO_FILE *fp;
190 if (fp->_IO_write_ptr > fp->_IO_read_end)
191 fp->_IO_read_end = fp->_IO_write_ptr;
192 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
194 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
195 fp->_IO_read_ptr = fp->_IO_write_ptr;
196 fp->_IO_write_ptr = fp->_IO_write_end;
198 if (fp->_IO_read_ptr < fp->_IO_read_end)
199 return *((unsigned char *) fp->_IO_read_ptr);
200 else
201 return EOF;
203 INTDEF(_IO_str_underflow)
205 /* The size of the valid part of the buffer. */
207 _IO_ssize_t
208 _IO_str_count (fp)
209 _IO_FILE *fp;
211 return ((fp->_IO_write_ptr > fp->_IO_read_end
212 ? fp->_IO_write_ptr : fp->_IO_read_end)
213 - fp->_IO_read_base);
216 _IO_off64_t
217 _IO_str_seekoff (fp, offset, dir, mode)
218 _IO_FILE *fp;
219 _IO_off64_t offset;
220 int dir;
221 int mode;
223 _IO_off64_t new_pos;
225 if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
226 mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
228 if (mode == 0)
230 /* Don't move any pointers. But there is no clear indication what
231 mode FP is in. Let's guess. */
232 if (fp->_IO_file_flags & _IO_NO_WRITES)
233 new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
234 else
235 new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
237 else
239 _IO_ssize_t cur_size = _IO_str_count(fp);
240 new_pos = EOF;
242 /* Move the get pointer, if requested. */
243 if (mode & _IOS_INPUT)
245 switch (dir)
247 case _IO_seek_end:
248 offset += cur_size;
249 break;
250 case _IO_seek_cur:
251 offset += fp->_IO_read_ptr - fp->_IO_read_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_read_ptr = fp->_IO_read_base + offset;
259 fp->_IO_read_end = fp->_IO_read_base + cur_size;
260 new_pos = offset;
263 /* Move the put pointer, if requested. */
264 if (mode & _IOS_OUTPUT)
266 switch (dir)
268 case _IO_seek_end:
269 offset += cur_size;
270 break;
271 case _IO_seek_cur:
272 offset += fp->_IO_write_ptr - fp->_IO_write_base;
273 break;
274 default: /* case _IO_seek_set: */
275 break;
277 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
278 return EOF;
279 fp->_IO_write_ptr = fp->_IO_write_base + offset;
280 new_pos = offset;
283 return new_pos;
285 INTDEF(_IO_str_seekoff)
288 _IO_str_pbackfail (fp, c)
289 _IO_FILE *fp;
290 int c;
292 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
293 return EOF;
294 return INTUSE(_IO_default_pbackfail) (fp, c);
296 INTDEF(_IO_str_pbackfail)
298 void
299 _IO_str_finish (fp, dummy)
300 _IO_FILE *fp;
301 int dummy;
303 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
304 (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
305 fp->_IO_buf_base = NULL;
307 INTUSE(_IO_default_finish) (fp, 0);
310 struct _IO_jump_t _IO_str_jumps =
312 JUMP_INIT_DUMMY,
313 JUMP_INIT(finish, _IO_str_finish),
314 JUMP_INIT(overflow, INTUSE(_IO_str_overflow)),
315 JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
316 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
317 JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
318 JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
319 JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
320 JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
321 JUMP_INIT(seekpos, _IO_default_seekpos),
322 JUMP_INIT(setbuf, _IO_default_setbuf),
323 JUMP_INIT(sync, _IO_default_sync),
324 JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
325 JUMP_INIT(read, _IO_default_read),
326 JUMP_INIT(write, _IO_default_write),
327 JUMP_INIT(seek, _IO_default_seek),
328 JUMP_INIT(close, _IO_default_close),
329 JUMP_INIT(stat, _IO_default_stat),
330 JUMP_INIT(showmanyc, _IO_default_showmanyc),
331 JUMP_INIT(imbue, _IO_default_imbue)