1 /* Copyright (C) 1993-2014 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, see
16 <http://www.gnu.org/licenses/>.
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
32 #include <stdio_ext.h>
35 _IO_wstr_init_static (fp
, ptr
, size
, pstart
)
44 end
= ptr
+ __wcslen (ptr
);
45 else if ((_IO_size_t
) ptr
+ size
* sizeof (wchar_t) > (_IO_size_t
) ptr
)
48 /* Even for misaligned ptr make sure there is integral number of wide
50 end
= ptr
+ (-1 - (_IO_size_t
) ptr
) / sizeof (wchar_t);
51 _IO_wsetb (fp
, ptr
, end
, 0);
53 fp
->_wide_data
->_IO_write_base
= ptr
;
54 fp
->_wide_data
->_IO_read_base
= ptr
;
55 fp
->_wide_data
->_IO_read_ptr
= ptr
;
58 fp
->_wide_data
->_IO_write_ptr
= pstart
;
59 fp
->_wide_data
->_IO_write_end
= end
;
60 fp
->_wide_data
->_IO_read_end
= pstart
;
64 fp
->_wide_data
->_IO_write_ptr
= ptr
;
65 fp
->_wide_data
->_IO_write_end
= ptr
;
66 fp
->_wide_data
->_IO_read_end
= end
;
68 /* A null _allocate_buffer function flags the strfile as being static. */
69 (((_IO_strfile
*) fp
)->_s
._allocate_buffer
) = (_IO_alloc_type
)0;
73 _IO_wstr_overflow (fp
, c
)
77 int flush_only
= c
== WEOF
;
79 if (fp
->_flags
& _IO_NO_WRITES
)
80 return flush_only
? 0 : WEOF
;
81 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && !(fp
->_flags
& _IO_CURRENTLY_PUTTING
))
83 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
84 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_read_ptr
;
85 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
87 pos
= fp
->_wide_data
->_IO_write_ptr
- fp
->_wide_data
->_IO_write_base
;
88 if (pos
>= (_IO_size_t
) (_IO_wblen (fp
) + flush_only
))
90 if (fp
->_flags2
& _IO_FLAGS2_USER_WBUF
) /* not allowed to enlarge */
95 wchar_t *old_buf
= fp
->_wide_data
->_IO_buf_base
;
96 size_t old_wblen
= _IO_wblen (fp
);
97 _IO_size_t new_size
= 2 * old_wblen
+ 100;
98 if (new_size
< old_wblen
)
101 = (wchar_t *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (new_size
105 /* __ferror(fp) = 1; */
110 __wmemcpy (new_buf
, old_buf
, old_wblen
);
111 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (old_buf
);
112 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
113 fp
->_wide_data
->_IO_buf_base
= NULL
;
116 wmemset (new_buf
+ old_wblen
, L
'\0', new_size
- old_wblen
);
118 _IO_wsetb (fp
, new_buf
, new_buf
+ new_size
, 1);
119 fp
->_wide_data
->_IO_read_base
=
120 new_buf
+ (fp
->_wide_data
->_IO_read_base
- old_buf
);
121 fp
->_wide_data
->_IO_read_ptr
=
122 new_buf
+ (fp
->_wide_data
->_IO_read_ptr
- old_buf
);
123 fp
->_wide_data
->_IO_read_end
=
124 new_buf
+ (fp
->_wide_data
->_IO_read_end
- old_buf
);
125 fp
->_wide_data
->_IO_write_ptr
=
126 new_buf
+ (fp
->_wide_data
->_IO_write_ptr
- old_buf
);
128 fp
->_wide_data
->_IO_write_base
= new_buf
;
129 fp
->_wide_data
->_IO_write_end
= fp
->_wide_data
->_IO_buf_end
;
134 *fp
->_wide_data
->_IO_write_ptr
++ = c
;
135 if (fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
)
136 fp
->_wide_data
->_IO_read_end
= fp
->_wide_data
->_IO_write_ptr
;
142 _IO_wstr_underflow (fp
)
145 if (fp
->_wide_data
->_IO_write_ptr
> fp
->_wide_data
->_IO_read_end
)
146 fp
->_wide_data
->_IO_read_end
= fp
->_wide_data
->_IO_write_ptr
;
147 if ((fp
->_flags
& _IO_TIED_PUT_GET
) && (fp
->_flags
& _IO_CURRENTLY_PUTTING
))
149 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
150 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_write_ptr
;
151 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_end
;
153 if (fp
->_wide_data
->_IO_read_ptr
< fp
->_wide_data
->_IO_read_end
)
154 return *fp
->_wide_data
->_IO_read_ptr
;
160 /* The size of the valid part of the buffer. */
165 struct _IO_wide_data
*wd
= fp
->_wide_data
;
167 return ((wd
->_IO_write_ptr
> wd
->_IO_read_end
168 ? wd
->_IO_write_ptr
: wd
->_IO_read_end
)
169 - wd
->_IO_read_base
);
174 enlarge_userbuf (_IO_FILE
*fp
, _IO_off64_t offset
, int reading
)
176 if ((_IO_ssize_t
) offset
<= _IO_blen (fp
))
179 struct _IO_wide_data
*wd
= fp
->_wide_data
;
181 _IO_ssize_t oldend
= wd
->_IO_write_end
- wd
->_IO_write_base
;
183 /* Try to enlarge the buffer. */
184 if (fp
->_flags2
& _IO_FLAGS2_USER_WBUF
)
185 /* User-provided buffer. */
188 _IO_size_t newsize
= offset
+ 100;
189 wchar_t *oldbuf
= wd
->_IO_buf_base
;
191 = (wchar_t *) (*((_IO_strfile
*) fp
)->_s
._allocate_buffer
) (newsize
198 __wmemcpy (newbuf
, oldbuf
, _IO_wblen (fp
));
199 (*((_IO_strfile
*) fp
)->_s
._free_buffer
) (oldbuf
);
200 /* Make sure _IO_setb won't try to delete
202 wd
->_IO_buf_base
= NULL
;
205 _IO_wsetb (fp
, newbuf
, newbuf
+ newsize
, 1);
209 wd
->_IO_write_base
= newbuf
+ (wd
->_IO_write_base
- oldbuf
);
210 wd
->_IO_write_ptr
= newbuf
+ (wd
->_IO_write_ptr
- oldbuf
);
211 wd
->_IO_write_end
= newbuf
+ (wd
->_IO_write_end
- oldbuf
);
212 wd
->_IO_read_ptr
= newbuf
+ (wd
->_IO_read_ptr
- oldbuf
);
214 wd
->_IO_read_base
= newbuf
;
215 wd
->_IO_read_end
= wd
->_IO_buf_end
;
219 wd
->_IO_read_base
= newbuf
+ (wd
->_IO_read_base
- oldbuf
);
220 wd
->_IO_read_ptr
= newbuf
+ (wd
->_IO_read_ptr
- oldbuf
);
221 wd
->_IO_read_end
= newbuf
+ (wd
->_IO_read_end
- oldbuf
);
222 wd
->_IO_write_ptr
= newbuf
+ (wd
->_IO_write_ptr
- oldbuf
);
224 wd
->_IO_write_base
= newbuf
;
225 wd
->_IO_write_end
= wd
->_IO_buf_end
;
228 /* Clear the area between the last write position and th
230 assert (offset
>= oldend
);
232 wmemset (wd
->_IO_read_base
+ oldend
, L
'\0', offset
- oldend
);
234 wmemset (wd
->_IO_write_base
+ oldend
, L
'\0', offset
- oldend
);
241 _IO_wstr_seekoff (fp
, offset
, dir
, mode
)
249 if (mode
== 0 && (fp
->_flags
& _IO_TIED_PUT_GET
))
250 mode
= (fp
->_flags
& _IO_CURRENTLY_PUTTING
? _IOS_OUTPUT
: _IOS_INPUT
);
254 /* Don't move any pointers. But there is no clear indication what
255 mode FP is in. Let's guess. */
256 if (fp
->_IO_file_flags
& _IO_NO_WRITES
)
257 new_pos
= fp
->_wide_data
->_IO_read_ptr
- fp
->_wide_data
->_IO_read_base
;
259 new_pos
= (fp
->_wide_data
->_IO_write_ptr
260 - fp
->_wide_data
->_IO_write_base
);
264 _IO_ssize_t cur_size
= _IO_wstr_count (fp
);
267 /* Move the get pointer, if requested. */
268 if (mode
& _IOS_INPUT
)
276 offset
+= (fp
->_wide_data
->_IO_read_ptr
277 - fp
->_wide_data
->_IO_read_base
);
279 default: /* case _IO_seek_set: */
284 if ((_IO_ssize_t
) offset
> cur_size
285 && enlarge_userbuf (fp
, offset
, 1) != 0)
287 fp
->_wide_data
->_IO_read_ptr
= (fp
->_wide_data
->_IO_read_base
289 fp
->_wide_data
->_IO_read_end
= (fp
->_wide_data
->_IO_read_base
294 /* Move the put pointer, if requested. */
295 if (mode
& _IOS_OUTPUT
)
303 offset
+= (fp
->_wide_data
->_IO_write_ptr
304 - fp
->_wide_data
->_IO_write_base
);
306 default: /* case _IO_seek_set: */
311 if ((_IO_ssize_t
) offset
> cur_size
312 && enlarge_userbuf (fp
, offset
, 0) != 0)
314 fp
->_wide_data
->_IO_write_ptr
= (fp
->_wide_data
->_IO_write_base
323 _IO_wstr_pbackfail (fp
, c
)
327 if ((fp
->_flags
& _IO_NO_WRITES
) && c
!= WEOF
)
329 return _IO_wdefault_pbackfail (fp
, c
);
333 _IO_wstr_finish (fp
, dummy
)
337 if (fp
->_wide_data
->_IO_buf_base
&& !(fp
->_flags2
& _IO_FLAGS2_USER_WBUF
))
338 (((_IO_strfile
*) fp
)->_s
._free_buffer
) (fp
->_wide_data
->_IO_buf_base
);
339 fp
->_wide_data
->_IO_buf_base
= NULL
;
341 _IO_wdefault_finish (fp
, 0);
344 const struct _IO_jump_t _IO_wstr_jumps
=
347 JUMP_INIT(finish
, _IO_wstr_finish
),
348 JUMP_INIT(overflow
, (_IO_overflow_t
) _IO_wstr_overflow
),
349 JUMP_INIT(underflow
, (_IO_underflow_t
) _IO_wstr_underflow
),
350 JUMP_INIT(uflow
, (_IO_underflow_t
) _IO_wdefault_uflow
),
351 JUMP_INIT(pbackfail
, (_IO_pbackfail_t
) _IO_wstr_pbackfail
),
352 JUMP_INIT(xsputn
, _IO_wdefault_xsputn
),
353 JUMP_INIT(xsgetn
, _IO_wdefault_xsgetn
),
354 JUMP_INIT(seekoff
, _IO_wstr_seekoff
),
355 JUMP_INIT(seekpos
, _IO_default_seekpos
),
356 JUMP_INIT(setbuf
, _IO_default_setbuf
),
357 JUMP_INIT(sync
, _IO_default_sync
),
358 JUMP_INIT(doallocate
, _IO_wdefault_doallocate
),
359 JUMP_INIT(read
, _IO_default_read
),
360 JUMP_INIT(write
, _IO_default_write
),
361 JUMP_INIT(seek
, _IO_default_seek
),
362 JUMP_INIT(close
, _IO_default_close
),
363 JUMP_INIT(stat
, _IO_default_stat
),
364 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
365 JUMP_INIT(imbue
, _IO_default_imbue
)