• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/arm-brcm-linux-uclibcgnueabi/include/c++/4.5.3/ext/
1// Iostreams wrapper for stdio FILE* -*- C++ -*-
2
3// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file ext/stdio_sync_filebuf.h
27 *  This file is a GNU extension to the Standard C++ Library.
28 */
29
30#ifndef _STDIO_SYNC_FILEBUF_H
31#define _STDIO_SYNC_FILEBUF_H 1
32
33#pragma GCC system_header
34
35#include <streambuf>
36#include <unistd.h>
37#include <cstdio>
38#include <bits/c++io.h>  // For __c_file
39
40#ifdef _GLIBCXX_USE_WCHAR_T
41#include <cwchar>
42#endif
43
44_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
45
46  /**
47   *  @brief Provides a layer of compatibility for C.
48   *  @ingroup io
49   *
50   *  This GNU extension provides extensions for working with standard
51   *  C FILE*'s.  It must be instantiated by the user with the type of
52   *  character used in the file stream, e.g., stdio_filebuf<char>.
53  */
54  template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
55    class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits>
56    {
57    public:
58      // Types:
59      typedef _CharT					char_type;
60      typedef _Traits					traits_type;
61      typedef typename traits_type::int_type		int_type;
62      typedef typename traits_type::pos_type		pos_type;
63      typedef typename traits_type::off_type		off_type;
64
65    private:
66      // Underlying stdio FILE
67      std::__c_file* const _M_file;
68
69      // Last character gotten. This is used when pbackfail is
70      // called from basic_streambuf::sungetc()
71      int_type _M_unget_buf;
72
73    public:
74      explicit
75      stdio_sync_filebuf(std::__c_file* __f)
76      : _M_file(__f), _M_unget_buf(traits_type::eof())
77      { }
78
79      /**
80       *  @return  The underlying FILE*.
81       *
82       *  This function can be used to access the underlying C file pointer.
83       *  Note that there is no way for the library to track what you do
84       *  with the file, so be careful.
85       */
86      std::__c_file* const
87      file() { return this->_M_file; }
88
89    protected:
90      int_type
91      syncgetc();
92
93      int_type
94      syncungetc(int_type __c);
95
96      int_type
97      syncputc(int_type __c);
98
99      virtual int_type
100      underflow()
101      {
102	int_type __c = this->syncgetc();
103	return this->syncungetc(__c);
104      }
105
106      virtual int_type
107      uflow()
108      {
109	// Store the gotten character in case we need to unget it.
110	_M_unget_buf = this->syncgetc();
111	return _M_unget_buf;
112      }
113
114      virtual int_type
115      pbackfail(int_type __c = traits_type::eof())
116      {
117	int_type __ret;
118	const int_type __eof = traits_type::eof();
119
120	// Check if the unget or putback was requested
121	if (traits_type::eq_int_type(__c, __eof)) // unget
122	  {
123	    if (!traits_type::eq_int_type(_M_unget_buf, __eof))
124	      __ret = this->syncungetc(_M_unget_buf);
125	    else // buffer invalid, fail.
126	      __ret = __eof;
127	  }
128	else // putback
129	  __ret = this->syncungetc(__c);
130
131	// The buffered character is no longer valid, discard it.
132	_M_unget_buf = __eof;
133	return __ret;
134      }
135
136      virtual std::streamsize
137      xsgetn(char_type* __s, std::streamsize __n);
138
139      virtual int_type
140      overflow(int_type __c = traits_type::eof())
141      {
142	int_type __ret;
143	if (traits_type::eq_int_type(__c, traits_type::eof()))
144	  {
145	    if (std::fflush(_M_file))
146	      __ret = traits_type::eof();
147	    else
148	      __ret = traits_type::not_eof(__c);
149	  }
150	else
151	  __ret = this->syncputc(__c);
152	return __ret;
153      }
154
155      virtual std::streamsize
156      xsputn(const char_type* __s, std::streamsize __n);
157
158      virtual int
159      sync()
160      { return std::fflush(_M_file); }
161
162      virtual std::streampos
163      seekoff(std::streamoff __off, std::ios_base::seekdir __dir,
164	      std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
165      {
166	std::streampos __ret(std::streamoff(-1));
167	int __whence;
168	if (__dir == std::ios_base::beg)
169	  __whence = SEEK_SET;
170	else if (__dir == std::ios_base::cur)
171	  __whence = SEEK_CUR;
172	else
173	  __whence = SEEK_END;
174#ifdef _GLIBCXX_USE_LFS
175	if (!fseeko64(_M_file, __off, __whence))
176	  __ret = std::streampos(ftello64(_M_file));
177#else
178	if (!fseek(_M_file, __off, __whence))
179	  __ret = std::streampos(std::ftell(_M_file));
180#endif
181	return __ret;
182      }
183
184      virtual std::streampos
185      seekpos(std::streampos __pos,
186	      std::ios_base::openmode __mode =
187	      std::ios_base::in | std::ios_base::out)
188      { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); }
189    };
190
191  template<>
192    inline stdio_sync_filebuf<char>::int_type
193    stdio_sync_filebuf<char>::syncgetc()
194    { return std::getc(_M_file); }
195
196  template<>
197    inline stdio_sync_filebuf<char>::int_type
198    stdio_sync_filebuf<char>::syncungetc(int_type __c)
199    { return std::ungetc(__c, _M_file); }
200
201  template<>
202    inline stdio_sync_filebuf<char>::int_type
203    stdio_sync_filebuf<char>::syncputc(int_type __c)
204    { return std::putc(__c, _M_file); }
205
206  template<>
207    inline std::streamsize
208    stdio_sync_filebuf<char>::xsgetn(char* __s, std::streamsize __n)
209    {
210      std::streamsize __ret = std::fread(__s, 1, __n, _M_file);
211      if (__ret > 0)
212	_M_unget_buf = traits_type::to_int_type(__s[__ret - 1]);
213      else
214	_M_unget_buf = traits_type::eof();
215      return __ret;
216    }
217
218  template<>
219    inline std::streamsize
220    stdio_sync_filebuf<char>::xsputn(const char* __s, std::streamsize __n)
221    { return std::fwrite(__s, 1, __n, _M_file); }
222
223#ifdef _GLIBCXX_USE_WCHAR_T
224  template<>
225    inline stdio_sync_filebuf<wchar_t>::int_type
226    stdio_sync_filebuf<wchar_t>::syncgetc()
227    { return std::getwc(_M_file); }
228
229  template<>
230    inline stdio_sync_filebuf<wchar_t>::int_type
231    stdio_sync_filebuf<wchar_t>::syncungetc(int_type __c)
232    { return std::ungetwc(__c, _M_file); }
233
234  template<>
235    inline stdio_sync_filebuf<wchar_t>::int_type
236    stdio_sync_filebuf<wchar_t>::syncputc(int_type __c)
237    { return std::putwc(__c, _M_file); }
238
239  template<>
240    inline std::streamsize
241    stdio_sync_filebuf<wchar_t>::xsgetn(wchar_t* __s, std::streamsize __n)
242    {
243      std::streamsize __ret = 0;
244      const int_type __eof = traits_type::eof();
245      while (__n--)
246	{
247	  int_type __c = this->syncgetc();
248	  if (traits_type::eq_int_type(__c, __eof))
249	    break;
250	  __s[__ret] = traits_type::to_char_type(__c);
251	  ++__ret;
252	}
253
254      if (__ret > 0)
255	_M_unget_buf = traits_type::to_int_type(__s[__ret - 1]);
256      else
257	_M_unget_buf = traits_type::eof();
258      return __ret;
259    }
260
261  template<>
262    inline std::streamsize
263    stdio_sync_filebuf<wchar_t>::xsputn(const wchar_t* __s,
264					std::streamsize __n)
265    {
266      std::streamsize __ret = 0;
267      const int_type __eof = traits_type::eof();
268      while (__n--)
269	{
270	  if (traits_type::eq_int_type(this->syncputc(*__s++), __eof))
271	    break;
272	  ++__ret;
273	}
274      return __ret;
275    }
276#endif
277
278#if _GLIBCXX_EXTERN_TEMPLATE
279  extern template class stdio_sync_filebuf<char>;
280#ifdef _GLIBCXX_USE_WCHAR_T
281  extern template class stdio_sync_filebuf<wchar_t>;
282#endif
283#endif
284
285_GLIBCXX_END_NAMESPACE
286
287#endif
288