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
)
205 _IO_ssize_t cur_size
= _IO_str_count(fp
);
206 _IO_pos_t new_pos
= EOF
;
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
;
252 DEFUN(_IO_str_pbackfail
, (fp
, c
),
253 register _IO_FILE
*fp AND
int c
)
255 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= EOF
)
257 return _IO_default_pbackfail(fp
, c
);
261 DEFUN (_IO_str_finish
, (fp
, dummy
),
262 register _IO_FILE
* fp AND
int dummy
)
264 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
265 (((_IO_strfile
*)fp
)->_s
._free_buffer
)(fp
->_IO_buf_base
);
266 fp
->_IO_buf_base
= NULL
;
268 _IO_default_finish(fp
, 0);
271 struct _IO_jump_t _IO_str_jumps
= {
273 JUMP_INIT(finish
, _IO_str_finish
),
274 JUMP_INIT(overflow
, _IO_str_overflow
),
275 JUMP_INIT(underflow
, _IO_str_underflow
),
276 JUMP_INIT(uflow
, _IO_default_uflow
),
277 JUMP_INIT(pbackfail
, _IO_str_pbackfail
),
278 JUMP_INIT(xsputn
, _IO_default_xsputn
),
279 JUMP_INIT(xsgetn
, _IO_default_xsgetn
),
280 JUMP_INIT(seekoff
, _IO_str_seekoff
),
281 JUMP_INIT(seekpos
, _IO_default_seekpos
),
282 JUMP_INIT(setbuf
, _IO_default_setbuf
),
283 JUMP_INIT(sync
, _IO_default_sync
),
284 JUMP_INIT(doallocate
, _IO_default_doallocate
),
285 JUMP_INIT(read
, _IO_default_read
),
286 JUMP_INIT(write
, _IO_default_write
),
287 JUMP_INIT(seek
, _IO_default_seek
),
288 JUMP_INIT(close
, _IO_default_close
),
289 JUMP_INIT(stat
, _IO_default_stat
)