1 /* Copyright (C) 1993,1997-1999,2001-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. */
33 #include <stdio_ext.h>
36 _IO_wstr_init_static (fp
, ptr
, size
, pstart
)
45 end
= ptr
+ __wcslen (ptr
);
46 else if ((_IO_size_t
) ptr
+ size
* sizeof (wchar_t) > (_IO_size_t
) ptr
)
49 /* Even for misaligned ptr make sure there is integral number of wide
51 end
= ptr
+ (-1 - (_IO_size_t
) ptr
) / sizeof (wchar_t);
52 INTUSE(_IO_wsetb
) (fp
, ptr
, end
, 0);
54 fp
->_wide_data
->_IO_write_base
= ptr
;
55 fp
->_wide_data
->_IO_read_base
= ptr
;
56 fp
->_wide_data
->_IO_read_ptr
= ptr
;
59 fp
->_wide_data
->_IO_write_ptr
= pstart
;
60 fp
->_wide_data
->_IO_write_end
= end
;
61 fp
->_wide_data
->_IO_read_end
= pstart
;
65 fp
->_wide_data
->_IO_write_ptr
= ptr
;
66 fp
->_wide_data
->_IO_write_end
= ptr
;
67 fp
->_wide_data
->_IO_read_end
= end
;
69 /* A null _allocate_buffer function flags the strfile as being static. */
70 (((_IO_strfile
*) fp
)->_s
._allocate_buffer
) = (_IO_alloc_type
)0;
74 _IO_wstr_overflow (fp
, c
)
78 int flush_only
= c
== WEOF
;
80 if (fp
->_flags
& _IO_NO_WRITES
)
81 return flush_only
? 0 : WEOF
;
82 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && !(fp
->_flags
& _IO_CURRENTLY_PUTTING
))
84 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
85 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_read_ptr
;
86 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
88 pos
= fp
->_wide_data
->_IO_write_ptr
- fp
->_wide_data
->_IO_write_base
;
89 if (pos
>= (_IO_size_t
) (_IO_wblen (fp
) + flush_only
))
91 if (fp
->_flags
& _IO_USER_BUF
) /* not allowed to enlarge */
96 wchar_t *old_buf
= fp
->_wide_data
->_IO_buf_base
;
97 size_t old_wblen
= _IO_wblen (fp
);
98 _IO_size_t new_size
= 2 * old_wblen
+ 100;
99 if (new_size
< old_wblen
)
102 = (wchar_t *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (new_size
106 /* __ferror(fp) = 1; */
111 __wmemcpy (new_buf
, old_buf
, old_wblen
);
112 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (old_buf
);
113 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
114 fp
->_wide_data
->_IO_buf_base
= NULL
;
117 wmemset (new_buf
+ old_wblen
, L
'\0', new_size
- old_wblen
);
119 INTUSE(_IO_wsetb
) (fp
, new_buf
, new_buf
+ new_size
, 1);
120 fp
->_wide_data
->_IO_read_base
=
121 new_buf
+ (fp
->_wide_data
->_IO_read_base
- old_buf
);
122 fp
->_wide_data
->_IO_read_ptr
=
123 new_buf
+ (fp
->_wide_data
->_IO_read_ptr
- old_buf
);
124 fp
->_wide_data
->_IO_read_end
=
125 new_buf
+ (fp
->_wide_data
->_IO_read_end
- old_buf
);
126 fp
->_wide_data
->_IO_write_ptr
=
127 new_buf
+ (fp
->_wide_data
->_IO_write_ptr
- old_buf
);
129 fp
->_wide_data
->_IO_write_base
= new_buf
;
130 fp
->_wide_data
->_IO_write_end
= fp
->_wide_data
->_IO_buf_end
;
135 *fp
->_wide_data
->_IO_write_ptr
++ = c
;
136 if (fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
)
137 fp
->_wide_data
->_IO_read_end
= fp
->_wide_data
->_IO_write_ptr
;
143 _IO_wstr_underflow (fp
)
146 if (fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
)
147 fp
->_wide_data
->_IO_read_end
= fp
->_wide_data
->_IO_write_ptr
;
148 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
150 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
151 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_write_ptr
;
152 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_end
;
154 if (fp
->_wide_data
->_IO_read_ptr
< fp
->_wide_data
->_IO_read_end
)
155 return *fp
->_wide_data
->_IO_read_ptr
;
161 /* The size of the valid part of the buffer. */
166 struct _IO_wide_data
*wd
= fp
->_wide_data
;
168 return ((wd
->_IO_write_ptr
> wd
->_IO_read_end
169 ? wd
->_IO_write_ptr
: wd
->_IO_read_end
)
170 - wd
->_IO_read_base
);
175 enlarge_userbuf (_IO_FILE
*fp
, _IO_off64_t offset
, int reading
)
177 if ((_IO_ssize_t
) offset
<= _IO_blen (fp
))
180 struct _IO_wide_data
*wd
= fp
->_wide_data
;
182 _IO_ssize_t oldend
= wd
->_IO_write_end
- wd
->_IO_write_base
;
184 /* Try to enlarge the buffer. */
185 if (fp
->_flags
& _IO_USER_BUF
)
186 /* User-provided buffer. */
189 _IO_size_t newsize
= offset
+ 100;
190 wchar_t *oldbuf
= wd
->_IO_buf_base
;
192 = (wchar_t *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (newsize
199 __wmemcpy (newbuf
, oldbuf
, _IO_wblen (fp
));
200 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (oldbuf
);
201 /* Make sure _IO_setb won't try to delete
203 wd
->_IO_buf_base
= NULL
;
206 INTUSE(_IO_wsetb
) (fp
, newbuf
, newbuf
+ newsize
, 1);
210 wd
->_IO_write_base
= newbuf
+ (wd
->_IO_write_base
- oldbuf
);
211 wd
->_IO_write_ptr
= newbuf
+ (wd
->_IO_write_ptr
- oldbuf
);
212 wd
->_IO_write_end
= newbuf
+ (wd
->_IO_write_end
- oldbuf
);
213 wd
->_IO_read_ptr
= newbuf
+ (wd
->_IO_read_ptr
- oldbuf
);
215 wd
->_IO_read_base
= newbuf
;
216 wd
->_IO_read_end
= wd
->_IO_buf_end
;
220 wd
->_IO_read_base
= newbuf
+ (wd
->_IO_read_base
- oldbuf
);
221 wd
->_IO_read_ptr
= newbuf
+ (wd
->_IO_read_ptr
- oldbuf
);
222 wd
->_IO_read_end
= newbuf
+ (wd
->_IO_read_end
- oldbuf
);
223 wd
->_IO_write_ptr
= newbuf
+ (wd
->_IO_write_ptr
- oldbuf
);
225 wd
->_IO_write_base
= newbuf
;
226 wd
->_IO_write_end
= wd
->_IO_buf_end
;
229 /* Clear the area between the last write position and th
231 assert (offset
>= oldend
);
233 wmemset (wd
->_IO_read_base
+ oldend
, L
'\0', offset
- oldend
);
235 wmemset (wd
->_IO_write_base
+ oldend
, L
'\0', offset
- oldend
);
242 _IO_wstr_seekoff (fp
, offset
, dir
, mode
)
250 if (mode
== 0 && (fp
->_flags
& _IO_TIED_PUT_GET
))
251 mode
= (fp
->_flags
& _IO_CURRENTLY_PUTTING
? _IOS_OUTPUT
: _IOS_INPUT
);
255 /* Don't move any pointers. But there is no clear indication what
256 mode FP is in. Let's guess. */
257 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
258 new_pos
= fp
->_wide_data
->_IO_read_ptr
- fp
->_wide_data
->_IO_read_base
;
260 new_pos
= (fp
->_wide_data
->_IO_write_ptr
261 - fp
->_wide_data
->_IO_write_base
);
265 _IO_ssize_t cur_size
= _IO_wstr_count (fp
);
268 /* Move the get pointer, if requested. */
269 if (mode
& _IOS_INPUT
)
277 offset
+= (fp
->_wide_data
->_IO_read_ptr
278 - fp
->_wide_data
->_IO_read_base
);
280 default: /* case _IO_seek_set: */
285 if ((_IO_ssize_t
) offset
> cur_size
286 && enlarge_userbuf (fp
, offset
, 1) != 0)
288 fp
->_wide_data
->_IO_read_ptr
= (fp
->_wide_data
->_IO_read_base
290 fp
->_wide_data
->_IO_read_end
= (fp
->_wide_data
->_IO_read_base
295 /* Move the put pointer, if requested. */
296 if (mode
& _IOS_OUTPUT
)
304 offset
+= (fp
->_wide_data
->_IO_write_ptr
305 - fp
->_wide_data
->_IO_write_base
);
307 default: /* case _IO_seek_set: */
312 if ((_IO_ssize_t
) offset
> cur_size
313 && enlarge_userbuf (fp
, offset
, 0) != 0)
315 fp
->_wide_data
->_IO_write_ptr
= (fp
->_wide_data
->_IO_write_base
324 _IO_wstr_pbackfail (fp
, c
)
328 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= WEOF
)
330 return INTUSE(_IO_wdefault_pbackfail
) (fp
, c
);
334 _IO_wstr_finish (fp
, dummy
)
338 if (fp
->_wide_data
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
339 (((_IO_strfile
*) fp
)->_s
._free_buffer
) (fp
->_wide_data
->_IO_buf_base
);
340 fp
->_wide_data
->_IO_buf_base
= NULL
;
342 INTUSE(_IO_wdefault_finish
) (fp
, 0);
345 const struct _IO_jump_t _IO_wstr_jumps
=
348 JUMP_INIT(finish
, _IO_wstr_finish
),
349 JUMP_INIT(overflow
, (_IO_overflow_t
) _IO_wstr_overflow
),
350 JUMP_INIT(underflow
, (_IO_underflow_t
) _IO_wstr_underflow
),
351 JUMP_INIT(uflow
, (_IO_underflow_t
) INTUSE(_IO_wdefault_uflow
)),
352 JUMP_INIT(pbackfail
, (_IO_pbackfail_t
) _IO_wstr_pbackfail
),
353 JUMP_INIT(xsputn
, INTUSE(_IO_wdefault_xsputn
)),
354 JUMP_INIT(xsgetn
, INTUSE(_IO_wdefault_xsgetn
)),
355 JUMP_INIT(seekoff
, _IO_wstr_seekoff
),
356 JUMP_INIT(seekpos
, _IO_default_seekpos
),
357 JUMP_INIT(setbuf
, _IO_default_setbuf
),
358 JUMP_INIT(sync
, _IO_default_sync
),
359 JUMP_INIT(doallocate
, INTUSE(_IO_wdefault_doallocate
)),
360 JUMP_INIT(read
, _IO_default_read
),
361 JUMP_INIT(write
, _IO_default_write
),
362 JUMP_INIT(seek
, _IO_default_seek
),
363 JUMP_INIT(close
, _IO_default_close
),
364 JUMP_INIT(stat
, _IO_default_stat
),
365 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
366 JUMP_INIT(imbue
, _IO_default_imbue
)