1 /* Copyright (C) 1993, 1997, 1998, 1999, 2000 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. */
33 /* The following definitions are for exposition only.
34 They map the terminology used in the ANSI/ISO C++ draft standard
35 to the implementation. */
37 /* allocated: set when a dynamic array object has been allocated, and
38 hence should be freed by the destructor for the strstreambuf object. */
39 #define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
41 /* constant: set when the array object has const elements,
42 so the output sequence cannot be written. */
43 #define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
45 /* alsize: the suggested minimum size for a dynamic array object. */
46 #define ALSIZE(FP) ??? /* not stored */
48 /* palloc: points to the function to call to allocate a dynamic array object.*/
50 ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
52 /* pfree: points to the function to call to free a dynamic array object. */
54 ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
59 /* An "unbounded buffer" is when a buffer is supplied, but with no
60 specified length. An example is the buffer argument to sprintf.
65 _IO_str_init_static (sf
, ptr
, size
, pstart
)
71 _IO_FILE
*fp
= &sf
->_sbf
._f
;
77 /* If size is negative 'the characters are assumed to
78 continue indefinitely.' This is kind of messy ... */
81 /* Try increasing powers of 2, as long as we don't wrap around. */
82 for (; s
= 2*size
, s
> 0 && ptr
+ s
> ptr
&& s
< 0x4000000L
; )
84 /* Try increasing size as much as we can without wrapping around. */
85 for (s
= size
>> 1; s
> 0; s
>>= 1)
87 if (ptr
+ size
+ s
> ptr
)
91 _IO_setb (fp
, ptr
, ptr
+ size
, 0);
93 fp
->_IO_write_base
= ptr
;
94 fp
->_IO_read_base
= ptr
;
95 fp
->_IO_read_ptr
= ptr
;
98 fp
->_IO_write_ptr
= pstart
;
99 fp
->_IO_write_end
= ptr
+ size
;
100 fp
->_IO_read_end
= pstart
;
104 fp
->_IO_write_ptr
= ptr
;
105 fp
->_IO_write_end
= ptr
;
106 fp
->_IO_read_end
= ptr
+size
;
108 /* A null _allocate_buffer function flags the strfile as being static. */
109 sf
->_s
._allocate_buffer
= (_IO_alloc_type
) 0;
113 _IO_str_init_readonly (sf
, ptr
, size
)
118 _IO_str_init_static (sf
, (char *) ptr
, size
, NULL
);
119 sf
->_sbf
._f
._IO_file_flags
|= _IO_NO_WRITES
;
123 _IO_str_overflow (fp
, c
)
127 int flush_only
= c
== EOF
;
129 if (fp
->_flags
& _IO_NO_WRITES
)
130 return flush_only
? 0 : EOF
;
131 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && !(fp
->_flags
& _IO_CURRENTLY_PUTTING
))
133 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
134 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
135 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
137 pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
138 if (pos
>= (_IO_size_t
) (_IO_blen (fp
) + flush_only
))
140 if (fp
->_flags
& _IO_USER_BUF
) /* not allowed to enlarge */
145 char *old_buf
= fp
->_IO_buf_base
;
146 _IO_size_t new_size
= 2 * _IO_blen (fp
) + 100;
148 = (char *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (new_size
);
151 /* __ferror(fp) = 1; */
156 memcpy (new_buf
, old_buf
, _IO_blen (fp
));
157 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (old_buf
);
158 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
159 fp
->_IO_buf_base
= NULL
;
162 if (lenp
== &LEN(fp
)) /* use '\0'-filling */
163 memset (new_buf
+ pos
, 0, blen() - pos
);
165 _IO_setb (fp
, new_buf
, new_buf
+ new_size
, 1);
166 fp
->_IO_read_base
= new_buf
+ (fp
->_IO_read_base
- old_buf
);
167 fp
->_IO_read_ptr
= new_buf
+ (fp
->_IO_read_ptr
- old_buf
);
168 fp
->_IO_read_end
= new_buf
+ (fp
->_IO_read_end
- old_buf
);
169 fp
->_IO_write_ptr
= new_buf
+ (fp
->_IO_write_ptr
- old_buf
);
171 fp
->_IO_write_base
= new_buf
;
172 fp
->_IO_write_end
= fp
->_IO_buf_end
;
177 *fp
->_IO_write_ptr
++ = (unsigned char) c
;
178 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
179 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
184 _IO_str_underflow (fp
)
187 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
188 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
189 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
191 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
192 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
193 fp
->_IO_write_ptr
= fp
->_IO_write_end
;
195 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
196 return *((unsigned char *) fp
->_IO_read_ptr
);
201 /* The size of the valid part of the buffer. */
207 return ((fp
->_IO_write_ptr
> fp
->_IO_read_end
208 ? fp
->_IO_write_ptr
: fp
->_IO_read_end
)
209 - fp
->_IO_read_base
);
213 _IO_str_seekoff (fp
, offset
, dir
, mode
)
221 if (mode
== 0 && (fp
->_flags
& _IO_TIED_PUT_GET
))
222 mode
= (fp
->_flags
& _IO_CURRENTLY_PUTTING
? _IOS_OUTPUT
: _IOS_INPUT
);
226 /* Don't move any pointers. But there is no clear indication what
227 mode FP is in. Let's guess. */
228 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
229 new_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
231 new_pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
235 _IO_ssize_t cur_size
= _IO_str_count(fp
);
238 /* Move the get pointer, if requested. */
239 if (mode
& _IOS_INPUT
)
247 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
249 default: /* case _IO_seek_set: */
252 if (offset
< 0 || (_IO_ssize_t
) offset
> cur_size
)
254 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ offset
;
255 fp
->_IO_read_end
= fp
->_IO_read_base
+ cur_size
;
259 /* Move the put pointer, if requested. */
260 if (mode
& _IOS_OUTPUT
)
268 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
270 default: /* case _IO_seek_set: */
273 if (offset
< 0 || (_IO_ssize_t
) offset
> cur_size
)
275 fp
->_IO_write_ptr
= fp
->_IO_write_base
+ offset
;
283 _IO_str_pbackfail (fp
, c
)
287 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= EOF
)
289 return _IO_default_pbackfail (fp
, c
);
293 _IO_str_finish (fp
, dummy
)
297 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
298 (((_IO_strfile
*) fp
)->_s
._free_buffer
) (fp
->_IO_buf_base
);
299 fp
->_IO_buf_base
= NULL
;
301 _IO_default_finish (fp
, 0);
304 struct _IO_jump_t _IO_str_jumps
=
307 JUMP_INIT(finish
, _IO_str_finish
),
308 JUMP_INIT(overflow
, _IO_str_overflow
),
309 JUMP_INIT(underflow
, _IO_str_underflow
),
310 JUMP_INIT(uflow
, _IO_default_uflow
),
311 JUMP_INIT(pbackfail
, _IO_str_pbackfail
),
312 JUMP_INIT(xsputn
, _IO_default_xsputn
),
313 JUMP_INIT(xsgetn
, _IO_default_xsgetn
),
314 JUMP_INIT(seekoff
, _IO_str_seekoff
),
315 JUMP_INIT(seekpos
, _IO_default_seekpos
),
316 JUMP_INIT(setbuf
, _IO_default_setbuf
),
317 JUMP_INIT(sync
, _IO_default_sync
),
318 JUMP_INIT(doallocate
, _IO_default_doallocate
),
319 JUMP_INIT(read
, _IO_default_read
),
320 JUMP_INIT(write
, _IO_default_write
),
321 JUMP_INIT(seek
, _IO_default_seek
),
322 JUMP_INIT(close
, _IO_default_close
),
323 JUMP_INIT(stat
, _IO_default_stat
),
324 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
325 JUMP_INIT(imbue
, _IO_default_imbue
)