]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/wgenops.c
Update.
[thirdparty/glibc.git] / libio / wgenops.c
CommitLineData
1dc72e4f 1/* Copyright (C) 1993,1995,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
d64b6ad0
UD
2 This file is part of the GNU IO Library.
3 Written by Ulrich Drepper <drepper@cygnus.com>.
4 Based on the single byte version by Per Bothner <bothner@cygnus.com>.
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2, or (at
9 your option) any later version.
10
11 This library is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this library; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA.
20
21 As a special exception, if you link this library with files
22 compiled with a GNU compiler to produce an executable, this does
23 not cause the resulting executable to be covered by the GNU General
24 Public License. This exception does not however invalidate any
25 other reasons why the executable file might be covered by the GNU
26 General Public License. */
27
28/* Generic or default I/O operations. */
29
30#include "libioP.h"
31#ifdef __STDC__
32#include <stdlib.h>
33#endif
34#include <string.h>
35#include <wchar.h>
36
37
319d719d
UD
38#ifndef _LIBC
39# define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
40#endif
41
d64b6ad0
UD
42
43static int save_for_wbackup __P ((_IO_FILE *fp, wchar_t *end_p))
44#ifdef _LIBC
45 internal_function
46#endif
47 ;
48
49/* Return minimum _pos markers
50 Assumes the current get area is the main get area. */
51_IO_ssize_t _IO_least_wmarker __P ((_IO_FILE *fp, wchar_t *end_p));
52
53_IO_ssize_t
54_IO_least_wmarker (fp, end_p)
55 _IO_FILE *fp;
56 wchar_t *end_p;
57{
58 _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base;
59 struct _IO_marker *mark;
60 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
61 if (mark->_pos < least_so_far)
62 least_so_far = mark->_pos;
63 return least_so_far;
64}
65
66/* Switch current get area from backup buffer to (start of) main get area. */
67void
68_IO_switch_to_main_wget_area (fp)
69 _IO_FILE *fp;
70{
71 wchar_t *tmp;
72 fp->_flags &= ~_IO_IN_BACKUP;
73 /* Swap _IO_read_end and _IO_save_end. */
74 tmp = fp->_wide_data->_IO_read_end;
75 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
76 fp->_wide_data->_IO_save_end= tmp;
77 /* Swap _IO_read_base and _IO_save_base. */
78 tmp = fp->_wide_data->_IO_read_base;
79 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
80 fp->_wide_data->_IO_save_base = tmp;
81 /* Set _IO_read_ptr. */
82 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
83}
84
85
86/* Switch current get area from main get area to (end of) backup area. */
87void
88_IO_switch_to_wbackup_area (fp)
89 _IO_FILE *fp;
90{
91 wchar_t *tmp;
92 fp->_flags |= _IO_IN_BACKUP;
93 /* Swap _IO_read_end and _IO_save_end. */
94 tmp = fp->_wide_data->_IO_read_end;
95 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
96 fp->_wide_data->_IO_save_end = tmp;
97 /* Swap _IO_read_base and _IO_save_base. */
98 tmp = fp->_wide_data->_IO_read_base;
99 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
100 fp->_wide_data->_IO_save_base = tmp;
101 /* Set _IO_read_ptr. */
102 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
103}
104
105
106void
107_IO_wsetb (f, b, eb, a)
108 _IO_FILE *f;
109 wchar_t *b;
110 wchar_t *eb;
111 int a;
112{
113 if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
114 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f));
115 f->_wide_data->_IO_buf_base = b;
116 f->_wide_data->_IO_buf_end = eb;
117 if (a)
118 f->_flags &= ~_IO_USER_BUF;
119 else
120 f->_flags |= _IO_USER_BUF;
121}
122
123
124wint_t
125_IO_wdefault_pbackfail (fp, c)
126 _IO_FILE *fp;
127 wint_t c;
128{
129 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
130 && !_IO_in_backup (fp)
131 && (wint_t) fp->_IO_read_ptr[-1] == c)
132 --fp->_IO_read_ptr;
133 else
134 {
135 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
136 if (!_IO_in_backup (fp))
137 {
138 /* We need to keep the invariant that the main get area
139 logically follows the backup area. */
140 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
141 && _IO_have_wbackup (fp))
142 {
143 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
144 return WEOF;
145 }
146 else if (!_IO_have_wbackup (fp))
147 {
148 /* No backup buffer: allocate one. */
149 /* Use nshort buffer, if unused? (probably not) FIXME */
150 int backup_size = 128;
151 wchar_t *bbuf = (wchar_t *) malloc (backup_size
152 * sizeof (wchar_t));
153 if (bbuf == NULL)
154 return WEOF;
155 fp->_wide_data->_IO_save_base = bbuf;
156 fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
157 + backup_size);
158 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
159 }
160 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
161 _IO_switch_to_wbackup_area (fp);
162 }
163 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
164 {
165 /* Increase size of existing backup buffer. */
166 _IO_size_t new_size;
167 _IO_size_t old_size = (fp->_wide_data->_IO_read_end
168 - fp->_wide_data->_IO_read_base);
169 wchar_t *new_buf;
170 new_size = 2 * old_size;
171 new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
172 if (new_buf == NULL)
173 return WEOF;
174 __wmemcpy (new_buf + (new_size - old_size),
175 fp->_wide_data->_IO_read_base, old_size);
176 free (fp->_wide_data->_IO_read_base);
177 _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
178 new_buf + new_size);
179 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
180 }
181
182 *--fp->_wide_data->_IO_read_ptr = c;
183 }
184 return c;
185}
186
187
188void
189_IO_wdefault_finish (fp, dummy)
190 _IO_FILE *fp;
191 int dummy;
192{
193 struct _IO_marker *mark;
194 if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
195 {
196 FREE_BUF (fp->_wide_data->_IO_buf_base,
197 _IO_wblen (fp) * sizeof (wchar_t));
198 fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL;
199 }
200
201 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
202 mark->_sbuf = NULL;
203
204 if (fp->_IO_save_base)
205 {
206 free (fp->_wide_data->_IO_save_base);
207 fp->_IO_save_base = NULL;
208 }
209
210#ifdef _IO_MTSAFE_IO
211 _IO_lock_fini (*fp->_lock);
212#endif
213
2ca8b1ee 214 _IO_un_link ((struct _IO_FILE_plus *) fp);
d64b6ad0
UD
215}
216
217
218wint_t
219_IO_wdefault_uflow (fp)
220 _IO_FILE *fp;
221{
222 wint_t wch;
223 wch = _IO_UNDERFLOW (fp);
224 if (wch == WEOF)
225 return WEOF;
226 return *fp->_wide_data->_IO_read_ptr++;
227}
228
229
230wint_t
231__woverflow (f, wch)
232 _IO_FILE *f;
233 wint_t wch;
234{
235 if (f->_mode == 0)
236 _IO_fwide (f, 1);
237 return _IO_OVERFLOW (f, wch);
238}
239
240
241wint_t
242__wuflow (fp)
243 _IO_FILE *fp;
244{
245 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
655c0697 246 return WEOF;
d64b6ad0
UD
247
248 if (fp->_mode == 0)
249 _IO_fwide (fp, 1);
250 if (_IO_in_put_mode (fp))
655c0697 251 if (_IO_switch_to_wget_mode (fp) == EOF)
d64b6ad0
UD
252 return WEOF;
253 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
254 return *fp->_wide_data->_IO_read_ptr++;
255 if (_IO_in_backup (fp))
256 {
257 _IO_switch_to_main_wget_area (fp);
258 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
259 return *fp->_wide_data->_IO_read_ptr++;
260 }
261 if (_IO_have_markers (fp))
262 {
263 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
264 return WEOF;
265 }
266 else if (_IO_have_wbackup (fp))
267 _IO_free_wbackup_area (fp);
268 return _IO_UFLOW (fp);
269}
270
271
272wint_t
273__wunderflow (fp)
274 _IO_FILE *fp;
275{
276 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
655c0697 277 return WEOF;
d64b6ad0 278
6f98fd7e
UD
279 if (fp->_mode == 0)
280 _IO_fwide (fp, 1);
d64b6ad0 281 if (_IO_in_put_mode (fp))
655c0697 282 if (_IO_switch_to_wget_mode (fp) == EOF)
d64b6ad0
UD
283 return WEOF;
284 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
285 return *fp->_wide_data->_IO_read_ptr;
286 if (_IO_in_backup (fp))
287 {
288 _IO_switch_to_main_wget_area (fp);
289 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
290 return *fp->_wide_data->_IO_read_ptr;
291 }
292 if (_IO_have_markers (fp))
293 {
294 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
655c0697 295 return WEOF;
d64b6ad0
UD
296 }
297 else if (_IO_have_backup (fp))
298 _IO_free_wbackup_area (fp);
299 return _IO_UNDERFLOW (fp);
300}
301
302
303_IO_size_t
304_IO_wdefault_xsputn (f, data, n)
305 _IO_FILE *f;
306 const void *data;
307 _IO_size_t n;
308{
309 const wchar_t *s = (const wchar_t *) data;
310 _IO_size_t more = n;
311 if (more <= 0)
312 return 0;
313 for (;;)
314 {
315 /* Space available. */
316 _IO_ssize_t count = (f->_wide_data->_IO_write_end
317 - f->_wide_data->_IO_write_ptr);
318 if (count > 0)
319 {
320 if ((_IO_size_t) count > more)
321 count = more;
322 if (count > 20)
323 {
324#ifdef _LIBC
325 f->_wide_data->_IO_write_ptr =
326 __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
327#else
328 memcpy (f->_wide_data->_IO_write_ptr, s, count);
329 f->_wide_data->_IO_write_ptr += count;
330#endif
331 s += count;
332 }
333 else if (count <= 0)
334 count = 0;
335 else
336 {
337 wchar_t *p = f->_wide_data->_IO_write_ptr;
338 _IO_ssize_t i;
339 for (i = count; --i >= 0; )
340 *p++ = *s++;
341 f->_wide_data->_IO_write_ptr = p;
342 }
343 more -= count;
344 }
345 if (more == 0 || __woverflow (f, *s++) == WEOF)
346 break;
347 more--;
348 }
349 return n - more;
350}
351
352
353_IO_size_t
354_IO_wdefault_xsgetn (fp, data, n)
355 _IO_FILE *fp;
356 void *data;
357 _IO_size_t n;
358{
359 _IO_size_t more = n;
360 wchar_t *s = (wchar_t*) data;
361 for (;;)
362 {
363 /* Data available. */
364 _IO_ssize_t count = (fp->_wide_data->_IO_read_end
365 - fp->_wide_data->_IO_read_ptr);
366 if (count > 0)
367 {
368 if ((_IO_size_t) count > more)
369 count = more;
370 if (count > 20)
371 {
372#ifdef _LIBC
373 s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count);
374#else
375 memcpy (s, fp->_wide_data->_IO_read_ptr, count);
376 s += count;
377#endif
378 fp->_wide_data->_IO_read_ptr += count;
379 }
380 else if (count <= 0)
381 count = 0;
382 else
383 {
384 wchar_t *p = fp->_wide_data->_IO_read_ptr;
385 int i = (int) count;
386 while (--i >= 0)
387 *s++ = *p++;
388 fp->_wide_data->_IO_read_ptr = p;
389 }
390 more -= count;
391 }
392 if (more == 0 || __wunderflow (fp) == WEOF)
393 break;
394 }
395 return n - more;
396}
397
398
399void
400_IO_wdoallocbuf (fp)
401 _IO_FILE *fp;
402{
403 if (fp->_wide_data->_IO_buf_base)
404 return;
405 if (!(fp->_flags & _IO_UNBUFFERED))
1dc72e4f 406 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
d64b6ad0
UD
407 return;
408 _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1, 0);
409}
410
411
412_IO_FILE *
413_IO_wdefault_setbuf (fp, p, len)
414 _IO_FILE *fp;
415 wchar_t *p;
416 _IO_ssize_t len;
417{
418 if (_IO_SYNC (fp) == EOF)
419 return NULL;
420 if (p == NULL || len == 0)
421 {
422 fp->_flags |= _IO_UNBUFFERED;
423 _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1,
424 0);
425 }
426 else
427 {
428 fp->_flags &= ~_IO_UNBUFFERED;
429 _IO_wsetb (fp, p, p + len, 0);
430 }
431 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
432 = fp->_wide_data->_IO_write_end = 0;
433 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr
434 = fp->_wide_data->_IO_read_end = 0;
435 return fp;
436}
437
438
439int
440_IO_wdefault_doallocate (fp)
441 _IO_FILE *fp;
442{
443 wchar_t *buf;
444
445 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
446 _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1);
447 return 1;
448}
449
450
451int
452_IO_switch_to_wget_mode (fp)
453 _IO_FILE *fp;
454{
455 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
1dc72e4f 456 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
d64b6ad0
UD
457 return EOF;
458 if (_IO_in_backup (fp))
459 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
460 else
461 {
462 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base;
463 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
464 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
465 }
466 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
467
468 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
469 = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr;
470
471 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
472 return 0;
473}
474
475void
476_IO_free_wbackup_area (fp)
477 _IO_FILE *fp;
478{
479 if (_IO_in_backup (fp))
480 _IO_switch_to_main_wget_area (fp); /* Just in case. */
481 free (fp->_wide_data->_IO_save_base);
482 fp->_wide_data->_IO_save_base = NULL;
483 fp->_wide_data->_IO_save_end = NULL;
484 fp->_wide_data->_IO_backup_base = NULL;
485}
486
487#if 0
488int
489_IO_switch_to_wput_mode (fp)
490 _IO_FILE *fp;
491{
492 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr;
493 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
494 /* Following is wrong if line- or un-buffered? */
495 fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
496 ? fp->_wide_data->_IO_read_end
497 : fp->_wide_data->_IO_buf_end);
498
499 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
500 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end;
501
502 fp->_flags |= _IO_CURRENTLY_PUTTING;
503 return 0;
504}
505#endif
506
507
508static int
509#ifdef _LIBC
510internal_function
511#endif
512save_for_wbackup (fp, end_p)
513 _IO_FILE *fp;
514 wchar_t *end_p;
515{
516 /* Append [_IO_read_base..end_p] to backup area. */
517 _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p);
518 /* needed_size is how much space we need in the backup area. */
519 _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base)
520 - least_mark);
521 /* FIXME: Dubious arithmetic if pointers are NULL */
522 _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end
523 - fp->_wide_data->_IO_save_base);
524 _IO_size_t avail; /* Extra space available for future expansion. */
525 _IO_ssize_t delta;
526 struct _IO_marker *mark;
527 if (needed_size > current_Bsize)
528 {
529 wchar_t *new_buffer;
530 avail = 100;
531 new_buffer = (wchar_t *) malloc ((avail + needed_size)
532 * sizeof (wchar_t));
533 if (new_buffer == NULL)
534 return EOF; /* FIXME */
535 if (least_mark < 0)
536 {
537#ifdef _LIBC
538 __wmempcpy (__wmempcpy (new_buffer + avail,
539 fp->_wide_data->_IO_save_end + least_mark,
540 -least_mark),
541 fp->_wide_data->_IO_read_base,
542 end_p - fp->_wide_data->_IO_read_base);
543#else
544 memcpy (new_buffer + avail,
545 fp->_wide_data->_IO_save_end + least_mark,
546 -least_mark * sizeof (wchar_t));
547 memcpy (new_buffer + avail - least_mark,
548 fp->_wide_data->_IO_read_base,
549 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
550#endif
551 }
552 else
553 {
554#ifdef _LIBC
555 __wmemcpy (new_buffer + avail,
556 fp->_wide_data->_IO_read_base + least_mark,
557 needed_size);
558#else
559 memcpy (new_buffer + avail,
560 fp->_wide_data->_IO_read_base + least_mark,
561 needed_size * sizeof (wchar_t));
562#endif
563 }
564 if (fp->_wide_data->_IO_save_base)
565 free (fp->_wide_data->_IO_save_base);
566 fp->_wide_data->_IO_save_base = new_buffer;
567 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
568 }
569 else
570 {
571 avail = current_Bsize - needed_size;
572 if (least_mark < 0)
573 {
574#ifdef _LIBC
575 __wmemmove (fp->_wide_data->_IO_save_base + avail,
576 fp->_wide_data->_IO_save_end + least_mark,
577 -least_mark);
578 __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
579 fp->_wide_data->_IO_read_base,
580 end_p - fp->_wide_data->_IO_read_base);
581#else
582 memmove (fp->_wide_data->_IO_save_base + avail,
583 fp->_wide_data->_IO_save_end + least_mark,
584 -least_mark * sizeof (wchar_t));
585 memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
586 fp->_wide_data->_IO_read_base,
587 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
588#endif
589 }
590 else if (needed_size > 0)
591#ifdef _LIBC
592 __wmemcpy (fp->_wide_data->_IO_save_base + avail,
593 fp->_wide_data->_IO_read_base + least_mark,
594 needed_size);
595#else
596 memcpy (fp->_wide_data->_IO_save_base + avail,
597 fp->_wide_data->_IO_read_base + least_mark,
598 needed_size * sizeof (wchar_t));
599#endif
600 }
601 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
602 /* Adjust all the streammarkers. */
603 delta = end_p - fp->_wide_data->_IO_read_base;
604 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
605 mark->_pos -= delta;
606 return 0;
607}
608
609wint_t
610_IO_sputbackwc (fp, c)
611 _IO_FILE *fp;
612 wint_t c;
613{
614 wint_t result;
615
616 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
617 && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
618 {
619 fp->_wide_data->_IO_read_ptr--;
620 result = c;
621 }
622 else
623 result = _IO_PBACKFAIL (fp, c);
624
1dc72e4f 625 if (result != WEOF)
d64b6ad0
UD
626 fp->_flags &= ~_IO_EOF_SEEN;
627
628 return result;
629}
630
631wint_t
632_IO_sungetwc (fp)
633 _IO_FILE *fp;
634{
1dc72e4f 635 wint_t result;
d64b6ad0
UD
636
637 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
638 {
639 fp->_wide_data->_IO_read_ptr--;
640 result = *fp->_wide_data->_IO_read_ptr;
641 }
642 else
643 result = _IO_PBACKFAIL (fp, EOF);
644
645 if (result != WEOF)
646 fp->_flags &= ~_IO_EOF_SEEN;
647
648 return result;
649}
650
651
652unsigned
653_IO_adjust_wcolumn (start, line, count)
654 unsigned start;
655 const wchar_t *line;
656 int count;
657{
658 const wchar_t *ptr = line + count;
659 while (ptr > line)
660 if (*--ptr == L'\n')
661 return line + count - ptr - 1;
662 return start + count;
663}
664
665void
666_IO_init_wmarker (marker, fp)
667 struct _IO_marker *marker;
668 _IO_FILE *fp;
669{
670 marker->_sbuf = fp;
671 if (_IO_in_put_mode (fp))
655c0697 672 _IO_switch_to_wget_mode (fp);
d64b6ad0
UD
673 if (_IO_in_backup (fp))
674 marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
675 else
676 marker->_pos = (fp->_wide_data->_IO_read_ptr
677 - fp->_wide_data->_IO_read_base);
678
679 /* Should perhaps sort the chain? */
680 marker->_next = fp->_markers;
681 fp->_markers = marker;
682}
683
684#define BAD_DELTA EOF
685
686/* Return difference between MARK and current position of MARK's stream. */
687int
688_IO_wmarker_delta (mark)
689 struct _IO_marker *mark;
690{
691 int cur_pos;
692 if (mark->_sbuf == NULL)
693 return BAD_DELTA;
694 if (_IO_in_backup (mark->_sbuf))
695 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
696 - mark->_sbuf->_wide_data->_IO_read_end);
697 else
698 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
699 - mark->_sbuf->_wide_data->_IO_read_base);
700 return mark->_pos - cur_pos;
701}
702
703int
704_IO_seekwmark (fp, mark, delta)
705 _IO_FILE *fp;
706 struct _IO_marker *mark;
707 int delta;
708{
709 if (mark->_sbuf != fp)
710 return EOF;
711 if (mark->_pos >= 0)
712 {
713 if (_IO_in_backup (fp))
714 _IO_switch_to_main_wget_area (fp);
715 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
716 + mark->_pos);
717 }
718 else
719 {
720 if (!_IO_in_backup (fp))
721 _IO_switch_to_wbackup_area (fp);
722 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
723 }
724 return 0;
725}
726
727void
728_IO_unsave_wmarkers (fp)
729 _IO_FILE *fp;
730{
731 struct _IO_marker *mark = fp->_markers;
732 if (mark)
733 {
734#ifdef TODO
735 streampos offset = seekoff (0, ios::cur, ios::in);
736 if (offset != EOF)
737 {
738 offset += eGptr () - Gbase ();
739 for ( ; mark != NULL; mark = mark->_next)
740 mark->set_streampos (mark->_pos + offset);
741 }
742 else
743 {
744 for ( ; mark != NULL; mark = mark->_next)
745 mark->set_streampos (EOF);
746 }
747#endif
748 fp->_markers = 0;
749 }
750
751 if (_IO_have_backup (fp))
752 _IO_free_wbackup_area (fp);
753}