Update.
[glibc.git] / libio / strops.c
blobafc293bd7d2fce1e9c136c0616f776de89309677
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_ssize_t cur_size = _IO_str_count(fp);
206 _IO_pos_t new_pos = EOF;
208 /* Move the get pointer, if requested. */
209 if (mode & _IOS_INPUT)
211 switch (dir)
213 case _IO_seek_end:
214 offset += cur_size;
215 break;
216 case _IO_seek_cur:
217 offset += fp->_IO_read_ptr - fp->_IO_read_base;
218 break;
219 default: /* case _IO_seek_set: */
220 break;
222 if (offset < 0 || (_IO_ssize_t)offset > cur_size)
223 return EOF;
224 fp->_IO_read_ptr = fp->_IO_read_base + offset;
225 fp->_IO_read_end = fp->_IO_read_base + cur_size;
226 new_pos = offset;
229 /* Move the put pointer, if requested. */
230 if (mode & _IOS_OUTPUT)
232 switch (dir)
234 case _IO_seek_end:
235 offset += cur_size;
236 break;
237 case _IO_seek_cur:
238 offset += fp->_IO_write_ptr - fp->_IO_write_base;
239 break;
240 default: /* case _IO_seek_set: */
241 break;
243 if (offset < 0 || (_IO_ssize_t)offset > cur_size)
244 return EOF;
245 fp->_IO_write_ptr = fp->_IO_write_base + offset;
246 new_pos = offset;
248 return new_pos;
252 DEFUN(_IO_str_pbackfail, (fp, c),
253 register _IO_FILE *fp AND int c)
255 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
256 return EOF;
257 return _IO_default_pbackfail(fp, c);
260 void
261 DEFUN (_IO_str_finish, (fp, dummy),
262 register _IO_FILE* fp AND int dummy)
264 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
265 (((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
266 fp->_IO_buf_base = NULL;
268 _IO_default_finish(fp, 0);
271 struct _IO_jump_t _IO_str_jumps = {
272 JUMP_INIT_DUMMY,
273 JUMP_INIT(finish, _IO_str_finish),
274 JUMP_INIT(overflow, _IO_str_overflow),
275 JUMP_INIT(underflow, _IO_str_underflow),
276 JUMP_INIT(uflow, _IO_default_uflow),
277 JUMP_INIT(pbackfail, _IO_str_pbackfail),
278 JUMP_INIT(xsputn, _IO_default_xsputn),
279 JUMP_INIT(xsgetn, _IO_default_xsgetn),
280 JUMP_INIT(seekoff, _IO_str_seekoff),
281 JUMP_INIT(seekpos, _IO_default_seekpos),
282 JUMP_INIT(setbuf, _IO_default_setbuf),
283 JUMP_INIT(sync, _IO_default_sync),
284 JUMP_INIT(doallocate, _IO_default_doallocate),
285 JUMP_INIT(read, _IO_default_read),
286 JUMP_INIT(write, _IO_default_write),
287 JUMP_INIT(seek, _IO_default_seek),
288 JUMP_INIT(close, _IO_default_close),
289 JUMP_INIT(stat, _IO_default_stat)