Update.
[glibc.git] / libio / wgenops.c
blobb0580e51251b64b17f7b3bc96c7445f54d80a26d
1 /* Copyright (C) 1993,1995,1997-2001,2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Ulrich Drepper <drepper@cygnus.com>.
4 Based on the single byte version by Per Bothner <bothner@cygnus.com>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 As a special exception, if you link the code in this file with
22 files compiled with a GNU compiler to produce an executable,
23 that does not cause the resulting executable to be covered by
24 the GNU Lesser General Public License. This exception does not
25 however invalidate any other reasons why the executable file
26 might be covered by the GNU Lesser General Public License.
27 This exception applies to code released by its copyright holders
28 in files containing the exception. */
30 /* Generic or default I/O operations. */
32 #include "libioP.h"
33 #ifdef __STDC__
34 #include <stdlib.h>
35 #endif
36 #include <string.h>
37 #include <wchar.h>
40 #ifndef _LIBC
41 # define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
42 #endif
45 static int save_for_wbackup __P ((_IO_FILE *fp, wchar_t *end_p))
46 #ifdef _LIBC
47 internal_function
48 #endif
51 /* Return minimum _pos markers
52 Assumes the current get area is the main get area. */
53 _IO_ssize_t _IO_least_wmarker __P ((_IO_FILE *fp, wchar_t *end_p));
55 _IO_ssize_t
56 _IO_least_wmarker (fp, end_p)
57 _IO_FILE *fp;
58 wchar_t *end_p;
60 _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base;
61 struct _IO_marker *mark;
62 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
63 if (mark->_pos < least_so_far)
64 least_so_far = mark->_pos;
65 return least_so_far;
67 INTDEF(_IO_least_wmarker)
69 /* Switch current get area from backup buffer to (start of) main get area. */
70 void
71 _IO_switch_to_main_wget_area (fp)
72 _IO_FILE *fp;
74 wchar_t *tmp;
75 fp->_flags &= ~_IO_IN_BACKUP;
76 /* Swap _IO_read_end and _IO_save_end. */
77 tmp = fp->_wide_data->_IO_read_end;
78 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
79 fp->_wide_data->_IO_save_end= tmp;
80 /* Swap _IO_read_base and _IO_save_base. */
81 tmp = fp->_wide_data->_IO_read_base;
82 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
83 fp->_wide_data->_IO_save_base = tmp;
84 /* Set _IO_read_ptr. */
85 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
87 INTDEF(_IO_switch_to_main_wget_area)
90 /* Switch current get area from main get area to (end of) backup area. */
91 void
92 _IO_switch_to_wbackup_area (fp)
93 _IO_FILE *fp;
95 wchar_t *tmp;
96 fp->_flags |= _IO_IN_BACKUP;
97 /* Swap _IO_read_end and _IO_save_end. */
98 tmp = fp->_wide_data->_IO_read_end;
99 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
100 fp->_wide_data->_IO_save_end = tmp;
101 /* Swap _IO_read_base and _IO_save_base. */
102 tmp = fp->_wide_data->_IO_read_base;
103 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
104 fp->_wide_data->_IO_save_base = tmp;
105 /* Set _IO_read_ptr. */
106 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
108 INTDEF(_IO_switch_to_wbackup_area)
111 void
112 _IO_wsetb (f, b, eb, a)
113 _IO_FILE *f;
114 wchar_t *b;
115 wchar_t *eb;
116 int a;
118 if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
119 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f));
120 f->_wide_data->_IO_buf_base = b;
121 f->_wide_data->_IO_buf_end = eb;
122 if (a)
123 f->_flags &= ~_IO_USER_BUF;
124 else
125 f->_flags |= _IO_USER_BUF;
127 INTDEF(_IO_wsetb)
130 wint_t
131 _IO_wdefault_pbackfail (fp, c)
132 _IO_FILE *fp;
133 wint_t c;
135 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
136 && !_IO_in_backup (fp)
137 && (wint_t) fp->_IO_read_ptr[-1] == c)
138 --fp->_IO_read_ptr;
139 else
141 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
142 if (!_IO_in_backup (fp))
144 /* We need to keep the invariant that the main get area
145 logically follows the backup area. */
146 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
147 && _IO_have_wbackup (fp))
149 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
150 return WEOF;
152 else if (!_IO_have_wbackup (fp))
154 /* No backup buffer: allocate one. */
155 /* Use nshort buffer, if unused? (probably not) FIXME */
156 int backup_size = 128;
157 wchar_t *bbuf = (wchar_t *) malloc (backup_size
158 * sizeof (wchar_t));
159 if (bbuf == NULL)
160 return WEOF;
161 fp->_wide_data->_IO_save_base = bbuf;
162 fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
163 + backup_size);
164 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
166 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
167 INTUSE(_IO_switch_to_wbackup_area) (fp);
169 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
171 /* Increase size of existing backup buffer. */
172 _IO_size_t new_size;
173 _IO_size_t old_size = (fp->_wide_data->_IO_read_end
174 - fp->_wide_data->_IO_read_base);
175 wchar_t *new_buf;
176 new_size = 2 * old_size;
177 new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
178 if (new_buf == NULL)
179 return WEOF;
180 __wmemcpy (new_buf + (new_size - old_size),
181 fp->_wide_data->_IO_read_base, old_size);
182 free (fp->_wide_data->_IO_read_base);
183 _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
184 new_buf + new_size);
185 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
188 *--fp->_wide_data->_IO_read_ptr = c;
190 return c;
192 INTDEF(_IO_wdefault_pbackfail)
195 void
196 _IO_wdefault_finish (fp, dummy)
197 _IO_FILE *fp;
198 int dummy;
200 struct _IO_marker *mark;
201 if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
203 FREE_BUF (fp->_wide_data->_IO_buf_base,
204 _IO_wblen (fp) * sizeof (wchar_t));
205 fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL;
208 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
209 mark->_sbuf = NULL;
211 if (fp->_IO_save_base)
213 free (fp->_wide_data->_IO_save_base);
214 fp->_IO_save_base = NULL;
217 #ifdef _IO_MTSAFE_IO
218 if (fp->_lock != NULL)
219 _IO_lock_fini (*fp->_lock);
220 #endif
222 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
224 INTDEF(_IO_wdefault_finish)
227 wint_t
228 _IO_wdefault_uflow (fp)
229 _IO_FILE *fp;
231 wint_t wch;
232 wch = _IO_UNDERFLOW (fp);
233 if (wch == WEOF)
234 return WEOF;
235 return *fp->_wide_data->_IO_read_ptr++;
237 INTDEF(_IO_wdefault_uflow)
240 wint_t
241 __woverflow (f, wch)
242 _IO_FILE *f;
243 wint_t wch;
245 if (f->_mode == 0)
246 _IO_fwide (f, 1);
247 return _IO_OVERFLOW (f, wch);
251 wint_t
252 __wuflow (fp)
253 _IO_FILE *fp;
255 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
256 return WEOF;
258 if (fp->_mode == 0)
259 _IO_fwide (fp, 1);
260 if (_IO_in_put_mode (fp))
261 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
262 return WEOF;
263 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
264 return *fp->_wide_data->_IO_read_ptr++;
265 if (_IO_in_backup (fp))
267 INTUSE(_IO_switch_to_main_wget_area) (fp);
268 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
269 return *fp->_wide_data->_IO_read_ptr++;
271 if (_IO_have_markers (fp))
273 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
274 return WEOF;
276 else if (_IO_have_wbackup (fp))
277 INTUSE(_IO_free_wbackup_area) (fp);
278 return _IO_UFLOW (fp);
282 wint_t
283 __wunderflow (fp)
284 _IO_FILE *fp;
286 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
287 return WEOF;
289 if (fp->_mode == 0)
290 _IO_fwide (fp, 1);
291 if (_IO_in_put_mode (fp))
292 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
293 return WEOF;
294 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
295 return *fp->_wide_data->_IO_read_ptr;
296 if (_IO_in_backup (fp))
298 INTUSE(_IO_switch_to_main_wget_area) (fp);
299 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
300 return *fp->_wide_data->_IO_read_ptr;
302 if (_IO_have_markers (fp))
304 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
305 return WEOF;
307 else if (_IO_have_backup (fp))
308 INTUSE(_IO_free_wbackup_area) (fp);
309 return _IO_UNDERFLOW (fp);
313 _IO_size_t
314 _IO_wdefault_xsputn (f, data, n)
315 _IO_FILE *f;
316 const void *data;
317 _IO_size_t n;
319 const wchar_t *s = (const wchar_t *) data;
320 _IO_size_t more = n;
321 if (more <= 0)
322 return 0;
323 for (;;)
325 /* Space available. */
326 _IO_ssize_t count = (f->_wide_data->_IO_write_end
327 - f->_wide_data->_IO_write_ptr);
328 if (count > 0)
330 if ((_IO_size_t) count > more)
331 count = more;
332 if (count > 20)
334 #ifdef _LIBC
335 f->_wide_data->_IO_write_ptr =
336 __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
337 #else
338 memcpy (f->_wide_data->_IO_write_ptr, s, count);
339 f->_wide_data->_IO_write_ptr += count;
340 #endif
341 s += count;
343 else if (count <= 0)
344 count = 0;
345 else
347 wchar_t *p = f->_wide_data->_IO_write_ptr;
348 _IO_ssize_t i;
349 for (i = count; --i >= 0; )
350 *p++ = *s++;
351 f->_wide_data->_IO_write_ptr = p;
353 more -= count;
355 if (more == 0 || __woverflow (f, *s++) == WEOF)
356 break;
357 more--;
359 return n - more;
361 INTDEF(_IO_wdefault_xsputn)
364 _IO_size_t
365 _IO_wdefault_xsgetn (fp, data, n)
366 _IO_FILE *fp;
367 void *data;
368 _IO_size_t n;
370 _IO_size_t more = n;
371 wchar_t *s = (wchar_t*) data;
372 for (;;)
374 /* Data available. */
375 _IO_ssize_t count = (fp->_wide_data->_IO_read_end
376 - fp->_wide_data->_IO_read_ptr);
377 if (count > 0)
379 if ((_IO_size_t) count > more)
380 count = more;
381 if (count > 20)
383 #ifdef _LIBC
384 s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count);
385 #else
386 memcpy (s, fp->_wide_data->_IO_read_ptr, count);
387 s += count;
388 #endif
389 fp->_wide_data->_IO_read_ptr += count;
391 else if (count <= 0)
392 count = 0;
393 else
395 wchar_t *p = fp->_wide_data->_IO_read_ptr;
396 int i = (int) count;
397 while (--i >= 0)
398 *s++ = *p++;
399 fp->_wide_data->_IO_read_ptr = p;
401 more -= count;
403 if (more == 0 || __wunderflow (fp) == WEOF)
404 break;
406 return n - more;
408 INTDEF(_IO_wdefault_xsgetn)
411 void
412 _IO_wdoallocbuf (fp)
413 _IO_FILE *fp;
415 if (fp->_wide_data->_IO_buf_base)
416 return;
417 if (!(fp->_flags & _IO_UNBUFFERED))
418 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
419 return;
420 INTUSE(_IO_wsetb) (fp, fp->_wide_data->_shortbuf,
421 fp->_wide_data->_shortbuf + 1, 0);
423 INTDEF(_IO_wdoallocbuf)
426 _IO_FILE *
427 _IO_wdefault_setbuf (fp, p, len)
428 _IO_FILE *fp;
429 wchar_t *p;
430 _IO_ssize_t len;
432 if (_IO_SYNC (fp) == EOF)
433 return NULL;
434 if (p == NULL || len == 0)
436 fp->_flags |= _IO_UNBUFFERED;
437 INTUSE(_IO_wsetb) (fp, fp->_wide_data->_shortbuf,
438 fp->_wide_data->_shortbuf + 1, 0);
440 else
442 fp->_flags &= ~_IO_UNBUFFERED;
443 INTUSE(_IO_wsetb) (fp, p, p + len, 0);
445 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
446 = fp->_wide_data->_IO_write_end = 0;
447 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr
448 = fp->_wide_data->_IO_read_end = 0;
449 return fp;
451 INTDEF(_IO_wdefault_setbuf)
455 _IO_wdefault_doallocate (fp)
456 _IO_FILE *fp;
458 wchar_t *buf;
460 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
461 INTUSE(_IO_wsetb) (fp, buf, buf + _IO_BUFSIZ, 1);
462 return 1;
464 INTDEF(_IO_wdefault_doallocate)
468 _IO_switch_to_wget_mode (fp)
469 _IO_FILE *fp;
471 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
472 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
473 return EOF;
474 if (_IO_in_backup (fp))
475 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
476 else
478 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base;
479 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
480 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
482 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
484 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
485 = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr;
487 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
488 return 0;
490 INTDEF(_IO_switch_to_wget_mode)
492 void
493 _IO_free_wbackup_area (fp)
494 _IO_FILE *fp;
496 if (_IO_in_backup (fp))
497 INTUSE(_IO_switch_to_main_wget_area) (fp); /* Just in case. */
498 free (fp->_wide_data->_IO_save_base);
499 fp->_wide_data->_IO_save_base = NULL;
500 fp->_wide_data->_IO_save_end = NULL;
501 fp->_wide_data->_IO_backup_base = NULL;
503 INTDEF(_IO_free_wbackup_area)
505 #if 0
507 _IO_switch_to_wput_mode (fp)
508 _IO_FILE *fp;
510 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr;
511 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
512 /* Following is wrong if line- or un-buffered? */
513 fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
514 ? fp->_wide_data->_IO_read_end
515 : fp->_wide_data->_IO_buf_end);
517 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
518 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end;
520 fp->_flags |= _IO_CURRENTLY_PUTTING;
521 return 0;
523 #endif
526 static int
527 #ifdef _LIBC
528 internal_function
529 #endif
530 save_for_wbackup (fp, end_p)
531 _IO_FILE *fp;
532 wchar_t *end_p;
534 /* Append [_IO_read_base..end_p] to backup area. */
535 _IO_ssize_t least_mark = INTUSE(_IO_least_wmarker) (fp, end_p);
536 /* needed_size is how much space we need in the backup area. */
537 _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base)
538 - least_mark);
539 /* FIXME: Dubious arithmetic if pointers are NULL */
540 _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end
541 - fp->_wide_data->_IO_save_base);
542 _IO_size_t avail; /* Extra space available for future expansion. */
543 _IO_ssize_t delta;
544 struct _IO_marker *mark;
545 if (needed_size > current_Bsize)
547 wchar_t *new_buffer;
548 avail = 100;
549 new_buffer = (wchar_t *) malloc ((avail + needed_size)
550 * sizeof (wchar_t));
551 if (new_buffer == NULL)
552 return EOF; /* FIXME */
553 if (least_mark < 0)
555 #ifdef _LIBC
556 __wmempcpy (__wmempcpy (new_buffer + avail,
557 fp->_wide_data->_IO_save_end + least_mark,
558 -least_mark),
559 fp->_wide_data->_IO_read_base,
560 end_p - fp->_wide_data->_IO_read_base);
561 #else
562 memcpy (new_buffer + avail,
563 fp->_wide_data->_IO_save_end + least_mark,
564 -least_mark * sizeof (wchar_t));
565 memcpy (new_buffer + avail - least_mark,
566 fp->_wide_data->_IO_read_base,
567 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
568 #endif
570 else
572 #ifdef _LIBC
573 __wmemcpy (new_buffer + avail,
574 fp->_wide_data->_IO_read_base + least_mark,
575 needed_size);
576 #else
577 memcpy (new_buffer + avail,
578 fp->_wide_data->_IO_read_base + least_mark,
579 needed_size * sizeof (wchar_t));
580 #endif
582 if (fp->_wide_data->_IO_save_base)
583 free (fp->_wide_data->_IO_save_base);
584 fp->_wide_data->_IO_save_base = new_buffer;
585 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
587 else
589 avail = current_Bsize - needed_size;
590 if (least_mark < 0)
592 #ifdef _LIBC
593 __wmemmove (fp->_wide_data->_IO_save_base + avail,
594 fp->_wide_data->_IO_save_end + least_mark,
595 -least_mark);
596 __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
597 fp->_wide_data->_IO_read_base,
598 end_p - fp->_wide_data->_IO_read_base);
599 #else
600 memmove (fp->_wide_data->_IO_save_base + avail,
601 fp->_wide_data->_IO_save_end + least_mark,
602 -least_mark * sizeof (wchar_t));
603 memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
604 fp->_wide_data->_IO_read_base,
605 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
606 #endif
608 else if (needed_size > 0)
609 #ifdef _LIBC
610 __wmemcpy (fp->_wide_data->_IO_save_base + avail,
611 fp->_wide_data->_IO_read_base + least_mark,
612 needed_size);
613 #else
614 memcpy (fp->_wide_data->_IO_save_base + avail,
615 fp->_wide_data->_IO_read_base + least_mark,
616 needed_size * sizeof (wchar_t));
617 #endif
619 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
620 /* Adjust all the streammarkers. */
621 delta = end_p - fp->_wide_data->_IO_read_base;
622 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
623 mark->_pos -= delta;
624 return 0;
627 wint_t
628 _IO_sputbackwc (fp, c)
629 _IO_FILE *fp;
630 wint_t c;
632 wint_t result;
634 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
635 && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
637 fp->_wide_data->_IO_read_ptr--;
638 result = c;
640 else
641 result = _IO_PBACKFAIL (fp, c);
643 if (result != WEOF)
644 fp->_flags &= ~_IO_EOF_SEEN;
646 return result;
648 INTDEF(_IO_sputbackwc)
650 wint_t
651 _IO_sungetwc (fp)
652 _IO_FILE *fp;
654 wint_t result;
656 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
658 fp->_wide_data->_IO_read_ptr--;
659 result = *fp->_wide_data->_IO_read_ptr;
661 else
662 result = _IO_PBACKFAIL (fp, EOF);
664 if (result != WEOF)
665 fp->_flags &= ~_IO_EOF_SEEN;
667 return result;
671 unsigned
672 _IO_adjust_wcolumn (start, line, count)
673 unsigned start;
674 const wchar_t *line;
675 int count;
677 const wchar_t *ptr = line + count;
678 while (ptr > line)
679 if (*--ptr == L'\n')
680 return line + count - ptr - 1;
681 return start + count;
684 void
685 _IO_init_wmarker (marker, fp)
686 struct _IO_marker *marker;
687 _IO_FILE *fp;
689 marker->_sbuf = fp;
690 if (_IO_in_put_mode (fp))
691 INTUSE(_IO_switch_to_wget_mode) (fp);
692 if (_IO_in_backup (fp))
693 marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
694 else
695 marker->_pos = (fp->_wide_data->_IO_read_ptr
696 - fp->_wide_data->_IO_read_base);
698 /* Should perhaps sort the chain? */
699 marker->_next = fp->_markers;
700 fp->_markers = marker;
703 #define BAD_DELTA EOF
705 /* Return difference between MARK and current position of MARK's stream. */
707 _IO_wmarker_delta (mark)
708 struct _IO_marker *mark;
710 int cur_pos;
711 if (mark->_sbuf == NULL)
712 return BAD_DELTA;
713 if (_IO_in_backup (mark->_sbuf))
714 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
715 - mark->_sbuf->_wide_data->_IO_read_end);
716 else
717 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
718 - mark->_sbuf->_wide_data->_IO_read_base);
719 return mark->_pos - cur_pos;
723 _IO_seekwmark (fp, mark, delta)
724 _IO_FILE *fp;
725 struct _IO_marker *mark;
726 int delta;
728 if (mark->_sbuf != fp)
729 return EOF;
730 if (mark->_pos >= 0)
732 if (_IO_in_backup (fp))
733 INTUSE(_IO_switch_to_main_wget_area) (fp);
734 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
735 + mark->_pos);
737 else
739 if (!_IO_in_backup (fp))
740 INTUSE(_IO_switch_to_wbackup_area) (fp);
741 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
743 return 0;
746 void
747 _IO_unsave_wmarkers (fp)
748 _IO_FILE *fp;
750 struct _IO_marker *mark = fp->_markers;
751 if (mark)
753 #ifdef TODO
754 streampos offset = seekoff (0, ios::cur, ios::in);
755 if (offset != EOF)
757 offset += eGptr () - Gbase ();
758 for ( ; mark != NULL; mark = mark->_next)
759 mark->set_streampos (mark->_pos + offset);
761 else
763 for ( ; mark != NULL; mark = mark->_next)
764 mark->set_streampos (EOF);
766 #endif
767 fp->_markers = 0;
770 if (_IO_have_backup (fp))
771 INTUSE(_IO_free_wbackup_area) (fp);