···11-// Wrapper of C-language FILE struct -*- C++ -*-
22-33-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2009, 2010
44-// Free Software Foundation, Inc.
55-//
66-// This file is part of the GNU ISO C++ Library. This library is free
77-// software; you can redistribute it and/or modify it under the
88-// terms of the GNU General Public License as published by the
99-// Free Software Foundation; either version 3, or (at your option)
1010-// any later version.
1111-1212-// This library is distributed in the hope that it will be useful,
1313-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1414-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515-// GNU General Public License for more details.
1616-1717-// Under Section 7 of GPL version 3, you are granted additional
1818-// permissions described in the GCC Runtime Library Exception, version
1919-// 3.1, as published by the Free Software Foundation.
2020-2121-// You should have received a copy of the GNU General Public License and
2222-// a copy of the GCC Runtime Library Exception along with this program;
2323-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2424-// <http://www.gnu.org/licenses/>.
2525-2626-//
2727-// ISO C++ 14882: 27.8 File-based streams
2828-//
2929-3030-//#include <bits/basic_file.h>
3131-#define __c_file __sFILE
3232-#define _IO_FILE __sFILE
3333-#include "basic_file_stdio.h"
3434-#include <fcntl.h>
3535-#include <errno.h>
3636-3737-#ifdef _GLIBCXX_HAVE_POLL
3838-#include <poll.h>
3939-#endif
4040-4141-// Pick up ioctl on Solaris 2.8
4242-#ifdef _GLIBCXX_HAVE_UNISTD_H
4343-#include <unistd.h>
4444-#endif
4545-4646-// Pick up FIONREAD on Solaris 2
4747-#ifdef _GLIBCXX_HAVE_SYS_IOCTL_H
4848-#define BSD_COMP
4949-#include <sys/ioctl.h>
5050-#endif
5151-5252-// Pick up FIONREAD on Solaris 2.5.
5353-#ifdef _GLIBCXX_HAVE_SYS_FILIO_H
5454-#include <sys/filio.h>
5555-#endif
5656-5757-#ifdef _GLIBCXX_HAVE_SYS_UIO_H
5858-#include <sys/uio.h>
5959-#endif
6060-6161-struct __sFILE;
6262-6363-extern "C" __sFILE* __darwin_fopen(const char* path, const char* mode);
6464-extern "C" __sFILE* __darwin_fdopen(int fd, const char* mode);
6565-extern "C" int __darwin_fclose(__sFILE* f);
6666-extern "C" int __darwin_fileno(__sFILE* f);
6767-6868-#define fopen __darwin_fopen
6969-#define fopen64 __darwin_fopen
7070-#define fdopen __darwin_fdopen
7171-#define fclose __darwin_fclose
7272-#define fileno __darwin_fileno
7373-7474-#if defined(_GLIBCXX_HAVE_S_ISREG) || defined(_GLIBCXX_HAVE_S_IFREG)
7575-# include <sys/stat.h>
7676-# ifdef _GLIBCXX_HAVE_S_ISREG
7777-# define _GLIBCXX_ISREG(x) S_ISREG(x)
7878-# else
7979-# define _GLIBCXX_ISREG(x) (((x) & S_IFMT) == S_IFREG)
8080-# endif
8181-#endif
8282-8383-#include <limits> // For <off_t>::max() and min() and <streamsize>::max()
8484-8585-namespace
8686-{
8787- // Map ios_base::openmode flags to a string for use in fopen().
8888- // Table of valid combinations as given in [lib.filebuf.members]/2.
8989- static const char*
9090- fopen_mode(std::ios_base::openmode mode)
9191- {
9292- enum
9393- {
9494- in = std::ios_base::in,
9595- out = std::ios_base::out,
9696- trunc = std::ios_base::trunc,
9797- app = std::ios_base::app,
9898- binary = std::ios_base::binary
9999- };
100100-101101- // _GLIBCXX_RESOLVE_LIB_DEFECTS
102102- // 596. 27.8.1.3 Table 112 omits "a+" and "a+b" modes.
103103- switch (mode & (in|out|trunc|app|binary))
104104- {
105105- case ( out ): return "w";
106106- case ( out |app ): return "a";
107107- case ( app ): return "a";
108108- case ( out|trunc ): return "w";
109109- case (in ): return "r";
110110- case (in|out ): return "r+";
111111- case (in|out|trunc ): return "w+";
112112- case (in|out |app ): return "a+";
113113- case (in |app ): return "a+";
114114-115115- case ( out |binary): return "wb";
116116- case ( out |app|binary): return "ab";
117117- case ( app|binary): return "ab";
118118- case ( out|trunc |binary): return "wb";
119119- case (in |binary): return "rb";
120120- case (in|out |binary): return "r+b";
121121- case (in|out|trunc |binary): return "w+b";
122122- case (in|out |app|binary): return "a+b";
123123- case (in |app|binary): return "a+b";
124124-125125- default: return 0; // invalid
126126- }
127127- }
128128-129129- // Wrapper handling partial write.
130130- static std::streamsize
131131- xwrite(int __fd, const char* __s, std::streamsize __n)
132132- {
133133- std::streamsize __nleft = __n;
134134-135135- for (;;)
136136- {
137137- const std::streamsize __ret = write(__fd, __s, __nleft);
138138- if (__ret == -1L && errno == EINTR)
139139- continue;
140140- if (__ret == -1L)
141141- break;
142142-143143- __nleft -= __ret;
144144- if (__nleft == 0)
145145- break;
146146-147147- __s += __ret;
148148- }
149149-150150- return __n - __nleft;
151151- }
152152-153153-#ifdef _GLIBCXX_HAVE_WRITEV
154154- // Wrapper handling partial writev.
155155- static std::streamsize
156156- xwritev(int __fd, const char* __s1, std::streamsize __n1,
157157- const char* __s2, std::streamsize __n2)
158158- {
159159- std::streamsize __nleft = __n1 + __n2;
160160- std::streamsize __n1_left = __n1;
161161-162162- struct iovec __iov[2];
163163- __iov[1].iov_base = const_cast<char*>(__s2);
164164- __iov[1].iov_len = __n2;
165165-166166- for (;;)
167167- {
168168- __iov[0].iov_base = const_cast<char*>(__s1);
169169- __iov[0].iov_len = __n1_left;
170170-171171- const std::streamsize __ret = writev(__fd, __iov, 2);
172172- if (__ret == -1L && errno == EINTR)
173173- continue;
174174- if (__ret == -1L)
175175- break;
176176-177177- __nleft -= __ret;
178178- if (__nleft == 0)
179179- break;
180180-181181- const std::streamsize __off = __ret - __n1_left;
182182- if (__off >= 0)
183183- {
184184- __nleft -= xwrite(__fd, __s2 + __off, __n2 - __off);
185185- break;
186186- }
187187-188188- __s1 += __ret;
189189- __n1_left -= __ret;
190190- }
191191-192192- return __n1 + __n2 - __nleft;
193193- }
194194-#endif
195195-} // anonymous namespace
196196-197197-198198-namespace std _GLIBCXX_VISIBILITY(default)
199199-{
200200-_GLIBCXX_BEGIN_NAMESPACE_VERSION
201201-202202- // Definitions for __basic_file<char>.
203203- __basic_file<char>::__basic_file(__c_lock* /*__lock*/) throw()
204204- : _M_cfile(NULL), _M_cfile_created(false) { }
205205-206206- __basic_file<char>::~__basic_file()
207207- { this->close(); }
208208-209209- __basic_file<char>*
210210- __basic_file<char>::sys_open(__c_file* __file, ios_base::openmode)
211211- {
212212- __basic_file* __ret = NULL;
213213- if (!this->is_open() && __file)
214214- {
215215- int __err;
216216- errno = 0;
217217- do
218218- __err = this->sync();
219219- while (__err && errno == EINTR);
220220- if (!__err)
221221- {
222222- _M_cfile = __file;
223223- _M_cfile_created = false;
224224- __ret = this;
225225- }
226226- }
227227- return __ret;
228228- }
229229-230230- __basic_file<char>*
231231- __basic_file<char>::sys_open(int __fd, ios_base::openmode __mode) throw ()
232232- {
233233- __basic_file* __ret = NULL;
234234- const char* __c_mode = fopen_mode(__mode);
235235- if (__c_mode && !this->is_open() && (_M_cfile = fdopen(__fd, __c_mode)))
236236- {
237237- char* __buf = NULL;
238238- _M_cfile_created = true;
239239- if (__fd == 0)
240240- setvbuf(_M_cfile, __buf, _IONBF, 0);
241241- __ret = this;
242242- }
243243- return __ret;
244244- }
245245-246246- __basic_file<char>*
247247- __basic_file<char>::open(const char* __name, ios_base::openmode __mode,
248248- int /*__prot*/)
249249- {
250250- __basic_file* __ret = NULL;
251251- const char* __c_mode = fopen_mode(__mode);
252252- if (__c_mode && !this->is_open())
253253- {
254254-#ifdef _GLIBCXX_USE_LFS
255255- if ((_M_cfile = fopen64(__name, __c_mode)))
256256-#else
257257- if ((_M_cfile = fopen(__name, __c_mode)))
258258-#endif
259259- {
260260- _M_cfile_created = true;
261261- __ret = this;
262262- }
263263- }
264264- return __ret;
265265- }
266266-267267- bool
268268- __basic_file<char>::is_open() const throw ()
269269- { return _M_cfile != 0; }
270270-271271- int
272272- __basic_file<char>::fd() throw ()
273273- { return fileno(_M_cfile); }
274274-275275- __c_file*
276276- __basic_file<char>::file() throw ()
277277- { return _M_cfile; }
278278-279279- __basic_file<char>*
280280- __basic_file<char>::close()
281281- {
282282- __basic_file* __ret = static_cast<__basic_file*>(NULL);
283283- if (this->is_open())
284284- {
285285- int __err = 0;
286286- if (_M_cfile_created)
287287- {
288288- // In general, no need to zero errno in advance if checking
289289- // for error first. However, C89/C99 (at variance with IEEE
290290- // 1003.1, f.i.) do not mandate that fclose must set errno
291291- // upon error.
292292- errno = 0;
293293- do
294294- __err = fclose(_M_cfile);
295295- while (__err && errno == EINTR);
296296- }
297297- _M_cfile = 0;
298298- if (!__err)
299299- __ret = this;
300300- }
301301- return __ret;
302302- }
303303-304304- streamsize
305305- __basic_file<char>::xsgetn(char* __s, streamsize __n)
306306- {
307307- streamsize __ret;
308308- do
309309- __ret = read(this->fd(), __s, __n);
310310- while (__ret == -1L && errno == EINTR);
311311- return __ret;
312312- }
313313-314314- streamsize
315315- __basic_file<char>::xsputn(const char* __s, streamsize __n)
316316- { return xwrite(this->fd(), __s, __n); }
317317-318318- streamsize
319319- __basic_file<char>::xsputn_2(const char* __s1, streamsize __n1,
320320- const char* __s2, streamsize __n2)
321321- {
322322- streamsize __ret = 0;
323323-#ifdef _GLIBCXX_HAVE_WRITEV
324324- __ret = xwritev(this->fd(), __s1, __n1, __s2, __n2);
325325-#else
326326- if (__n1)
327327- __ret = xwrite(this->fd(), __s1, __n1);
328328-329329- if (__ret == __n1)
330330- __ret += xwrite(this->fd(), __s2, __n2);
331331-#endif
332332- return __ret;
333333- }
334334-335335- streamoff
336336- __basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way) throw ()
337337- {
338338-#ifdef _GLIBCXX_USE_LFS
339339- return lseek64(this->fd(), __off, __way);
340340-#else
341341- if (__off > numeric_limits<off_t>::max()
342342- || __off < numeric_limits<off_t>::min())
343343- return -1L;
344344- return lseek(this->fd(), __off, __way);
345345-#endif
346346- }
347347-348348- int
349349- __basic_file<char>::sync()
350350- { return fflush(_M_cfile); }
351351-352352- streamsize
353353- __basic_file<char>::showmanyc()
354354- {
355355-#ifndef _GLIBCXX_NO_IOCTL
356356-#ifdef FIONREAD
357357- // Pipes and sockets.
358358-#ifdef _GLIBCXX_FIONREAD_TAKES_OFF_T
359359- off_t __num = 0;
360360-#else
361361- int __num = 0;
362362-#endif
363363- int __r = ioctl(this->fd(), FIONREAD, &__num);
364364- if (!__r && __num >= 0)
365365- return __num;
366366-#endif
367367-#endif
368368-369369-#ifdef _GLIBCXX_HAVE_POLL
370370- // Cheap test.
371371- struct pollfd __pfd[1];
372372- __pfd[0].fd = this->fd();
373373- __pfd[0].events = POLLIN;
374374- if (poll(__pfd, 1, 0) <= 0)
375375- return 0;
376376-#endif
377377-378378-#if defined(_GLIBCXX_HAVE_S_ISREG) || defined(_GLIBCXX_HAVE_S_IFREG)
379379- // Regular files.
380380-#ifdef _GLIBCXX_USE_LFS
381381- struct stat64 __buffer;
382382- const int __err = fstat64(this->fd(), &__buffer);
383383- if (!__err && _GLIBCXX_ISREG(__buffer.st_mode))
384384- {
385385- const streamoff __off = __buffer.st_size - lseek64(this->fd(), 0,
386386- ios_base::cur);
387387- return std::min(__off, streamoff(numeric_limits<streamsize>::max()));
388388- }
389389-#else
390390- struct stat __buffer;
391391- const int __err = fstat(this->fd(), &__buffer);
392392- if (!__err && _GLIBCXX_ISREG(__buffer.st_mode))
393393- return __buffer.st_size - lseek(this->fd(), 0, ios_base::cur);
394394-#endif
395395-#endif
396396- return 0;
397397- }
398398-399399-_GLIBCXX_END_NAMESPACE_VERSION
400400-} // namespace
401401-
-115
src/libstdc++darwin/basic_file_stdio.h
···11-// Wrapper of C-language FILE struct -*- C++ -*-
22-33-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
44-// Free Software Foundation, Inc.
55-//
66-// This file is part of the GNU ISO C++ Library. This library is free
77-// software; you can redistribute it and/or modify it under the
88-// terms of the GNU General Public License as published by the
99-// Free Software Foundation; either version 3, or (at your option)
1010-// any later version.
1111-1212-// This library is distributed in the hope that it will be useful,
1313-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1414-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515-// GNU General Public License for more details.
1616-1717-// Under Section 7 of GPL version 3, you are granted additional
1818-// permissions described in the GCC Runtime Library Exception, version
1919-// 3.1, as published by the Free Software Foundation.
2020-2121-// You should have received a copy of the GNU General Public License and
2222-// a copy of the GCC Runtime Library Exception along with this program;
2323-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2424-// <http://www.gnu.org/licenses/>.
2525-2626-//
2727-// ISO C++ 14882: 27.8 File-based streams
2828-//
2929-3030-/** @file bits/basic_file.h
3131- * This is an internal header file, included by other library headers.
3232- * Do not attempt to use it directly. @headername{ios}
3333- */
3434-3535-#ifndef _GLIBCXX_BASIC_FILE_STDIO_H
3636-#define _GLIBCXX_BASIC_FILE_STDIO_H 1
3737-#define __c_file __sFILE
3838-#define _IO_FILE __sFILE
3939-4040-#pragma GCC system_header
4141-4242-#include <bits/c++config.h>
4343-#include "c_io_stdio.h"
4444-//#include <bits/c++io.h> // for __c_lock and __c_file
4545-#include <ios>
4646-4747-4848-namespace std _GLIBCXX_VISIBILITY(default)
4949-{
5050-_GLIBCXX_BEGIN_NAMESPACE_VERSION
5151-5252- // Generic declaration.
5353- template<typename _CharT>
5454- class __basic_file;
5555-5656- // Specialization.
5757- template<>
5858- class __basic_file<char>
5959- {
6060- // Underlying data source/sink.
6161- __c_file* _M_cfile;
6262-6363- // True iff we opened _M_cfile, and thus must close it ourselves.
6464- bool _M_cfile_created;
6565-6666- public:
6767- __basic_file(__c_lock* __lock = 0) throw ();
6868-6969- __basic_file*
7070- open(const char* __name, ios_base::openmode __mode, int __prot = 0664);
7171-7272- __basic_file*
7373- sys_open(__c_file* __file, ios_base::openmode);
7474-7575- __basic_file*
7676- sys_open(int __fd, ios_base::openmode __mode) throw ();
7777-7878- __basic_file*
7979- close();
8080-8181- _GLIBCXX_PURE bool
8282- is_open() const throw ();
8383-8484- _GLIBCXX_PURE int
8585- fd() throw ();
8686-8787- _GLIBCXX_PURE __c_file*
8888- file() throw ();
8989-9090- ~__basic_file();
9191-9292- streamsize
9393- xsputn(const char* __s, streamsize __n);
9494-9595- streamsize
9696- xsputn_2(const char* __s1, streamsize __n1,
9797- const char* __s2, streamsize __n2);
9898-9999- streamsize
100100- xsgetn(char* __s, streamsize __n);
101101-102102- streamoff
103103- seekoff(streamoff __off, ios_base::seekdir __way) throw ();
104104-105105- int
106106- sync();
107107-108108- streamsize
109109- showmanyc();
110110- };
111111-112112-_GLIBCXX_END_NAMESPACE_VERSION
113113-} // namespace
114114-115115-#endif
-53
src/libstdc++darwin/c_io_stdio.h
···11-// Underlying io library details -*- C++ -*-
22-33-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010
44-// Free Software Foundation, Inc.
55-//
66-// This file is part of the GNU ISO C++ Library. This library is free
77-// software; you can redistribute it and/or modify it under the
88-// terms of the GNU General Public License as published by the
99-// Free Software Foundation; either version 3, or (at your option)
1010-// any later version.
1111-1212-// This library is distributed in the hope that it will be useful,
1313-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1414-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515-// GNU General Public License for more details.
1616-1717-// Under Section 7 of GPL version 3, you are granted additional
1818-// permissions described in the GCC Runtime Library Exception, version
1919-// 3.1, as published by the Free Software Foundation.
2020-2121-// You should have received a copy of the GNU General Public License and
2222-// a copy of the GCC Runtime Library Exception along with this program;
2323-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2424-// <http://www.gnu.org/licenses/>.
2525-2626-/** @file bits/c++io.h
2727- * This is an internal header file, included by other library headers.
2828- * Do not attempt to use it directly. @headername{ios}
2929- */
3030-3131-// c_io_stdio.h - Defines for using "C" stdio.h
3232-3333-#ifndef _GLIBCXX_CXX_IO_H
3434-#define _GLIBCXX_CXX_IO_H 1
3535-3636-#include <cstdio>
3737-#include <bits/gthr.h>
3838-3939-struct __sFILE;
4040-4141-namespace std _GLIBCXX_VISIBILITY(default)
4242-{
4343-_GLIBCXX_BEGIN_NAMESPACE_VERSION
4444-4545- typedef __gthread_mutex_t __c_lock;
4646-4747- // for basic_file.h
4848- typedef __sFILE __c_file;
4949-5050-_GLIBCXX_END_NAMESPACE_VERSION
5151-} // namespace
5252-5353-#endif
-14
src/libstdc++darwin/filebuf_abi_fix.cpp
···11-// http://stackoverflow.com/a/452955
22-#define _GLIBCXX_VISIBILITY(x) __attribute((visibility(#x)))
33-#define _GLIBCXX_BEGIN_NAMESPACE_VERSION
44-#define _GLIBCXX_END_NAMESPACE_VERSION
55-#include "basic_file_stdio.cc"
66-#include "fstream"
77-#include "fstream.tcc"
88-99-template class std::__basic_file<char>;
1010-template class std::basic_filebuf<char, std::char_traits<char> >;
1111-template class std::basic_streambuf<char, std::char_traits<char> >;
1212-template class std::basic_ios<char, std::char_traits<char> >;
1313-template class std::basic_ostream<char, std::char_traits<char> >;
1414-
-950
src/libstdc++darwin/fstream
···11-// File based streams -*- C++ -*-
22-33-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
44-// 2006, 2007, 2008, 2009, 2010, 2011
55-// Free Software Foundation, Inc.
66-//
77-// This file is part of the GNU ISO C++ Library. This library is free
88-// software; you can redistribute it and/or modify it under the
99-// terms of the GNU General Public License as published by the
1010-// Free Software Foundation; either version 3, or (at your option)
1111-// any later version.
1212-1313-// This library is distributed in the hope that it will be useful,
1414-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1515-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1616-// GNU General Public License for more details.
1717-1818-// Under Section 7 of GPL version 3, you are granted additional
1919-// permissions described in the GCC Runtime Library Exception, version
2020-// 3.1, as published by the Free Software Foundation.
2121-2222-// You should have received a copy of the GNU General Public License and
2323-// a copy of the GCC Runtime Library Exception along with this program;
2424-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2525-// <http://www.gnu.org/licenses/>.
2626-2727-/** @file include/fstream
2828- * This is a Standard C++ Library header.
2929- */
3030-3131-//
3232-// ISO C++ 14882: 27.8 File-based streams
3333-//
3434-3535-#ifndef _GLIBCXX_FSTREAM
3636-#define _GLIBCXX_FSTREAM 1
3737-3838-#pragma GCC system_header
3939-4040-#include <istream>
4141-#include <ostream>
4242-#include <bits/codecvt.h>
4343-#include <cstdio> // For BUFSIZ
4444-#ifdef __GXX_EXPERIMENTAL_CXX0X__
4545-#include <string> // For std::string overloads.
4646-#endif
4747-4848-namespace std _GLIBCXX_VISIBILITY(default)
4949-{
5050-_GLIBCXX_BEGIN_NAMESPACE_VERSION
5151-5252- // [27.8.1.1] template class basic_filebuf
5353- /**
5454- * @brief The actual work of input and output (for files).
5555- * @ingroup io
5656- *
5757- * This class associates both its input and output sequence with an
5858- * external disk file, and maintains a joint file position for both
5959- * sequences. Many of its semantics are described in terms of similar
6060- * behavior in the Standard C Library's @c FILE streams.
6161- */
6262- // Requirements on traits_type, specific to this class:
6363- // traits_type::pos_type must be fpos<traits_type::state_type>
6464- // traits_type::off_type must be streamoff
6565- // traits_type::state_type must be Assignable and DefaultConstructible,
6666- // and traits_type::state_type() must be the initial state for codecvt.
6767- template<typename _CharT, typename _Traits>
6868- class basic_filebuf : public basic_streambuf<_CharT, _Traits>
6969- {
7070- public:
7171- // Types:
7272- typedef _CharT char_type;
7373- typedef _Traits traits_type;
7474- typedef typename traits_type::int_type int_type;
7575- typedef typename traits_type::pos_type pos_type;
7676- typedef typename traits_type::off_type off_type;
7777-7878- typedef basic_streambuf<char_type, traits_type> __streambuf_type;
7979- typedef basic_filebuf<char_type, traits_type> __filebuf_type;
8080- typedef __basic_file<char> __file_type;
8181- typedef typename traits_type::state_type __state_type;
8282- typedef codecvt<char_type, char, __state_type> __codecvt_type;
8383-8484- friend class ios_base; // For sync_with_stdio.
8585-8686- protected:
8787- // Data Members:
8888- // MT lock inherited from libio or other low-level io library.
8989-9090- // Darling MODIFICATION
9191- union
9292- {
9393- __c_lock _M_lock;
9494- // 64 on 64-bit
9595- // 44 on 32-bit
9696- struct
9797- {
9898- char __align0[24];
9999- long __align0x[5];
100100- };
101101- };
102102-103103- // External buffer.
104104- __file_type _M_file;
105105-106106- /// Place to stash in || out || in | out settings for current filebuf.
107107- ios_base::openmode _M_mode;
108108-109109- // Beginning state type for codecvt.
110110- // Darling MODIFICATION
111111- union
112112- {
113113- __state_type _M_state_beg;
114114- char __align1[128];
115115- };
116116-117117- // During output, the state that corresponds to pptr(),
118118- // during input, the state that corresponds to egptr() and
119119- // _M_ext_next.
120120- // Darling MODIFICATION
121121- union
122122- {
123123- __state_type _M_state_cur;
124124- char __align2[128];
125125- };
126126-127127- // Not used for output. During input, the state that corresponds
128128- // to eback() and _M_ext_buf.
129129- // Darling MODIFICATION
130130- union
131131- {
132132- __state_type _M_state_last;
133133- char __align3[128];
134134- };
135135-136136- /// Pointer to the beginning of internal buffer.
137137- char_type* _M_buf;
138138-139139- /**
140140- * Actual size of internal buffer. This number is equal to the size
141141- * of the put area + 1 position, reserved for the overflow char of
142142- * a full area.
143143- */
144144- size_t _M_buf_size;
145145-146146- // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
147147- bool _M_buf_allocated;
148148-149149- /**
150150- * _M_reading == false && _M_writing == false for @b uncommitted mode;
151151- * _M_reading == true for @b read mode;
152152- * _M_writing == true for @b write mode;
153153- *
154154- * NB: _M_reading == true && _M_writing == true is unused.
155155- */
156156- bool _M_reading;
157157- bool _M_writing;
158158-159159- //@{
160160- /**
161161- * Necessary bits for putback buffer management.
162162- *
163163- * @note pbacks of over one character are not currently supported.
164164- */
165165- char_type _M_pback;
166166- char_type* _M_pback_cur_save;
167167- char_type* _M_pback_end_save;
168168- bool _M_pback_init;
169169- //@}
170170-171171- // Cached codecvt facet.
172172- const __codecvt_type* _M_codecvt;
173173-174174- /**
175175- * Buffer for external characters. Used for input when
176176- * codecvt::always_noconv() == false. When valid, this corresponds
177177- * to eback().
178178- */
179179- char* _M_ext_buf;
180180-181181- /**
182182- * Size of buffer held by _M_ext_buf.
183183- */
184184- streamsize _M_ext_buf_size;
185185-186186- /**
187187- * Pointers into the buffer held by _M_ext_buf that delimit a
188188- * subsequence of bytes that have been read but not yet converted.
189189- * When valid, _M_ext_next corresponds to egptr().
190190- */
191191- const char* _M_ext_next;
192192- char* _M_ext_end;
193193-194194- /**
195195- * Initializes pback buffers, and moves normal buffers to safety.
196196- * Assumptions:
197197- * _M_in_cur has already been moved back
198198- */
199199- void
200200- _M_create_pback()
201201- {
202202- if (!_M_pback_init)
203203- {
204204- _M_pback_cur_save = this->gptr();
205205- _M_pback_end_save = this->egptr();
206206- this->setg(&_M_pback, &_M_pback, &_M_pback + 1);
207207- _M_pback_init = true;
208208- }
209209- }
210210-211211- /**
212212- * Deactivates pback buffer contents, and restores normal buffer.
213213- * Assumptions:
214214- * The pback buffer has only moved forward.
215215- */
216216- void
217217- _M_destroy_pback() throw()
218218- {
219219- if (_M_pback_init)
220220- {
221221- // Length _M_in_cur moved in the pback buffer.
222222- _M_pback_cur_save += this->gptr() != this->eback();
223223- this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save);
224224- _M_pback_init = false;
225225- }
226226- }
227227-228228- public:
229229- // Constructors/destructor:
230230- /**
231231- * @brief Does not open any files.
232232- *
233233- * The default constructor initializes the parent class using its
234234- * own default ctor.
235235- */
236236- basic_filebuf();
237237-238238- /**
239239- * @brief The destructor closes the file first.
240240- */
241241- virtual
242242- ~basic_filebuf()
243243- { this->close(); }
244244-245245- // Members:
246246- /**
247247- * @brief Returns true if the external file is open.
248248- */
249249- bool
250250- is_open() const throw()
251251- { return _M_file.is_open(); }
252252-253253- /**
254254- * @brief Opens an external file.
255255- * @param s The name of the file.
256256- * @param mode The open mode flags.
257257- * @return @c this on success, NULL on failure
258258- *
259259- * If a file is already open, this function immediately fails.
260260- * Otherwise it tries to open the file named @a s using the flags
261261- * given in @a mode.
262262- *
263263- * Table 92, adapted here, gives the relation between openmode
264264- * combinations and the equivalent fopen() flags.
265265- * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app,
266266- * and binary|in|app per DR 596)
267267- * +---------------------------------------------------------+
268268- * | ios_base Flag combination stdio equivalent |
269269- * |binary in out trunc app |
270270- * +---------------------------------------------------------+
271271- * | + w |
272272- * | + + a |
273273- * | + a |
274274- * | + + w |
275275- * | + r |
276276- * | + + r+ |
277277- * | + + + w+ |
278278- * | + + + a+ |
279279- * | + + a+ |
280280- * +---------------------------------------------------------+
281281- * | + + wb |
282282- * | + + + ab |
283283- * | + + ab |
284284- * | + + + wb |
285285- * | + + rb |
286286- * | + + + r+b |
287287- * | + + + + w+b |
288288- * | + + + + a+b |
289289- * | + + + a+b |
290290- * +---------------------------------------------------------+
291291- */
292292- __filebuf_type*
293293- open(const char* __s, ios_base::openmode __mode);
294294-295295-#ifdef __GXX_EXPERIMENTAL_CXX0X__
296296- /**
297297- * @brief Opens an external file.
298298- * @param s The name of the file.
299299- * @param mode The open mode flags.
300300- * @return @c this on success, NULL on failure
301301- */
302302- __filebuf_type*
303303- open(const std::string& __s, ios_base::openmode __mode)
304304- { return open(__s.c_str(), __mode); }
305305-#endif
306306-307307- /**
308308- * @brief Closes the currently associated file.
309309- * @return @c this on success, NULL on failure
310310- *
311311- * If no file is currently open, this function immediately fails.
312312- *
313313- * If a <em>put buffer area</em> exists, @c overflow(eof) is
314314- * called to flush all the characters. The file is then
315315- * closed.
316316- *
317317- * If any operations fail, this function also fails.
318318- */
319319- __filebuf_type*
320320- close();
321321-322322- protected:
323323- void
324324- _M_allocate_internal_buffer();
325325-326326- void
327327- _M_destroy_internal_buffer() throw();
328328-329329- // [27.8.1.4] overridden virtual functions
330330- virtual streamsize
331331- showmanyc();
332332-333333- // Stroustrup, 1998, p. 628
334334- // underflow() and uflow() functions are called to get the next
335335- // character from the real input source when the buffer is empty.
336336- // Buffered input uses underflow()
337337-338338- virtual int_type
339339- underflow();
340340-341341- virtual int_type
342342- pbackfail(int_type __c = _Traits::eof());
343343-344344- // Stroustrup, 1998, p 648
345345- // The overflow() function is called to transfer characters to the
346346- // real output destination when the buffer is full. A call to
347347- // overflow(c) outputs the contents of the buffer plus the
348348- // character c.
349349- // 27.5.2.4.5
350350- // Consume some sequence of the characters in the pending sequence.
351351- virtual int_type
352352- overflow(int_type __c = _Traits::eof());
353353-354354- // Convert internal byte sequence to external, char-based
355355- // sequence via codecvt.
356356- bool
357357- _M_convert_to_external(char_type*, streamsize);
358358-359359- /**
360360- * @brief Manipulates the buffer.
361361- * @param s Pointer to a buffer area.
362362- * @param n Size of @a s.
363363- * @return @c this
364364- *
365365- * If no file has been opened, and both @a s and @a n are zero, then
366366- * the stream becomes unbuffered. Otherwise, @c s is used as a
367367- * buffer; see
368368- * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html
369369- * for more.
370370- */
371371- virtual __streambuf_type*
372372- setbuf(char_type* __s, streamsize __n);
373373-374374- virtual pos_type
375375- seekoff(off_type __off, ios_base::seekdir __way,
376376- ios_base::openmode __mode = ios_base::in | ios_base::out);
377377-378378- virtual pos_type
379379- seekpos(pos_type __pos,
380380- ios_base::openmode __mode = ios_base::in | ios_base::out);
381381-382382- // Common code for seekoff, seekpos, and overflow
383383- pos_type
384384- _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
385385-386386- int
387387- _M_get_ext_pos(__state_type &__state);
388388-389389- virtual int
390390- sync();
391391-392392- virtual void
393393- imbue(const locale& __loc);
394394-395395- virtual streamsize
396396- xsgetn(char_type* __s, streamsize __n);
397397-398398- virtual streamsize
399399- xsputn(const char_type* __s, streamsize __n);
400400-401401- // Flushes output buffer, then writes unshift sequence.
402402- bool
403403- _M_terminate_output();
404404-405405- /**
406406- * This function sets the pointers of the internal buffer, both get
407407- * and put areas. Typically:
408408- *
409409- * __off == egptr() - eback() upon underflow/uflow (@b read mode);
410410- * __off == 0 upon overflow (@b write mode);
411411- * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode).
412412- *
413413- * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size
414414- * reflects the actual allocated memory and the last cell is reserved
415415- * for the overflow char of a full put area.
416416- */
417417- void
418418- _M_set_buffer(streamsize __off)
419419- {
420420- const bool __testin = _M_mode & ios_base::in;
421421- const bool __testout = _M_mode & ios_base::out;
422422-423423- if (__testin && __off > 0)
424424- this->setg(_M_buf, _M_buf, _M_buf + __off);
425425- else
426426- this->setg(_M_buf, _M_buf, _M_buf);
427427-428428- if (__testout && __off == 0 && _M_buf_size > 1 )
429429- this->setp(_M_buf, _M_buf + _M_buf_size - 1);
430430- else
431431- this->setp(0, 0);
432432- }
433433- };
434434-435435- // [27.8.1.5] Template class basic_ifstream
436436- /**
437437- * @brief Controlling input for files.
438438- * @ingroup io
439439- *
440440- * This class supports reading from named files, using the inherited
441441- * functions from std::basic_istream. To control the associated
442442- * sequence, an instance of std::basic_filebuf is used, which this page
443443- * refers to as @c sb.
444444- */
445445- template<typename _CharT, typename _Traits>
446446- class basic_ifstream : public basic_istream<_CharT, _Traits>
447447- {
448448- public:
449449- // Types:
450450- typedef _CharT char_type;
451451- typedef _Traits traits_type;
452452- typedef typename traits_type::int_type int_type;
453453- typedef typename traits_type::pos_type pos_type;
454454- typedef typename traits_type::off_type off_type;
455455-456456- // Non-standard types:
457457- typedef basic_filebuf<char_type, traits_type> __filebuf_type;
458458- typedef basic_istream<char_type, traits_type> __istream_type;
459459-460460- private:
461461- __filebuf_type _M_filebuf;
462462-463463- public:
464464- // Constructors/Destructors:
465465- /**
466466- * @brief Default constructor.
467467- *
468468- * Initializes @c sb using its default constructor, and passes
469469- * @c &sb to the base class initializer. Does not open any files
470470- * (you haven't given it a filename to open).
471471- */
472472- basic_ifstream() : __istream_type(), _M_filebuf()
473473- { this->init(&_M_filebuf); }
474474-475475- /**
476476- * @brief Create an input file stream.
477477- * @param s Null terminated string specifying the filename.
478478- * @param mode Open file in specified mode (see std::ios_base).
479479- *
480480- * @c ios_base::in is automatically included in @a mode.
481481- *
482482- * Tip: When using std::string to hold the filename, you must use
483483- * .c_str() before passing it to this constructor.
484484- */
485485- explicit
486486- basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
487487- : __istream_type(), _M_filebuf()
488488- {
489489- this->init(&_M_filebuf);
490490- this->open(__s, __mode);
491491- }
492492-493493-#ifdef __GXX_EXPERIMENTAL_CXX0X__
494494- /**
495495- * @brief Create an input file stream.
496496- * @param s std::string specifying the filename.
497497- * @param mode Open file in specified mode (see std::ios_base).
498498- *
499499- * @c ios_base::in is automatically included in @a mode.
500500- */
501501- explicit
502502- basic_ifstream(const std::string& __s,
503503- ios_base::openmode __mode = ios_base::in)
504504- : __istream_type(), _M_filebuf()
505505- {
506506- this->init(&_M_filebuf);
507507- this->open(__s, __mode);
508508- }
509509-#endif
510510-511511- /**
512512- * @brief The destructor does nothing.
513513- *
514514- * The file is closed by the filebuf object, not the formatting
515515- * stream.
516516- */
517517- ~basic_ifstream()
518518- { }
519519-520520- // Members:
521521- /**
522522- * @brief Accessing the underlying buffer.
523523- * @return The current basic_filebuf buffer.
524524- *
525525- * This hides both signatures of std::basic_ios::rdbuf().
526526- */
527527- __filebuf_type*
528528- rdbuf() const
529529- { return const_cast<__filebuf_type*>(&_M_filebuf); }
530530-531531- /**
532532- * @brief Wrapper to test for an open file.
533533- * @return @c rdbuf()->is_open()
534534- */
535535- bool
536536- is_open()
537537- { return _M_filebuf.is_open(); }
538538-539539- // _GLIBCXX_RESOLVE_LIB_DEFECTS
540540- // 365. Lack of const-qualification in clause 27
541541- bool
542542- is_open() const
543543- { return _M_filebuf.is_open(); }
544544-545545- /**
546546- * @brief Opens an external file.
547547- * @param s The name of the file.
548548- * @param mode The open mode flags.
549549- *
550550- * Calls @c std::basic_filebuf::open(s,mode|in). If that function
551551- * fails, @c failbit is set in the stream's error state.
552552- *
553553- * Tip: When using std::string to hold the filename, you must use
554554- * .c_str() before passing it to this constructor.
555555- */
556556- void
557557- open(const char* __s, ios_base::openmode __mode = ios_base::in)
558558- {
559559- if (!_M_filebuf.open(__s, __mode | ios_base::in))
560560- this->setstate(ios_base::failbit);
561561- else
562562- // _GLIBCXX_RESOLVE_LIB_DEFECTS
563563- // 409. Closing an fstream should clear error state
564564- this->clear();
565565- }
566566-567567-#ifdef __GXX_EXPERIMENTAL_CXX0X__
568568- /**
569569- * @brief Opens an external file.
570570- * @param s The name of the file.
571571- * @param mode The open mode flags.
572572- *
573573- * Calls @c std::basic_filebuf::open(s,mode|in). If that function
574574- * fails, @c failbit is set in the stream's error state.
575575- */
576576- void
577577- open(const std::string& __s, ios_base::openmode __mode = ios_base::in)
578578- {
579579- if (!_M_filebuf.open(__s, __mode | ios_base::in))
580580- this->setstate(ios_base::failbit);
581581- else
582582- // _GLIBCXX_RESOLVE_LIB_DEFECTS
583583- // 409. Closing an fstream should clear error state
584584- this->clear();
585585- }
586586-#endif
587587-588588- /**
589589- * @brief Close the file.
590590- *
591591- * Calls @c std::basic_filebuf::close(). If that function
592592- * fails, @c failbit is set in the stream's error state.
593593- */
594594- void
595595- close()
596596- {
597597- if (!_M_filebuf.close())
598598- this->setstate(ios_base::failbit);
599599- }
600600- };
601601-602602-603603- // [27.8.1.8] Template class basic_ofstream
604604- /**
605605- * @brief Controlling output for files.
606606- * @ingroup io
607607- *
608608- * This class supports reading from named files, using the inherited
609609- * functions from std::basic_ostream. To control the associated
610610- * sequence, an instance of std::basic_filebuf is used, which this page
611611- * refers to as @c sb.
612612- */
613613- template<typename _CharT, typename _Traits>
614614- class basic_ofstream : public basic_ostream<_CharT,_Traits>
615615- {
616616- public:
617617- // Types:
618618- typedef _CharT char_type;
619619- typedef _Traits traits_type;
620620- typedef typename traits_type::int_type int_type;
621621- typedef typename traits_type::pos_type pos_type;
622622- typedef typename traits_type::off_type off_type;
623623-624624- // Non-standard types:
625625- typedef basic_filebuf<char_type, traits_type> __filebuf_type;
626626- typedef basic_ostream<char_type, traits_type> __ostream_type;
627627-628628- private:
629629- __filebuf_type _M_filebuf;
630630-631631- public:
632632- // Constructors:
633633- /**
634634- * @brief Default constructor.
635635- *
636636- * Initializes @c sb using its default constructor, and passes
637637- * @c &sb to the base class initializer. Does not open any files
638638- * (you haven't given it a filename to open).
639639- */
640640- basic_ofstream(): __ostream_type(), _M_filebuf()
641641- { this->init(&_M_filebuf); }
642642-643643- /**
644644- * @brief Create an output file stream.
645645- * @param s Null terminated string specifying the filename.
646646- * @param mode Open file in specified mode (see std::ios_base).
647647- *
648648- * @c ios_base::out|ios_base::trunc is automatically included in
649649- * @a mode.
650650- *
651651- * Tip: When using std::string to hold the filename, you must use
652652- * .c_str() before passing it to this constructor.
653653- */
654654- explicit
655655- basic_ofstream(const char* __s,
656656- ios_base::openmode __mode = ios_base::out|ios_base::trunc)
657657- : __ostream_type(), _M_filebuf()
658658- {
659659- this->init(&_M_filebuf);
660660- this->open(__s, __mode);
661661- }
662662-663663-#ifdef __GXX_EXPERIMENTAL_CXX0X__
664664- /**
665665- * @brief Create an output file stream.
666666- * @param s std::string specifying the filename.
667667- * @param mode Open file in specified mode (see std::ios_base).
668668- *
669669- * @c ios_base::out|ios_base::trunc is automatically included in
670670- * @a mode.
671671- */
672672- explicit
673673- basic_ofstream(const std::string& __s,
674674- ios_base::openmode __mode = ios_base::out|ios_base::trunc)
675675- : __ostream_type(), _M_filebuf()
676676- {
677677- this->init(&_M_filebuf);
678678- this->open(__s, __mode);
679679- }
680680-#endif
681681-682682- /**
683683- * @brief The destructor does nothing.
684684- *
685685- * The file is closed by the filebuf object, not the formatting
686686- * stream.
687687- */
688688- ~basic_ofstream()
689689- { }
690690-691691- // Members:
692692- /**
693693- * @brief Accessing the underlying buffer.
694694- * @return The current basic_filebuf buffer.
695695- *
696696- * This hides both signatures of std::basic_ios::rdbuf().
697697- */
698698- __filebuf_type*
699699- rdbuf() const
700700- { return const_cast<__filebuf_type*>(&_M_filebuf); }
701701-702702- /**
703703- * @brief Wrapper to test for an open file.
704704- * @return @c rdbuf()->is_open()
705705- */
706706- bool
707707- is_open()
708708- { return _M_filebuf.is_open(); }
709709-710710- // _GLIBCXX_RESOLVE_LIB_DEFECTS
711711- // 365. Lack of const-qualification in clause 27
712712- bool
713713- is_open() const
714714- { return _M_filebuf.is_open(); }
715715-716716- /**
717717- * @brief Opens an external file.
718718- * @param s The name of the file.
719719- * @param mode The open mode flags.
720720- *
721721- * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that
722722- * function fails, @c failbit is set in the stream's error state.
723723- *
724724- * Tip: When using std::string to hold the filename, you must use
725725- * .c_str() before passing it to this constructor.
726726- */
727727- void
728728- open(const char* __s,
729729- ios_base::openmode __mode = ios_base::out | ios_base::trunc)
730730- {
731731- if (!_M_filebuf.open(__s, __mode | ios_base::out))
732732- this->setstate(ios_base::failbit);
733733- else
734734- // _GLIBCXX_RESOLVE_LIB_DEFECTS
735735- // 409. Closing an fstream should clear error state
736736- this->clear();
737737- }
738738-739739-#ifdef __GXX_EXPERIMENTAL_CXX0X__
740740- /**
741741- * @brief Opens an external file.
742742- * @param s The name of the file.
743743- * @param mode The open mode flags.
744744- *
745745- * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that
746746- * function fails, @c failbit is set in the stream's error state.
747747- */
748748- void
749749- open(const std::string& __s,
750750- ios_base::openmode __mode = ios_base::out | ios_base::trunc)
751751- {
752752- if (!_M_filebuf.open(__s, __mode | ios_base::out))
753753- this->setstate(ios_base::failbit);
754754- else
755755- // _GLIBCXX_RESOLVE_LIB_DEFECTS
756756- // 409. Closing an fstream should clear error state
757757- this->clear();
758758- }
759759-#endif
760760-761761- /**
762762- * @brief Close the file.
763763- *
764764- * Calls @c std::basic_filebuf::close(). If that function
765765- * fails, @c failbit is set in the stream's error state.
766766- */
767767- void
768768- close()
769769- {
770770- if (!_M_filebuf.close())
771771- this->setstate(ios_base::failbit);
772772- }
773773- };
774774-775775-776776- // [27.8.1.11] Template class basic_fstream
777777- /**
778778- * @brief Controlling input and output for files.
779779- * @ingroup io
780780- *
781781- * This class supports reading from and writing to named files, using
782782- * the inherited functions from std::basic_iostream. To control the
783783- * associated sequence, an instance of std::basic_filebuf is used, which
784784- * this page refers to as @c sb.
785785- */
786786- template<typename _CharT, typename _Traits>
787787- class basic_fstream : public basic_iostream<_CharT, _Traits>
788788- {
789789- public:
790790- // Types:
791791- typedef _CharT char_type;
792792- typedef _Traits traits_type;
793793- typedef typename traits_type::int_type int_type;
794794- typedef typename traits_type::pos_type pos_type;
795795- typedef typename traits_type::off_type off_type;
796796-797797- // Non-standard types:
798798- typedef basic_filebuf<char_type, traits_type> __filebuf_type;
799799- typedef basic_ios<char_type, traits_type> __ios_type;
800800- typedef basic_iostream<char_type, traits_type> __iostream_type;
801801-802802- private:
803803- __filebuf_type _M_filebuf;
804804-805805- public:
806806- // Constructors/destructor:
807807- /**
808808- * @brief Default constructor.
809809- *
810810- * Initializes @c sb using its default constructor, and passes
811811- * @c &sb to the base class initializer. Does not open any files
812812- * (you haven't given it a filename to open).
813813- */
814814- basic_fstream()
815815- : __iostream_type(), _M_filebuf()
816816- { this->init(&_M_filebuf); }
817817-818818- /**
819819- * @brief Create an input/output file stream.
820820- * @param s Null terminated string specifying the filename.
821821- * @param mode Open file in specified mode (see std::ios_base).
822822- *
823823- * Tip: When using std::string to hold the filename, you must use
824824- * .c_str() before passing it to this constructor.
825825- */
826826- explicit
827827- basic_fstream(const char* __s,
828828- ios_base::openmode __mode = ios_base::in | ios_base::out)
829829- : __iostream_type(0), _M_filebuf()
830830- {
831831- this->init(&_M_filebuf);
832832- this->open(__s, __mode);
833833- }
834834-835835-#ifdef __GXX_EXPERIMENTAL_CXX0X__
836836- /**
837837- * @brief Create an input/output file stream.
838838- * @param s Null terminated string specifying the filename.
839839- * @param mode Open file in specified mode (see std::ios_base).
840840- */
841841- explicit
842842- basic_fstream(const std::string& __s,
843843- ios_base::openmode __mode = ios_base::in | ios_base::out)
844844- : __iostream_type(0), _M_filebuf()
845845- {
846846- this->init(&_M_filebuf);
847847- this->open(__s, __mode);
848848- }
849849-#endif
850850-851851- /**
852852- * @brief The destructor does nothing.
853853- *
854854- * The file is closed by the filebuf object, not the formatting
855855- * stream.
856856- */
857857- ~basic_fstream()
858858- { }
859859-860860- // Members:
861861- /**
862862- * @brief Accessing the underlying buffer.
863863- * @return The current basic_filebuf buffer.
864864- *
865865- * This hides both signatures of std::basic_ios::rdbuf().
866866- */
867867- __filebuf_type*
868868- rdbuf() const
869869- { return const_cast<__filebuf_type*>(&_M_filebuf); }
870870-871871- /**
872872- * @brief Wrapper to test for an open file.
873873- * @return @c rdbuf()->is_open()
874874- */
875875- bool
876876- is_open()
877877- { return _M_filebuf.is_open(); }
878878-879879- // _GLIBCXX_RESOLVE_LIB_DEFECTS
880880- // 365. Lack of const-qualification in clause 27
881881- bool
882882- is_open() const
883883- { return _M_filebuf.is_open(); }
884884-885885- /**
886886- * @brief Opens an external file.
887887- * @param s The name of the file.
888888- * @param mode The open mode flags.
889889- *
890890- * Calls @c std::basic_filebuf::open(s,mode). If that
891891- * function fails, @c failbit is set in the stream's error state.
892892- *
893893- * Tip: When using std::string to hold the filename, you must use
894894- * .c_str() before passing it to this constructor.
895895- */
896896- void
897897- open(const char* __s,
898898- ios_base::openmode __mode = ios_base::in | ios_base::out)
899899- {
900900- if (!_M_filebuf.open(__s, __mode))
901901- this->setstate(ios_base::failbit);
902902- else
903903- // _GLIBCXX_RESOLVE_LIB_DEFECTS
904904- // 409. Closing an fstream should clear error state
905905- this->clear();
906906- }
907907-908908-#ifdef __GXX_EXPERIMENTAL_CXX0X__
909909- /**
910910- * @brief Opens an external file.
911911- * @param s The name of the file.
912912- * @param mode The open mode flags.
913913- *
914914- * Calls @c std::basic_filebuf::open(s,mode). If that
915915- * function fails, @c failbit is set in the stream's error state.
916916- */
917917- void
918918- open(const std::string& __s,
919919- ios_base::openmode __mode = ios_base::in | ios_base::out)
920920- {
921921- if (!_M_filebuf.open(__s, __mode))
922922- this->setstate(ios_base::failbit);
923923- else
924924- // _GLIBCXX_RESOLVE_LIB_DEFECTS
925925- // 409. Closing an fstream should clear error state
926926- this->clear();
927927- }
928928-#endif
929929-930930- /**
931931- * @brief Close the file.
932932- *
933933- * Calls @c std::basic_filebuf::close(). If that function
934934- * fails, @c failbit is set in the stream's error state.
935935- */
936936- void
937937- close()
938938- {
939939- if (!_M_filebuf.close())
940940- this->setstate(ios_base::failbit);
941941- }
942942- };
943943-944944-_GLIBCXX_END_NAMESPACE_VERSION
945945-} // namespace
946946-947947-// Darling MODIFICATION
948948-#include "fstream.tcc"
949949-950950-#endif /* _GLIBCXX_FSTREAM */
-984
src/libstdc++darwin/fstream.tcc
···11-// File based streams -*- C++ -*-
22-33-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
44-// 2007, 2008, 2009, 2010, 2011
55-// Free Software Foundation, Inc.
66-//
77-// This file is part of the GNU ISO C++ Library. This library is free
88-// software; you can redistribute it and/or modify it under the
99-// terms of the GNU General Public License as published by the
1010-// Free Software Foundation; either version 3, or (at your option)
1111-// any later version.
1212-1313-// This library is distributed in the hope that it will be useful,
1414-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1515-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1616-// GNU General Public License for more details.
1717-1818-// Under Section 7 of GPL version 3, you are granted additional
1919-// permissions described in the GCC Runtime Library Exception, version
2020-// 3.1, as published by the Free Software Foundation.
2121-2222-// You should have received a copy of the GNU General Public License and
2323-// a copy of the GCC Runtime Library Exception along with this program;
2424-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2525-// <http://www.gnu.org/licenses/>.
2626-2727-/** @file bits/fstream.tcc
2828- * This is an internal header file, included by other library headers.
2929- * Do not attempt to use it directly. @headername{fstream}
3030- */
3131-3232-//
3333-// ISO C++ 14882: 27.8 File-based streams
3434-//
3535-3636-#ifndef _FSTREAM_TCC
3737-#define _FSTREAM_TCC 1
3838-3939-#pragma GCC system_header
4040-4141-#include <bits/cxxabi_forced.h>
4242-4343-namespace std _GLIBCXX_VISIBILITY(default)
4444-{
4545-_GLIBCXX_BEGIN_NAMESPACE_VERSION
4646-4747- template<typename _CharT, typename _Traits>
4848- void
4949- basic_filebuf<_CharT, _Traits>::
5050- _M_allocate_internal_buffer()
5151- {
5252- // Allocate internal buffer only if one doesn't already exist
5353- // (either allocated or provided by the user via setbuf).
5454- if (!_M_buf_allocated && !_M_buf)
5555- {
5656- _M_buf = new char_type[_M_buf_size];
5757- _M_buf_allocated = true;
5858- }
5959- }
6060-6161- template<typename _CharT, typename _Traits>
6262- void
6363- basic_filebuf<_CharT, _Traits>::
6464- _M_destroy_internal_buffer() throw()
6565- {
6666- if (_M_buf_allocated)
6767- {
6868- delete [] _M_buf;
6969- _M_buf = 0;
7070- _M_buf_allocated = false;
7171- }
7272- delete [] _M_ext_buf;
7373- _M_ext_buf = 0;
7474- _M_ext_buf_size = 0;
7575- _M_ext_next = 0;
7676- _M_ext_end = 0;
7777- }
7878-7979- template<typename _CharT, typename _Traits>
8080- basic_filebuf<_CharT, _Traits>::
8181- basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock),
8282- _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(),
8383- _M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ),
8484- _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(),
8585- _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false),
8686- _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0),
8787- _M_ext_end(0)
8888- {
8989- if (has_facet<__codecvt_type>(this->_M_buf_locale))
9090- _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale);
9191- }
9292-9393- template<typename _CharT, typename _Traits>
9494- typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
9595- basic_filebuf<_CharT, _Traits>::
9696- open(const char* __s, ios_base::openmode __mode)
9797- {
9898- __filebuf_type *__ret = 0;
9999- if (!this->is_open())
100100- {
101101- _M_file.open(__s, __mode);
102102- if (this->is_open())
103103- {
104104- _M_allocate_internal_buffer();
105105- _M_mode = __mode;
106106-107107- // Setup initial buffer to 'uncommitted' mode.
108108- _M_reading = false;
109109- _M_writing = false;
110110- _M_set_buffer(-1);
111111-112112- // Reset to initial state.
113113- _M_state_last = _M_state_cur = _M_state_beg;
114114-115115- // 27.8.1.3,4
116116- if ((__mode & ios_base::ate)
117117- && this->seekoff(0, ios_base::end, __mode)
118118- == pos_type(off_type(-1)))
119119- this->close();
120120- else
121121- __ret = this;
122122- }
123123- }
124124- return __ret;
125125- }
126126-127127- template<typename _CharT, typename _Traits>
128128- typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
129129- basic_filebuf<_CharT, _Traits>::
130130- close()
131131- {
132132- if (!this->is_open())
133133- return 0;
134134-135135- bool __testfail = false;
136136- {
137137- // NB: Do this here so that re-opened filebufs will be cool...
138138- struct __close_sentry
139139- {
140140- basic_filebuf *__fb;
141141- __close_sentry (basic_filebuf *__fbi): __fb(__fbi) { }
142142- ~__close_sentry ()
143143- {
144144- __fb->_M_mode = ios_base::openmode(0);
145145- __fb->_M_pback_init = false;
146146- __fb->_M_destroy_internal_buffer();
147147- __fb->_M_reading = false;
148148- __fb->_M_writing = false;
149149- __fb->_M_set_buffer(-1);
150150- __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg;
151151- }
152152- } __cs (this);
153153-154154- __try
155155- {
156156- if (!_M_terminate_output())
157157- __testfail = true;
158158- }
159159- __catch(__cxxabiv1::__forced_unwind&)
160160- {
161161- _M_file.close();
162162- __throw_exception_again;
163163- }
164164- __catch(...)
165165- { __testfail = true; }
166166- }
167167-168168- if (!_M_file.close())
169169- __testfail = true;
170170-171171- if (__testfail)
172172- return 0;
173173- else
174174- return this;
175175- }
176176-177177- template<typename _CharT, typename _Traits>
178178- streamsize
179179- basic_filebuf<_CharT, _Traits>::
180180- showmanyc()
181181- {
182182- streamsize __ret = -1;
183183- const bool __testin = _M_mode & ios_base::in;
184184- if (__testin && this->is_open())
185185- {
186186- // For a stateful encoding (-1) the pending sequence might be just
187187- // shift and unshift prefixes with no actual character.
188188- __ret = this->egptr() - this->gptr();
189189-190190-#if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
191191- // About this workaround, see libstdc++/20806.
192192- const bool __testbinary = _M_mode & ios_base::binary;
193193- if (__check_facet(_M_codecvt).encoding() >= 0
194194- && __testbinary)
195195-#else
196196- if (__check_facet(_M_codecvt).encoding() >= 0)
197197-#endif
198198- __ret += _M_file.showmanyc() / _M_codecvt->max_length();
199199- }
200200- return __ret;
201201- }
202202-203203- template<typename _CharT, typename _Traits>
204204- typename basic_filebuf<_CharT, _Traits>::int_type
205205- basic_filebuf<_CharT, _Traits>::
206206- underflow()
207207- {
208208- int_type __ret = traits_type::eof();
209209- const bool __testin = _M_mode & ios_base::in;
210210- if (__testin)
211211- {
212212- if (_M_writing)
213213- {
214214- if (overflow() == traits_type::eof())
215215- return __ret;
216216- _M_set_buffer(-1);
217217- _M_writing = false;
218218- }
219219- // Check for pback madness, and if so switch back to the
220220- // normal buffers and jet outta here before expensive
221221- // fileops happen...
222222- _M_destroy_pback();
223223-224224- if (this->gptr() < this->egptr())
225225- return traits_type::to_int_type(*this->gptr());
226226-227227- // Get and convert input sequence.
228228- const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
229229-230230- // Will be set to true if ::read() returns 0 indicating EOF.
231231- bool __got_eof = false;
232232- // Number of internal characters produced.
233233- streamsize __ilen = 0;
234234- codecvt_base::result __r = codecvt_base::ok;
235235- if (__check_facet(_M_codecvt).always_noconv())
236236- {
237237- __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
238238- __buflen);
239239- if (__ilen == 0)
240240- __got_eof = true;
241241- }
242242- else
243243- {
244244- // Worst-case number of external bytes.
245245- // XXX Not done encoding() == -1.
246246- const int __enc = _M_codecvt->encoding();
247247- streamsize __blen; // Minimum buffer size.
248248- streamsize __rlen; // Number of chars to read.
249249- if (__enc > 0)
250250- __blen = __rlen = __buflen * __enc;
251251- else
252252- {
253253- __blen = __buflen + _M_codecvt->max_length() - 1;
254254- __rlen = __buflen;
255255- }
256256- const streamsize __remainder = _M_ext_end - _M_ext_next;
257257- __rlen = __rlen > __remainder ? __rlen - __remainder : 0;
258258-259259- // An imbue in 'read' mode implies first converting the external
260260- // chars already present.
261261- if (_M_reading && this->egptr() == this->eback() && __remainder)
262262- __rlen = 0;
263263-264264- // Allocate buffer if necessary and move unconverted
265265- // bytes to front.
266266- if (_M_ext_buf_size < __blen)
267267- {
268268- char* __buf = new char[__blen];
269269- if (__remainder)
270270- __builtin_memcpy(__buf, _M_ext_next, __remainder);
271271-272272- delete [] _M_ext_buf;
273273- _M_ext_buf = __buf;
274274- _M_ext_buf_size = __blen;
275275- }
276276- else if (__remainder)
277277- __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
278278-279279- _M_ext_next = _M_ext_buf;
280280- _M_ext_end = _M_ext_buf + __remainder;
281281- _M_state_last = _M_state_cur;
282282-283283- do
284284- {
285285- if (__rlen > 0)
286286- {
287287- // Sanity check!
288288- // This may fail if the return value of
289289- // codecvt::max_length() is bogus.
290290- if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
291291- {
292292- __throw_ios_failure(__N("basic_filebuf::underflow "
293293- "codecvt::max_length() "
294294- "is not valid"));
295295- }
296296- streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
297297- if (__elen == 0)
298298- __got_eof = true;
299299- else if (__elen == -1)
300300- break;
301301- _M_ext_end += __elen;
302302- }
303303-304304- char_type* __iend = this->eback();
305305- if (_M_ext_next < _M_ext_end)
306306- __r = _M_codecvt->in(_M_state_cur, _M_ext_next,
307307- _M_ext_end, _M_ext_next,
308308- this->eback(),
309309- this->eback() + __buflen, __iend);
310310- if (__r == codecvt_base::noconv)
311311- {
312312- size_t __avail = _M_ext_end - _M_ext_buf;
313313- __ilen = std::min(__avail, __buflen);
314314- traits_type::copy(this->eback(),
315315- reinterpret_cast<char_type*>
316316- (_M_ext_buf), __ilen);
317317- _M_ext_next = _M_ext_buf + __ilen;
318318- }
319319- else
320320- __ilen = __iend - this->eback();
321321-322322- // _M_codecvt->in may return error while __ilen > 0: this is
323323- // ok, and actually occurs in case of mixed encodings (e.g.,
324324- // XML files).
325325- if (__r == codecvt_base::error)
326326- break;
327327-328328- __rlen = 1;
329329- }
330330- while (__ilen == 0 && !__got_eof);
331331- }
332332-333333- if (__ilen > 0)
334334- {
335335- _M_set_buffer(__ilen);
336336- _M_reading = true;
337337- __ret = traits_type::to_int_type(*this->gptr());
338338- }
339339- else if (__got_eof)
340340- {
341341- // If the actual end of file is reached, set 'uncommitted'
342342- // mode, thus allowing an immediate write without an
343343- // intervening seek.
344344- _M_set_buffer(-1);
345345- _M_reading = false;
346346- // However, reaching it while looping on partial means that
347347- // the file has got an incomplete character.
348348- if (__r == codecvt_base::partial)
349349- __throw_ios_failure(__N("basic_filebuf::underflow "
350350- "incomplete character in file"));
351351- }
352352- else if (__r == codecvt_base::error)
353353- __throw_ios_failure(__N("basic_filebuf::underflow "
354354- "invalid byte sequence in file"));
355355- else
356356- __throw_ios_failure(__N("basic_filebuf::underflow "
357357- "error reading the file"));
358358- }
359359- return __ret;
360360- }
361361-362362- template<typename _CharT, typename _Traits>
363363- typename basic_filebuf<_CharT, _Traits>::int_type
364364- basic_filebuf<_CharT, _Traits>::
365365- pbackfail(int_type __i)
366366- {
367367- int_type __ret = traits_type::eof();
368368- const bool __testin = _M_mode & ios_base::in;
369369- if (__testin)
370370- {
371371- if (_M_writing)
372372- {
373373- if (overflow() == traits_type::eof())
374374- return __ret;
375375- _M_set_buffer(-1);
376376- _M_writing = false;
377377- }
378378- // Remember whether the pback buffer is active, otherwise below
379379- // we may try to store in it a second char (libstdc++/9761).
380380- const bool __testpb = _M_pback_init;
381381- const bool __testeof = traits_type::eq_int_type(__i, __ret);
382382- int_type __tmp;
383383- if (this->eback() < this->gptr())
384384- {
385385- this->gbump(-1);
386386- __tmp = traits_type::to_int_type(*this->gptr());
387387- }
388388- else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1)))
389389- {
390390- __tmp = this->underflow();
391391- if (traits_type::eq_int_type(__tmp, __ret))
392392- return __ret;
393393- }
394394- else
395395- {
396396- // At the beginning of the buffer, need to make a
397397- // putback position available. But the seek may fail
398398- // (f.i., at the beginning of a file, see
399399- // libstdc++/9439) and in that case we return
400400- // traits_type::eof().
401401- return __ret;
402402- }
403403-404404- // Try to put back __i into input sequence in one of three ways.
405405- // Order these tests done in is unspecified by the standard.
406406- if (!__testeof && traits_type::eq_int_type(__i, __tmp))
407407- __ret = __i;
408408- else if (__testeof)
409409- __ret = traits_type::not_eof(__i);
410410- else if (!__testpb)
411411- {
412412- _M_create_pback();
413413- _M_reading = true;
414414- *this->gptr() = traits_type::to_char_type(__i);
415415- __ret = __i;
416416- }
417417- }
418418- return __ret;
419419- }
420420-421421- template<typename _CharT, typename _Traits>
422422- typename basic_filebuf<_CharT, _Traits>::int_type
423423- basic_filebuf<_CharT, _Traits>::
424424- overflow(int_type __c)
425425- {
426426- int_type __ret = traits_type::eof();
427427- const bool __testeof = traits_type::eq_int_type(__c, __ret);
428428- const bool __testout = _M_mode & ios_base::out;
429429- if (__testout)
430430- {
431431- if (_M_reading)
432432- {
433433- _M_destroy_pback();
434434- const int __gptr_off = _M_get_ext_pos(_M_state_last);
435435- if (_M_seek(__gptr_off, ios_base::cur, _M_state_last)
436436- == pos_type(off_type(-1)))
437437- return __ret;
438438- }
439439- if (this->pbase() < this->pptr())
440440- {
441441- // If appropriate, append the overflow char.
442442- if (!__testeof)
443443- {
444444- *this->pptr() = traits_type::to_char_type(__c);
445445- this->pbump(1);
446446- }
447447-448448- // Convert pending sequence to external representation,
449449- // and output.
450450- if (_M_convert_to_external(this->pbase(),
451451- this->pptr() - this->pbase()))
452452- {
453453- _M_set_buffer(0);
454454- __ret = traits_type::not_eof(__c);
455455- }
456456- }
457457- else if (_M_buf_size > 1)
458458- {
459459- // Overflow in 'uncommitted' mode: set _M_writing, set
460460- // the buffer to the initial 'write' mode, and put __c
461461- // into the buffer.
462462- _M_set_buffer(0);
463463- _M_writing = true;
464464- if (!__testeof)
465465- {
466466- *this->pptr() = traits_type::to_char_type(__c);
467467- this->pbump(1);
468468- }
469469- __ret = traits_type::not_eof(__c);
470470- }
471471- else
472472- {
473473- // Unbuffered.
474474- char_type __conv = traits_type::to_char_type(__c);
475475- if (__testeof || _M_convert_to_external(&__conv, 1))
476476- {
477477- _M_writing = true;
478478- __ret = traits_type::not_eof(__c);
479479- }
480480- }
481481- }
482482- return __ret;
483483- }
484484-485485- template<typename _CharT, typename _Traits>
486486- bool
487487- basic_filebuf<_CharT, _Traits>::
488488- _M_convert_to_external(_CharT* __ibuf, streamsize __ilen)
489489- {
490490- // Sizes of external and pending output.
491491- streamsize __elen;
492492- streamsize __plen;
493493- if (__check_facet(_M_codecvt).always_noconv())
494494- {
495495- __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
496496- __plen = __ilen;
497497- }
498498- else
499499- {
500500- // Worst-case number of external bytes needed.
501501- // XXX Not done encoding() == -1.
502502- streamsize __blen = __ilen * _M_codecvt->max_length();
503503- char* __buf = static_cast<char*>(__builtin_alloca(__blen));
504504-505505- char* __bend;
506506- const char_type* __iend;
507507- codecvt_base::result __r;
508508- __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
509509- __iend, __buf, __buf + __blen, __bend);
510510-511511- if (__r == codecvt_base::ok || __r == codecvt_base::partial)
512512- __blen = __bend - __buf;
513513- else if (__r == codecvt_base::noconv)
514514- {
515515- // Same as the always_noconv case above.
516516- __buf = reinterpret_cast<char*>(__ibuf);
517517- __blen = __ilen;
518518- }
519519- else
520520- __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
521521- "conversion error"));
522522-523523- __elen = _M_file.xsputn(__buf, __blen);
524524- __plen = __blen;
525525-526526- // Try once more for partial conversions.
527527- if (__r == codecvt_base::partial && __elen == __plen)
528528- {
529529- const char_type* __iresume = __iend;
530530- streamsize __rlen = this->pptr() - __iend;
531531- __r = _M_codecvt->out(_M_state_cur, __iresume,
532532- __iresume + __rlen, __iend, __buf,
533533- __buf + __blen, __bend);
534534- if (__r != codecvt_base::error)
535535- {
536536- __rlen = __bend - __buf;
537537- __elen = _M_file.xsputn(__buf, __rlen);
538538- __plen = __rlen;
539539- }
540540- else
541541- __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external "
542542- "conversion error"));
543543- }
544544- }
545545- return __elen == __plen;
546546- }
547547-548548- template<typename _CharT, typename _Traits>
549549- streamsize
550550- basic_filebuf<_CharT, _Traits>::
551551- xsgetn(_CharT* __s, streamsize __n)
552552- {
553553- // Clear out pback buffer before going on to the real deal...
554554- streamsize __ret = 0;
555555- if (_M_pback_init)
556556- {
557557- if (__n > 0 && this->gptr() == this->eback())
558558- {
559559- *__s++ = *this->gptr(); // emulate non-underflowing sbumpc
560560- this->gbump(1);
561561- __ret = 1;
562562- --__n;
563563- }
564564- _M_destroy_pback();
565565- }
566566- else if (_M_writing)
567567- {
568568- if (overflow() == traits_type::eof())
569569- return __ret;
570570- _M_set_buffer(-1);
571571- _M_writing = false;
572572- }
573573-574574- // Optimization in the always_noconv() case, to be generalized in the
575575- // future: when __n > __buflen we read directly instead of using the
576576- // buffer repeatedly.
577577- const bool __testin = _M_mode & ios_base::in;
578578- const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
579579-580580- if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
581581- && __testin)
582582- {
583583- // First, copy the chars already present in the buffer.
584584- const streamsize __avail = this->egptr() - this->gptr();
585585- if (__avail != 0)
586586- {
587587- traits_type::copy(__s, this->gptr(), __avail);
588588- __s += __avail;
589589- this->setg(this->eback(), this->gptr() + __avail,
590590- this->egptr());
591591- __ret += __avail;
592592- __n -= __avail;
593593- }
594594-595595- // Need to loop in case of short reads (relatively common
596596- // with pipes).
597597- streamsize __len;
598598- for (;;)
599599- {
600600- __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
601601- __n);
602602- if (__len == -1)
603603- __throw_ios_failure(__N("basic_filebuf::xsgetn "
604604- "error reading the file"));
605605- if (__len == 0)
606606- break;
607607-608608- __n -= __len;
609609- __ret += __len;
610610- if (__n == 0)
611611- break;
612612-613613- __s += __len;
614614- }
615615-616616- if (__n == 0)
617617- {
618618- _M_set_buffer(0);
619619- _M_reading = true;
620620- }
621621- else if (__len == 0)
622622- {
623623- // If end of file is reached, set 'uncommitted'
624624- // mode, thus allowing an immediate write without
625625- // an intervening seek.
626626- _M_set_buffer(-1);
627627- _M_reading = false;
628628- }
629629- }
630630- else
631631- __ret += __streambuf_type::xsgetn(__s, __n);
632632-633633- return __ret;
634634- }
635635-636636- template<typename _CharT, typename _Traits>
637637- streamsize
638638- basic_filebuf<_CharT, _Traits>::
639639- xsputn(const _CharT* __s, streamsize __n)
640640- {
641641- streamsize __ret = 0;
642642- // Optimization in the always_noconv() case, to be generalized in the
643643- // future: when __n is sufficiently large we write directly instead of
644644- // using the buffer.
645645- const bool __testout = _M_mode & ios_base::out;
646646- if (__check_facet(_M_codecvt).always_noconv()
647647- && __testout && !_M_reading)
648648- {
649649- // Measurement would reveal the best choice.
650650- const streamsize __chunk = 1ul << 10;
651651- streamsize __bufavail = this->epptr() - this->pptr();
652652-653653- // Don't mistake 'uncommitted' mode buffered with unbuffered.
654654- if (!_M_writing && _M_buf_size > 1)
655655- __bufavail = _M_buf_size - 1;
656656-657657- const streamsize __limit = std::min(__chunk, __bufavail);
658658- if (__n >= __limit)
659659- {
660660- const streamsize __buffill = this->pptr() - this->pbase();
661661- const char* __buf = reinterpret_cast<const char*>(this->pbase());
662662- __ret = _M_file.xsputn_2(__buf, __buffill,
663663- reinterpret_cast<const char*>(__s),
664664- __n);
665665- if (__ret == __buffill + __n)
666666- {
667667- _M_set_buffer(0);
668668- _M_writing = true;
669669- }
670670- if (__ret > __buffill)
671671- __ret -= __buffill;
672672- else
673673- __ret = 0;
674674- }
675675- else
676676- __ret = __streambuf_type::xsputn(__s, __n);
677677- }
678678- else
679679- __ret = __streambuf_type::xsputn(__s, __n);
680680- return __ret;
681681- }
682682-683683- template<typename _CharT, typename _Traits>
684684- typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
685685- basic_filebuf<_CharT, _Traits>::
686686- setbuf(char_type* __s, streamsize __n)
687687- {
688688- if (!this->is_open())
689689- {
690690- if (__s == 0 && __n == 0)
691691- _M_buf_size = 1;
692692- else if (__s && __n > 0)
693693- {
694694- // This is implementation-defined behavior, and assumes that
695695- // an external char_type array of length __n exists and has
696696- // been pre-allocated. If this is not the case, things will
697697- // quickly blow up. When __n > 1, __n - 1 positions will be
698698- // used for the get area, __n - 1 for the put area and 1
699699- // position to host the overflow char of a full put area.
700700- // When __n == 1, 1 position will be used for the get area
701701- // and 0 for the put area, as in the unbuffered case above.
702702- _M_buf = __s;
703703- _M_buf_size = __n;
704704- }
705705- }
706706- return this;
707707- }
708708-709709-710710- // According to 27.8.1.4 p11 - 13, seekoff should ignore the last
711711- // argument (of type openmode).
712712- template<typename _CharT, typename _Traits>
713713- typename basic_filebuf<_CharT, _Traits>::pos_type
714714- basic_filebuf<_CharT, _Traits>::
715715- seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
716716- {
717717- int __width = 0;
718718- if (_M_codecvt)
719719- __width = _M_codecvt->encoding();
720720- if (__width < 0)
721721- __width = 0;
722722-723723- pos_type __ret = pos_type(off_type(-1));
724724- const bool __testfail = __off != 0 && __width <= 0;
725725- if (this->is_open() && !__testfail)
726726- {
727727- // tellg and tellp queries do not affect any state, unless
728728- // ! always_noconv and the put sequence is not empty.
729729- // In that case, determining the position requires converting the
730730- // put sequence. That doesn't use ext_buf, so requires a flush.
731731- bool __no_movement = __way == ios_base::cur && __off == 0
732732- && (!_M_writing || _M_codecvt->always_noconv());
733733-734734- // Ditch any pback buffers to avoid confusion.
735735- if (!__no_movement)
736736- _M_destroy_pback();
737737-738738- // Correct state at destination. Note that this is the correct
739739- // state for the current position during output, because
740740- // codecvt::unshift() returns the state to the initial state.
741741- // This is also the correct state at the end of the file because
742742- // an unshift sequence should have been written at the end.
743743- __state_type __state = _M_state_beg;
744744- off_type __computed_off = __off * __width;
745745- if (_M_reading && __way == ios_base::cur)
746746- {
747747- __state = _M_state_last;
748748- __computed_off += _M_get_ext_pos(__state);
749749- }
750750- if (!__no_movement)
751751- __ret = _M_seek(__computed_off, __way, __state);
752752- else
753753- {
754754- if (_M_writing)
755755- __computed_off = this->pptr() - this->pbase();
756756-757757- off_type __file_off = _M_file.seekoff(0, ios_base::cur);
758758- if (__file_off != off_type(-1))
759759- {
760760- __ret = __file_off + __computed_off;
761761- __ret.state(__state);
762762- }
763763- }
764764- }
765765- return __ret;
766766- }
767767-768768- // _GLIBCXX_RESOLVE_LIB_DEFECTS
769769- // 171. Strange seekpos() semantics due to joint position
770770- // According to the resolution of DR 171, seekpos should ignore the last
771771- // argument (of type openmode).
772772- template<typename _CharT, typename _Traits>
773773- typename basic_filebuf<_CharT, _Traits>::pos_type
774774- basic_filebuf<_CharT, _Traits>::
775775- seekpos(pos_type __pos, ios_base::openmode)
776776- {
777777- pos_type __ret = pos_type(off_type(-1));
778778- if (this->is_open())
779779- {
780780- // Ditch any pback buffers to avoid confusion.
781781- _M_destroy_pback();
782782- __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state());
783783- }
784784- return __ret;
785785- }
786786-787787- template<typename _CharT, typename _Traits>
788788- typename basic_filebuf<_CharT, _Traits>::pos_type
789789- basic_filebuf<_CharT, _Traits>::
790790- _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
791791- {
792792- pos_type __ret = pos_type(off_type(-1));
793793- if (_M_terminate_output())
794794- {
795795- off_type __file_off = _M_file.seekoff(__off, __way);
796796- if (__file_off != off_type(-1))
797797- {
798798- _M_reading = false;
799799- _M_writing = false;
800800- _M_ext_next = _M_ext_end = _M_ext_buf;
801801- _M_set_buffer(-1);
802802- _M_state_cur = __state;
803803- __ret = __file_off;
804804- __ret.state(_M_state_cur);
805805- }
806806- }
807807- return __ret;
808808- }
809809-810810- // Returns the distance from the end of the ext buffer to the point
811811- // corresponding to gptr(). This is a negative value. Updates __state
812812- // from eback() correspondence to gptr().
813813- template<typename _CharT, typename _Traits>
814814- int basic_filebuf<_CharT, _Traits>::
815815- _M_get_ext_pos(__state_type& __state)
816816- {
817817- if (_M_codecvt->always_noconv())
818818- return this->gptr() - this->egptr();
819819- else
820820- {
821821- // Calculate offset from _M_ext_buf that corresponds to
822822- // gptr(). Precondition: __state == _M_state_last, which
823823- // corresponds to eback().
824824- const int __gptr_off =
825825- _M_codecvt->length(__state, _M_ext_buf, _M_ext_next,
826826- this->gptr() - this->eback());
827827- return _M_ext_buf + __gptr_off - _M_ext_end;
828828- }
829829- }
830830-831831- template<typename _CharT, typename _Traits>
832832- bool
833833- basic_filebuf<_CharT, _Traits>::
834834- _M_terminate_output()
835835- {
836836- // Part one: update the output sequence.
837837- bool __testvalid = true;
838838- if (this->pbase() < this->pptr())
839839- {
840840- const int_type __tmp = this->overflow();
841841- if (traits_type::eq_int_type(__tmp, traits_type::eof()))
842842- __testvalid = false;
843843- }
844844-845845- // Part two: output unshift sequence.
846846- if (_M_writing && !__check_facet(_M_codecvt).always_noconv()
847847- && __testvalid)
848848- {
849849- // Note: this value is arbitrary, since there is no way to
850850- // get the length of the unshift sequence from codecvt,
851851- // without calling unshift.
852852- const size_t __blen = 128;
853853- char __buf[__blen];
854854- codecvt_base::result __r;
855855- streamsize __ilen = 0;
856856-857857- do
858858- {
859859- char* __next;
860860- __r = _M_codecvt->unshift(_M_state_cur, __buf,
861861- __buf + __blen, __next);
862862- if (__r == codecvt_base::error)
863863- __testvalid = false;
864864- else if (__r == codecvt_base::ok ||
865865- __r == codecvt_base::partial)
866866- {
867867- __ilen = __next - __buf;
868868- if (__ilen > 0)
869869- {
870870- const streamsize __elen = _M_file.xsputn(__buf, __ilen);
871871- if (__elen != __ilen)
872872- __testvalid = false;
873873- }
874874- }
875875- }
876876- while (__r == codecvt_base::partial && __ilen > 0 && __testvalid);
877877-878878- if (__testvalid)
879879- {
880880- // This second call to overflow() is required by the standard,
881881- // but it's not clear why it's needed, since the output buffer
882882- // should be empty by this point (it should have been emptied
883883- // in the first call to overflow()).
884884- const int_type __tmp = this->overflow();
885885- if (traits_type::eq_int_type(__tmp, traits_type::eof()))
886886- __testvalid = false;
887887- }
888888- }
889889- return __testvalid;
890890- }
891891-892892- template<typename _CharT, typename _Traits>
893893- int
894894- basic_filebuf<_CharT, _Traits>::
895895- sync()
896896- {
897897- // Make sure that the internal buffer resyncs its idea of
898898- // the file position with the external file.
899899- int __ret = 0;
900900- if (this->pbase() < this->pptr())
901901- {
902902- const int_type __tmp = this->overflow();
903903- if (traits_type::eq_int_type(__tmp, traits_type::eof()))
904904- __ret = -1;
905905- }
906906- return __ret;
907907- }
908908-909909- template<typename _CharT, typename _Traits>
910910- void
911911- basic_filebuf<_CharT, _Traits>::
912912- imbue(const locale& __loc)
913913- {
914914- bool __testvalid = true;
915915-916916- const __codecvt_type* _M_codecvt_tmp = 0;
917917- if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
918918- _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc);
919919-920920- if (this->is_open())
921921- {
922922- // encoding() == -1 is ok only at the beginning.
923923- if ((_M_reading || _M_writing)
924924- && __check_facet(_M_codecvt).encoding() == -1)
925925- __testvalid = false;
926926- else
927927- {
928928- if (_M_reading)
929929- {
930930- if (__check_facet(_M_codecvt).always_noconv())
931931- {
932932- if (_M_codecvt_tmp
933933- && !__check_facet(_M_codecvt_tmp).always_noconv())
934934- __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
935935- != pos_type(off_type(-1));
936936- }
937937- else
938938- {
939939- // External position corresponding to gptr().
940940- _M_ext_next = _M_ext_buf
941941- + _M_codecvt->length(_M_state_last, _M_ext_buf,
942942- _M_ext_next,
943943- this->gptr() - this->eback());
944944- const streamsize __remainder = _M_ext_end - _M_ext_next;
945945- if (__remainder)
946946- __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
947947-948948- _M_ext_next = _M_ext_buf;
949949- _M_ext_end = _M_ext_buf + __remainder;
950950- _M_set_buffer(-1);
951951- _M_state_last = _M_state_cur = _M_state_beg;
952952- }
953953- }
954954- else if (_M_writing && (__testvalid = _M_terminate_output()))
955955- _M_set_buffer(-1);
956956- }
957957- }
958958-959959- if (__testvalid)
960960- _M_codecvt = _M_codecvt_tmp;
961961- else
962962- _M_codecvt = 0;
963963- }
964964-965965- // Inhibit implicit instantiations for required instantiations,
966966- // which are defined via explicit instantiations elsewhere.
967967-#if _GLIBCXX_EXTERN_TEMPLATE
968968- extern template class basic_filebuf<char>;
969969- extern template class basic_ifstream<char>;
970970- extern template class basic_ofstream<char>;
971971- extern template class basic_fstream<char>;
972972-973973-#ifdef _GLIBCXX_USE_WCHAR_T
974974- extern template class basic_filebuf<wchar_t>;
975975- extern template class basic_ifstream<wchar_t>;
976976- extern template class basic_ofstream<wchar_t>;
977977- extern template class basic_fstream<wchar_t>;
978978-#endif
979979-#endif
980980-981981-_GLIBCXX_END_NAMESPACE_VERSION
982982-} // namespace std
983983-984984-#endif