1 /* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
2 This file is part of the GNU IO Library.
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2, or (at
7 your option) any later version.
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this library; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does
21 not cause the resulting executable to be covered by the GNU General
22 Public License. This exception does not however invalidate any
23 other reasons why the executable file might be covered by the GNU
24 General Public License. */
32 /* The following definitions are for exposition only.
33 They map the terminology used in the ANSI/ISO C++ draft standard
34 to the implementation. */
36 /* allocated: set when a dynamic array object has been allocated, and
37 hence should be freed by the destructor for the strstreambuf object. */
38 #define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
40 /* constant: set when the array object has const elements,
41 so the output sequence cannot be written. */
42 #define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
44 /* alsize: the suggested minimum size for a dynamic array object. */
45 #define ALSIZE(FP) ??? /* not stored */
47 /* palloc: points to the function to call to allocate a dynamic array object.*/
49 ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
51 /* pfree: points to the function to call to free a dynamic array object. */
53 ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
58 /* An "unbounded buffer" is when a buffer is supplied, but with no
59 specified length. An example is the buffer argument to sprintf.
64 _IO_wstr_init_static (fp
, ptr
, size
, pstart
)
71 size
= __wcslen (ptr
);
74 /* If size is negative 'the characters are assumed to
75 continue indefinitely.' This is kind of messy ... */
78 /* Try increasing powers of 2, as long as we don't wrap around. */
79 for (; s
= 2*size
, s
> 0 && ptr
+ s
> ptr
&& s
< 0x4000000L
; )
81 /* Try increasing size as much as we can without wrapping around. */
82 for (s
= size
>> 1; s
> 0; s
>>= 1)
84 if (ptr
+ size
+ s
> ptr
)
88 _IO_wsetb (fp
, ptr
, ptr
+ size
, 0);
90 fp
->_wide_data
->_IO_write_base
= ptr
;
91 fp
->_wide_data
->_IO_read_base
= ptr
;
92 fp
->_wide_data
->_IO_read_ptr
= ptr
;
95 fp
->_wide_data
->_IO_write_ptr
= pstart
;
96 fp
->_wide_data
->_IO_write_end
= ptr
+ size
;
97 fp
->_wide_data
->_IO_read_end
= pstart
;
101 fp
->_wide_data
->_IO_write_ptr
= ptr
;
102 fp
->_wide_data
->_IO_write_end
= ptr
;
103 fp
->_wide_data
->_IO_read_end
= ptr
+ size
;
105 /* A null _allocate_buffer function flags the strfile as being static. */
106 (((_IO_strfile
*) fp
)->_s
._allocate_buffer
) = (_IO_alloc_type
)0;
110 _IO_wstr_init_readonly (fp
, ptr
, size
)
115 _IO_wstr_init_static (fp
, (wchar_t *) ptr
, size
, NULL
);
116 fp
->_IO_file_flags
|= _IO_NO_WRITES
;
120 _IO_wstr_overflow (fp
, c
)
124 int flush_only
= c
== WEOF
;
126 if (fp
->_flags
& _IO_NO_WRITES
)
127 return flush_only
? 0 : WEOF
;
128 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && !(fp
->_flags
& _IO_CURRENTLY_PUTTING
))
130 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
131 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_read_ptr
;
132 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
134 pos
= fp
->_wide_data
->_IO_write_ptr
- fp
->_wide_data
->_IO_write_base
;
135 if (pos
>= (_IO_size_t
) (_IO_wblen (fp
) + flush_only
))
137 if (fp
->_flags
& _IO_USER_BUF
) /* not allowed to enlarge */
142 wchar_t *old_buf
= fp
->_wide_data
->_IO_buf_base
;
143 _IO_size_t new_size
= 2 * _IO_wblen (fp
) + 100;
145 = (wchar_t *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (new_size
149 /* __ferror(fp) = 1; */
154 __wmemcpy (new_buf
, old_buf
, _IO_wblen (fp
));
155 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (old_buf
);
156 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
157 fp
->_wide_data
->_IO_buf_base
= NULL
;
159 _IO_wsetb (fp
, new_buf
, new_buf
+ new_size
, 1);
160 fp
->_wide_data
->_IO_read_base
=
161 new_buf
+ (fp
->_wide_data
->_IO_read_base
- old_buf
);
162 fp
->_wide_data
->_IO_read_ptr
=
163 new_buf
+ (fp
->_wide_data
->_IO_read_ptr
- old_buf
);
164 fp
->_wide_data
->_IO_read_end
=
165 new_buf
+ (fp
->_wide_data
->_IO_read_end
- old_buf
);
166 fp
->_wide_data
->_IO_write_ptr
=
167 new_buf
+ (fp
->_wide_data
->_IO_write_ptr
- old_buf
);
169 fp
->_wide_data
->_IO_write_base
= new_buf
;
170 fp
->_wide_data
->_IO_write_end
= fp
->_wide_data
->_IO_buf_end
;
175 *fp
->_wide_data
->_IO_write_ptr
++ = c
;
176 if (fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
)
177 fp
->_wide_data
->_IO_read_end
= fp
->_wide_data
->_IO_write_ptr
;
182 _IO_wstr_underflow (fp
)
185 if (fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
)
186 fp
->_wide_data
->_IO_read_end
= fp
->_wide_data
->_IO_write_ptr
;
187 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
189 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
190 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_write_ptr
;
191 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_end
;
193 if (fp
->_wide_data
->_IO_read_ptr
< fp
->_wide_data
->_IO_read_end
)
194 return *fp
->_wide_data
->_IO_read_ptr
;
199 /* The size of the valid part of the buffer. */
205 return ((fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
206 ? fp
->_wide_data
->_IO_write_ptr
: fp
->_wide_data
->_IO_read_end
)
207 - fp
->_wide_data
->_IO_read_base
);
211 _IO_wstr_seekoff (fp
, offset
, dir
, mode
)
219 if (mode
== 0 && (fp
->_flags
& _IO_TIED_PUT_GET
))
220 mode
= (fp
->_flags
& _IO_CURRENTLY_PUTTING
? _IOS_OUTPUT
: _IOS_INPUT
);
224 /* Don't move any pointers. But there is no clear indication what
225 mode FP is in. Let's guess. */
226 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
227 new_pos
= fp
->_wide_data
->_IO_read_ptr
- fp
->_wide_data
->_IO_read_base
;
229 new_pos
= (fp
->_wide_data
->_IO_write_ptr
230 - fp
->_wide_data
->_IO_write_base
);
234 _IO_ssize_t cur_size
= _IO_wstr_count (fp
);
237 /* Move the get pointer, if requested. */
238 if (mode
& _IOS_INPUT
)
246 offset
+= (fp
->_wide_data
->_IO_read_ptr
247 - fp
->_wide_data
->_IO_read_base
);
249 default: /* case _IO_seek_set: */
252 if (offset
< 0 || (_IO_ssize_t
) offset
> cur_size
)
254 fp
->_wide_data
->_IO_read_ptr
= (fp
->_wide_data
->_IO_read_base
256 fp
->_wide_data
->_IO_read_end
= (fp
->_wide_data
->_IO_read_base
261 /* Move the put pointer, if requested. */
262 if (mode
& _IOS_OUTPUT
)
270 offset
+= (fp
->_wide_data
->_IO_write_ptr
271 - fp
->_wide_data
->_IO_write_base
);
273 default: /* case _IO_seek_set: */
276 if (offset
< 0 || (_IO_ssize_t
) offset
> cur_size
)
278 fp
->_wide_data
->_IO_write_ptr
= (fp
->_wide_data
->_IO_write_base
287 _IO_wstr_pbackfail (fp
, c
)
291 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= EOF
)
293 return _IO_wdefault_pbackfail (fp
, c
);
297 _IO_wstr_finish (fp
, dummy
)
301 if (fp
->_wide_data
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
302 (((_IO_strfile
*) fp
)->_s
._free_buffer
) (fp
->_wide_data
->_IO_buf_base
);
303 fp
->_wide_data
->_IO_buf_base
= NULL
;
305 _IO_wdefault_finish (fp
, 0);
308 struct _IO_jump_t _IO_wstr_jumps
=
311 JUMP_INIT(finish
, _IO_wstr_finish
),
312 JUMP_INIT(overflow
, (_IO_overflow_t
) _IO_wstr_overflow
),
313 JUMP_INIT(underflow
, (_IO_underflow_t
) _IO_wstr_underflow
),
314 JUMP_INIT(uflow
, (_IO_underflow_t
) _IO_wdefault_uflow
),
315 JUMP_INIT(pbackfail
, (_IO_pbackfail_t
) _IO_wstr_pbackfail
),
316 JUMP_INIT(xsputn
, _IO_wdefault_xsputn
),
317 JUMP_INIT(xsgetn
, _IO_wdefault_xsgetn
),
318 JUMP_INIT(seekoff
, _IO_wstr_seekoff
),
319 JUMP_INIT(seekpos
, _IO_default_seekpos
),
320 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_wdefault_setbuf
),
321 JUMP_INIT(sync
, _IO_default_sync
),
322 JUMP_INIT(doallocate
, _IO_wdefault_doallocate
),
323 JUMP_INIT(read
, _IO_default_read
),
324 JUMP_INIT(write
, _IO_default_write
),
325 JUMP_INIT(seek
, _IO_default_seek
),
326 JUMP_INIT(close
, _IO_default_close
),
327 JUMP_INIT(stat
, _IO_default_stat
),
328 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
329 JUMP_INIT(imbue
, _IO_default_imbue
)