1 /* Copyright (C) 1993, 1997-2003, 2004, 2006 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
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. */
32 #include <stdio_ext.h>
35 _IO_str_init_static_internal (sf
, ptr
, size
, pstart
)
41 _IO_FILE
*fp
= &sf
->_sbf
._f
;
45 end
= __rawmemchr (ptr
, '\0');
46 else if ((_IO_size_t
) ptr
+ size
> (_IO_size_t
) ptr
)
50 INTUSE(_IO_setb
) (fp
, ptr
, end
, 0);
52 fp
->_IO_write_base
= ptr
;
53 fp
->_IO_read_base
= ptr
;
54 fp
->_IO_read_ptr
= ptr
;
57 fp
->_IO_write_ptr
= pstart
;
58 fp
->_IO_write_end
= end
;
59 fp
->_IO_read_end
= pstart
;
63 fp
->_IO_write_ptr
= ptr
;
64 fp
->_IO_write_end
= ptr
;
65 fp
->_IO_read_end
= end
;
67 /* A null _allocate_buffer function flags the strfile as being static. */
68 sf
->_s
._allocate_buffer
= (_IO_alloc_type
) 0;
72 _IO_str_init_static (sf
, ptr
, size
, pstart
)
78 return _IO_str_init_static_internal (sf
, ptr
, size
< 0 ? -1 : size
, pstart
);
82 _IO_str_init_readonly (sf
, ptr
, size
)
87 _IO_str_init_static_internal (sf
, (char *) ptr
, size
< 0 ? -1 : size
, NULL
);
88 sf
->_sbf
._f
._IO_file_flags
|= _IO_NO_WRITES
;
92 _IO_str_overflow (fp
, c
)
96 int flush_only
= c
== EOF
;
98 if (fp
->_flags
& _IO_NO_WRITES
)
99 return flush_only
? 0 : EOF
;
100 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && !(fp
->_flags
& _IO_CURRENTLY_PUTTING
))
102 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
103 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
104 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
106 pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
107 if (pos
>= (_IO_size_t
) (_IO_blen (fp
) + flush_only
))
109 if (fp
->_flags
& _IO_USER_BUF
) /* not allowed to enlarge */
114 char *old_buf
= fp
->_IO_buf_base
;
115 size_t old_blen
= _IO_blen (fp
);
116 _IO_size_t new_size
= 2 * old_blen
+ 100;
117 if (new_size
< old_blen
)
120 = (char *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (new_size
);
123 /* __ferror(fp) = 1; */
128 memcpy (new_buf
, old_buf
, old_blen
);
129 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (old_buf
);
130 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
131 fp
->_IO_buf_base
= NULL
;
133 memset (new_buf
+ old_blen
, '\0', new_size
- old_blen
);
135 INTUSE(_IO_setb
) (fp
, new_buf
, new_buf
+ new_size
, 1);
136 fp
->_IO_read_base
= new_buf
+ (fp
->_IO_read_base
- old_buf
);
137 fp
->_IO_read_ptr
= new_buf
+ (fp
->_IO_read_ptr
- old_buf
);
138 fp
->_IO_read_end
= new_buf
+ (fp
->_IO_read_end
- old_buf
);
139 fp
->_IO_write_ptr
= new_buf
+ (fp
->_IO_write_ptr
- old_buf
);
141 fp
->_IO_write_base
= new_buf
;
142 fp
->_IO_write_end
= fp
->_IO_buf_end
;
147 *fp
->_IO_write_ptr
++ = (unsigned char) c
;
148 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
149 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
152 INTDEF(_IO_str_overflow
)
155 _IO_str_underflow (fp
)
158 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
159 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
160 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
162 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
163 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
164 fp
->_IO_write_ptr
= fp
->_IO_write_end
;
166 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
167 return *((unsigned char *) fp
->_IO_read_ptr
);
171 INTDEF(_IO_str_underflow
)
173 /* The size of the valid part of the buffer. */
179 return ((fp
->_IO_write_ptr
> fp
->_IO_read_end
180 ? fp
->_IO_write_ptr
: fp
->_IO_read_end
)
181 - fp
->_IO_read_base
);
186 enlarge_userbuf (_IO_FILE
*fp
, _IO_off64_t offset
, int reading
)
188 if ((_IO_ssize_t
) offset
<= _IO_blen (fp
))
191 _IO_ssize_t oldend
= fp
->_IO_write_end
- fp
->_IO_write_base
;
193 /* Try to enlarge the buffer. */
194 if (fp
->_flags
& _IO_USER_BUF
)
195 /* User-provided buffer. */
198 _IO_size_t newsize
= offset
+ 100;
199 char *oldbuf
= fp
->_IO_buf_base
;
201 = (char *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (newsize
);
207 memcpy (newbuf
, oldbuf
, _IO_blen (fp
));
208 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (oldbuf
);
209 /* Make sure _IO_setb won't try to delete
211 fp
->_IO_buf_base
= NULL
;
214 INTUSE(_IO_setb
) (fp
, newbuf
, newbuf
+ newsize
, 1);
218 fp
->_IO_write_base
= newbuf
+ (fp
->_IO_write_base
- oldbuf
);
219 fp
->_IO_write_ptr
= newbuf
+ (fp
->_IO_write_ptr
- oldbuf
);
220 fp
->_IO_write_end
= newbuf
+ (fp
->_IO_write_end
- oldbuf
);
221 fp
->_IO_read_ptr
= newbuf
+ (fp
->_IO_read_ptr
- oldbuf
);
223 fp
->_IO_read_base
= newbuf
;
224 fp
->_IO_read_end
= fp
->_IO_buf_end
;
228 fp
->_IO_read_base
= newbuf
+ (fp
->_IO_read_base
- oldbuf
);
229 fp
->_IO_read_ptr
= newbuf
+ (fp
->_IO_read_ptr
- oldbuf
);
230 fp
->_IO_read_end
= newbuf
+ (fp
->_IO_read_end
- oldbuf
);
231 fp
->_IO_write_ptr
= newbuf
+ (fp
->_IO_write_ptr
- oldbuf
);
233 fp
->_IO_write_base
= newbuf
;
234 fp
->_IO_write_end
= fp
->_IO_buf_end
;
237 /* Clear the area between the last write position and th
239 assert (offset
>= oldend
);
241 memset (fp
->_IO_read_base
+ oldend
, '\0', offset
- oldend
);
243 memset (fp
->_IO_write_base
+ oldend
, '\0', offset
- oldend
);
250 _IO_str_seekoff (fp
, offset
, dir
, mode
)
258 if (mode
== 0 && (fp
->_flags
& _IO_TIED_PUT_GET
))
259 mode
= (fp
->_flags
& _IO_CURRENTLY_PUTTING
? _IOS_OUTPUT
: _IOS_INPUT
);
263 /* Don't move any pointers. But there is no clear indication what
264 mode FP is in. Let's guess. */
265 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
266 new_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
268 new_pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
272 _IO_ssize_t cur_size
= _IO_str_count(fp
);
275 /* Move the get pointer, if requested. */
276 if (mode
& _IOS_INPUT
)
284 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
286 default: /* case _IO_seek_set: */
291 if ((_IO_ssize_t
) offset
> cur_size
292 && enlarge_userbuf (fp
, offset
, 1) != 0)
294 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ offset
;
295 fp
->_IO_read_end
= fp
->_IO_read_base
+ cur_size
;
299 /* Move the put pointer, if requested. */
300 if (mode
& _IOS_OUTPUT
)
308 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
310 default: /* case _IO_seek_set: */
315 if ((_IO_ssize_t
) offset
> cur_size
316 && enlarge_userbuf (fp
, offset
, 0) != 0)
318 fp
->_IO_write_ptr
= fp
->_IO_write_base
+ offset
;
324 INTDEF(_IO_str_seekoff
)
327 _IO_str_pbackfail (fp
, c
)
331 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= EOF
)
333 return INTUSE(_IO_default_pbackfail
) (fp
, c
);
335 INTDEF(_IO_str_pbackfail
)
338 _IO_str_finish (fp
, dummy
)
342 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
343 (((_IO_strfile
*) fp
)->_s
._free_buffer
) (fp
->_IO_buf_base
);
344 fp
->_IO_buf_base
= NULL
;
346 INTUSE(_IO_default_finish
) (fp
, 0);
349 const struct _IO_jump_t _IO_str_jumps
=
352 JUMP_INIT(finish
, _IO_str_finish
),
353 JUMP_INIT(overflow
, INTUSE(_IO_str_overflow
)),
354 JUMP_INIT(underflow
, INTUSE(_IO_str_underflow
)),
355 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
356 JUMP_INIT(pbackfail
, INTUSE(_IO_str_pbackfail
)),
357 JUMP_INIT(xsputn
, INTUSE(_IO_default_xsputn
)),
358 JUMP_INIT(xsgetn
, INTUSE(_IO_default_xsgetn
)),
359 JUMP_INIT(seekoff
, INTUSE(_IO_str_seekoff
)),
360 JUMP_INIT(seekpos
, _IO_default_seekpos
),
361 JUMP_INIT(setbuf
, _IO_default_setbuf
),
362 JUMP_INIT(sync
, _IO_default_sync
),
363 JUMP_INIT(doallocate
, INTUSE(_IO_default_doallocate
)),
364 JUMP_INIT(read
, _IO_default_read
),
365 JUMP_INIT(write
, _IO_default_write
),
366 JUMP_INIT(seek
, _IO_default_seek
),
367 JUMP_INIT(close
, _IO_default_close
),
368 JUMP_INIT(stat
, _IO_default_stat
),
369 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
370 JUMP_INIT(imbue
, _IO_default_imbue
)