···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/cxx/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/cxx/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/cxx/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