stdio_filebuf.h revision 102782
1188943Sthompsa// File descriptor layer for filebuf -*- C++ -*-
2188943Sthompsa
3188943Sthompsa// Copyright (C) 2002 Free Software Foundation, Inc.
4188943Sthompsa//
5188943Sthompsa// This file is part of the GNU ISO C++ Library.  This library is free
6188943Sthompsa// software; you can redistribute it and/or modify it under the
7188943Sthompsa// terms of the GNU General Public License as published by the
8188943Sthompsa// Free Software Foundation; either version 2, or (at your option)
9188943Sthompsa// any later version.
10188943Sthompsa
11188943Sthompsa// This library is distributed in the hope that it will be useful,
12188943Sthompsa// but WITHOUT ANY WARRANTY; without even the implied warranty of
13188943Sthompsa// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14188943Sthompsa// GNU General Public License for more details.
15188943Sthompsa
16188943Sthompsa// You should have received a copy of the GNU General Public License along
17188943Sthompsa// with this library; see the file COPYING.  If not, write to the Free
18188943Sthompsa// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19188943Sthompsa// USA.
20188943Sthompsa
21188943Sthompsa// As a special exception, you may use this file as part of a free software
22188943Sthompsa// library without restriction.  Specifically, if other files instantiate
23188943Sthompsa// templates or use macros or inline functions from this file, or you compile
24188943Sthompsa// this file and link it with other files to produce an executable, this
25188943Sthompsa// file does not by itself cause the resulting executable to be covered by
26188943Sthompsa// the GNU General Public License.  This exception does not however
27188943Sthompsa// invalidate any other reasons why the executable file might be covered by
28188943Sthompsa// the GNU General Public License.
29188943Sthompsa
30188943Sthompsa/** @file ext/stdio_filebuf.h
31188943Sthompsa *  This file is a GNU extension to the Standard C++ Library.
32188943Sthompsa */
33188943Sthompsa
34188943Sthompsa#ifndef _EXT_STDIO_FILEBUF
35188943Sthompsa#define _EXT_STDIO_FILEBUF
36188943Sthompsa
37#pragma GCC system_header
38#include <fstream>
39
40namespace __gnu_cxx
41{
42  /**
43   *  @class stdio_filebuf ext/stdio_filebuf.h <ext/stdio_filebuf.h>
44   *  @brief Provides a layer of compatibility for C/POSIX.
45   *
46   *  This GNU extension provides extensions for working with standard C
47   *  FILE*'s and POSIX file descriptors.  It must be instantiated by the
48   *  user with the type of character used in the file stream, e.g.,
49   *  stdio_filebuf<char>.
50  */
51  template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
52    class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits>
53    {
54    public:
55      // Types:
56      typedef _CharT                     	        char_type;
57      typedef _Traits                    	        traits_type;
58      typedef typename traits_type::int_type 		int_type;
59      typedef typename traits_type::pos_type 		pos_type;
60      typedef typename traits_type::off_type 		off_type;
61
62    protected:
63      // Stack-based buffer for unbuffered input.
64      char_type			_M_unbuf[4];
65
66    public:
67      /**
68       *  @param  fd  An open file descriptor.
69       *  @param  mode  Same meaning as in a standard filebuf.
70       *  @param  del  Whether to close the file on destruction.
71       *  @param  size  Optimal or preferred size of internal buffer, in bytes.
72       *
73       *  This constructor associates a file stream buffer with an open
74       *  POSIX file descriptor.  Iff @a del is true, then the associated
75       *  file will be closed when the stdio_filebuf is closed/destroyed.
76      */
77      stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del,
78		    int_type __size);
79
80      /**
81       *  @param  f  An open @c FILE*.
82       *  @param  mode  Same meaning as in a standard filebuf.
83       *  @param  size  Optimal or preferred size of internal buffer, in bytes.
84       *                Defaults to system's @c BUFSIZ.
85       *
86       *  This constructor associates a file stream buffer with an open
87       *  C @c FILE*.  The @c FILE* will not be automatically closed when the
88       *  stdio_filebuf is closed/destroyed.
89      */
90      stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
91		    int_type __size = static_cast<int_type>(BUFSIZ));
92
93      /**
94       *  Possibly closes the external data stream, in the case of the file
95       *  descriptor constructor and @c del @c == @c true.
96      */
97      virtual
98      ~stdio_filebuf();
99
100      /**
101       *  @return  The underlying file descriptor.
102       *
103       *  Once associated with an external data stream, this function can be
104       *  used to access the underlying POSIX file descriptor.  Note that
105       *  there is no way for the library to track what you do with the
106       *  descriptor, so be careful.
107      */
108      int
109      fd()
110      { return _M_file.fd(); }
111    };
112
113  template<typename _CharT, typename _Traits>
114    stdio_filebuf<_CharT, _Traits>::~stdio_filebuf()
115    { }
116
117  template<typename _CharT, typename _Traits>
118    stdio_filebuf<_CharT, _Traits>::
119    stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del,
120		  int_type __size)
121    {
122      _M_file.sys_open(__fd, __mode, __del);
123      if (this->is_open())
124	{
125	  _M_mode = __mode;
126	  if (__size > 0 && __size < 4)
127	    {
128	      // Specify unbuffered.
129	      _M_buf = _M_unbuf;
130	      _M_buf_size = __size;
131	      _M_buf_size_opt = 0;
132	    }
133	  else
134	    {
135	      _M_buf_size_opt = __size;
136	      _M_allocate_internal_buffer();
137	    }
138	  _M_set_indeterminate();
139	}
140    }
141
142  template<typename _CharT, typename _Traits>
143    stdio_filebuf<_CharT, _Traits>::
144    stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
145		  int_type __size)
146    {
147      _M_file.sys_open(__f, __mode);
148      if (this->is_open())
149	{
150	  _M_mode = __mode;
151	  if (__size > 0 && __size < 4)
152	    {
153	      // Specify unbuffered.
154	      _M_buf = _M_unbuf;
155	      _M_buf_size = __size;
156	      _M_buf_size_opt = 0;
157	    }
158	  else
159	    {
160	      _M_buf_size_opt = __size;
161	      _M_allocate_internal_buffer();
162	    }
163	  _M_set_indeterminate();
164	}
165    }
166} // namespace __gnu_cxx
167
168#endif /* _EXT_STDIO_FILEBUF */
169