···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 "fstream"
66+77+template class std::basic_filebuf<char, std::char_traits<char> >;
88+template class std::basic_streambuf<char, std::char_traits<char> >;
99+template class std::basic_ios<char, std::char_traits<char> >;
1010+template class std::basic_ostream<char, std::char_traits<char> >;
1111+
+951
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+#include <bits/basic_file.h> // For __basic_file, __c_lock
4545+#ifdef __GXX_EXPERIMENTAL_CXX0X__
4646+#include <string> // For std::string overloads.
4747+#endif
4848+4949+namespace std _GLIBCXX_VISIBILITY(default)
5050+{
5151+_GLIBCXX_BEGIN_NAMESPACE_VERSION
5252+5353+ // [27.8.1.1] template class basic_filebuf
5454+ /**
5555+ * @brief The actual work of input and output (for files).
5656+ * @ingroup io
5757+ *
5858+ * This class associates both its input and output sequence with an
5959+ * external disk file, and maintains a joint file position for both
6060+ * sequences. Many of its semantics are described in terms of similar
6161+ * behavior in the Standard C Library's @c FILE streams.
6262+ */
6363+ // Requirements on traits_type, specific to this class:
6464+ // traits_type::pos_type must be fpos<traits_type::state_type>
6565+ // traits_type::off_type must be streamoff
6666+ // traits_type::state_type must be Assignable and DefaultConstructible,
6767+ // and traits_type::state_type() must be the initial state for codecvt.
6868+ template<typename _CharT, typename _Traits>
6969+ class basic_filebuf : public basic_streambuf<_CharT, _Traits>
7070+ {
7171+ public:
7272+ // Types:
7373+ typedef _CharT char_type;
7474+ typedef _Traits traits_type;
7575+ typedef typename traits_type::int_type int_type;
7676+ typedef typename traits_type::pos_type pos_type;
7777+ typedef typename traits_type::off_type off_type;
7878+7979+ typedef basic_streambuf<char_type, traits_type> __streambuf_type;
8080+ typedef basic_filebuf<char_type, traits_type> __filebuf_type;
8181+ typedef __basic_file<char> __file_type;
8282+ typedef typename traits_type::state_type __state_type;
8383+ typedef codecvt<char_type, char, __state_type> __codecvt_type;
8484+8585+ friend class ios_base; // For sync_with_stdio.
8686+8787+ protected:
8888+ // Data Members:
8989+ // MT lock inherited from libio or other low-level io library.
9090+9191+ // Darling MODIFICATION
9292+ union
9393+ {
9494+ __c_lock _M_lock;
9595+ // 64 on 64-bit
9696+ // 44 on 32-bit
9797+ struct
9898+ {
9999+ char __align0[24];
100100+ long __align0x[5];
101101+ };
102102+ };
103103+104104+ // External buffer.
105105+ __file_type _M_file;
106106+107107+ /// Place to stash in || out || in | out settings for current filebuf.
108108+ ios_base::openmode _M_mode;
109109+110110+ // Beginning state type for codecvt.
111111+ // Darling MODIFICATION
112112+ union
113113+ {
114114+ __state_type _M_state_beg;
115115+ char __align1[128];
116116+ };
117117+118118+ // During output, the state that corresponds to pptr(),
119119+ // during input, the state that corresponds to egptr() and
120120+ // _M_ext_next.
121121+ // Darling MODIFICATION
122122+ union
123123+ {
124124+ __state_type _M_state_cur;
125125+ char __align2[128];
126126+ };
127127+128128+ // Not used for output. During input, the state that corresponds
129129+ // to eback() and _M_ext_buf.
130130+ // Darling MODIFICATION
131131+ union
132132+ {
133133+ __state_type _M_state_last;
134134+ char __align3[128];
135135+ };
136136+137137+ /// Pointer to the beginning of internal buffer.
138138+ char_type* _M_buf;
139139+140140+ /**
141141+ * Actual size of internal buffer. This number is equal to the size
142142+ * of the put area + 1 position, reserved for the overflow char of
143143+ * a full area.
144144+ */
145145+ size_t _M_buf_size;
146146+147147+ // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
148148+ bool _M_buf_allocated;
149149+150150+ /**
151151+ * _M_reading == false && _M_writing == false for @b uncommitted mode;
152152+ * _M_reading == true for @b read mode;
153153+ * _M_writing == true for @b write mode;
154154+ *
155155+ * NB: _M_reading == true && _M_writing == true is unused.
156156+ */
157157+ bool _M_reading;
158158+ bool _M_writing;
159159+160160+ //@{
161161+ /**
162162+ * Necessary bits for putback buffer management.
163163+ *
164164+ * @note pbacks of over one character are not currently supported.
165165+ */
166166+ char_type _M_pback;
167167+ char_type* _M_pback_cur_save;
168168+ char_type* _M_pback_end_save;
169169+ bool _M_pback_init;
170170+ //@}
171171+172172+ // Cached codecvt facet.
173173+ const __codecvt_type* _M_codecvt;
174174+175175+ /**
176176+ * Buffer for external characters. Used for input when
177177+ * codecvt::always_noconv() == false. When valid, this corresponds
178178+ * to eback().
179179+ */
180180+ char* _M_ext_buf;
181181+182182+ /**
183183+ * Size of buffer held by _M_ext_buf.
184184+ */
185185+ streamsize _M_ext_buf_size;
186186+187187+ /**
188188+ * Pointers into the buffer held by _M_ext_buf that delimit a
189189+ * subsequence of bytes that have been read but not yet converted.
190190+ * When valid, _M_ext_next corresponds to egptr().
191191+ */
192192+ const char* _M_ext_next;
193193+ char* _M_ext_end;
194194+195195+ /**
196196+ * Initializes pback buffers, and moves normal buffers to safety.
197197+ * Assumptions:
198198+ * _M_in_cur has already been moved back
199199+ */
200200+ void
201201+ _M_create_pback()
202202+ {
203203+ if (!_M_pback_init)
204204+ {
205205+ _M_pback_cur_save = this->gptr();
206206+ _M_pback_end_save = this->egptr();
207207+ this->setg(&_M_pback, &_M_pback, &_M_pback + 1);
208208+ _M_pback_init = true;
209209+ }
210210+ }
211211+212212+ /**
213213+ * Deactivates pback buffer contents, and restores normal buffer.
214214+ * Assumptions:
215215+ * The pback buffer has only moved forward.
216216+ */
217217+ void
218218+ _M_destroy_pback() throw()
219219+ {
220220+ if (_M_pback_init)
221221+ {
222222+ // Length _M_in_cur moved in the pback buffer.
223223+ _M_pback_cur_save += this->gptr() != this->eback();
224224+ this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save);
225225+ _M_pback_init = false;
226226+ }
227227+ }
228228+229229+ public:
230230+ // Constructors/destructor:
231231+ /**
232232+ * @brief Does not open any files.
233233+ *
234234+ * The default constructor initializes the parent class using its
235235+ * own default ctor.
236236+ */
237237+ basic_filebuf();
238238+239239+ /**
240240+ * @brief The destructor closes the file first.
241241+ */
242242+ virtual
243243+ ~basic_filebuf()
244244+ { this->close(); }
245245+246246+ // Members:
247247+ /**
248248+ * @brief Returns true if the external file is open.
249249+ */
250250+ bool
251251+ is_open() const throw()
252252+ { return _M_file.is_open(); }
253253+254254+ /**
255255+ * @brief Opens an external file.
256256+ * @param s The name of the file.
257257+ * @param mode The open mode flags.
258258+ * @return @c this on success, NULL on failure
259259+ *
260260+ * If a file is already open, this function immediately fails.
261261+ * Otherwise it tries to open the file named @a s using the flags
262262+ * given in @a mode.
263263+ *
264264+ * Table 92, adapted here, gives the relation between openmode
265265+ * combinations and the equivalent fopen() flags.
266266+ * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app,
267267+ * and binary|in|app per DR 596)
268268+ * +---------------------------------------------------------+
269269+ * | ios_base Flag combination stdio equivalent |
270270+ * |binary in out trunc app |
271271+ * +---------------------------------------------------------+
272272+ * | + w |
273273+ * | + + a |
274274+ * | + a |
275275+ * | + + w |
276276+ * | + r |
277277+ * | + + r+ |
278278+ * | + + + w+ |
279279+ * | + + + a+ |
280280+ * | + + a+ |
281281+ * +---------------------------------------------------------+
282282+ * | + + wb |
283283+ * | + + + ab |
284284+ * | + + ab |
285285+ * | + + + wb |
286286+ * | + + rb |
287287+ * | + + + r+b |
288288+ * | + + + + w+b |
289289+ * | + + + + a+b |
290290+ * | + + + a+b |
291291+ * +---------------------------------------------------------+
292292+ */
293293+ __filebuf_type*
294294+ open(const char* __s, ios_base::openmode __mode);
295295+296296+#ifdef __GXX_EXPERIMENTAL_CXX0X__
297297+ /**
298298+ * @brief Opens an external file.
299299+ * @param s The name of the file.
300300+ * @param mode The open mode flags.
301301+ * @return @c this on success, NULL on failure
302302+ */
303303+ __filebuf_type*
304304+ open(const std::string& __s, ios_base::openmode __mode)
305305+ { return open(__s.c_str(), __mode); }
306306+#endif
307307+308308+ /**
309309+ * @brief Closes the currently associated file.
310310+ * @return @c this on success, NULL on failure
311311+ *
312312+ * If no file is currently open, this function immediately fails.
313313+ *
314314+ * If a <em>put buffer area</em> exists, @c overflow(eof) is
315315+ * called to flush all the characters. The file is then
316316+ * closed.
317317+ *
318318+ * If any operations fail, this function also fails.
319319+ */
320320+ __filebuf_type*
321321+ close();
322322+323323+ protected:
324324+ void
325325+ _M_allocate_internal_buffer();
326326+327327+ void
328328+ _M_destroy_internal_buffer() throw();
329329+330330+ // [27.8.1.4] overridden virtual functions
331331+ virtual streamsize
332332+ showmanyc();
333333+334334+ // Stroustrup, 1998, p. 628
335335+ // underflow() and uflow() functions are called to get the next
336336+ // character from the real input source when the buffer is empty.
337337+ // Buffered input uses underflow()
338338+339339+ virtual int_type
340340+ underflow();
341341+342342+ virtual int_type
343343+ pbackfail(int_type __c = _Traits::eof());
344344+345345+ // Stroustrup, 1998, p 648
346346+ // The overflow() function is called to transfer characters to the
347347+ // real output destination when the buffer is full. A call to
348348+ // overflow(c) outputs the contents of the buffer plus the
349349+ // character c.
350350+ // 27.5.2.4.5
351351+ // Consume some sequence of the characters in the pending sequence.
352352+ virtual int_type
353353+ overflow(int_type __c = _Traits::eof());
354354+355355+ // Convert internal byte sequence to external, char-based
356356+ // sequence via codecvt.
357357+ bool
358358+ _M_convert_to_external(char_type*, streamsize);
359359+360360+ /**
361361+ * @brief Manipulates the buffer.
362362+ * @param s Pointer to a buffer area.
363363+ * @param n Size of @a s.
364364+ * @return @c this
365365+ *
366366+ * If no file has been opened, and both @a s and @a n are zero, then
367367+ * the stream becomes unbuffered. Otherwise, @c s is used as a
368368+ * buffer; see
369369+ * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html
370370+ * for more.
371371+ */
372372+ virtual __streambuf_type*
373373+ setbuf(char_type* __s, streamsize __n);
374374+375375+ virtual pos_type
376376+ seekoff(off_type __off, ios_base::seekdir __way,
377377+ ios_base::openmode __mode = ios_base::in | ios_base::out);
378378+379379+ virtual pos_type
380380+ seekpos(pos_type __pos,
381381+ ios_base::openmode __mode = ios_base::in | ios_base::out);
382382+383383+ // Common code for seekoff, seekpos, and overflow
384384+ pos_type
385385+ _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
386386+387387+ int
388388+ _M_get_ext_pos(__state_type &__state);
389389+390390+ virtual int
391391+ sync();
392392+393393+ virtual void
394394+ imbue(const locale& __loc);
395395+396396+ virtual streamsize
397397+ xsgetn(char_type* __s, streamsize __n);
398398+399399+ virtual streamsize
400400+ xsputn(const char_type* __s, streamsize __n);
401401+402402+ // Flushes output buffer, then writes unshift sequence.
403403+ bool
404404+ _M_terminate_output();
405405+406406+ /**
407407+ * This function sets the pointers of the internal buffer, both get
408408+ * and put areas. Typically:
409409+ *
410410+ * __off == egptr() - eback() upon underflow/uflow (@b read mode);
411411+ * __off == 0 upon overflow (@b write mode);
412412+ * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode).
413413+ *
414414+ * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size
415415+ * reflects the actual allocated memory and the last cell is reserved
416416+ * for the overflow char of a full put area.
417417+ */
418418+ void
419419+ _M_set_buffer(streamsize __off)
420420+ {
421421+ const bool __testin = _M_mode & ios_base::in;
422422+ const bool __testout = _M_mode & ios_base::out;
423423+424424+ if (__testin && __off > 0)
425425+ this->setg(_M_buf, _M_buf, _M_buf + __off);
426426+ else
427427+ this->setg(_M_buf, _M_buf, _M_buf);
428428+429429+ if (__testout && __off == 0 && _M_buf_size > 1 )
430430+ this->setp(_M_buf, _M_buf + _M_buf_size - 1);
431431+ else
432432+ this->setp(0, 0);
433433+ }
434434+ };
435435+436436+ // [27.8.1.5] Template class basic_ifstream
437437+ /**
438438+ * @brief Controlling input for files.
439439+ * @ingroup io
440440+ *
441441+ * This class supports reading from named files, using the inherited
442442+ * functions from std::basic_istream. To control the associated
443443+ * sequence, an instance of std::basic_filebuf is used, which this page
444444+ * refers to as @c sb.
445445+ */
446446+ template<typename _CharT, typename _Traits>
447447+ class basic_ifstream : public basic_istream<_CharT, _Traits>
448448+ {
449449+ public:
450450+ // Types:
451451+ typedef _CharT char_type;
452452+ typedef _Traits traits_type;
453453+ typedef typename traits_type::int_type int_type;
454454+ typedef typename traits_type::pos_type pos_type;
455455+ typedef typename traits_type::off_type off_type;
456456+457457+ // Non-standard types:
458458+ typedef basic_filebuf<char_type, traits_type> __filebuf_type;
459459+ typedef basic_istream<char_type, traits_type> __istream_type;
460460+461461+ private:
462462+ __filebuf_type _M_filebuf;
463463+464464+ public:
465465+ // Constructors/Destructors:
466466+ /**
467467+ * @brief Default constructor.
468468+ *
469469+ * Initializes @c sb using its default constructor, and passes
470470+ * @c &sb to the base class initializer. Does not open any files
471471+ * (you haven't given it a filename to open).
472472+ */
473473+ basic_ifstream() : __istream_type(), _M_filebuf()
474474+ { this->init(&_M_filebuf); }
475475+476476+ /**
477477+ * @brief Create an input file stream.
478478+ * @param s Null terminated string specifying the filename.
479479+ * @param mode Open file in specified mode (see std::ios_base).
480480+ *
481481+ * @c ios_base::in is automatically included in @a mode.
482482+ *
483483+ * Tip: When using std::string to hold the filename, you must use
484484+ * .c_str() before passing it to this constructor.
485485+ */
486486+ explicit
487487+ basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
488488+ : __istream_type(), _M_filebuf()
489489+ {
490490+ this->init(&_M_filebuf);
491491+ this->open(__s, __mode);
492492+ }
493493+494494+#ifdef __GXX_EXPERIMENTAL_CXX0X__
495495+ /**
496496+ * @brief Create an input file stream.
497497+ * @param s std::string specifying the filename.
498498+ * @param mode Open file in specified mode (see std::ios_base).
499499+ *
500500+ * @c ios_base::in is automatically included in @a mode.
501501+ */
502502+ explicit
503503+ basic_ifstream(const std::string& __s,
504504+ ios_base::openmode __mode = ios_base::in)
505505+ : __istream_type(), _M_filebuf()
506506+ {
507507+ this->init(&_M_filebuf);
508508+ this->open(__s, __mode);
509509+ }
510510+#endif
511511+512512+ /**
513513+ * @brief The destructor does nothing.
514514+ *
515515+ * The file is closed by the filebuf object, not the formatting
516516+ * stream.
517517+ */
518518+ ~basic_ifstream()
519519+ { }
520520+521521+ // Members:
522522+ /**
523523+ * @brief Accessing the underlying buffer.
524524+ * @return The current basic_filebuf buffer.
525525+ *
526526+ * This hides both signatures of std::basic_ios::rdbuf().
527527+ */
528528+ __filebuf_type*
529529+ rdbuf() const
530530+ { return const_cast<__filebuf_type*>(&_M_filebuf); }
531531+532532+ /**
533533+ * @brief Wrapper to test for an open file.
534534+ * @return @c rdbuf()->is_open()
535535+ */
536536+ bool
537537+ is_open()
538538+ { return _M_filebuf.is_open(); }
539539+540540+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
541541+ // 365. Lack of const-qualification in clause 27
542542+ bool
543543+ is_open() const
544544+ { return _M_filebuf.is_open(); }
545545+546546+ /**
547547+ * @brief Opens an external file.
548548+ * @param s The name of the file.
549549+ * @param mode The open mode flags.
550550+ *
551551+ * Calls @c std::basic_filebuf::open(s,mode|in). If that function
552552+ * fails, @c failbit is set in the stream's error state.
553553+ *
554554+ * Tip: When using std::string to hold the filename, you must use
555555+ * .c_str() before passing it to this constructor.
556556+ */
557557+ void
558558+ open(const char* __s, ios_base::openmode __mode = ios_base::in)
559559+ {
560560+ if (!_M_filebuf.open(__s, __mode | ios_base::in))
561561+ this->setstate(ios_base::failbit);
562562+ else
563563+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
564564+ // 409. Closing an fstream should clear error state
565565+ this->clear();
566566+ }
567567+568568+#ifdef __GXX_EXPERIMENTAL_CXX0X__
569569+ /**
570570+ * @brief Opens an external file.
571571+ * @param s The name of the file.
572572+ * @param mode The open mode flags.
573573+ *
574574+ * Calls @c std::basic_filebuf::open(s,mode|in). If that function
575575+ * fails, @c failbit is set in the stream's error state.
576576+ */
577577+ void
578578+ open(const std::string& __s, ios_base::openmode __mode = ios_base::in)
579579+ {
580580+ if (!_M_filebuf.open(__s, __mode | ios_base::in))
581581+ this->setstate(ios_base::failbit);
582582+ else
583583+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
584584+ // 409. Closing an fstream should clear error state
585585+ this->clear();
586586+ }
587587+#endif
588588+589589+ /**
590590+ * @brief Close the file.
591591+ *
592592+ * Calls @c std::basic_filebuf::close(). If that function
593593+ * fails, @c failbit is set in the stream's error state.
594594+ */
595595+ void
596596+ close()
597597+ {
598598+ if (!_M_filebuf.close())
599599+ this->setstate(ios_base::failbit);
600600+ }
601601+ };
602602+603603+604604+ // [27.8.1.8] Template class basic_ofstream
605605+ /**
606606+ * @brief Controlling output for files.
607607+ * @ingroup io
608608+ *
609609+ * This class supports reading from named files, using the inherited
610610+ * functions from std::basic_ostream. To control the associated
611611+ * sequence, an instance of std::basic_filebuf is used, which this page
612612+ * refers to as @c sb.
613613+ */
614614+ template<typename _CharT, typename _Traits>
615615+ class basic_ofstream : public basic_ostream<_CharT,_Traits>
616616+ {
617617+ public:
618618+ // Types:
619619+ typedef _CharT char_type;
620620+ typedef _Traits traits_type;
621621+ typedef typename traits_type::int_type int_type;
622622+ typedef typename traits_type::pos_type pos_type;
623623+ typedef typename traits_type::off_type off_type;
624624+625625+ // Non-standard types:
626626+ typedef basic_filebuf<char_type, traits_type> __filebuf_type;
627627+ typedef basic_ostream<char_type, traits_type> __ostream_type;
628628+629629+ private:
630630+ __filebuf_type _M_filebuf;
631631+632632+ public:
633633+ // Constructors:
634634+ /**
635635+ * @brief Default constructor.
636636+ *
637637+ * Initializes @c sb using its default constructor, and passes
638638+ * @c &sb to the base class initializer. Does not open any files
639639+ * (you haven't given it a filename to open).
640640+ */
641641+ basic_ofstream(): __ostream_type(), _M_filebuf()
642642+ { this->init(&_M_filebuf); }
643643+644644+ /**
645645+ * @brief Create an output file stream.
646646+ * @param s Null terminated string specifying the filename.
647647+ * @param mode Open file in specified mode (see std::ios_base).
648648+ *
649649+ * @c ios_base::out|ios_base::trunc is automatically included in
650650+ * @a mode.
651651+ *
652652+ * Tip: When using std::string to hold the filename, you must use
653653+ * .c_str() before passing it to this constructor.
654654+ */
655655+ explicit
656656+ basic_ofstream(const char* __s,
657657+ ios_base::openmode __mode = ios_base::out|ios_base::trunc)
658658+ : __ostream_type(), _M_filebuf()
659659+ {
660660+ this->init(&_M_filebuf);
661661+ this->open(__s, __mode);
662662+ }
663663+664664+#ifdef __GXX_EXPERIMENTAL_CXX0X__
665665+ /**
666666+ * @brief Create an output file stream.
667667+ * @param s std::string specifying the filename.
668668+ * @param mode Open file in specified mode (see std::ios_base).
669669+ *
670670+ * @c ios_base::out|ios_base::trunc is automatically included in
671671+ * @a mode.
672672+ */
673673+ explicit
674674+ basic_ofstream(const std::string& __s,
675675+ ios_base::openmode __mode = ios_base::out|ios_base::trunc)
676676+ : __ostream_type(), _M_filebuf()
677677+ {
678678+ this->init(&_M_filebuf);
679679+ this->open(__s, __mode);
680680+ }
681681+#endif
682682+683683+ /**
684684+ * @brief The destructor does nothing.
685685+ *
686686+ * The file is closed by the filebuf object, not the formatting
687687+ * stream.
688688+ */
689689+ ~basic_ofstream()
690690+ { }
691691+692692+ // Members:
693693+ /**
694694+ * @brief Accessing the underlying buffer.
695695+ * @return The current basic_filebuf buffer.
696696+ *
697697+ * This hides both signatures of std::basic_ios::rdbuf().
698698+ */
699699+ __filebuf_type*
700700+ rdbuf() const
701701+ { return const_cast<__filebuf_type*>(&_M_filebuf); }
702702+703703+ /**
704704+ * @brief Wrapper to test for an open file.
705705+ * @return @c rdbuf()->is_open()
706706+ */
707707+ bool
708708+ is_open()
709709+ { return _M_filebuf.is_open(); }
710710+711711+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
712712+ // 365. Lack of const-qualification in clause 27
713713+ bool
714714+ is_open() const
715715+ { return _M_filebuf.is_open(); }
716716+717717+ /**
718718+ * @brief Opens an external file.
719719+ * @param s The name of the file.
720720+ * @param mode The open mode flags.
721721+ *
722722+ * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that
723723+ * function fails, @c failbit is set in the stream's error state.
724724+ *
725725+ * Tip: When using std::string to hold the filename, you must use
726726+ * .c_str() before passing it to this constructor.
727727+ */
728728+ void
729729+ open(const char* __s,
730730+ ios_base::openmode __mode = ios_base::out | ios_base::trunc)
731731+ {
732732+ if (!_M_filebuf.open(__s, __mode | ios_base::out))
733733+ this->setstate(ios_base::failbit);
734734+ else
735735+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
736736+ // 409. Closing an fstream should clear error state
737737+ this->clear();
738738+ }
739739+740740+#ifdef __GXX_EXPERIMENTAL_CXX0X__
741741+ /**
742742+ * @brief Opens an external file.
743743+ * @param s The name of the file.
744744+ * @param mode The open mode flags.
745745+ *
746746+ * Calls @c std::basic_filebuf::open(s,mode|out|trunc). If that
747747+ * function fails, @c failbit is set in the stream's error state.
748748+ */
749749+ void
750750+ open(const std::string& __s,
751751+ ios_base::openmode __mode = ios_base::out | ios_base::trunc)
752752+ {
753753+ if (!_M_filebuf.open(__s, __mode | ios_base::out))
754754+ this->setstate(ios_base::failbit);
755755+ else
756756+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
757757+ // 409. Closing an fstream should clear error state
758758+ this->clear();
759759+ }
760760+#endif
761761+762762+ /**
763763+ * @brief Close the file.
764764+ *
765765+ * Calls @c std::basic_filebuf::close(). If that function
766766+ * fails, @c failbit is set in the stream's error state.
767767+ */
768768+ void
769769+ close()
770770+ {
771771+ if (!_M_filebuf.close())
772772+ this->setstate(ios_base::failbit);
773773+ }
774774+ };
775775+776776+777777+ // [27.8.1.11] Template class basic_fstream
778778+ /**
779779+ * @brief Controlling input and output for files.
780780+ * @ingroup io
781781+ *
782782+ * This class supports reading from and writing to named files, using
783783+ * the inherited functions from std::basic_iostream. To control the
784784+ * associated sequence, an instance of std::basic_filebuf is used, which
785785+ * this page refers to as @c sb.
786786+ */
787787+ template<typename _CharT, typename _Traits>
788788+ class basic_fstream : public basic_iostream<_CharT, _Traits>
789789+ {
790790+ public:
791791+ // Types:
792792+ typedef _CharT char_type;
793793+ typedef _Traits traits_type;
794794+ typedef typename traits_type::int_type int_type;
795795+ typedef typename traits_type::pos_type pos_type;
796796+ typedef typename traits_type::off_type off_type;
797797+798798+ // Non-standard types:
799799+ typedef basic_filebuf<char_type, traits_type> __filebuf_type;
800800+ typedef basic_ios<char_type, traits_type> __ios_type;
801801+ typedef basic_iostream<char_type, traits_type> __iostream_type;
802802+803803+ private:
804804+ __filebuf_type _M_filebuf;
805805+806806+ public:
807807+ // Constructors/destructor:
808808+ /**
809809+ * @brief Default constructor.
810810+ *
811811+ * Initializes @c sb using its default constructor, and passes
812812+ * @c &sb to the base class initializer. Does not open any files
813813+ * (you haven't given it a filename to open).
814814+ */
815815+ basic_fstream()
816816+ : __iostream_type(), _M_filebuf()
817817+ { this->init(&_M_filebuf); }
818818+819819+ /**
820820+ * @brief Create an input/output file stream.
821821+ * @param s Null terminated string specifying the filename.
822822+ * @param mode Open file in specified mode (see std::ios_base).
823823+ *
824824+ * Tip: When using std::string to hold the filename, you must use
825825+ * .c_str() before passing it to this constructor.
826826+ */
827827+ explicit
828828+ basic_fstream(const char* __s,
829829+ ios_base::openmode __mode = ios_base::in | ios_base::out)
830830+ : __iostream_type(0), _M_filebuf()
831831+ {
832832+ this->init(&_M_filebuf);
833833+ this->open(__s, __mode);
834834+ }
835835+836836+#ifdef __GXX_EXPERIMENTAL_CXX0X__
837837+ /**
838838+ * @brief Create an input/output file stream.
839839+ * @param s Null terminated string specifying the filename.
840840+ * @param mode Open file in specified mode (see std::ios_base).
841841+ */
842842+ explicit
843843+ basic_fstream(const std::string& __s,
844844+ ios_base::openmode __mode = ios_base::in | ios_base::out)
845845+ : __iostream_type(0), _M_filebuf()
846846+ {
847847+ this->init(&_M_filebuf);
848848+ this->open(__s, __mode);
849849+ }
850850+#endif
851851+852852+ /**
853853+ * @brief The destructor does nothing.
854854+ *
855855+ * The file is closed by the filebuf object, not the formatting
856856+ * stream.
857857+ */
858858+ ~basic_fstream()
859859+ { }
860860+861861+ // Members:
862862+ /**
863863+ * @brief Accessing the underlying buffer.
864864+ * @return The current basic_filebuf buffer.
865865+ *
866866+ * This hides both signatures of std::basic_ios::rdbuf().
867867+ */
868868+ __filebuf_type*
869869+ rdbuf() const
870870+ { return const_cast<__filebuf_type*>(&_M_filebuf); }
871871+872872+ /**
873873+ * @brief Wrapper to test for an open file.
874874+ * @return @c rdbuf()->is_open()
875875+ */
876876+ bool
877877+ is_open()
878878+ { return _M_filebuf.is_open(); }
879879+880880+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
881881+ // 365. Lack of const-qualification in clause 27
882882+ bool
883883+ is_open() const
884884+ { return _M_filebuf.is_open(); }
885885+886886+ /**
887887+ * @brief Opens an external file.
888888+ * @param s The name of the file.
889889+ * @param mode The open mode flags.
890890+ *
891891+ * Calls @c std::basic_filebuf::open(s,mode). If that
892892+ * function fails, @c failbit is set in the stream's error state.
893893+ *
894894+ * Tip: When using std::string to hold the filename, you must use
895895+ * .c_str() before passing it to this constructor.
896896+ */
897897+ void
898898+ open(const char* __s,
899899+ ios_base::openmode __mode = ios_base::in | ios_base::out)
900900+ {
901901+ if (!_M_filebuf.open(__s, __mode))
902902+ this->setstate(ios_base::failbit);
903903+ else
904904+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
905905+ // 409. Closing an fstream should clear error state
906906+ this->clear();
907907+ }
908908+909909+#ifdef __GXX_EXPERIMENTAL_CXX0X__
910910+ /**
911911+ * @brief Opens an external file.
912912+ * @param s The name of the file.
913913+ * @param mode The open mode flags.
914914+ *
915915+ * Calls @c std::basic_filebuf::open(s,mode). If that
916916+ * function fails, @c failbit is set in the stream's error state.
917917+ */
918918+ void
919919+ open(const std::string& __s,
920920+ ios_base::openmode __mode = ios_base::in | ios_base::out)
921921+ {
922922+ if (!_M_filebuf.open(__s, __mode))
923923+ this->setstate(ios_base::failbit);
924924+ else
925925+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
926926+ // 409. Closing an fstream should clear error state
927927+ this->clear();
928928+ }
929929+#endif
930930+931931+ /**
932932+ * @brief Close the file.
933933+ *
934934+ * Calls @c std::basic_filebuf::close(). If that function
935935+ * fails, @c failbit is set in the stream's error state.
936936+ */
937937+ void
938938+ close()
939939+ {
940940+ if (!_M_filebuf.close())
941941+ this->setstate(ios_base::failbit);
942942+ }
943943+ };
944944+945945+_GLIBCXX_END_NAMESPACE_VERSION
946946+} // namespace
947947+948948+// Darling MODIFICATION
949949+#include "fstream.tcc"
950950+951951+#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
+3
src/libstdc++darwin/genrenames.txt
···11+nm filebuf_abi_fix.o | grep basic_filebuf | grep -v Ev | cut -f 3 -d' ' | sed '/^$/d' > orignames.txt
22+( for line in $(cat orignames.txt ); do echo "$line __darwin_$line"; done ) > renames.list
33+( for line in $(cat orignames.txt ); do echo "$line = __darwin_$line;"; done ) > renames.cmd