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. */
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 INTUSE(_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 _IO_size_t new_size
= 2 * _IO_blen (fp
) + 100;
116 = (char *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (new_size
);
119 /* __ferror(fp) = 1; */
124 memcpy (new_buf
, old_buf
, _IO_blen (fp
));
125 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (old_buf
);
126 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
127 fp
->_IO_buf_base
= NULL
;
130 if (lenp
== &LEN(fp
)) /* use '\0'-filling */
131 memset (new_buf
+ pos
, 0, blen() - pos
);
133 INTUSE(_IO_setb
) (fp
, new_buf
, new_buf
+ new_size
, 1);
134 fp
->_IO_read_base
= new_buf
+ (fp
->_IO_read_base
- old_buf
);
135 fp
->_IO_read_ptr
= new_buf
+ (fp
->_IO_read_ptr
- old_buf
);
136 fp
->_IO_read_end
= new_buf
+ (fp
->_IO_read_end
- old_buf
);
137 fp
->_IO_write_ptr
= new_buf
+ (fp
->_IO_write_ptr
- old_buf
);
139 fp
->_IO_write_base
= new_buf
;
140 fp
->_IO_write_end
= fp
->_IO_buf_end
;
145 *fp
->_IO_write_ptr
++ = (unsigned char) c
;
146 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
147 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
150 INTDEF(_IO_str_overflow
)
153 _IO_str_underflow (fp
)
156 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
157 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
158 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
160 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
161 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
162 fp
->_IO_write_ptr
= fp
->_IO_write_end
;
164 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
165 return *((unsigned char *) fp
->_IO_read_ptr
);
169 INTDEF(_IO_str_underflow
)
171 /* The size of the valid part of the buffer. */
177 return ((fp
->_IO_write_ptr
> fp
->_IO_read_end
178 ? fp
->_IO_write_ptr
: fp
->_IO_read_end
)
179 - fp
->_IO_read_base
);
183 _IO_str_seekoff (fp
, offset
, dir
, mode
)
191 if (mode
== 0 && (fp
->_flags
& _IO_TIED_PUT_GET
))
192 mode
= (fp
->_flags
& _IO_CURRENTLY_PUTTING
? _IOS_OUTPUT
: _IOS_INPUT
);
196 /* Don't move any pointers. But there is no clear indication what
197 mode FP is in. Let's guess. */
198 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
199 new_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
201 new_pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
205 _IO_ssize_t cur_size
= _IO_str_count(fp
);
208 /* Move the get pointer, if requested. */
209 if (mode
& _IOS_INPUT
)
217 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
219 default: /* case _IO_seek_set: */
222 if (offset
< 0 || (_IO_ssize_t
) offset
> cur_size
)
224 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ offset
;
225 fp
->_IO_read_end
= fp
->_IO_read_base
+ cur_size
;
229 /* Move the put pointer, if requested. */
230 if (mode
& _IOS_OUTPUT
)
238 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
240 default: /* case _IO_seek_set: */
243 if (offset
< 0 || (_IO_ssize_t
) offset
> cur_size
)
245 fp
->_IO_write_ptr
= fp
->_IO_write_base
+ offset
;
251 INTDEF(_IO_str_seekoff
)
254 _IO_str_pbackfail (fp
, c
)
258 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= EOF
)
260 return INTUSE(_IO_default_pbackfail
) (fp
, c
);
262 INTDEF(_IO_str_pbackfail
)
265 _IO_str_finish (fp
, dummy
)
269 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
270 (((_IO_strfile
*) fp
)->_s
._free_buffer
) (fp
->_IO_buf_base
);
271 fp
->_IO_buf_base
= NULL
;
273 INTUSE(_IO_default_finish
) (fp
, 0);
276 const struct _IO_jump_t _IO_str_jumps
=
279 JUMP_INIT(finish
, _IO_str_finish
),
280 JUMP_INIT(overflow
, INTUSE(_IO_str_overflow
)),
281 JUMP_INIT(underflow
, INTUSE(_IO_str_underflow
)),
282 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
283 JUMP_INIT(pbackfail
, INTUSE(_IO_str_pbackfail
)),
284 JUMP_INIT(xsputn
, INTUSE(_IO_default_xsputn
)),
285 JUMP_INIT(xsgetn
, INTUSE(_IO_default_xsgetn
)),
286 JUMP_INIT(seekoff
, INTUSE(_IO_str_seekoff
)),
287 JUMP_INIT(seekpos
, _IO_default_seekpos
),
288 JUMP_INIT(setbuf
, _IO_default_setbuf
),
289 JUMP_INIT(sync
, _IO_default_sync
),
290 JUMP_INIT(doallocate
, INTUSE(_IO_default_doallocate
)),
291 JUMP_INIT(read
, _IO_default_read
),
292 JUMP_INIT(write
, _IO_default_write
),
293 JUMP_INIT(seek
, _IO_default_seek
),
294 JUMP_INIT(close
, _IO_default_close
),
295 JUMP_INIT(stat
, _IO_default_stat
),
296 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
297 JUMP_INIT(imbue
, _IO_default_imbue
)