genericopenlibs/cppstdlib/stl/stlport/stl/_fstream.h
changeset 31 ce057bb09d0b
child 45 4b03adbd26ca
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 /*
       
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     3  *
       
     4  * Copyright (c) 1999
       
     5  * Silicon Graphics Computer Systems, Inc.
       
     6  *
       
     7  * Copyright (c) 1999
       
     8  * Boris Fomitchev
       
     9  *
       
    10  * This material is provided "as is", with absolutely no warranty expressed
       
    11  * or implied. Any use is at your own risk.
       
    12  *
       
    13  * Permission to use or copy this software for any purpose is hereby granted
       
    14  * without fee, provided the above notices are retained on all copies.
       
    15  * Permission to modify the code and to distribute modified code is granted,
       
    16  * provided the above notices are retained, and a notice that the code was
       
    17  * modified is included with the above copyright notice.
       
    18  *
       
    19  */
       
    20 // This header defines classes basic_filebuf, basic_ifstream,
       
    21 // basic_ofstream, and basic_fstream.  These classes represent
       
    22 // streambufs and streams whose sources or destinations are files.
       
    23 
       
    24 #ifndef _STLP_INTERNAL_FSTREAM_H
       
    25 #define _STLP_INTERNAL_FSTREAM_H
       
    26 
       
    27 #if defined(__sgi) && !defined(__GNUC__) && !defined(_STANDARD_C_PLUS_PLUS)
       
    28 #  error This header file requires the -LANG:std option
       
    29 #endif
       
    30 
       
    31 #ifndef _STLP_INTERNAL_STREAMBUF
       
    32 #  include <stl/_streambuf.h>
       
    33 #endif
       
    34 
       
    35 #ifndef _STLP_INTERNAL_ISTREAM
       
    36 #  include <stl/_istream.h>
       
    37 #endif
       
    38 
       
    39 #ifndef _STLP_INTERNAL_CODECVT_H
       
    40 #  include <stl/_codecvt.h>
       
    41 #endif
       
    42 
       
    43 #if !defined (_STLP_USE_UNIX_IO) && !defined(_STLP_USE_WIN32_IO) && \
       
    44     !defined (_STLP_USE_UNIX_EMULATION_IO) && !defined (_STLP_USE_STDIO_IO)
       
    45 
       
    46 #  if defined (_STLP_UNIX)  || defined (__CYGWIN__) || defined (__amigaos__) || defined (__EMX__)
       
    47 // open/close/read/write
       
    48 #    define _STLP_USE_UNIX_IO
       
    49 #  elif defined (_STLP_WIN32) && !defined (__SYMBIAN32__)
       
    50 // CreateFile/ReadFile/WriteFile
       
    51 #    define _STLP_USE_WIN32_IO
       
    52 #  elif defined (_STLP_WIN16) || defined (_STLP_MAC)
       
    53 // _open/_read/_write
       
    54 #    define _STLP_USE_UNIX_EMULATION_IO
       
    55 #  else
       
    56 // fopen/fread/fwrite
       
    57 #    define _STLP_USE_STDIO_IO
       
    58 #  endif /* _STLP_UNIX */
       
    59 #endif /* mode selection */
       
    60 
       
    61 #if defined (_STLP_USE_WIN32_IO)
       
    62 typedef void* _STLP_fd;
       
    63 #elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO) || defined (_STLP_USE_UNIX_IO)
       
    64 typedef int _STLP_fd;
       
    65 #else
       
    66 #  error "Configure i/o !"
       
    67 #endif
       
    68 
       
    69 #if defined(__SYMBIAN32__WSD__)
       
    70 size_t& get_fstream_Filebuf_Base_GetPageSize();
       
    71 #define _M_page_size  get_fstream_Filebuf_Base_GetPageSize()
       
    72 #endif //__SYMBIAN32__WSD__
       
    73 
       
    74 _STLP_BEGIN_NAMESPACE
       
    75 
       
    76 //----------------------------------------------------------------------
       
    77 // Class _Filebuf_base, a private base class to factor out the system-
       
    78 // dependent code from basic_filebuf<>.
       
    79 
       
    80 class _STLP_CLASS_DECLSPEC _Filebuf_base {
       
    81 public:                      // Opening and closing files.
       
    82   _STLP_DECLSPEC _Filebuf_base();
       
    83 
       
    84   _STLP_DECLSPEC bool _M_open(const char*, ios_base::openmode, long __protection);
       
    85   _STLP_DECLSPEC bool _M_open(const char*, ios_base::openmode);
       
    86   _STLP_DECLSPEC bool _M_open(int __id, ios_base::openmode = ios_base::__default_mode);
       
    87 #if defined (_STLP_USE_WIN32_IO)
       
    88   bool _M_open(_STLP_fd __id, ios_base::openmode = ios_base::__default_mode);
       
    89 #endif /* _STLP_USE_WIN32_IO */
       
    90   _STLP_DECLSPEC bool _M_close();
       
    91 
       
    92 public:                      // Low-level I/O, like Unix read/write
       
    93   _STLP_DECLSPEC ptrdiff_t _M_read(char* __buf,  ptrdiff_t __n);
       
    94   _STLP_DECLSPEC streamoff _M_seek(streamoff __offset, ios_base::seekdir __dir);
       
    95   _STLP_DECLSPEC streamoff _M_file_size();
       
    96   _STLP_DECLSPEC bool _M_write(char* __buf,  ptrdiff_t __n);
       
    97 
       
    98 public:                      // Memory-mapped I/O.
       
    99   _STLP_DECLSPEC void* _M_mmap(streamoff __offset, streamoff __len);
       
   100   _STLP_DECLSPEC void _M_unmap(void* __mmap_base, streamoff __len);
       
   101 
       
   102 public:
       
   103   // Returns a value n such that, if pos is the file pointer at the
       
   104   // beginning of the range [first, last), pos + n is the file pointer at
       
   105   // the end.  On many operating systems n == __last - __first.
       
   106   // In Unix, writing n characters always bumps the file position by n.
       
   107   // In Windows text mode, however, it bumps the file position by n + m,
       
   108   // where m is the number of newlines in the range.  That's because an
       
   109   // internal \n corresponds to an external two-character sequence.
       
   110   streamoff _M_get_offset(char* __first, char* __last) {
       
   111 #if defined (_STLP_UNIX) || defined (_STLP_MAC)
       
   112     return __last - __first;
       
   113 #else // defined (_STLP_WIN32) || defined (_STLP_WIN16) || defined (_STLP_DOS) || defined(N_PLAT_NLM)
       
   114     return ( (_M_openmode & ios_base::binary) != 0 )
       
   115       ? (__last - __first)
       
   116       : count(__first, __last, '\n') + (__last - __first);
       
   117 #endif
       
   118   }
       
   119 
       
   120   // Returns true if we're in binary mode or if we're using an OS or file
       
   121   // system where there is no distinction between text and binary mode.
       
   122   bool _M_in_binary_mode() const {
       
   123 #if defined (_STLP_UNIX) || defined (_STLP_MAC)  || defined(__BEOS__) || defined (__amigaos__) || defined (__SYMBIAN32__)
       
   124     return true;
       
   125 #elif defined (_STLP_WIN32) || defined (_STLP_WIN16) || defined (_STLP_DOS) || defined (_STLP_VM) || defined (__EMX__) || defined(N_PLAT_NLM)
       
   126     return (_M_openmode & ios_base::binary) != 0;
       
   127 #else
       
   128 #  error "Port!"
       
   129 #endif
       
   130   }
       
   131 
       
   132   static void _S_initialize();
       
   133 
       
   134 protected:                      // Static data members.
       
   135 # if !defined(__SYMBIAN32__WSD__)
       
   136   static size_t _M_page_size;
       
   137 #endif //__SYMBIAN32__
       
   138 
       
   139 protected:                      // Data members.
       
   140   _STLP_fd _M_file_id;
       
   141 #if defined (_STLP_USE_STDIO_IO)
       
   142   // for stdio, the whole FILE* is being kept here
       
   143   FILE* _M_file;
       
   144 #endif
       
   145 #if defined (_STLP_USE_WIN32_IO)
       
   146   _STLP_fd _M_view_id;
       
   147 #endif
       
   148 
       
   149   ios_base::openmode _M_openmode     ;
       
   150   unsigned char      _M_is_open      ;
       
   151   unsigned char      _M_should_close ;
       
   152   unsigned char      _M_regular_file ;
       
   153 
       
   154 public :
       
   155 #if defined(__SYMBIAN32__) && defined (__EPOC32__)
       
   156   /* On Symbian,we can't make this inline.   It violates one address rule */ 	
       
   157   _STLP_DECLSPEC static size_t __page_size();
       
   158 #else
       
   159   static size_t  _STLP_CALL __page_size() { return _M_page_size; }
       
   160 #endif  
       
   161   int  __o_mode() const { return (int)_M_openmode; }
       
   162   bool __is_open()      const { return (_M_is_open !=0 ); }
       
   163   bool __should_close() const { return (_M_should_close != 0); }
       
   164   bool __regular_file() const { return (_M_regular_file != 0); }
       
   165   _STLP_fd __get_fd() const { return _M_file_id; }
       
   166 };
       
   167 
       
   168 //----------------------------------------------------------------------
       
   169 // Class basic_filebuf<>.
       
   170 
       
   171 // Forward declaration of two helper classes.
       
   172 template <class _Traits> class _Noconv_input;
       
   173 _STLP_TEMPLATE_NULL
       
   174 class _Noconv_input<char_traits<char> >;
       
   175 
       
   176 template <class _Traits> class _Noconv_output;
       
   177 _STLP_TEMPLATE_NULL
       
   178 class _Noconv_output< char_traits<char> >;
       
   179 
       
   180 // There is a specialized version of underflow, for basic_filebuf<char>,
       
   181 // in fstream.cxx.
       
   182 
       
   183 template <class _CharT, class _Traits>
       
   184 class _Underflow;
       
   185 
       
   186 _STLP_TEMPLATE_NULL class _Underflow< char, char_traits<char> >;
       
   187 
       
   188 // public:
       
   189 // helper class.
       
   190 template <class _CharT>
       
   191 struct _Filebuf_Tmp_Buf {
       
   192   _CharT* _M_ptr;
       
   193   _Filebuf_Tmp_Buf(ptrdiff_t __n) : _M_ptr(0) { _M_ptr = new _CharT[__n]; }
       
   194   ~_Filebuf_Tmp_Buf() { delete[] _M_ptr; }
       
   195 };
       
   196 
       
   197 template <class _CharT, class _Traits>
       
   198 class basic_filebuf : public basic_streambuf<_CharT, _Traits> {
       
   199 public:                         // Types.
       
   200   typedef _CharT                     char_type;
       
   201   typedef typename _Traits::int_type int_type;
       
   202   typedef typename _Traits::pos_type pos_type;
       
   203   typedef typename _Traits::off_type off_type;
       
   204   typedef _Traits                    traits_type;
       
   205 
       
   206   typedef typename _Traits::state_type _State_type;
       
   207   typedef basic_streambuf<_CharT, _Traits> _Base;
       
   208   typedef basic_filebuf<_CharT, _Traits> _Self;
       
   209 
       
   210 public:                         // Constructors, destructor.
       
   211   basic_filebuf();
       
   212   ~basic_filebuf()
       
   213   {
       
   214 	this->close();
       
   215 	_M_deallocate_buffers();
       
   216   }
       
   217 
       
   218 public:                         // Opening and closing files.
       
   219   bool is_open() const { return _M_base.__is_open(); }
       
   220 
       
   221   _Self* open(const char* __s, ios_base::openmode __m) {
       
   222     return _M_base._M_open(__s, __m) ? this : 0;
       
   223   }
       
   224 
       
   225 #if !defined (_STLP_NO_EXTENSIONS)
       
   226   // These two version of open() and file descriptor getter are extensions.
       
   227   _Self* open(const char* __s, ios_base::openmode __m,
       
   228               long __protection) {
       
   229     return _M_base._M_open(__s, __m, __protection) ? this : 0;
       
   230   }
       
   231 
       
   232   _STLP_fd fd() const { return _M_base.__get_fd(); }
       
   233 
       
   234   _Self* open(int __id, ios_base::openmode _Init_mode = ios_base::__default_mode) {
       
   235     return this->_M_open(__id, _Init_mode);
       
   236   }
       
   237 
       
   238 #  if defined (_STLP_USE_WIN32_IO)
       
   239   _Self* open(_STLP_fd __id, ios_base::openmode _Init_mode = ios_base::__default_mode) {
       
   240     return _M_base._M_open(__id, _Init_mode) ? this : 0;
       
   241   }
       
   242 #  endif /* _STLP_USE_WIN32_IO */
       
   243 
       
   244 #endif
       
   245 
       
   246   _Self* _M_open(int __id, ios_base::openmode _Init_mode = ios_base::__default_mode) {
       
   247     return _M_base._M_open(__id, _Init_mode) ? this : 0;
       
   248   }
       
   249 
       
   250   _Self* close();
       
   251 
       
   252 protected:         // Virtual functions from basic_streambuf.
       
   253   
       
   254   virtual streamsize showmanyc() {
       
   255 
       
   256       // Is there any possibility that reads can succeed?
       
   257       if (!this->is_open() || _M_in_output_mode || _M_in_error_mode)
       
   258         return -1;
       
   259       else if (_M_in_putback_mode)
       
   260         return this->egptr() - this->gptr();
       
   261       else if (_M_constant_width) {
       
   262         streamoff __pos  = _M_base._M_seek(0, ios_base::cur);
       
   263         streamoff __size = _M_base._M_file_size();
       
   264         return __pos >= 0 && __size > __pos ? __size - __pos : 0;
       
   265       }
       
   266       else
       
   267         return 0;
       
   268 
       
   269   }
       
   270   virtual int_type underflow() {
       
   271 
       
   272       return _Underflow<_CharT, _Traits>::_M_doit(this);
       
   273 
       
   274   }
       
   275 
       
   276   virtual int_type pbackfail(int_type __c= traits_type::eof()) {
       
   277 
       
   278       const int_type __eof = traits_type::eof();
       
   279 
       
   280       // If we aren't already in input mode, pushback is impossible.
       
   281       if (!_M_in_input_mode)
       
   282         return __eof;
       
   283 
       
   284       // We can use the ordinary get buffer if there's enough space, and
       
   285       // if it's a buffer that we're allowed to write to.
       
   286       if (this->gptr() != this->eback() &&
       
   287           (traits_type::eq_int_type(__c, __eof) ||
       
   288            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]) ||
       
   289            !_M_mmap_base)) {
       
   290         this->gbump(-1);
       
   291         if (traits_type::eq_int_type(__c, __eof) ||
       
   292             traits_type::eq(traits_type::to_char_type(__c), *this->gptr()))
       
   293           return traits_type::to_int_type(*this->gptr());
       
   294       }
       
   295       else if (!traits_type::eq_int_type(__c, __eof)) {
       
   296         // Are we in the putback buffer already?
       
   297         _CharT* __pback_end = _M_pback_buf + __STATIC_CAST(int,_S_pback_buf_size);
       
   298         if (_M_in_putback_mode) {
       
   299           // Do we have more room in the putback buffer?
       
   300           if (this->eback() != _M_pback_buf)
       
   301             this->setg(this->egptr() - 1, this->egptr() - 1, __pback_end);
       
   302           else
       
   303             return __eof;           // No more room in the buffer, so fail.
       
   304         }
       
   305         else {                      // We're not yet in the putback buffer.
       
   306           _M_saved_eback = this->eback();
       
   307           _M_saved_gptr  = this->gptr();
       
   308           _M_saved_egptr = this->egptr();
       
   309           this->setg(__pback_end - 1, __pback_end - 1, __pback_end);
       
   310           _M_in_putback_mode = true;
       
   311         }
       
   312       }
       
   313       else
       
   314         return __eof;
       
   315 
       
   316       // We have made a putback position available.  Assign to it, and return.
       
   317       *this->gptr() = traits_type::to_char_type(__c);
       
   318       return __c;
       
   319 
       
   320   }
       
   321   
       
   322   virtual int_type overflow(int_type __c) {
       
   323 
       
   324       // Switch to output mode, if necessary.
       
   325       if (!_M_in_output_mode)
       
   326         if (!_M_switch_to_output_mode())
       
   327           return traits_type::eof();
       
   328 
       
   329       _CharT* __ibegin = this->_M_int_buf;
       
   330       _CharT* __iend   = this->pptr();
       
   331       this->setp(_M_int_buf, _M_int_buf_EOS - 1);
       
   332 
       
   333       // Put __c at the end of the internal buffer.
       
   334       if (!traits_type::eq_int_type(__c, traits_type::eof()))
       
   335         *__iend++ = _Traits::to_char_type(__c);
       
   336 
       
   337       // For variable-width encodings, output may take more than one pass.
       
   338       while (__ibegin != __iend) {
       
   339         const _CharT* __inext = __ibegin;
       
   340         char* __enext         = _M_ext_buf;
       
   341         typename _Codecvt::result __status
       
   342           = _M_codecvt->out(_M_state, __ibegin, __iend, __inext,
       
   343                             _M_ext_buf, _M_ext_buf_EOS, __enext);
       
   344         if (__status == _Codecvt::noconv) {
       
   345           return _Noconv_output<_Traits>::_M_doit(this, __ibegin, __iend)
       
   346             ? traits_type::not_eof(__c)
       
   347             : _M_output_error();
       
   348         }
       
   349 
       
   350         // For a constant-width encoding we know that the external buffer
       
   351         // is large enough, so failure to consume the entire internal buffer
       
   352         // or to produce the correct number of external characters, is an error.
       
   353         // For a variable-width encoding, however, we require only that we
       
   354         // consume at least one internal character
       
   355         else if (__status != _Codecvt::error &&
       
   356                  (((__inext == __iend) &&
       
   357                    (__enext - _M_ext_buf == _M_width * (__iend - __ibegin))) ||
       
   358                   (!_M_constant_width && __inext != __ibegin))) {
       
   359             // We successfully converted part or all of the internal buffer.
       
   360           ptrdiff_t __n = __enext - _M_ext_buf;
       
   361           if (_M_write(_M_ext_buf, __n))
       
   362             __ibegin += __inext - __ibegin;
       
   363           else
       
   364             return _M_output_error();
       
   365         }
       
   366         else
       
   367           return _M_output_error();
       
   368       }
       
   369 
       
   370       return traits_type::not_eof(__c);
       
   371 
       
   372   }
       
   373 
       
   374   virtual basic_streambuf<_CharT, _Traits>* setbuf(_CharT* __buf, streamsize __n) {
       
   375 
       
   376       if (!_M_in_input_mode &&! _M_in_output_mode && !_M_in_error_mode &&
       
   377           _M_int_buf == 0) {
       
   378         if (__buf == 0 && __n == 0)
       
   379           _M_allocate_buffers(0, 1);
       
   380         else if (__buf != 0 && __n > 0)
       
   381           _M_allocate_buffers(__buf, __n);
       
   382       }
       
   383       return this;
       
   384 
       
   385   }
       
   386   
       
   387   virtual pos_type seekoff(off_type __off,
       
   388           ios_base::seekdir __whence,
       
   389           ios_base::openmode /* dummy */) {
       
   390 
       
   391       if (this->is_open() &&
       
   392           (__off == 0 || (_M_constant_width && this->_M_base._M_in_binary_mode()))) {
       
   393 
       
   394         if (!_M_seek_init(__off != 0 || __whence != ios_base::cur))
       
   395           return pos_type(-1);
       
   396 
       
   397         // Seek to beginning or end, regardless of whether we're in input mode.
       
   398         if (__whence == ios_base::beg || __whence == ios_base::end)
       
   399           return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence),
       
   400                                 _State_type());
       
   401 
       
   402         // Seek relative to current position. Complicated if we're in input mode.
       
   403         else if (__whence == ios_base::cur) {
       
   404           if (!_M_in_input_mode)
       
   405             return _M_seek_return(_M_base._M_seek(_M_width * __off, __whence),
       
   406                                   _State_type());
       
   407           else if (_M_mmap_base != 0) {
       
   408             // __off is relative to gptr().  We need to do a bit of arithmetic
       
   409             // to get an offset relative to the external file pointer.
       
   410             streamoff __adjust = _M_mmap_len - (this->gptr() - (_CharT*) _M_mmap_base);
       
   411 
       
   412             // if __off == 0, we do not need to exit input mode and to shift file pointer
       
   413             return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __adjust)
       
   414                               : _M_seek_return(_M_base._M_seek(__off - __adjust, ios_base::cur), _State_type());
       
   415           }
       
   416           else if (_M_constant_width) { // Get or set the position.
       
   417             streamoff __iadj = _M_width * (this->gptr() - this->eback());
       
   418 
       
   419             // Compensate for offset relative to gptr versus offset relative
       
   420             // to external pointer.  For a text-oriented stream, where the
       
   421             // compensation is more than just pointer arithmetic, we may get
       
   422             // but not set the current position.
       
   423 
       
   424             if (__iadj <= _M_ext_buf_end - _M_ext_buf) {
       
   425               streamoff __eadj =  _M_base._M_get_offset(_M_ext_buf + __STATIC_CAST(ptrdiff_t, __iadj), _M_ext_buf_end);
       
   426 
       
   427               return __off == 0 ? pos_type(_M_base._M_seek(0, ios_base::cur) - __eadj)
       
   428                                 : _M_seek_return(_M_base._M_seek(__off - __eadj, ios_base::cur), _State_type());
       
   429             }
       
   430           } else {                    // Get the position.  Encoding is var width.
       
   431             // Get position in internal buffer.
       
   432             ptrdiff_t __ipos = this->gptr() - this->eback();
       
   433 
       
   434             // Get corresponding position in external buffer.
       
   435             _State_type __state = _M_state;
       
   436             int __epos = _M_codecvt->length(__state, _M_ext_buf, _M_ext_buf_end,
       
   437                                             __ipos);
       
   438 
       
   439             if (__epos >= 0) {
       
   440               // Sanity check (expensive): make sure __epos is the right answer.
       
   441               _State_type __tmp_state = _M_state;
       
   442               _Filebuf_Tmp_Buf<_CharT> __buf(__ipos);
       
   443               _CharT* __ibegin = __buf._M_ptr; 
       
   444               _CharT* __inext  = __ibegin;
       
   445 
       
   446               const char* __dummy;
       
   447               typename _Codecvt::result __status
       
   448                 = _M_codecvt->in(__tmp_state,
       
   449                                  _M_ext_buf, _M_ext_buf + __epos, __dummy,
       
   450                                  __ibegin, __ibegin + __ipos, __inext);
       
   451               if (__status != _Codecvt::error &&
       
   452                   (__status == _Codecvt::noconv ||
       
   453                    (__inext == __ibegin + __ipos &&
       
   454                     equal(this->eback(), this->gptr(), __ibegin, _STLP_PRIV _Eq_traits<traits_type>())))) {
       
   455                 // Get the current position (at the end of the external buffer),
       
   456                 // then adjust it.  Again, it might be a text-oriented stream.
       
   457                 streamoff __cur = _M_base._M_seek(0, ios_base::cur);
       
   458                 streamoff __adj =
       
   459                   _M_base._M_get_offset(_M_ext_buf, _M_ext_buf + __epos) -
       
   460                   _M_base._M_get_offset(_M_ext_buf, _M_ext_buf_end);
       
   461                 if (__cur != -1 && __cur + __adj >= 0)
       
   462                   return __off == 0 ? pos_type(__cur + __adj)
       
   463                                     : _M_seek_return(__cur + __adj, __state);
       
   464                   //return _M_seek_return(__cur + __adj, __state);
       
   465               }
       
   466               // We failed the sanity check here.
       
   467             }
       
   468           }
       
   469         }
       
   470         // Unrecognized value for __whence here.
       
   471       }
       
   472 
       
   473       return pos_type(-1);
       
   474 
       
   475   }
       
   476   
       
   477   virtual pos_type seekpos(pos_type __pos,
       
   478           ios_base::openmode /* dummy */) {
       
   479 
       
   480       if (this->is_open()) {
       
   481         if (!_M_seek_init(true))
       
   482           return pos_type(-1);
       
   483 
       
   484         streamoff __off = off_type(__pos);
       
   485         if (__off != -1 && _M_base._M_seek(__off, ios_base::beg) != -1) {
       
   486           _M_state = __pos.state();
       
   487           return _M_seek_return(__off, __pos.state());
       
   488         }
       
   489       }
       
   490 
       
   491       return pos_type(-1);
       
   492 
       
   493   }
       
   494 
       
   495   virtual int sync() {
       
   496 
       
   497       if (_M_in_output_mode)
       
   498         return traits_type::eq_int_type(this->overflow(traits_type::eof()),
       
   499                                         traits_type::eof()) ? -1 : 0;
       
   500       return 0;
       
   501 
       
   502   }
       
   503   
       
   504   virtual void imbue(const locale& __loc) {
       
   505 
       
   506       if (!_M_in_input_mode && !_M_in_output_mode && !_M_in_error_mode) {
       
   507         this->_M_setup_codecvt(__loc);
       
   508       }
       
   509 
       
   510   }
       
   511   
       
   512   
       
   513 private:                        // Helper functions.
       
   514 
       
   515   // Precondition: we are currently in putback input mode.  Effect:
       
   516   // switches back to ordinary input mode.
       
   517   void _M_exit_putback_mode() {
       
   518     this->setg(_M_saved_eback, _M_saved_gptr, _M_saved_egptr);
       
   519     _M_in_putback_mode = false;
       
   520   }
       
   521   bool _M_switch_to_input_mode();
       
   522   void _M_exit_input_mode();
       
   523   bool _M_switch_to_output_mode();
       
   524 
       
   525   int_type _M_input_error();
       
   526   int_type _M_underflow_aux();
       
   527   //  friend class _Noconv_input<_Traits>;
       
   528   //  friend class _Noconv_output<_Traits>;
       
   529   friend class _Underflow<_CharT, _Traits>;
       
   530 
       
   531   int_type _M_output_error();
       
   532   bool _M_unshift();
       
   533 
       
   534   bool _M_allocate_buffers(_CharT* __buf, streamsize __n);
       
   535   bool _M_allocate_buffers();
       
   536   void _M_deallocate_buffers();
       
   537 
       
   538   pos_type _M_seek_return(off_type __off, _State_type __state) {
       
   539     if (__off != -1) {
       
   540       if (_M_in_input_mode)
       
   541         _M_exit_input_mode();
       
   542       _M_in_input_mode = false;
       
   543       _M_in_output_mode = false;
       
   544       _M_in_putback_mode = false;
       
   545       _M_in_error_mode = false;
       
   546       this->setg(0, 0, 0);
       
   547       this->setp(0, 0);
       
   548     }
       
   549 
       
   550     pos_type __result(__off);
       
   551     __result.state(__state);
       
   552     return __result;
       
   553   }
       
   554 
       
   555   bool _M_seek_init(bool __do_unshift);
       
   556 
       
   557   void _M_setup_codecvt(const locale&, bool __on_imbue = true);
       
   558 
       
   559 private:                        // Data members used in all modes.
       
   560 
       
   561   _Filebuf_base _M_base;
       
   562 
       
   563 private:                        // Locale-related information.
       
   564 
       
   565   unsigned char _M_constant_width;
       
   566   unsigned char _M_always_noconv;
       
   567 
       
   568   // private:                        // Mode flags.
       
   569   unsigned char _M_int_buf_dynamic;  // True if internal buffer is heap allocated,
       
   570   // false if it was supplied by the user.
       
   571   unsigned char _M_in_input_mode;
       
   572   unsigned char _M_in_output_mode;
       
   573   unsigned char _M_in_error_mode;
       
   574   unsigned char _M_in_putback_mode;
       
   575 
       
   576   // Internal buffer: characters seen by the filebuf's clients.
       
   577   _CharT* _M_int_buf;
       
   578   _CharT* _M_int_buf_EOS;
       
   579 
       
   580   // External buffer: characters corresponding to the external file.
       
   581   char* _M_ext_buf;
       
   582   char* _M_ext_buf_EOS;
       
   583 
       
   584   // The range [_M_ext_buf, _M_ext_buf_converted) contains the external
       
   585   // characters corresponding to the sequence in the internal buffer.  The
       
   586   // range [_M_ext_buf_converted, _M_ext_buf_end) contains characters that
       
   587   // have been read into the external buffer but have not been converted
       
   588   // to an internal sequence.
       
   589   char* _M_ext_buf_converted;
       
   590   char* _M_ext_buf_end;
       
   591 
       
   592   // State corresponding to beginning of internal buffer.
       
   593   _State_type _M_state;
       
   594 
       
   595 private:                        // Data members used only in input mode.
       
   596 
       
   597   // Similar to _M_state except that it corresponds to
       
   598   // the end of the internal buffer instead of the beginning.
       
   599   _State_type _M_end_state;
       
   600 
       
   601   // This is a null pointer unless we are in mmap input mode.
       
   602   void*     _M_mmap_base;
       
   603   streamoff _M_mmap_len;
       
   604 
       
   605 private:                        // Data members used only in putback mode.
       
   606   _CharT* _M_saved_eback;
       
   607   _CharT* _M_saved_gptr;
       
   608   _CharT* _M_saved_egptr;
       
   609 
       
   610   typedef codecvt<_CharT, char, _State_type> _Codecvt;
       
   611   const _Codecvt* _M_codecvt;
       
   612 
       
   613   int _M_width;                 // Width of the encoding (if constant), else 1
       
   614   int _M_max_width;             // Largest possible width of single character.
       
   615 
       
   616 
       
   617   enum { _S_pback_buf_size = 8 };
       
   618   _CharT _M_pback_buf[_S_pback_buf_size];
       
   619 
       
   620   // for _Noconv_output
       
   621 public:
       
   622   bool _M_write(char* __buf,  ptrdiff_t __n) {return _M_base._M_write(__buf, __n); }
       
   623 
       
   624 public:
       
   625   int_type
       
   626   _M_do_noconv_input() {
       
   627     _M_ext_buf_converted = _M_ext_buf_end;
       
   628     /* this-> */ _Base::setg((char_type*)_M_ext_buf, (char_type*)_M_ext_buf, (char_type*)_M_ext_buf_end);
       
   629     return traits_type::to_int_type(*_M_ext_buf);
       
   630   }
       
   631 };
       
   632 
       
   633 #if defined (_STLP_USE_TEMPLATE_EXPORT)
       
   634 _STLP_EXPORT_TEMPLATE_CLASS basic_filebuf<char, char_traits<char> >;
       
   635 #  if ! defined (_STLP_NO_WCHAR_T)
       
   636 _STLP_EXPORT_TEMPLATE_CLASS basic_filebuf<wchar_t, char_traits<wchar_t> >;
       
   637 #  endif
       
   638 #endif /* _STLP_USE_TEMPLATE_EXPORT */
       
   639 
       
   640 //
       
   641 // This class had to be designed very carefully to work
       
   642 // with Visual C++.
       
   643 //
       
   644 template <class _Traits>
       
   645 class _Noconv_output {
       
   646 public:
       
   647   typedef typename _Traits::char_type char_type;
       
   648   static bool  _STLP_CALL _M_doit(basic_filebuf<char_type, _Traits >*,
       
   649                                   char_type*, char_type*)
       
   650   { return false; }
       
   651 };
       
   652 
       
   653 _STLP_TEMPLATE_NULL
       
   654 class _STLP_CLASS_DECLSPEC _Noconv_output< char_traits<char> > {
       
   655 public:
       
   656   static bool  _STLP_CALL
       
   657   _M_doit(basic_filebuf<char, char_traits<char> >* __buf,
       
   658           char* __first, char* __last) {
       
   659     ptrdiff_t __n = __last - __first;
       
   660     return (__buf->_M_write(__first, __n));
       
   661   }
       
   662 };
       
   663 
       
   664 //----------------------------------------------------------------------
       
   665 // basic_filebuf<> helper functions.
       
   666 
       
   667 
       
   668 //----------------------------------------
       
   669 // Helper functions for switching between modes.
       
   670 
       
   671 //
       
   672 // This class had to be designed very carefully to work
       
   673 // with Visual C++.
       
   674 //
       
   675 template <class _Traits>
       
   676 class _Noconv_input {
       
   677 public:
       
   678   typedef typename _Traits::int_type int_type;
       
   679   typedef typename _Traits::char_type char_type;
       
   680 
       
   681   static inline int_type _STLP_CALL
       
   682   _M_doit(basic_filebuf<char_type, _Traits>*)
       
   683   { return _Traits::eof(); }
       
   684 };
       
   685 
       
   686 _STLP_TEMPLATE_NULL
       
   687 class _Noconv_input<char_traits<char> > {
       
   688 public:
       
   689   static inline int _STLP_CALL
       
   690   _M_doit(basic_filebuf<char, char_traits<char> >* __buf) {
       
   691     return __buf->_M_do_noconv_input();
       
   692   }
       
   693 };
       
   694 
       
   695 // underflow() may be called for one of two reasons.  (1) We've
       
   696 // been going through the special putback buffer, and we need to move back
       
   697 // to the regular internal buffer.  (2) We've exhausted the internal buffer,
       
   698 // and we need to replentish it.
       
   699 template <class _CharT, class _Traits>
       
   700 class _Underflow {
       
   701 public:
       
   702   typedef typename _Traits::int_type int_type;
       
   703   typedef _Traits                    traits_type;
       
   704 
       
   705   static int_type _STLP_CALL _M_doit(basic_filebuf<_CharT, _Traits>* __this);
       
   706 };
       
   707 
       
   708 
       
   709 // Specialization of underflow: if the character type is char, maybe
       
   710 // we can use mmap instead of read.
       
   711 _STLP_TEMPLATE_NULL
       
   712 class _STLP_CLASS_DECLSPEC _Underflow< char, char_traits<char> > {
       
   713 public:
       
   714   typedef char_traits<char>::int_type int_type;
       
   715   typedef char_traits<char> traits_type;
       
   716   _STLP_DECLSPEC static  int _STLP_CALL _M_doit(basic_filebuf<char, traits_type >* __this);
       
   717 };
       
   718 
       
   719 // There is a specialized version of underflow, for basic_filebuf<char>,
       
   720 // in fstream.cxx.
       
   721 
       
   722 template <class _CharT, class _Traits>
       
   723 _STLP_TYPENAME_ON_RETURN_TYPE _Underflow<_CharT, _Traits>::int_type // _STLP_CALL
       
   724  _Underflow<_CharT, _Traits>::_M_doit(basic_filebuf<_CharT, _Traits>* __this) {
       
   725   if (!__this->_M_in_input_mode) {
       
   726     if (!__this->_M_switch_to_input_mode())
       
   727       return traits_type::eof();
       
   728   }
       
   729   else if (__this->_M_in_putback_mode) {
       
   730     __this->_M_exit_putback_mode();
       
   731     if (__this->gptr() != __this->egptr()) {
       
   732       int_type __c = traits_type::to_int_type(*__this->gptr());
       
   733       return __c;
       
   734     }
       
   735   }
       
   736 
       
   737   return __this->_M_underflow_aux();
       
   738 }
       
   739 
       
   740 #if defined (_STLP_USE_TEMPLATE_EXPORT) && !defined (_STLP_NO_WCHAR_T)
       
   741 _STLP_EXPORT_TEMPLATE_CLASS _Underflow<wchar_t, char_traits<wchar_t> >;
       
   742 #endif
       
   743 
       
   744 //----------------------------------------------------------------------
       
   745 // Class basic_ifstream<>
       
   746 
       
   747 template <class _CharT, class _Traits>
       
   748 class basic_ifstream : public basic_istream<_CharT, _Traits> {
       
   749 public:                         // Types
       
   750   typedef _CharT                     char_type;
       
   751   typedef typename _Traits::int_type int_type;
       
   752   typedef typename _Traits::pos_type pos_type;
       
   753   typedef typename _Traits::off_type off_type;
       
   754   typedef _Traits                    traits_type;
       
   755 
       
   756   typedef basic_ios<_CharT, _Traits>                _Basic_ios;
       
   757   typedef basic_istream<_CharT, _Traits>            _Base;
       
   758   typedef basic_filebuf<_CharT, _Traits>            _Buf;
       
   759 
       
   760 public:                         // Constructors, destructor.
       
   761 
       
   762   basic_ifstream() :
       
   763     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
       
   764       this->init(&_M_buf);
       
   765   }
       
   766 
       
   767   explicit basic_ifstream(const char* __s, ios_base::openmode __mod = ios_base::in) :
       
   768     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0),
       
   769     _M_buf() {
       
   770       this->init(&_M_buf);
       
   771       if (!_M_buf.open(__s, __mod | ios_base::in))
       
   772         this->setstate(ios_base::failbit);
       
   773   }
       
   774 
       
   775 #if !defined (_STLP_NO_EXTENSIONS)
       
   776   explicit basic_ifstream(int __id, ios_base::openmode __mod = ios_base::in) :
       
   777     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
       
   778     this->init(&_M_buf);
       
   779     if (!_M_buf.open(__id, __mod | ios_base::in))
       
   780       this->setstate(ios_base::failbit);
       
   781   }
       
   782   basic_ifstream(const char* __s, ios_base::openmode __m,
       
   783      long __protection) :
       
   784     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
       
   785     this->init(&_M_buf);
       
   786     if (!_M_buf.open(__s, __m | ios_base::in, __protection))
       
   787       this->setstate(ios_base::failbit);
       
   788   }
       
   789 
       
   790 #  if defined (_STLP_USE_WIN32_IO)
       
   791   explicit basic_ifstream(_STLP_fd __id, ios_base::openmode __mod = ios_base::in) :
       
   792     basic_ios<_CharT, _Traits>(),  basic_istream<_CharT, _Traits>(0), _M_buf() {
       
   793     this->init(&_M_buf);
       
   794     if (!_M_buf.open(__id, __mod | ios_base::in))
       
   795       this->setstate(ios_base::failbit);
       
   796   }
       
   797 #  endif /* _STLP_USE_WIN32_IO */
       
   798 #endif
       
   799 
       
   800   ~basic_ifstream() {}
       
   801 
       
   802 public:                         // File and buffer operations.
       
   803   basic_filebuf<_CharT, _Traits>* rdbuf() const
       
   804     { return __CONST_CAST(_Buf*,&_M_buf); }
       
   805 
       
   806   bool is_open() {
       
   807     return this->rdbuf()->is_open();
       
   808   }
       
   809 
       
   810   void open(const char* __s, ios_base::openmode __mod = ios_base::in) {
       
   811     if (!this->rdbuf()->open(__s, __mod | ios_base::in))
       
   812       this->setstate(ios_base::failbit);
       
   813   }
       
   814 
       
   815   void close() {
       
   816     if (!this->rdbuf()->close())
       
   817       this->setstate(ios_base::failbit);
       
   818   }
       
   819 
       
   820 private:
       
   821   basic_filebuf<_CharT, _Traits> _M_buf;
       
   822 };
       
   823 
       
   824 
       
   825 //----------------------------------------------------------------------
       
   826 // Class basic_ofstream<>
       
   827 
       
   828 template <class _CharT, class _Traits>
       
   829 class basic_ofstream : public basic_ostream<_CharT, _Traits> {
       
   830 public:                         // Types
       
   831   typedef _CharT                     char_type;
       
   832   typedef typename _Traits::int_type int_type;
       
   833   typedef typename _Traits::pos_type pos_type;
       
   834   typedef typename _Traits::off_type off_type;
       
   835   typedef _Traits                    traits_type;
       
   836 
       
   837   typedef basic_ios<_CharT, _Traits>                _Basic_ios;
       
   838   typedef basic_ostream<_CharT, _Traits>            _Base;
       
   839   typedef basic_filebuf<_CharT, _Traits>            _Buf;
       
   840 
       
   841 public:                         // Constructors, destructor.
       
   842   basic_ofstream() :
       
   843     basic_ios<_CharT, _Traits>(),
       
   844     basic_ostream<_CharT, _Traits>(0), _M_buf() {
       
   845       this->init(&_M_buf);
       
   846   }
       
   847   explicit basic_ofstream(const char* __s, ios_base::openmode __mod = ios_base::out)
       
   848     : basic_ios<_CharT, _Traits>(), basic_ostream<_CharT, _Traits>(0), _M_buf() {
       
   849     this->init(&_M_buf);
       
   850     if (!_M_buf.open(__s, __mod | ios_base::out))
       
   851       this->setstate(ios_base::failbit);
       
   852   }
       
   853 
       
   854 #if !defined (_STLP_NO_EXTENSIONS)
       
   855   explicit basic_ofstream(int __id, ios_base::openmode __mod = ios_base::out)
       
   856     : basic_ios<_CharT, _Traits>(), basic_ostream<_CharT, _Traits>(0),
       
   857     _M_buf() {
       
   858    this->init(&_M_buf);
       
   859    if (!_M_buf.open(__id, __mod | ios_base::out))
       
   860      this->setstate(ios_base::failbit);
       
   861   }
       
   862   basic_ofstream(const char* __s, ios_base::openmode __m, long __protection) :
       
   863     basic_ios<_CharT, _Traits>(),  basic_ostream<_CharT, _Traits>(0), _M_buf() {
       
   864     this->init(&_M_buf);
       
   865     if (!_M_buf.open(__s, __m | ios_base::out, __protection))
       
   866       this->setstate(ios_base::failbit);
       
   867   }
       
   868 #  if defined (_STLP_USE_WIN32_IO)
       
   869   explicit basic_ofstream(_STLP_fd __id, ios_base::openmode __mod = ios_base::out)
       
   870     : basic_ios<_CharT, _Traits>(), basic_ostream<_CharT, _Traits>(0),
       
   871     _M_buf() {
       
   872    this->init(&_M_buf);
       
   873    if (!_M_buf.open(__id, __mod | ios_base::out))
       
   874      this->setstate(ios_base::failbit);
       
   875   }
       
   876 #  endif /* _STLP_USE_WIN32_IO */
       
   877 #endif
       
   878 
       
   879   ~basic_ofstream() {}
       
   880 
       
   881 public:                         // File and buffer operations.
       
   882   basic_filebuf<_CharT, _Traits>* rdbuf() const
       
   883     { return __CONST_CAST(_Buf*,&_M_buf); }
       
   884 
       
   885   bool is_open() {
       
   886     return this->rdbuf()->is_open();
       
   887   }
       
   888 
       
   889   void open(const char* __s, ios_base::openmode __mod= ios_base::out) {
       
   890     if (!this->rdbuf()->open(__s, __mod | ios_base::out))
       
   891       this->setstate(ios_base::failbit);
       
   892   }
       
   893 
       
   894   void close() {
       
   895     if (!this->rdbuf()->close())
       
   896       this->setstate(ios_base::failbit);
       
   897   }
       
   898 
       
   899 private:
       
   900   basic_filebuf<_CharT, _Traits> _M_buf;
       
   901 };
       
   902 
       
   903 
       
   904 //----------------------------------------------------------------------
       
   905 // Class basic_fstream<>
       
   906 
       
   907 template <class _CharT, class _Traits>
       
   908 class basic_fstream : public basic_iostream<_CharT, _Traits> {
       
   909 public:                         // Types
       
   910   typedef _CharT                     char_type;
       
   911   typedef typename _Traits::int_type int_type;
       
   912   typedef typename _Traits::pos_type pos_type;
       
   913   typedef typename _Traits::off_type off_type;
       
   914   typedef _Traits                    traits_type;
       
   915 
       
   916   typedef basic_ios<_CharT, _Traits>                _Basic_ios;
       
   917   typedef basic_iostream<_CharT, _Traits>           _Base;
       
   918   typedef basic_filebuf<_CharT, _Traits>            _Buf;
       
   919 
       
   920 public:                         // Constructors, destructor.
       
   921 
       
   922   basic_fstream()
       
   923     : basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
       
   924       this->init(&_M_buf);
       
   925   }
       
   926 
       
   927   explicit basic_fstream(const char* __s,
       
   928                          ios_base::openmode __mod = ios_base::in | ios_base::out) :
       
   929     basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
       
   930       this->init(&_M_buf);
       
   931       if (!_M_buf.open(__s, __mod))
       
   932         this->setstate(ios_base::failbit);
       
   933   }
       
   934 
       
   935 #if !defined (_STLP_NO_EXTENSIONS)
       
   936   explicit basic_fstream(int __id,
       
   937                          ios_base::openmode __mod = ios_base::in | ios_base::out) :
       
   938     basic_ios<_CharT, _Traits>(), basic_iostream<_CharT, _Traits>(0), _M_buf() {
       
   939     this->init(&_M_buf);
       
   940     if (!_M_buf.open(__id, __mod))
       
   941       this->setstate(ios_base::failbit);
       
   942   }
       
   943   basic_fstream(const char* __s, ios_base::openmode __m, long __protection) :
       
   944     basic_ios<_CharT, _Traits>(),  basic_iostream<_CharT, _Traits>(0), _M_buf() {
       
   945     this->init(&_M_buf);
       
   946     if (!_M_buf.open(__s, __m, __protection))
       
   947       this->setstate(ios_base::failbit);
       
   948   }
       
   949 #  if defined (_STLP_USE_WIN32_IO)
       
   950   explicit basic_fstream(_STLP_fd __id,
       
   951     ios_base::openmode __mod = ios_base::in | ios_base::out) :
       
   952     basic_ios<_CharT, _Traits>(),  basic_iostream<_CharT, _Traits>(0), _M_buf() {
       
   953     this->init(&_M_buf);
       
   954     if (!_M_buf.open(__id, __mod))
       
   955       this->setstate(ios_base::failbit);
       
   956   }
       
   957 #  endif /* _STLP_USE_WIN32_IO */
       
   958 #endif
       
   959   ~basic_fstream() {}
       
   960 
       
   961 public:                         // File and buffer operations.
       
   962 
       
   963   basic_filebuf<_CharT, _Traits>* rdbuf() const
       
   964     { return __CONST_CAST(_Buf*,&_M_buf); }
       
   965 
       
   966   bool is_open() {
       
   967     return this->rdbuf()->is_open();
       
   968   }
       
   969 
       
   970   void open(const char* __s,
       
   971       ios_base::openmode __mod =
       
   972       ios_base::in | ios_base::out) {
       
   973     if (!this->rdbuf()->open(__s, __mod))
       
   974       this->setstate(ios_base::failbit);
       
   975   }
       
   976 
       
   977   void close() {
       
   978     if (!this->rdbuf()->close())
       
   979       this->setstate(ios_base::failbit);
       
   980   }
       
   981 
       
   982 private:
       
   983   basic_filebuf<_CharT, _Traits> _M_buf;
       
   984 
       
   985 #if defined (_STLP_MSVC) && (_STLP_MSVC >= 1300 && _STLP_MSVC <= 1310)
       
   986   typedef basic_fstream<_CharT, _Traits> _Self;
       
   987   //explicitely defined as private to avoid warnings:
       
   988   basic_fstream(_Self const&);
       
   989   _Self& operator = (_Self const&);
       
   990 #endif
       
   991 };
       
   992 
       
   993 _STLP_END_NAMESPACE
       
   994 
       
   995 #if defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)
       
   996 #  include <stl/_fstream.c>
       
   997 #endif
       
   998 
       
   999 _STLP_BEGIN_NAMESPACE
       
  1000 
       
  1001 #if defined (_STLP_USE_TEMPLATE_EXPORT)
       
  1002 _STLP_EXPORT_TEMPLATE_CLASS basic_ifstream<char, char_traits<char> >;
       
  1003 _STLP_EXPORT_TEMPLATE_CLASS basic_ofstream<char, char_traits<char> >;
       
  1004 _STLP_EXPORT_TEMPLATE_CLASS basic_fstream<char, char_traits<char> >;
       
  1005 #  if ! defined (_STLP_NO_WCHAR_T)
       
  1006 _STLP_EXPORT_TEMPLATE_CLASS basic_ifstream<wchar_t, char_traits<wchar_t> >;
       
  1007 _STLP_EXPORT_TEMPLATE_CLASS basic_ofstream<wchar_t, char_traits<wchar_t> >;
       
  1008 _STLP_EXPORT_TEMPLATE_CLASS basic_fstream<wchar_t, char_traits<wchar_t> >;
       
  1009 #  endif
       
  1010 #endif /* _STLP_USE_TEMPLATE_EXPORT */
       
  1011 
       
  1012 _STLP_END_NAMESPACE
       
  1013 
       
  1014 #endif /* _STLP_FSTREAM */
       
  1015 
       
  1016 
       
  1017 // Local Variables:
       
  1018 // mode:C++
       
  1019 // End: