]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/strops.c
Update.
[thirdparty/glibc.git] / libio / strops.c
CommitLineData
a68b0d31 1/*
96aa2d94
RM
2Copyright (C) 1993 Free Software Foundation
3
4This file is part of the GNU IO Library. This library is free
5software; you can redistribute it and/or modify it under the
6terms of the GNU General Public License as published by the
7Free Software Foundation; either version 2, or (at your option)
8any later version.
9
10This library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this library; see the file COPYING. If not, write to the Free
17Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19As a special exception, if you link this library with files
20compiled with a GNU compiler to produce an executable, this does not cause
21the resulting executable to be covered by the GNU General Public License.
22This exception does not however invalidate any other reasons why
23the executable file might be covered by the GNU General Public License. */
24
25#include "strfile.h"
26#include "libioP.h"
27#include <string.h>
28
8a523922
UD
29#if 0
30/* The following definitions are for exposition only.
6d52618b 31 They map the terminology used in the ANSI/ISO C++ draft standard
8a523922
UD
32 to the implementation. */
33
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))
37
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)
41
42/* alsize: the suggested minimum size for a dynamic array object. */
43#define ALSIZE(FP) ??? /* not stored */
44
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)
48
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)
52
53#endif
96aa2d94
RM
54
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.
58 */
59#endif
60
61void
62DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
63 _IO_FILE *fp AND char *ptr AND int size AND char *pstart)
64{
65 if (size == 0)
66 size = strlen(ptr);
67 else if (size < 0)
68 {
69 /* If size is negative 'the characters are assumed to
70 continue indefinitely.' This is kind of messy ... */
96aa2d94
RM
71 int s;
72 size = 512;
8a523922
UD
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; )
96aa2d94 75 size = s;
8a523922
UD
76 /* Try increasing size as much as we can without wrapping around. */
77 for (s = size >> 1; s > 0; s >>= 1)
78 {
79 if (ptr + size + s > ptr)
80 size += s;
81 }
96aa2d94
RM
82 }
83 _IO_setb(fp, ptr, ptr+size, 0);
84
85 fp->_IO_write_base = ptr;
86 fp->_IO_read_base = ptr;
87 fp->_IO_read_ptr = ptr;
88 if (pstart)
89 {
90 fp->_IO_write_ptr = pstart;
9c2322bc 91 fp->_IO_write_end = pstart;
96aa2d94
RM
92 fp->_IO_read_end = pstart;
93 }
94 else
95 {
96 fp->_IO_write_ptr = ptr;
97 fp->_IO_write_end = ptr;
98 fp->_IO_read_end = ptr+size;
99 }
96aa2d94
RM
100 /* A null _allocate_buffer function flags the strfile as being static. */
101 (((_IO_strfile*)(fp))->_s._allocate_buffer) = (_IO_alloc_type)0;
102}
103
104void
105DEFUN(_IO_str_init_readonly, (fp, ptr, size),
106 _IO_FILE *fp AND const char *ptr AND int size)
107{
108 _IO_str_init_static (fp, (char*)ptr, size, NULL);
109 fp->_IO_file_flags |= _IO_NO_WRITES;
110}
111
112int
113DEFUN(_IO_str_overflow, (fp, c),
114 register _IO_FILE* fp AND int c)
115{
116 int flush_only = c == EOF;
8a523922 117 _IO_size_t pos;
96aa2d94
RM
118 if (fp->_flags & _IO_NO_WRITES)
119 return flush_only ? 0 : EOF;
96aa2d94
RM
120 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
121 {
96aa2d94 122 fp->_flags |= _IO_CURRENTLY_PUTTING;
8a523922
UD
123 fp->_IO_write_ptr = fp->_IO_read_ptr;
124 fp->_IO_read_ptr = fp->_IO_read_end;
96aa2d94 125 }
8a523922 126 pos = fp->_IO_write_ptr - fp->_IO_write_base;
f8b87ef0 127 if (pos >= (_IO_size_t) (_IO_blen(fp) + flush_only))
96aa2d94
RM
128 {
129 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
8a523922 130 return EOF;
96aa2d94
RM
131 else
132 {
133 char *new_buf;
8a523922
UD
134 char *old_buf = fp->_IO_buf_base;
135 _IO_size_t new_size = 2 * _IO_blen(fp) + 100;
96aa2d94
RM
136 new_buf
137 = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
138 if (new_buf == NULL)
139 {
140 /* __ferror(fp) = 1; */
141 return EOF;
142 }
96aa2d94
RM
143 if (fp->_IO_buf_base)
144 {
8a523922 145 memcpy(new_buf, old_buf, _IO_blen(fp));
96aa2d94
RM
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;
149 }
8a523922
UD
150#if 0
151 if (lenp == &LEN(fp)) /* use '\0'-filling */
152 memset(new_buf + pos, 0, blen() - pos);
153#endif
96aa2d94 154 _IO_setb(fp, new_buf, new_buf + new_size, 1);
8a523922
UD
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);
159
96aa2d94 160 fp->_IO_write_base = new_buf;
9c2322bc 161 fp->_IO_write_end = new_buf + (fp->_IO_write_end - old_buf);
96aa2d94 162 }
96aa2d94
RM
163 }
164
96aa2d94
RM
165 if (!flush_only)
166 *fp->_IO_write_ptr++ = (unsigned char) c;
8a523922
UD
167 if (fp->_IO_write_ptr > fp->_IO_read_end)
168 fp->_IO_read_end = fp->_IO_write_ptr;
96aa2d94
RM
169 return c;
170}
171
172int
173DEFUN(_IO_str_underflow, (fp),
174 register _IO_FILE* fp)
175{
8a523922
UD
176 if (fp->_IO_write_ptr > fp->_IO_read_end)
177 fp->_IO_read_end = fp->_IO_write_ptr;
96aa2d94
RM
178 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
179 {
180 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
8a523922 181 fp->_IO_read_ptr = fp->_IO_write_ptr;
96aa2d94
RM
182 fp->_IO_write_ptr = fp->_IO_write_end;
183 }
96aa2d94
RM
184 if (fp->_IO_read_ptr < fp->_IO_read_end)
185 return *fp->_IO_read_ptr;
186 else
187 return EOF;
188}
189
8a523922
UD
190/* The size of the valid part of the buffer. */
191
96aa2d94
RM
192_IO_ssize_t
193DEFUN(_IO_str_count, (fp),
194 register _IO_FILE *fp)
195{
478b92f0 196 return (fp->_IO_write_end > fp->_IO_read_end ? fp->_IO_write_end
8a523922
UD
197 : fp->_IO_read_end)
198 - fp->_IO_read_base;
a68b0d31 199}
96aa2d94
RM
200
201_IO_pos_t
202DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
203 register _IO_FILE *fp AND _IO_off_t offset AND int dir AND int mode)
204{
205 _IO_ssize_t cur_size = _IO_str_count(fp);
206 _IO_pos_t new_pos = EOF;
207
208 /* Move the get pointer, if requested. */
209 if (mode & _IOS_INPUT)
210 {
211 switch (dir)
212 {
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;
221 }
a68b0d31 222 if (offset < 0 || (_IO_ssize_t)offset > cur_size)
96aa2d94
RM
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;
227 }
228
229 /* Move the put pointer, if requested. */
230 if (mode & _IOS_OUTPUT)
231 {
232 switch (dir)
233 {
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;
242 }
a68b0d31 243 if (offset < 0 || (_IO_ssize_t)offset > cur_size)
96aa2d94 244 return EOF;
96aa2d94
RM
245 fp->_IO_write_ptr = fp->_IO_write_base + offset;
246 new_pos = offset;
247 }
248 return new_pos;
249}
250
251int
252DEFUN(_IO_str_pbackfail, (fp, c),
253 register _IO_FILE *fp AND int c)
254{
255 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
256 return EOF;
257 return _IO_default_pbackfail(fp, c);
258}
259
260void
ceb2d9aa
UD
261DEFUN (_IO_str_finish, (fp, dummy),
262 register _IO_FILE* fp AND int dummy)
96aa2d94
RM
263{
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;
267
ceb2d9aa 268 _IO_default_finish(fp, 0);
96aa2d94
RM
269}
270
271struct _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)
290};