2005-12-27 Roland McGrath <roland@redhat.com>
[glibc.git] / libio / strops.c
blob2de83403a2a06ea792f3e55cfaca1935c5dbb288
1 /* Copyright (C) 1993, 1997-2003, 2004 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_internal (sf, ptr, size, pstart)
67 _IO_strfile *sf;
68 char *ptr;
69 _IO_size_t size;
70 char *pstart;
72 _IO_FILE *fp = &sf->_sbf._f;
73 char *end;
75 if (size == 0)
76 end = __rawmemchr (ptr, '\0');
77 else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr)
78 end = ptr + size;
79 else
80 end = (char *) -1;
81 INTUSE(_IO_setb) (fp, ptr, end, 0);
83 fp->_IO_write_base = ptr;
84 fp->_IO_read_base = ptr;
85 fp->_IO_read_ptr = ptr;
86 if (pstart)
88 fp->_IO_write_ptr = pstart;
89 fp->_IO_write_end = end;
90 fp->_IO_read_end = pstart;
92 else
94 fp->_IO_write_ptr = ptr;
95 fp->_IO_write_end = ptr;
96 fp->_IO_read_end = end;
98 /* A null _allocate_buffer function flags the strfile as being static. */
99 sf->_s._allocate_buffer = (_IO_alloc_type) 0;
102 void
103 _IO_str_init_static (sf, ptr, size, pstart)
104 _IO_strfile *sf;
105 char *ptr;
106 int size;
107 char *pstart;
109 return _IO_str_init_static_internal (sf, ptr, size < 0 ? -1 : size, pstart);
112 void
113 _IO_str_init_readonly (sf, ptr, size)
114 _IO_strfile *sf;
115 const char *ptr;
116 int size;
118 _IO_str_init_static_internal (sf, (char *) ptr, size < 0 ? -1 : size, NULL);
119 sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
123 _IO_str_overflow (fp, c)
124 _IO_FILE *fp;
125 int c;
127 int flush_only = c == EOF;
128 _IO_size_t pos;
129 if (fp->_flags & _IO_NO_WRITES)
130 return flush_only ? 0 : EOF;
131 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
133 fp->_flags |= _IO_CURRENTLY_PUTTING;
134 fp->_IO_write_ptr = fp->_IO_read_ptr;
135 fp->_IO_read_ptr = fp->_IO_read_end;
137 pos = fp->_IO_write_ptr - fp->_IO_write_base;
138 if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
140 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
141 return EOF;
142 else
144 char *new_buf;
145 char *old_buf = fp->_IO_buf_base;
146 _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
147 new_buf
148 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
149 if (new_buf == NULL)
151 /* __ferror(fp) = 1; */
152 return EOF;
154 if (old_buf)
156 memcpy (new_buf, old_buf, _IO_blen (fp));
157 (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
158 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
159 fp->_IO_buf_base = NULL;
161 #if 0
162 if (lenp == &LEN(fp)) /* use '\0'-filling */
163 memset (new_buf + pos, 0, blen() - pos);
164 #endif
165 INTUSE(_IO_setb) (fp, new_buf, new_buf + new_size, 1);
166 fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
167 fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
168 fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
169 fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
171 fp->_IO_write_base = new_buf;
172 fp->_IO_write_end = fp->_IO_buf_end;
176 if (!flush_only)
177 *fp->_IO_write_ptr++ = (unsigned char) c;
178 if (fp->_IO_write_ptr > fp->_IO_read_end)
179 fp->_IO_read_end = fp->_IO_write_ptr;
180 return c;
182 INTDEF(_IO_str_overflow)
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;
201 INTDEF(_IO_str_underflow)
203 /* The size of the valid part of the buffer. */
205 _IO_ssize_t
206 _IO_str_count (fp)
207 _IO_FILE *fp;
209 return ((fp->_IO_write_ptr > fp->_IO_read_end
210 ? fp->_IO_write_ptr : fp->_IO_read_end)
211 - fp->_IO_read_base);
214 _IO_off64_t
215 _IO_str_seekoff (fp, offset, dir, mode)
216 _IO_FILE *fp;
217 _IO_off64_t offset;
218 int dir;
219 int mode;
221 _IO_off64_t new_pos;
223 if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
224 mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
226 if (mode == 0)
228 /* Don't move any pointers. But there is no clear indication what
229 mode FP is in. Let's guess. */
230 if (fp->_IO_file_flags & _IO_NO_WRITES)
231 new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
232 else
233 new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
235 else
237 _IO_ssize_t cur_size = _IO_str_count(fp);
238 new_pos = EOF;
240 /* Move the get pointer, if requested. */
241 if (mode & _IOS_INPUT)
243 switch (dir)
245 case _IO_seek_end:
246 offset += cur_size;
247 break;
248 case _IO_seek_cur:
249 offset += fp->_IO_read_ptr - fp->_IO_read_base;
250 break;
251 default: /* case _IO_seek_set: */
252 break;
254 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
255 return EOF;
256 fp->_IO_read_ptr = fp->_IO_read_base + offset;
257 fp->_IO_read_end = fp->_IO_read_base + cur_size;
258 new_pos = offset;
261 /* Move the put pointer, if requested. */
262 if (mode & _IOS_OUTPUT)
264 switch (dir)
266 case _IO_seek_end:
267 offset += cur_size;
268 break;
269 case _IO_seek_cur:
270 offset += fp->_IO_write_ptr - fp->_IO_write_base;
271 break;
272 default: /* case _IO_seek_set: */
273 break;
275 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
276 return EOF;
277 fp->_IO_write_ptr = fp->_IO_write_base + offset;
278 new_pos = offset;
281 return new_pos;
283 INTDEF(_IO_str_seekoff)
286 _IO_str_pbackfail (fp, c)
287 _IO_FILE *fp;
288 int c;
290 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
291 return EOF;
292 return INTUSE(_IO_default_pbackfail) (fp, c);
294 INTDEF(_IO_str_pbackfail)
296 void
297 _IO_str_finish (fp, dummy)
298 _IO_FILE *fp;
299 int dummy;
301 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
302 (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
303 fp->_IO_buf_base = NULL;
305 INTUSE(_IO_default_finish) (fp, 0);
308 const struct _IO_jump_t _IO_str_jumps =
310 JUMP_INIT_DUMMY,
311 JUMP_INIT(finish, _IO_str_finish),
312 JUMP_INIT(overflow, INTUSE(_IO_str_overflow)),
313 JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
314 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
315 JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
316 JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
317 JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
318 JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
319 JUMP_INIT(seekpos, _IO_default_seekpos),
320 JUMP_INIT(setbuf, _IO_default_setbuf),
321 JUMP_INIT(sync, _IO_default_sync),
322 JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
323 JUMP_INIT(read, _IO_default_read),
324 JUMP_INIT(write, _IO_default_write),
325 JUMP_INIT(seek, _IO_default_seek),
326 JUMP_INIT(close, _IO_default_close),
327 JUMP_INIT(stat, _IO_default_stat),
328 JUMP_INIT(showmanyc, _IO_default_showmanyc),
329 JUMP_INIT(imbue, _IO_default_imbue)