1 /* Copyright (C) 1993-2013 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, see
16 <http://www.gnu.org/licenses/>.
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
31 #include <stdio_ext.h>
34 _IO_str_init_static_internal (sf, ptr, size, pstart)
40 _IO_FILE *fp = &sf->_sbf._f;
44 end = __rawmemchr (ptr, '\0');
45 else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr)
49 _IO_setb (fp, ptr, end, 0);
51 fp->_IO_write_base = ptr;
52 fp->_IO_read_base = ptr;
53 fp->_IO_read_ptr = ptr;
56 fp->_IO_write_ptr = pstart;
57 fp->_IO_write_end = end;
58 fp->_IO_read_end = pstart;
62 fp->_IO_write_ptr = ptr;
63 fp->_IO_write_end = ptr;
64 fp->_IO_read_end = end;
66 /* A null _allocate_buffer function flags the strfile as being static. */
67 sf->_s._allocate_buffer = (_IO_alloc_type) 0;
71 _IO_str_init_static (sf, ptr, size, pstart)
77 return _IO_str_init_static_internal (sf, ptr, size < 0 ? -1 : size, pstart);
81 _IO_str_init_readonly (sf, ptr, size)
86 _IO_str_init_static_internal (sf, (char *) ptr, size < 0 ? -1 : size, NULL);
87 sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
91 _IO_str_overflow (fp, c)
95 int flush_only = c == EOF;
97 if (fp->_flags & _IO_NO_WRITES)
98 return flush_only ? 0 : EOF;
99 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
101 fp->_flags |= _IO_CURRENTLY_PUTTING;
102 fp->_IO_write_ptr = fp->_IO_read_ptr;
103 fp->_IO_read_ptr = fp->_IO_read_end;
105 pos = fp->_IO_write_ptr - fp->_IO_write_base;
106 if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
108 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
113 char *old_buf = fp->_IO_buf_base;
114 size_t old_blen = _IO_blen (fp);
115 _IO_size_t new_size = 2 * old_blen + 100;
116 if (new_size < old_blen)
119 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
122 /* __ferror(fp) = 1; */
127 memcpy (new_buf, old_buf, old_blen);
128 (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
129 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
130 fp->_IO_buf_base = NULL;
132 memset (new_buf + old_blen, '\0', new_size - old_blen);
134 _IO_setb (fp, new_buf, new_buf + new_size, 1);
135 fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
136 fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
137 fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
138 fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
140 fp->_IO_write_base = new_buf;
141 fp->_IO_write_end = fp->_IO_buf_end;
146 *fp->_IO_write_ptr++ = (unsigned char) c;
147 if (fp->_IO_write_ptr > fp->_IO_read_end)
148 fp->_IO_read_end = fp->_IO_write_ptr;
151 libc_hidden_def (_IO_str_overflow)
154 _IO_str_underflow (fp)
157 if (fp->_IO_write_ptr > fp->_IO_read_end)
158 fp->_IO_read_end = fp->_IO_write_ptr;
159 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
161 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
162 fp->_IO_read_ptr = fp->_IO_write_ptr;
163 fp->_IO_write_ptr = fp->_IO_write_end;
165 if (fp->_IO_read_ptr < fp->_IO_read_end)
166 return *((unsigned char *) fp->_IO_read_ptr);
170 libc_hidden_def (_IO_str_underflow)
172 /* The size of the valid part of the buffer. */
178 return ((fp->_IO_write_ptr > fp->_IO_read_end
179 ? fp->_IO_write_ptr : fp->_IO_read_end)
180 - fp->_IO_read_base);
185 enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
187 if ((_IO_ssize_t) offset <= _IO_blen (fp))
190 _IO_ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base;
192 /* Try to enlarge the buffer. */
193 if (fp->_flags & _IO_USER_BUF)
194 /* User-provided buffer. */
197 _IO_size_t newsize = offset + 100;
198 char *oldbuf = fp->_IO_buf_base;
200 = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize);
206 memcpy (newbuf, oldbuf, _IO_blen (fp));
207 (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
208 /* Make sure _IO_setb won't try to delete
210 fp->_IO_buf_base = NULL;
213 _IO_setb (fp, newbuf, newbuf + newsize, 1);
217 fp->_IO_write_base = newbuf + (fp->_IO_write_base - oldbuf);
218 fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf);
219 fp->_IO_write_end = newbuf + (fp->_IO_write_end - oldbuf);
220 fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf);
222 fp->_IO_read_base = newbuf;
223 fp->_IO_read_end = fp->_IO_buf_end;
227 fp->_IO_read_base = newbuf + (fp->_IO_read_base - oldbuf);
228 fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf);
229 fp->_IO_read_end = newbuf + (fp->_IO_read_end - oldbuf);
230 fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf);
232 fp->_IO_write_base = newbuf;
233 fp->_IO_write_end = fp->_IO_buf_end;
236 /* Clear the area between the last write position and th
238 assert (offset >= oldend);
240 memset (fp->_IO_read_base + oldend, '\0', offset - oldend);
242 memset (fp->_IO_write_base + oldend, '\0', offset - oldend);
249 _IO_str_seekoff (fp, offset, dir, mode)
257 if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
258 mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
262 /* Don't move any pointers. But there is no clear indication what
263 mode FP is in. Let's guess. */
264 if (fp->_IO_file_flags & _IO_NO_WRITES)
265 new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
267 new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
271 _IO_ssize_t cur_size = _IO_str_count(fp);
274 /* Move the get pointer, if requested. */
275 if (mode & _IOS_INPUT)
283 offset += fp->_IO_read_ptr - fp->_IO_read_base;
285 default: /* case _IO_seek_set: */
290 if ((_IO_ssize_t) offset > cur_size
291 && enlarge_userbuf (fp, offset, 1) != 0)
293 fp->_IO_read_ptr = fp->_IO_read_base + offset;
294 fp->_IO_read_end = fp->_IO_read_base + cur_size;
298 /* Move the put pointer, if requested. */
299 if (mode & _IOS_OUTPUT)
307 offset += fp->_IO_write_ptr - fp->_IO_write_base;
309 default: /* case _IO_seek_set: */
314 if ((_IO_ssize_t) offset > cur_size
315 && enlarge_userbuf (fp, offset, 0) != 0)
317 fp->_IO_write_ptr = fp->_IO_write_base + offset;
323 libc_hidden_def (_IO_str_seekoff)
326 _IO_str_pbackfail (fp, c)
330 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
332 return _IO_default_pbackfail (fp, c);
334 libc_hidden_def (_IO_str_pbackfail)
337 _IO_str_finish (fp, dummy)
341 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
342 (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
343 fp->_IO_buf_base = NULL;
345 _IO_default_finish (fp, 0);
348 const struct _IO_jump_t _IO_str_jumps =
351 JUMP_INIT(finish, _IO_str_finish),
352 JUMP_INIT(overflow, _IO_str_overflow),
353 JUMP_INIT(underflow, _IO_str_underflow),
354 JUMP_INIT(uflow, _IO_default_uflow),
355 JUMP_INIT(pbackfail, _IO_str_pbackfail),
356 JUMP_INIT(xsputn, _IO_default_xsputn),
357 JUMP_INIT(xsgetn, _IO_default_xsgetn),
358 JUMP_INIT(seekoff, _IO_str_seekoff),
359 JUMP_INIT(seekpos, _IO_default_seekpos),
360 JUMP_INIT(setbuf, _IO_default_setbuf),
361 JUMP_INIT(sync, _IO_default_sync),
362 JUMP_INIT(doallocate, _IO_default_doallocate),
363 JUMP_INIT(read, _IO_default_read),
364 JUMP_INIT(write, _IO_default_write),
365 JUMP_INIT(seek, _IO_default_seek),
366 JUMP_INIT(close, _IO_default_close),
367 JUMP_INIT(stat, _IO_default_stat),
368 JUMP_INIT(showmanyc, _IO_default_showmanyc),
369 JUMP_INIT(imbue, _IO_default_imbue)