stdio_filebuf.h revision 102782
1// File descriptor layer for filebuf -*- C++ -*-
2
3// Copyright (C) 2002 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2, or (at your option)
9// any later version.
10
11// This 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
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING.  If not, write to the Free
18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction.  Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License.  This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30/** @file ext/stdio_filebuf.h
31 *  This file is a GNU extension to the Standard C++ Library.
32 */
33
34#ifndef _EXT_STDIO_FILEBUF
35#define _EXT_STDIO_FILEBUF
36
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