1f2ced752SOliver Tappe/* This is part of libio/iostream, providing -*- C++ -*- input/output.
2f2ced752SOliver TappeCopyright (C) 1993 Free Software Foundation
3f2ced752SOliver Tappe
4f2ced752SOliver TappeThis file is part of the GNU IO Library.  This library is free
5f2ced752SOliver Tappesoftware; you can redistribute it and/or modify it under the
6f2ced752SOliver Tappeterms of the GNU General Public License as published by the
7f2ced752SOliver TappeFree Software Foundation; either version 2, or (at your option)
8f2ced752SOliver Tappeany later version.
9f2ced752SOliver Tappe
10f2ced752SOliver TappeThis library is distributed in the hope that it will be useful,
11f2ced752SOliver Tappebut WITHOUT ANY WARRANTY; without even the implied warranty of
13f2ced752SOliver TappeGNU General Public License for more details.
14f2ced752SOliver Tappe
15f2ced752SOliver TappeYou should have received a copy of the GNU General Public License
16f2ced752SOliver Tappealong with this library; see the file COPYING.  If not, write to the Free
17f2ced752SOliver TappeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18f2ced752SOliver Tappe
19f2ced752SOliver TappeAs a special exception, if you link this library with files
20f2ced752SOliver Tappecompiled with a GNU compiler to produce an executable, this does not cause
21f2ced752SOliver Tappethe resulting executable to be covered by the GNU General Public License.
22f2ced752SOliver TappeThis exception does not however invalidate any other reasons why
23f2ced752SOliver Tappethe executable file might be covered by the GNU General Public License.
24f2ced752SOliver Tappe
25f2ced752SOliver TappeWritten by Per Bothner (bothner@cygnus.com). */
26f2ced752SOliver Tappe
27f2ced752SOliver Tappe#ifdef __GNUG__
28f2ced752SOliver Tappe#pragma implementation
29f2ced752SOliver Tappe#endif
30f2ced752SOliver Tappe
31f2ced752SOliver Tappe#include <indstream.h>
32f2ced752SOliver Tappe
33f2ced752SOliver Tappeindirectbuf::indirectbuf(streambuf *get, streambuf *put, int delete_mode)
34f2ced752SOliver Tappe: streambuf()
35f2ced752SOliver Tappe{
36f2ced752SOliver Tappe    _get_stream = get;
37f2ced752SOliver Tappe    _put_stream = put == NULL ? get : put;
38f2ced752SOliver Tappe    _delete_flags = delete_mode;
39f2ced752SOliver Tappe}
40f2ced752SOliver Tappe
41f2ced752SOliver Tappeindirectbuf::~indirectbuf()
42f2ced752SOliver Tappe{
43f2ced752SOliver Tappe    if (_delete_flags & ios::in)  delete get_stream();
44f2ced752SOliver Tappe    if (_delete_flags & ios::out)  delete put_stream();
45f2ced752SOliver Tappe}
46f2ced752SOliver Tappe
47f2ced752SOliver Tappestreamsize indirectbuf::xsputn(const char* s, streamsize n)
48f2ced752SOliver Tappe{
49f2ced752SOliver Tappe    return put_stream()->sputn(s, n);
50f2ced752SOliver Tappe}
51f2ced752SOliver Tappe
52f2ced752SOliver Tappestreamsize indirectbuf::xsgetn(char* s, streamsize n)
53f2ced752SOliver Tappe{
54f2ced752SOliver Tappe    return get_stream()->sgetn(s, n);
55f2ced752SOliver Tappe}
56f2ced752SOliver Tappe
57f2ced752SOliver Tappeint indirectbuf::overflow(int c /* = EOF */)
58f2ced752SOliver Tappe{
59f2ced752SOliver Tappe    if (c == EOF)
60f2ced752SOliver Tappe	return put_stream()->overflow(c);
61f2ced752SOliver Tappe    else
62f2ced752SOliver Tappe	return put_stream()->sputc(c);
63f2ced752SOliver Tappe}
64f2ced752SOliver Tappe
65f2ced752SOliver Tappeint indirectbuf::underflow()
66f2ced752SOliver Tappe{
67f2ced752SOliver Tappe    return get_stream()->sgetc();
68f2ced752SOliver Tappe}
69f2ced752SOliver Tappe
70f2ced752SOliver Tappeint indirectbuf::uflow()
71f2ced752SOliver Tappe{
72f2ced752SOliver Tappe    return get_stream()->sbumpc();
73f2ced752SOliver Tappe}
74f2ced752SOliver Tappe
75f2ced752SOliver Tappestreampos indirectbuf::seekoff(streamoff off, _seek_dir dir, int mode)
76f2ced752SOliver Tappe{
77f2ced752SOliver Tappe    int ret_val = 0;
78f2ced752SOliver Tappe    int select = mode == 0 ? (ios::in|ios::out) : mode;
79f2ced752SOliver Tappe    streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL;
80f2ced752SOliver Tappe    streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL;
81f2ced752SOliver Tappe    if (gbuf == pbuf)
82f2ced752SOliver Tappe	ret_val = gbuf->seekoff(off, dir, mode);
83f2ced752SOliver Tappe    else {
84f2ced752SOliver Tappe	if (gbuf)
85f2ced752SOliver Tappe	    ret_val = gbuf->seekoff(off, dir, ios::in);
86f2ced752SOliver Tappe	if (pbuf && ret_val != EOF)
87f2ced752SOliver Tappe	    ret_val = pbuf->seekoff(off, dir, ios::out);
88f2ced752SOliver Tappe    }
89f2ced752SOliver Tappe    return ret_val;
90f2ced752SOliver Tappe}
91f2ced752SOliver Tappe
92f2ced752SOliver Tappestreampos indirectbuf::seekpos(streampos pos, int mode)
93f2ced752SOliver Tappe{
94f2ced752SOliver Tappe    int ret_val = EOF;
95f2ced752SOliver Tappe    int select = mode == 0 ? (ios::in|ios::out) : mode;
96f2ced752SOliver Tappe    streambuf *gbuf = (select & ios::in) ? get_stream() : (streambuf*)NULL;
97f2ced752SOliver Tappe    streambuf *pbuf = (select & ios::out) ? put_stream() : (streambuf*)NULL;
98f2ced752SOliver Tappe    if (gbuf == pbuf && gbuf != NULL)
99f2ced752SOliver Tappe	ret_val = gbuf->seekpos(pos, mode);
100f2ced752SOliver Tappe    else {
101f2ced752SOliver Tappe	if (gbuf)
102f2ced752SOliver Tappe	    ret_val = gbuf->seekpos(pos, ios::in);
103f2ced752SOliver Tappe	if (pbuf && ret_val != EOF)
104f2ced752SOliver Tappe	    ret_val = pbuf->seekpos(pos, ios::out);
105f2ced752SOliver Tappe    }
106f2ced752SOliver Tappe    return ret_val;
107f2ced752SOliver Tappe}
108f2ced752SOliver Tappe
109f2ced752SOliver Tappeint indirectbuf::sync()
110f2ced752SOliver Tappe{
111f2ced752SOliver Tappe  streambuf *gbuf = get_stream();
112f2ced752SOliver Tappe  int get_ret_val = gbuf ? gbuf->sync() : 0;
113f2ced752SOliver Tappe  streambuf *pbuf = put_stream();
114f2ced752SOliver Tappe  int put_ret_val = (pbuf && pbuf != gbuf) ?  pbuf->sync() : 0;
115f2ced752SOliver Tappe  return get_ret_val || put_ret_val;
116f2ced752SOliver Tappe}
117f2ced752SOliver Tappe
118f2ced752SOliver Tappeint indirectbuf::pbackfail(int c)
119f2ced752SOliver Tappe{
120f2ced752SOliver Tappe    return get_stream()->sputbackc(c);
121f2ced752SOliver Tappe}