197403Sobrien// File descriptor layer for filebuf -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
497403Sobrien//
597403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
697403Sobrien// software; you can redistribute it and/or modify it under the
797403Sobrien// terms of the GNU General Public License as published by the
897403Sobrien// Free Software Foundation; either version 2, or (at your option)
997403Sobrien// any later version.
1097403Sobrien
1197403Sobrien// This library is distributed in the hope that it will be useful,
1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1497403Sobrien// GNU General Public License for more details.
1597403Sobrien
1697403Sobrien// You should have received a copy of the GNU General Public License along
1797403Sobrien// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1997403Sobrien// USA.
2097403Sobrien
2197403Sobrien// As a special exception, you may use this file as part of a free software
2297403Sobrien// library without restriction.  Specifically, if other files instantiate
2397403Sobrien// templates or use macros or inline functions from this file, or you compile
2497403Sobrien// this file and link it with other files to produce an executable, this
2597403Sobrien// file does not by itself cause the resulting executable to be covered by
2697403Sobrien// the GNU General Public License.  This exception does not however
2797403Sobrien// invalidate any other reasons why the executable file might be covered by
2897403Sobrien// the GNU General Public License.
2997403Sobrien
30102782Skan/** @file ext/stdio_filebuf.h
31102782Skan *  This file is a GNU extension to the Standard C++ Library.
32102782Skan */
33102782Skan
34132720Skan#ifndef _STDIO_FILEBUF_H
35132720Skan#define _STDIO_FILEBUF_H 1
36102782Skan
37102782Skan#pragma GCC system_header
38132720Skan
3997403Sobrien#include <fstream>
4097403Sobrien
41169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
42169691Skan
43102782Skan  /**
44102782Skan   *  @brief Provides a layer of compatibility for C/POSIX.
45102782Skan   *
46102782Skan   *  This GNU extension provides extensions for working with standard C
47102782Skan   *  FILE*'s and POSIX file descriptors.  It must be instantiated by the
48102782Skan   *  user with the type of character used in the file stream, e.g.,
49102782Skan   *  stdio_filebuf<char>.
50102782Skan  */
5197403Sobrien  template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
5297403Sobrien    class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits>
5397403Sobrien    {
5497403Sobrien    public:
5597403Sobrien      // Types:
56132720Skan      typedef _CharT				        char_type;
57132720Skan      typedef _Traits				        traits_type;
58132720Skan      typedef typename traits_type::int_type		int_type;
59132720Skan      typedef typename traits_type::pos_type		pos_type;
60132720Skan      typedef typename traits_type::off_type		off_type;
61117397Skan      typedef std::size_t                               size_t;
62132720Skan
6397403Sobrien    public:
64102782Skan      /**
65132720Skan       * deferred initialization
66132720Skan      */
67132720Skan      stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {}
68132720Skan
69132720Skan      /**
70102782Skan       *  @param  fd  An open file descriptor.
71102782Skan       *  @param  mode  Same meaning as in a standard filebuf.
72132720Skan       *  @param  size  Optimal or preferred size of internal buffer, in chars.
73102782Skan       *
74102782Skan       *  This constructor associates a file stream buffer with an open
75132720Skan       *  POSIX file descriptor. The file descriptor will be automatically
76132720Skan       *  closed when the stdio_filebuf is closed/destroyed.
77102782Skan      */
78132720Skan      stdio_filebuf(int __fd, std::ios_base::openmode __mode,
79132720Skan		    size_t __size = static_cast<size_t>(BUFSIZ));
8097403Sobrien
81102782Skan      /**
82102782Skan       *  @param  f  An open @c FILE*.
83102782Skan       *  @param  mode  Same meaning as in a standard filebuf.
84132720Skan       *  @param  size  Optimal or preferred size of internal buffer, in chars.
85102782Skan       *                Defaults to system's @c BUFSIZ.
86102782Skan       *
87102782Skan       *  This constructor associates a file stream buffer with an open
88102782Skan       *  C @c FILE*.  The @c FILE* will not be automatically closed when the
89102782Skan       *  stdio_filebuf is closed/destroyed.
90102782Skan      */
91132720Skan      stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
92117397Skan		    size_t __size = static_cast<size_t>(BUFSIZ));
9397403Sobrien
94102782Skan      /**
95132720Skan       *  Closes the external data stream if the file descriptor constructor
96132720Skan       *  was used.
97102782Skan      */
9897403Sobrien      virtual
9997403Sobrien      ~stdio_filebuf();
10097403Sobrien
101102782Skan      /**
102102782Skan       *  @return  The underlying file descriptor.
103102782Skan       *
104102782Skan       *  Once associated with an external data stream, this function can be
105102782Skan       *  used to access the underlying POSIX file descriptor.  Note that
106102782Skan       *  there is no way for the library to track what you do with the
107102782Skan       *  descriptor, so be careful.
108102782Skan      */
10997403Sobrien      int
110132720Skan      fd() { return this->_M_file.fd(); }
111132720Skan
112132720Skan      /**
113132720Skan       *  @return  The underlying FILE*.
114132720Skan       *
115132720Skan       *  This function can be used to access the underlying "C" file pointer.
116132720Skan       *  Note that there is no way for the library to track what you do
117132720Skan       *  with the file, so be careful.
118132720Skan       */
119132720Skan      std::__c_file*
120132720Skan      file() { return this->_M_file.file(); }
12197403Sobrien    };
12297403Sobrien
12397403Sobrien  template<typename _CharT, typename _Traits>
12497403Sobrien    stdio_filebuf<_CharT, _Traits>::~stdio_filebuf()
12597403Sobrien    { }
12697403Sobrien
12797403Sobrien  template<typename _CharT, typename _Traits>
12897403Sobrien    stdio_filebuf<_CharT, _Traits>::
129132720Skan    stdio_filebuf(int __fd, std::ios_base::openmode __mode, size_t __size)
13097403Sobrien    {
131132720Skan      this->_M_file.sys_open(__fd, __mode);
13297403Sobrien      if (this->is_open())
13397403Sobrien	{
134132720Skan	  this->_M_mode = __mode;
135132720Skan	  this->_M_buf_size = __size;
136132720Skan	  this->_M_allocate_internal_buffer();
137132720Skan	  this->_M_reading = false;
138132720Skan	  this->_M_writing = false;
139132720Skan	  this->_M_set_buffer(-1);
14097403Sobrien	}
14197403Sobrien    }
14297403Sobrien
14397403Sobrien  template<typename _CharT, typename _Traits>
14497403Sobrien    stdio_filebuf<_CharT, _Traits>::
145132720Skan    stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
146117397Skan		  size_t __size)
14797403Sobrien    {
148132720Skan      this->_M_file.sys_open(__f, __mode);
14997403Sobrien      if (this->is_open())
15097403Sobrien	{
151132720Skan	  this->_M_mode = __mode;
152132720Skan	  this->_M_buf_size = __size;
153132720Skan	  this->_M_allocate_internal_buffer();
154132720Skan	  this->_M_reading = false;
155132720Skan	  this->_M_writing = false;
156132720Skan	  this->_M_set_buffer(-1);
15797403Sobrien	}
15897403Sobrien    }
159102782Skan
160169691Skan_GLIBCXX_END_NAMESPACE
161169691Skan
162132720Skan#endif
163