2 Copyright (C) 1993 Free Software Foundation
4 This file is part of the GNU IO Library. This library is free
5 software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option)
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING. If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does not cause
21 the resulting executable to be covered by the GNU General Public License.
22 This exception does not however invalidate any other reasons why
23 the executable file might be covered by the GNU General Public License. */
30 /* The following definitions are for exposition only.
31 They map the terminology used in the ANSI/ISO C++ draft standard
32 to the implementation. */
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))
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)
42 /* alsize: the suggested minimum size for a dynamic array object. */
43 #define ALSIZE(FP) ??? /* not stored */
45 /* palloc: points to the function to call to allocate a dynamic array object.*/
47 ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
49 /* pfree: points to the function to call to free a dynamic array object. */
51 ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
56 /* An "unbounded buffer" is when a buffer is supplied, but with no
57 specified length. An example is the buffer argument to sprintf.
62 DEFUN(_IO_str_init_static
, (fp
, ptr
, size
, pstart
),
63 _IO_FILE
*fp AND
char *ptr AND
int size AND
char *pstart
)
69 /* If size is negative 'the characters are assumed to
70 continue indefinitely.' This is kind of messy ... */
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
; )
76 /* Try increasing size as much as we can without wrapping around. */
77 for (s
= size
>> 1; s
> 0; s
>>= 1)
79 if (ptr
+ size
+ s
> ptr
)
83 _IO_setb(fp
, ptr
, ptr
+size
, 0);
85 fp
->_IO_write_base
= ptr
;
86 fp
->_IO_read_base
= ptr
;
87 fp
->_IO_read_ptr
= ptr
;
90 fp
->_IO_write_ptr
= pstart
;
91 fp
->_IO_write_end
= ptr
+ size
;
92 fp
->_IO_read_end
= pstart
;
96 fp
->_IO_write_ptr
= ptr
;
97 fp
->_IO_write_end
= ptr
;
98 fp
->_IO_read_end
= ptr
+size
;
100 /* A null _allocate_buffer function flags the strfile as being static. */
101 (((_IO_strfile
*)(fp
))->_s
._allocate_buffer
) = (_IO_alloc_type
)0;
105 DEFUN(_IO_str_init_readonly
, (fp
, ptr
, size
),
106 _IO_FILE
*fp AND
const char *ptr AND
int size
)
108 _IO_str_init_static (fp
, (char*)ptr
, size
, NULL
);
109 fp
->_IO_file_flags
|= _IO_NO_WRITES
;
113 DEFUN(_IO_str_overflow
, (fp
, c
),
114 register _IO_FILE
* fp AND
int c
)
116 int flush_only
= c
== EOF
;
118 if (fp
->_flags
& _IO_NO_WRITES
)
119 return flush_only
? 0 : EOF
;
120 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && !(fp
->_flags
& _IO_CURRENTLY_PUTTING
))
122 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
123 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
124 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
126 pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
127 if (pos
>= (_IO_size_t
) (_IO_blen(fp
) + flush_only
))
129 if (fp
->_flags
& _IO_USER_BUF
) /* not allowed to enlarge */
134 char *old_buf
= fp
->_IO_buf_base
;
135 _IO_size_t new_size
= 2 * _IO_blen(fp
) + 100;
137 = (char*)(*((_IO_strfile
*)fp
)->_s
._allocate_buffer
)(new_size
);
140 /* __ferror(fp) = 1; */
143 if (fp
->_IO_buf_base
)
145 memcpy(new_buf
, old_buf
, _IO_blen(fp
));
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
;
151 if (lenp
== &LEN(fp
)) /* use '\0'-filling */
152 memset(new_buf
+ pos
, 0, blen() - pos
);
154 _IO_setb(fp
, new_buf
, new_buf
+ new_size
, 1);
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
);
160 fp
->_IO_write_base
= new_buf
;
161 fp
->_IO_write_end
= fp
->_IO_buf_end
;
166 *fp
->_IO_write_ptr
++ = (unsigned char) c
;
167 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
168 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
173 DEFUN(_IO_str_underflow
, (fp
),
174 register _IO_FILE
* fp
)
176 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
177 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
178 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
180 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
181 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
182 fp
->_IO_write_ptr
= fp
->_IO_write_end
;
184 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
185 return *fp
->_IO_read_ptr
;
190 /* The size of the valid part of the buffer. */
193 DEFUN(_IO_str_count
, (fp
),
194 register _IO_FILE
*fp
)
196 return (fp
->_IO_write_end
> fp
->_IO_read_end
? fp
->_IO_write_end
202 DEFUN(_IO_str_seekoff
, (fp
, offset
, dir
, mode
),
203 register _IO_FILE
*fp AND _IO_off_t offset AND
int dir AND
int mode
)
209 /* Don't move any pointers. But there is no clear indication what
210 mode FP is in. Let's guess. */
211 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
212 new_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
214 new_pos
= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
218 _IO_ssize_t cur_size
= _IO_str_count(fp
);
221 /* Move the get pointer, if requested. */
222 if (mode
& _IOS_INPUT
)
230 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
232 default: /* case _IO_seek_set: */
235 if (offset
< 0 || (_IO_ssize_t
)offset
> cur_size
)
237 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ offset
;
238 fp
->_IO_read_end
= fp
->_IO_read_base
+ cur_size
;
242 /* Move the put pointer, if requested. */
243 if (mode
& _IOS_OUTPUT
)
251 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
253 default: /* case _IO_seek_set: */
256 if (offset
< 0 || (_IO_ssize_t
)offset
> cur_size
)
258 fp
->_IO_write_ptr
= fp
->_IO_write_base
+ offset
;
266 DEFUN(_IO_str_pbackfail
, (fp
, c
),
267 register _IO_FILE
*fp AND
int c
)
269 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= EOF
)
271 return _IO_default_pbackfail(fp
, c
);
275 DEFUN (_IO_str_finish
, (fp
, dummy
),
276 register _IO_FILE
* fp AND
int dummy
)
278 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
279 (((_IO_strfile
*)fp
)->_s
._free_buffer
)(fp
->_IO_buf_base
);
280 fp
->_IO_buf_base
= NULL
;
282 _IO_default_finish(fp
, 0);
285 struct _IO_jump_t _IO_str_jumps
= {
287 JUMP_INIT(finish
, _IO_str_finish
),
288 JUMP_INIT(overflow
, _IO_str_overflow
),
289 JUMP_INIT(underflow
, _IO_str_underflow
),
290 JUMP_INIT(uflow
, _IO_default_uflow
),
291 JUMP_INIT(pbackfail
, _IO_str_pbackfail
),
292 JUMP_INIT(xsputn
, _IO_default_xsputn
),
293 JUMP_INIT(xsgetn
, _IO_default_xsgetn
),
294 JUMP_INIT(seekoff
, _IO_str_seekoff
),
295 JUMP_INIT(seekpos
, _IO_default_seekpos
),
296 JUMP_INIT(setbuf
, _IO_default_setbuf
),
297 JUMP_INIT(sync
, _IO_default_sync
),
298 JUMP_INIT(doallocate
, _IO_default_doallocate
),
299 JUMP_INIT(read
, _IO_default_read
),
300 JUMP_INIT(write
, _IO_default_write
),
301 JUMP_INIT(seek
, _IO_default_seek
),
302 JUMP_INIT(close
, _IO_default_close
),
303 JUMP_INIT(stat
, _IO_default_stat
)