home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / Runimage / Cbuilder4 / Include / FSTREAM.CC < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-26  |  35.5 KB  |  1,418 lines

  1. #ifndef __FSTREAM_CC
  2. #define __FSTREAM_CC
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. /***************************************************************************
  5.  *
  6.  * fstream.cc - Definition for the Standard Library file streams
  7.  *
  8.  ***************************************************************************
  9.  *
  10.  * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
  11.  * ALL RIGHTS RESERVED
  12.  *
  13.  * The software and information contained herein are proprietary to, and
  14.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  15.  * intends to preserve as trade secrets such software and information.
  16.  * This software is furnished pursuant to a written license agreement and
  17.  * may be used, copied, transmitted, and stored only in accordance with
  18.  * the terms of such license and with the inclusion of the above copyright
  19.  * notice.  This software and information or any other copies thereof may
  20.  * not be provided or otherwise made available to any other person.
  21.  *
  22.  * Notwithstanding any other lease or license that may pertain to, or
  23.  * accompany the delivery of, this computer software and information, the
  24.  * rights of the Government regarding its use, reproduction and disclosure
  25.  * are as set forth in Section 52.227-19 of the FARS Computer
  26.  * Software-Restricted Rights clause.
  27.  * 
  28.  * Use, duplication, or disclosure by the Government is subject to
  29.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  30.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  31.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  32.  * P.O. Box 2328, Corvallis, Oregon 97339.
  33.  *
  34.  * This computer software and information is distributed with "restricted
  35.  * rights."  Use, duplication or disclosure is subject to restrictions as
  36.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  37.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  38.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  39.  * then the "Alternate III" clause applies.
  40.  *
  41.  **************************************************************************/
  42.  
  43. #ifndef _RWSTD_NO_NEW_HEADER
  44. #include <cstdio>
  45. #else
  46. #include <stdio.h>
  47. #endif // _RWSTD_NO_NEW_HEADER
  48. #ifndef _RWSTD_NO_NAMESPACE
  49. namespace std {
  50. #endif
  51.  
  52. #ifdef __BORLANDC__
  53.   template <class T>
  54.   void __io_initialize (T& t, T val) { t = val; }
  55. #pragma option -w-par
  56. #endif
  57.  
  58.   /*
  59.    * class basic_filebuf
  60.    */
  61.  
  62.   /*
  63.    * basic_filebuf()
  64.    */
  65.  
  66.   template<class charT, class traits>
  67.   basic_filebuf<charT, traits>::basic_filebuf()
  68.   : basic_streambuf<charT, traits>()
  69.   , __file(__closed())
  70.   , __data(0)
  71.   , __read_buff(false)
  72.   , __write_buff(false)
  73.   , __last_numb_read(0)
  74.   , __rwBufferSize(512)
  75.   , __absolute_pos(0)
  76.   {
  77.     __state_beg = new state_t;
  78.     __state_end = new state_t;
  79.   }
  80.  
  81.   /*
  82.    * basic_filebuf(__file_type)
  83.    */
  84.  
  85.   template<class charT, class traits>
  86.   basic_filebuf<charT, traits>::basic_filebuf(__file_type fd)
  87.   : basic_streambuf<charT, traits>()
  88.   , __file(fd)
  89.   , __read_buff(false)
  90.   , __write_buff(false)
  91.   , __last_numb_read(0)
  92.   , __rwBufferSize(512)
  93.   , __absolute_pos(0)
  94.   {
  95.     __data = new char_type[__rwBufferSize+1];
  96.     __state_beg = new state_t;
  97.     __state_end = new state_t;
  98.  
  99. #ifndef _RWSTD_STRICT_ANSI
  100.     if ( fd == 0 )
  101.       basic_streambuf<charT,traits>::mode_ = ios_base::in;
  102.     else
  103.     {
  104.       if ( fd < 3 )
  105.         basic_streambuf<charT,traits>::mode_ = ios_base::out;
  106.     }
  107. #else
  108.     if ( fd == stdin )
  109.       basic_streambuf<charT,traits>::mode_ = ios_base::in;
  110.     else
  111.     {
  112.       if ( __file_is_std(fd) )
  113.         basic_streambuf<charT,traits>::mode_ = ios_base::out;
  114.     }
  115. #endif // _RWSTD_STRICT_ANSI
  116.  
  117.   }
  118.   /*
  119.    * ~basic_filebuf()
  120.    */
  121.  
  122.   template<class charT, class traits>
  123.   basic_filebuf<charT, traits>::~basic_filebuf()
  124.   {
  125.     close();
  126.     delete __state_beg;
  127.     delete __state_end;
  128.   }
  129.  
  130.   /*
  131.    * bool is_open() const
  132.    */
  133.  
  134.   template<class charT, class traits>
  135.   bool basic_filebuf<charT, traits>::is_open() const
  136.   {
  137. #ifndef _RWSTD_STRICT_ANSI
  138.     return !(__file == -1);
  139. #else
  140.     return !(__file == 0);
  141. #endif
  142.   }
  143.  
  144.   /*
  145.    * basic_filebuf *open(int fd)
  146.    * fstream compatibility
  147.    */
  148.  
  149. #ifndef _RWSTD_NO_EXTENSION
  150.  
  151.   template<class charT, class traits>
  152.   basic_filebuf<charT, traits> *
  153.   basic_filebuf<charT, traits>::
  154.   open(int fd )
  155.   {   
  156.     if(__file != __closed())
  157.       return 0;
  158.  
  159.     this->streambuf_init(false); 
  160.  
  161.     __file           = fd;
  162.     __read_buff      = false;
  163.     __write_buff     = false;
  164.     __last_numb_read = 0; 
  165.  
  166.     delete [] __data;
  167.     __data = new char_type[__rwBufferSize+1];
  168.  
  169.     if ( fd == 0 )
  170.       basic_streambuf<charT,traits>::mode_ = ios_base::in;
  171.     else
  172.     {
  173.       if ( fd < 3 )
  174.         basic_streambuf<charT,traits>::mode_ = ios_base::out;
  175.     }
  176.     return this;
  177.   }
  178. #endif // _RWSTD_NO_EXTENSION
  179.   /*
  180.    * basic_filebuf *open(const char *, ios_base::openmode, long )
  181.    * opens a file and allocates a buffer
  182.    */
  183.  
  184.   template<class charT, class traits>
  185.   basic_filebuf<charT, traits> *
  186.   basic_filebuf<charT, traits>::
  187.   open(const char *s, ios_base::openmode mode, long protection)
  188.   {
  189.     long    m;
  190.     if ( mode & ios_base::ate )
  191.       m = mode & (~ios_base::ate);
  192.     else
  193.       m = mode;
  194.     if(__file != __closed())
  195.       return 0;
  196.  
  197.     basic_streambuf<charT,traits>::mode_ = mode;
  198.     this->streambuf_init(false);
  199.  
  200. #ifndef _RWSTD_STRICT_ANSI
  201.     if(__RWSTD::__rwOpenTable[m] == -1) 
  202.       return 0;
  203.     if((__file = ::open(s, __RWSTD::__rwOpenTable[m], protection)) == __closed())
  204.       return 0;
  205. #else
  206.     if(__RWSTD::__rwOpenTable[m] == 0) 
  207.       return 0;
  208.     if((__file = fopen(s, __RWSTD::__rwOpenTable[m])) == __closed())
  209.       return 0;
  210.     setvbuf(__file,0,_IONBF,0);
  211. #endif // _RWSTD_STRICT_ANSI
  212.  
  213.     delete [] __data;
  214.     __data = new char_type[__rwBufferSize+1];
  215.  
  216.     if(mode & ios_base::ate)
  217.     {
  218.       if( (__absolute_pos = __file_seek(__file, 0, SEEK_END))== -1  )
  219.       {
  220.         close();
  221.         delete [] __data;  
  222.         __data = 0;
  223.         __file = __closed();
  224.         return 0;
  225.       }
  226.     }
  227.     return this;
  228.   }
  229.  
  230.   /*
  231.    * basic_filebuf *close()
  232.    * closes a file if one was already open.  Also deletes the
  233.    * data, if it was allocated
  234.    */
  235.  
  236.   template<class charT, class traits>
  237.   basic_filebuf<charT, traits> *
  238.   basic_filebuf<charT, traits>::close()
  239.   {
  240.     delete __state_beg;
  241.     delete __state_end;
  242.     __state_beg = new state_t;
  243.     __state_end = new state_t;
  244.  
  245.     __absolute_pos = 0;
  246.  
  247.     if ( (__file_is_std(__file))  && (__file != __closed()) )
  248.     {
  249.       if ( __write_buff )
  250.         overflow( traits::eof() );
  251.       __read_buff=false;
  252.       __write_buff=false;
  253.       __last_numb_read=0;
  254.       return this;
  255.     }
  256.    
  257.     if(__file != __closed())
  258.     {          
  259.       if ( __write_buff )
  260.         overflow( traits::eof() );
  261.       delete [] __data;
  262.       __data = 0;
  263.       __read_buff=false;
  264.       __write_buff=false;
  265.       __last_numb_read=0;
  266.  
  267.  
  268.       if(__file_close(__file) == -1)
  269.         return 0;
  270.  
  271.       __file = __closed();
  272.  
  273.       return this;
  274.     }
  275.     return 0;          
  276.   }
  277.  
  278.   /*
  279.    * int showmanyc()
  280.    */
  281.  
  282.   template<class charT, class traits>
  283.   int
  284.   basic_filebuf<charT, traits>::showmanyc()
  285.   { 
  286.     if ( this->gptr() )
  287.       return (int)(this->egptr()-this->gptr());
  288.    
  289.     if ( this->pptr() && __read_buff )
  290.       return (int)(this->epptr()-this->pptr());   
  291.  
  292.     return 0;
  293.  
  294.   }
  295.  
  296.   /*
  297.    * int_type overflow(int_type)
  298.    * this is called when the put pointer overruns the buffer.
  299.    * it should flush what was in the put buffer, and move the pointer
  300.    * back to the beginning
  301.    */
  302.  
  303.   template<class charT, class traits>
  304.   _TYPENAME basic_filebuf<charT, traits>::int_type
  305.   basic_filebuf<charT, traits>::overflow(int_type c)
  306.   {
  307.     long  count = this->pptr() - this->pbase();
  308.     bool   do_noconv;
  309.  
  310.     if(__file == __closed())        
  311.       return traits::eof();
  312.  
  313.     if ( (this->pptr()==0) && this->gptr() )
  314.     {
  315.       this->setp(this->eback(),this->eback()+__rwBufferSize);
  316.       pbump((int)(this->gptr()-this->eback()));
  317.       this->setg(0,0,0);
  318.       if ( this->pptr()<this->epptr() )
  319.       { 
  320.         if( !traits::eq_int_type(c,traits::eof()) ) 
  321.         {
  322.           sputc( traits::to_char_type(c) );
  323.           this->gbump(1);
  324.           __write_buff=true;
  325.           return traits::to_int_type(*this->pptr());
  326.         }
  327.       } 
  328.       count=  this->pptr() - this->pbase();
  329.     }
  330.  
  331.     if ( (this->pptr()==0) && (this->gptr()==0) )
  332.       this->setp(__data,__data+ __rwBufferSize);  
  333.  
  334.     __write_buff= false;
  335.  
  336.     if(count)
  337.     {        
  338. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  339.       do_noconv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  340. #else
  341.       do_noconv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  342. #endif
  343.       .always_noconv();
  344.  
  345.       if ( do_noconv )
  346.       {
  347.         if ( __read_buff ) 
  348.         {
  349.           if ( __file_seek(__file, -__last_numb_read, SEEK_CUR) == -1 )
  350.             return traits::eof();
  351.         }
  352.         if(!__file_write(__file,(char *)this->pbase(),sizeof(charT),count))
  353.           return traits::eof();
  354.       }
  355.       else
  356.       {
  357.         long size_to = count*sizeof(charT);
  358.         const charT *from_next =0;
  359.         char *to= new char[size_to];
  360.         char *to_next = 0;
  361.         codecvt_base::result conv_result;
  362.  
  363.         if ( __read_buff )
  364.         {
  365.           if ( __file_seek(__file, -__last_numb_read, SEEK_CUR) == -1 )
  366.             return traits::eof();
  367.           else
  368.           {
  369.             state_t *tmp = __state_beg;
  370.             __state_beg = __state_end;
  371.             __state_end = tmp;
  372.           }
  373.         }
  374.  
  375.         *__state_beg = *__state_end;
  376.  
  377.         do {
  378.  
  379. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  380.           conv_result = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  381. #else
  382.           conv_result = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  383. #endif
  384.           .out(*__state_end,this->pbase(),this->pptr(),from_next,
  385.                to,to+size_to,to_next); 
  386.  
  387.           if ( conv_result == codecvt_base::noconv ) break;
  388.  
  389.           if (  (conv_result == codecvt_base::partial) || ( from_next != this->pptr() ) )
  390.           {
  391.             size_to *= 2;
  392.             char *to_bis = new char[size_to];
  393.             long diff_to = to_next - to;
  394.             memcpy(to_bis,to,diff_to);
  395.             delete [] to;
  396.             to = to_bis;
  397.             to_next = to + diff_to;
  398.           }
  399.  
  400.         }while( (conv_result == codecvt_base::partial) || ( from_next != this->pptr()));
  401.  
  402.         if ( conv_result==codecvt_base::error )
  403.         {
  404.           delete [] to;
  405.           return traits::eof();
  406.         }
  407.  
  408.         if (conv_result == codecvt_base::noconv) 
  409.         {
  410.           if(!__file_write(__file, (char*)this->pbase(), sizeof(charT), count))
  411.           {
  412.             delete [] to;
  413.             return traits::eof();              
  414.           }
  415.         } 
  416.         else 
  417.         {
  418.           if(!__file_write(__file, to, sizeof(char),to_next-to))
  419.           {
  420.             delete [] to;
  421.             return traits::eof();                
  422.           }
  423.         }
  424.         delete [] to;
  425.       }
  426.     }
  427.  
  428.     this->setp(__data, __data+__rwBufferSize);    
  429.     this->setg(0,0,0);                       
  430.     __read_buff = false;              
  431.     __write_buff= false; 
  432.  
  433.     __absolute_pos = __file_seek(__file,0,SEEK_CUR);
  434.  
  435.     if( !traits::eq_int_type(c,traits::eof()) ) 
  436.     {
  437.       sputc(traits::to_char_type(c));
  438.       this->gbump(1);
  439.       __write_buff = true;
  440.     }
  441.     else
  442.       this->setp(0,0);
  443.  
  444.     return traits::not_eof(c);
  445.   }
  446.  
  447.   /*
  448.    * int_type pbackfail(int_type)
  449.    */
  450.  
  451.   template<class charT, class traits>
  452.   _TYPENAME basic_filebuf<charT, traits>::int_type
  453.   basic_filebuf<charT, traits>::pbackfail(int_type c)
  454.   {
  455.     if(__file == __closed())
  456.       return traits::eof();
  457.  
  458.     if ( (this->gptr()==0) && this->pptr() )
  459.     {
  460.       if ( __read_buff )
  461.         this->setg(this->pbase(),this->pptr(),this->epptr());
  462.       else
  463.         this->setg(this->pbase(),this->pptr(),this->pptr()); 
  464.     }
  465.  
  466.     if ( (!traits::eq_int_type(c,traits::eof())) && (this->gptr()>this->eback()) )
  467.     {
  468.       if ( traits::eq(*(this->gptr()-1),traits::to_char_type(c)) ) 
  469.       {
  470.         this->gbump(-1);
  471.         return c;
  472.       }
  473.       else
  474.       {
  475.         this->gbump(-1);
  476.         *this->gptr()=traits::to_char_type(c);
  477.         return c;
  478.       }
  479.     }       
  480.  
  481.     if ( (traits::eq_int_type(c,traits::eof())) && (this->gptr()>this->eback()) )  
  482.     { 
  483.       this->gbump(-1);
  484.       return traits::not_eof(c);
  485.     }
  486.                                                 
  487.     return traits::eof();
  488.   }
  489.  
  490.   /*
  491.    * basic_streambuf<charT,traits>* setbuf(char_type*,streamsize)
  492.    */
  493.  
  494.   template<class charT, class traits>
  495.   basic_streambuf<charT, traits>*
  496.   basic_filebuf<charT, traits>::setbuf(char_type *s, streamsize n)
  497.   {
  498.  
  499.     if (n>0)
  500.     { 
  501.       if ( __file != __closed() )
  502.       {
  503.         if ( !traits::eq_int_type(overflow( traits::eof() ),traits::eof()) )
  504.         {
  505.           if ( s )
  506.           { 
  507.             delete [] __data;
  508.             __rwBufferSize = n-1; 
  509.             __data=s;
  510.           }
  511.           else
  512.           {
  513.             charT *tmp;
  514.             __rwBufferSize = n;  
  515.             tmp = new char_type[__rwBufferSize+1];
  516.             delete [] __data;
  517.             __data = tmp;
  518.           }
  519.           this->setp(0,0);    
  520.           this->setg(0,0,0);                         
  521.           __read_buff=false;
  522.           __write_buff=false;
  523.         }
  524.       }
  525.       else
  526.       {
  527.         if ( s )
  528.         {
  529.           __rwBufferSize = n-1;
  530.           __data =s;
  531.           this->setp(0,0);    
  532.           this->setg(0,0,0);                        
  533.           __write_buff= false;
  534.           __read_buff = false; 
  535.         }
  536.         else
  537.           __rwBufferSize = n;
  538.       }  
  539.     } 
  540.     return (basic_streambuf<charT,traits>*)(this); 
  541.   }
  542.   /*
  543.    * int_type underflow()
  544.    * this is called when the get pointer "underflows" the buffer,
  545.    * or when there are no more "get" characters.
  546.    */
  547.  
  548.   template<class charT, class traits>
  549.   _TYPENAME basic_filebuf<charT, traits>::int_type
  550.   basic_filebuf<charT, traits>::underflow()
  551.   {
  552.     bool do_noconv;
  553.     long offset;
  554. #ifndef __BORLANDC__
  555.     offset = 0;
  556. #else
  557.     __io_initialize(offset,0L);
  558. #endif
  559.  
  560.     if(__file == __closed())
  561.       return traits::eof();
  562.  
  563.     if ( (this->gptr()==0) && this->pptr() )
  564.     {
  565.       if ( __read_buff )
  566.         this->setg(this->pbase(),this->pptr(),this->epptr());
  567.       else
  568.         this->setg(this->pbase(),this->pptr(),this->pptr());
  569.  
  570.       this->setp(0,0);
  571.     }
  572.  
  573.     if(this->gptr() && (this->gptr()<this->egptr()) ) return traits::to_int_type(*this->gptr());     
  574.  
  575.     if( ((__write_buff) && this->gptr() ) || ((__write_buff) && this->pptr() ) )
  576.     {
  577.       if ( traits::eq_int_type(overflow( traits::eof() ),traits::eof()) ) 
  578.         return traits::eof();
  579.       this->setg(this->pbase(),this->pptr(),this->epptr());
  580.       this->setp(0,0);
  581.       __write_buff = false; 
  582.     }                 
  583.  
  584.     __absolute_pos = __file_seek(__file,0,SEEK_CUR);
  585.  
  586. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  587.     do_noconv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  588. #else
  589.     do_noconv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  590. #endif
  591.       .always_noconv();
  592.  
  593.     if ( do_noconv )
  594.     {
  595.       streamoff last_numb_read = __file_read(__file, (char *)__data,sizeof(charT),__rwBufferSize);
  596.       if( last_numb_read <= 0 ) 
  597.         return traits::eof();
  598.       offset = last_numb_read/sizeof(charT);
  599.       __last_numb_read = __get_chars(__data,__data + last_numb_read);
  600.     }
  601.     else
  602.     {
  603.       long from_size = __rwBufferSize*sizeof(charT);
  604.       const char *from_next =0;
  605.       char *from= new char[from_size];
  606.       charT *to_next = 0;
  607.       codecvt_base::result conv_result;
  608.  
  609.       streamoff last_numb_read = 0;
  610.       long new_numb_read;
  611.  
  612.       do {
  613.         new_numb_read = __file_read(__file, from+last_numb_read
  614.                              ,sizeof(char),__rwBufferSize);
  615.  
  616.         if( new_numb_read <= 0 ) 
  617.           break;
  618.  
  619.         last_numb_read += new_numb_read;
  620.         *__state_beg = *__state_end;
  621.  
  622. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  623.         conv_result = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  624. #else
  625.         conv_result = use_facet(this->getloc(), (codecvt<charT,char,state_t>* )0)
  626. #endif
  627.         .in(*__state_end,from,from+last_numb_read,from_next,__data,
  628.             __data+__rwBufferSize,to_next); 
  629.  
  630.         if ( (conv_result == codecvt_base::error) ||
  631.              (conv_result == codecvt_base::noconv) ) break;
  632.  
  633.         if (  (to_next != (__data + __rwBufferSize) ) &&
  634.               ( (size_t)new_numb_read == __rwBufferSize*sizeof(charT) ) )
  635.         {
  636.           from_size *= 2;
  637.           char *from_bis = new char[from_size];
  638.           long diff_from = from_next - from;
  639.           memcpy(from_bis,from,last_numb_read);
  640.           delete [] from;
  641.           from = from_bis;
  642.           from_next = from + diff_from;
  643.         }
  644.  
  645.       } while ( (to_next != (__data + __rwBufferSize) ) &&
  646.                 ( (size_t)new_numb_read == __rwBufferSize*sizeof(charT) ) ); 
  647.  
  648.       if( last_numb_read <= 0 ) 
  649.         return traits::eof();
  650.       __last_numb_read = last_numb_read;
  651.                
  652.       if ( (conv_result==codecvt_base::error) ||
  653.            (conv_result==codecvt_base::partial) )
  654.       {
  655.         delete [] from;
  656.         return traits::eof();
  657.       } 
  658.       else 
  659.       {
  660.         if (conv_result==codecvt_base::noconv)
  661.         {
  662.           memcpy((char*)__data,from,__last_numb_read);
  663.           offset = __last_numb_read;
  664.         }
  665.         else
  666.         {
  667.           long diff_minus = new_numb_read - (from_next - from);
  668.           if ( __file_seek(__file, -diff_minus, SEEK_CUR) == -1 )
  669.             return traits::eof();
  670.           __last_numb_read -= diff_minus;
  671.           offset = to_next - __data;
  672.         }
  673.       }
  674.  
  675.       delete [] from;
  676.     }
  677.         
  678.     if(__last_numb_read) 
  679.     {   
  680.       this->setg(__data, __data, __data+offset); 
  681.       this->setp(0, 0);
  682.       __read_buff=true;
  683.       return traits::to_int_type(*this->gptr());
  684.     }
  685.  
  686.     return traits::eof();
  687.   }
  688.  
  689.   /*
  690.    * pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode)
  691.    */
  692.  
  693.   template<class charT, class traits>
  694.   _TYPENAME basic_filebuf<charT, traits>::pos_type
  695.   basic_filebuf<charT, traits>::seekoff(off_type off,
  696.                                         ios_base::seekdir way,
  697.                                         ios_base::openmode which)
  698.   {
  699.     off_type            loff = off;
  700.     pos_type            newoff;
  701.  
  702.     if(__file == __closed())
  703.       return pos_type(off_type(-1));
  704.  
  705.     if ( off == off_type(-1) )
  706.       return pos_type(off_type(-1));
  707.  
  708.     if ( (way==ios_base::cur) && (off==off_type(0)) )
  709.     {
  710.       streamsize remain_in_buffer=0;
  711.       charT * remain_start=0;
  712.       charT * remain_end=0;
  713.      
  714.       if ( __read_buff )
  715.       {
  716.         if ( this->gptr() )  
  717.         {
  718.           if (!this->eback())
  719.             remain_in_buffer= this->egptr()-this->gptr();
  720.           else
  721.             remain_in_buffer= __get_chars(this->gptr(),this->egptr());
  722.           remain_start = this->gptr();
  723.           remain_end = this->egptr();
  724.         }
  725.         else
  726.         {
  727.           if ( this->pbase() )  
  728.           {
  729.             remain_in_buffer= __get_chars(this->pptr(),this->epptr());
  730.             remain_start = this->pptr();
  731.             remain_end = this->epptr();
  732.           }
  733.         }
  734.       }
  735.       else 
  736.       {
  737.         if ( __write_buff )
  738.         {
  739.           if ( this->pbase() )  
  740.           {
  741.             remain_in_buffer= -(__get_chars(this->pbase(),this->pptr()));
  742.             remain_start = this->pbase();
  743.             remain_end = this->pptr();
  744.           }
  745.  
  746.           else
  747.           { 
  748.             if ( this->eback() )  
  749.             {
  750.               remain_in_buffer= -(__get_chars(this->eback(),this->gptr()));
  751.               remain_start = this->eback();
  752.               remain_end = this->gptr();
  753.             }
  754.           }
  755.         }     
  756.       }
  757.  
  758.       int const_conv;
  759.  
  760. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  761.       const_conv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  762. #else
  763.       const_conv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  764. #endif
  765.       .encoding(); 
  766.  
  767.       if ( const_conv > 0 )
  768.       {
  769.         return ( (__file_seek(__file,0,SEEK_CUR)-remain_in_buffer*const_conv)/const_conv);
  770.       }
  771.       else 
  772.       {
  773.         // First find current position in file
  774.         newoff = __file_seek(__file, 0, SEEK_CUR);
  775.  
  776.         // If necessary convert characters in buffer to 
  777.         // find offset from file position
  778.         if (remain_in_buffer != 0 && this->eback())
  779.         {
  780.           long to_size = __rwBufferSize;
  781.           const charT *from = remain_start;
  782.           const charT *from_next = from;
  783.           const charT *from_end = remain_end;
  784.           char *to_base = new char[to_size];
  785.           char *to = to_base;
  786.           char *to_next = to;
  787.           char *to_end = to + to_size;
  788.           codecvt_base::result conv_result;
  789.  
  790.           do {
  791.             *__state_beg = *__state_end;
  792.  
  793. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  794.             conv_result = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  795. #else
  796.             conv_result = use_facet(this->getloc(), (codecvt<charT,char,state_t>* )0)
  797. #endif
  798.              .out(*__state_end,from,from_end,from_next,to,to_end,to_next); 
  799.  
  800.             if ( (conv_result == codecvt_base::error) ||
  801.                (conv_result == codecvt_base::noconv) ) break;
  802.  
  803.             if ( to_next == to_end && from_next != from_end )
  804.             {
  805.               long diff_to = to_next - to_base;
  806.               to_size *= 2;
  807.               to = new char[to_size];
  808.               memcpy(to,to_base,diff_to);
  809.               delete [] to_base;
  810.               to_base = to;
  811.               to = to_base + diff_to;
  812.               to_next = to;
  813.               from = from_next;
  814.               to_end = to_base + to_size;
  815.             }
  816.  
  817.           } while ( from_next != from_end );
  818.           
  819.           // Calculate new file position
  820.           // The  + remain_in_buffer - ... stuff is used to deal
  821.           // with WIN32 CR/LF translations (see __get_chars())
  822.           if (remain_in_buffer > 0)
  823.             newoff -= (to_next - to_base) 
  824.                       + (remain_in_buffer - (remain_end-remain_start));
  825.           else
  826.             newoff += (to_next - to_base)
  827.                       + (-remain_in_buffer - (remain_end-remain_start));
  828.  
  829.           delete [] to;
  830.         }
  831.         return newoff;
  832.       }
  833.     } 
  834.  
  835.     int const_conv;
  836.  
  837. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  838.     const_conv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  839. #else
  840.     const_conv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  841. #endif
  842.     .encoding(); 
  843.  
  844.     if ( const_conv < 1 )
  845.     {
  846.       if ( (way==ios_base::beg) && (off==off_type(0)) )
  847.       {
  848.         seekpos(0);
  849.       }
  850.       else 
  851.         return pos_type(off_type(-1));
  852.     }
  853.  
  854.     if ( __write_buff)
  855.     {  
  856.       overflow( traits::eof() );
  857.       __write_buff =false;  
  858.     }
  859.  
  860.     int w = (way == ios_base::beg) ?
  861.           SEEK_SET : ((way == ios_base::cur) ? SEEK_CUR : SEEK_END);  
  862.     newoff = __file_seek(__file, loff*const_conv, w);
  863.  
  864.     this->setp(0,0);
  865.     this->setg(0,0,0);
  866.  
  867.     return newoff;
  868.   }
  869.  
  870.   /*
  871.    * pos_type seekpos(pos_type, ios_base::openmode)
  872.    */
  873.  
  874.   template<class charT, class traits>
  875.   _TYPENAME basic_filebuf<charT, traits>::pos_type
  876.   basic_filebuf<charT, traits>::
  877.   seekpos(pos_type sp, ios_base::openmode which)
  878.   { 
  879.     if(__file == __closed())
  880.       return pos_type(off_type(-1));
  881.  
  882.     if( sp == pos_type(off_type(-1)) )
  883.       return pos_type(off_type(-1)); 
  884.  
  885.     int const_conv;
  886.  
  887. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  888.     const_conv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  889. #else
  890.     const_conv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  891. #endif
  892.     .encoding();
  893.  
  894.     if ( const_conv > 0 )
  895.       return seekoff(off_type(sp.offset()), ios_base::beg, which);
  896.  
  897.     _TYPENAME traits::off_type end_pos = __file_seek(__file,0,SEEK_END);
  898.    
  899.     if ( __file_seek(__file, sp.offset(), SEEK_SET) == -1 )
  900.       return pos_type(off_type(-1));
  901.  
  902.     this->setp(0,0);
  903.     this->setg(0,0,0); 
  904.  
  905.     *__state_beg = *__state_end = sp.state();
  906.  
  907.     if ( traits::eq_int_type(underflow(),traits::eof()) && (end_pos > sp.offset()))
  908.       return pos_type(off_type(-1));
  909.  
  910.     return sp;   
  911.   }
  912.  
  913.   /*
  914.    * int sync()
  915.    * this synchronizes the buffers and their streams
  916.    */
  917.  
  918.   template<class charT, class traits>
  919.   int basic_filebuf<charT, traits>::sync()
  920.   {
  921.     if ( this->which_open_mode( ) & ios_base::out )
  922.     {
  923. #ifndef _RWSTD_STRICT_ANSI
  924.       if ( __file == 1 || __file == 2)
  925. #else
  926.       if ( __file == stdout || __file == stderr )
  927. #endif
  928.       {
  929.         if( traits::eq_int_type(overflow(traits::eof()),traits::eof()) ) 
  930.           return -1;
  931.       }
  932.       else
  933.       { 
  934.         pos_type p_out = seekoff(0,ios_base::cur,ios_base::out);
  935.         pos_type tmp_out = __file_seek(__file,0,SEEK_CUR);
  936.         pos_type end_out = __file_seek(__file,0,SEEK_END);
  937.         __file_seek(__file,tmp_out,SEEK_SET);
  938.         if ( end_out > p_out )
  939.         {
  940.           if( seekpos(p_out) == pos_type(off_type(-1)))
  941.             return -1;
  942.         }
  943.         else if (__write_buff)
  944.         {
  945.           if( traits::eq_int_type(overflow(traits::eof()),traits::eof()) )
  946.             return -1;
  947.         }
  948.       }
  949.     }
  950.  
  951.     if ( this->which_open_mode( ) & ios_base::in )
  952.     {
  953. #ifndef _RWSTD_STRICT_ANSI
  954.       if ( __file != 0 )
  955. #else
  956.       if ( __file != stdin )
  957. #endif
  958.       {
  959.         pos_type p_in = seekoff(0,ios_base::cur,ios_base::in);
  960.         pos_type tmp_in = __file_seek(__file,0,SEEK_CUR);
  961.         pos_type end_in = __file_seek(__file,0,SEEK_END);
  962.         __file_seek(__file,tmp_in,SEEK_SET);
  963.         if ( end_in > p_in )
  964.         {
  965.           if( seekpos(p_in) == pos_type(off_type(-1)))
  966.             return -1;
  967.         }
  968.       }
  969.     }
  970.  
  971.     return 0;
  972.   }
  973.   /*
  974.    * streamsize xsputn(const char_type *, streamsize)
  975.    */
  976.  
  977.   template<class charT, class traits>
  978.   streamsize basic_filebuf<charT, traits>::
  979.   xsputn(const char_type *s, streamsize n)
  980.   {
  981.     if ( !s || (n == 0) ) return 0;
  982.  
  983.     if ( n >  __rwBufferSize )
  984.     {
  985.  
  986.       if ( traits::eq_int_type(overflow( traits::eof() ),traits::eof()) )
  987.         return 0;
  988.  
  989.       char_type   *eback_s = this->eback();
  990.       char_type   *gptr_s  = this->gptr();
  991.       char_type   *egptr_s = this->egptr();
  992.  
  993.       char_type   *pbase_s = this->pbase();
  994.       char_type   *pptr_s  = this->pptr();
  995.       char_type   *epptr_s = this->epptr();
  996.  
  997.       this->setg(0,0,0);
  998.       this->setp((char_type *)s,(char_type *)(s+n));
  999.       basic_streambuf<charT, traits>::pbump(n);
  1000.  
  1001.       if ( traits::eq_int_type(overflow( traits::eof() ),traits::eof()) )
  1002.         return 0; 
  1003.   
  1004.       this->setg(eback_s,gptr_s,egptr_s);
  1005.       this->setp(pbase_s,epptr_s);
  1006.  
  1007.       pbump(pptr_s-pbase_s); 
  1008.  
  1009.       return n;
  1010.     }
  1011.     else
  1012.     {
  1013.       int         i=0;
  1014.       while((i < n) && ( !traits::eq_int_type(sputc(*s++),traits::eof())))
  1015.         i++;
  1016.       return i;
  1017.     }
  1018.  
  1019.   }
  1020.  
  1021.  
  1022.   /*
  1023.    * class basic_ifstream : public basic_istream
  1024.    */
  1025.  
  1026.   /*
  1027.    * basic_ifstream()
  1028.    */
  1029.  
  1030.   template<class charT, class traits>
  1031.   basic_ifstream<charT, traits>::basic_ifstream()
  1032.   : basic_istream<charT, traits>( )
  1033.   {
  1034.     init(&__fb);
  1035.   }
  1036.  
  1037.   /*
  1038.    * basic_ifstream(const char *, ios_base::openmode, long)
  1039.    * opens a filebuf for (most likely) reading
  1040.    */
  1041.  
  1042.   template<class charT, class traits>
  1043.   basic_ifstream<charT, traits>::basic_ifstream(const char *s,
  1044.                                                 ios_base::openmode mode,
  1045.                                                 long protection )
  1046.   : basic_istream<charT, traits>( )
  1047.   {
  1048.     init(&__fb);
  1049.     open(s, mode, protection);
  1050.   }
  1051.  
  1052.   /*
  1053.    * basic_ifstream(int fd)
  1054.    * opens a filebuf for reading
  1055.    */
  1056. #ifndef _RWSTD_NO_EXTENSION
  1057.  
  1058.   template<class charT, class traits>
  1059.   basic_ifstream<charT, traits>::
  1060.   basic_ifstream(int fd)
  1061.   : basic_istream<charT, traits>( )
  1062.   {
  1063.  
  1064.     init(&__fb);
  1065.  
  1066.     if ( !__fb.open(fd) ) 
  1067.       this->setstate(ios_base::failbit);
  1068.   }
  1069.  
  1070.   /*
  1071.    * basic_ifstream(int fd, char_type *buf, int len)
  1072.    * opens a filebuf for reading
  1073.    */
  1074.  
  1075.   template<class charT, class traits>
  1076.   basic_ifstream<charT, traits>::
  1077.   basic_ifstream(int fd, char_type *buf, int len)
  1078.   : basic_istream<charT, traits>( )
  1079.   {
  1080.  
  1081.     init(&__fb);
  1082.  
  1083.     if ( ( buf!=0 ) && ( len>0 ) )
  1084.       __fb.pubsetbuf(buf,len);
  1085.  
  1086.     if ( !__fb.open(fd) ) 
  1087.       this->setstate(ios_base::failbit);
  1088.   }
  1089. #endif // _RWSTD_NO_EXTENSION
  1090.  
  1091.   /*
  1092.    * ~basic_ifstream()
  1093.    */
  1094.  
  1095.   template<class charT, class traits>
  1096.   basic_ifstream<charT, traits>::~basic_ifstream()
  1097.   {
  1098.   }
  1099.  
  1100.   /*
  1101.    * basic_filebuf *rdbuf() const
  1102.    * returns the streambuf associated with this stream
  1103.    */
  1104.  
  1105.   template<class charT, class traits>
  1106.   basic_filebuf<charT, traits> *
  1107.   basic_ifstream<charT, traits>::rdbuf() const
  1108.   {
  1109.     return (basic_filebuf<charT, traits> *)&__fb;
  1110.   }
  1111.  
  1112.   /*
  1113.    * bool is_open()
  1114.    */
  1115.  
  1116.   template<class charT, class traits>
  1117.   bool basic_ifstream<charT, traits>::is_open()
  1118.   {
  1119.     return __fb.is_open();
  1120.   }
  1121.  
  1122.   /*
  1123.    * void open(const char *, ios_base::openmode, long )
  1124.    * opens up a file
  1125.    */
  1126.  
  1127.   template<class charT, class traits>
  1128.   void basic_ifstream<charT, traits>::open(const char *s,
  1129.                                            ios_base::openmode mode,
  1130.                                            long protection )
  1131.   {
  1132.     this->clear();
  1133.     mode |= ios_base::in; 
  1134.  
  1135.     if ( !__fb.open(s, mode, protection) )  
  1136.       this->setstate(ios_base::failbit);
  1137.   }
  1138.  
  1139.   /* 
  1140.    * void close()
  1141.    */
  1142.  
  1143.   template<class charT, class traits>
  1144.   void basic_ifstream<charT, traits>::close()
  1145.   {
  1146.     if(!is_open())
  1147.       return;
  1148.   
  1149.     if(!__fb.close())
  1150.       this->setstate(ios_base::failbit);
  1151.     else
  1152.       this->clear();
  1153.   }
  1154.   /*
  1155.    * class basic_ofstream : public basic_ostream
  1156.    */
  1157.  
  1158.   /*
  1159.    * basic_ofstream()
  1160.    */
  1161.  
  1162.   template<class charT, class traits>
  1163.   basic_ofstream<charT, traits>::basic_ofstream()
  1164.   : basic_ostream<charT, traits>( )
  1165.   {
  1166.     init(&__fb);
  1167.   }
  1168.  
  1169.   /*
  1170.    * basic_ofstream(const char *, ios_base::openmode, long )
  1171.    */
  1172.  
  1173.   template<class charT, class traits>
  1174.   basic_ofstream<charT, traits>::
  1175.   basic_ofstream(const char *s, ios_base::openmode mode, long protection)
  1176.   : basic_ostream<charT, traits>()
  1177.   {
  1178.        
  1179.     init(&__fb);
  1180.     open(s, mode, protection);
  1181.   }
  1182.  
  1183.   /*
  1184.    * basic_ofstream(int fd)
  1185.    * opens a filebuf for writing
  1186.    */
  1187. #ifndef _RWSTD_NO_EXTENSION
  1188.  
  1189.   template<class charT, class traits>
  1190.   basic_ofstream<charT, traits>::
  1191.   basic_ofstream(int fd)
  1192.   : basic_ostream<charT, traits>( )
  1193.   {
  1194.  
  1195.     init(&__fb);
  1196.  
  1197.     if ( !__fb.open(fd) ) 
  1198.       this->setstate(ios_base::failbit);
  1199.   }
  1200.  
  1201.   /*
  1202.    * basic_ofstream(int fd, char_type *buf, int len)
  1203.    * opens a filebuf for writing
  1204.    */
  1205.  
  1206.   template<class charT, class traits>
  1207.   basic_ofstream<charT, traits>::
  1208.   basic_ofstream(int fd, char_type *buf, int len)
  1209.   : basic_ostream<charT, traits>( )
  1210.   {
  1211.  
  1212.     init(&__fb);
  1213.  
  1214.     if ( ( buf!=0 ) && ( len>0 ) )
  1215.       __fb.pubsetbuf(buf,len);
  1216.  
  1217.     if ( !__fb.open(fd) ) 
  1218.       this->setstate(ios_base::failbit);
  1219.   }
  1220. #endif // _RWSTD_NO_EXTENSION
  1221.  
  1222.   /*
  1223.    * ~basic_ofstream()
  1224.    */
  1225.  
  1226.   template<class charT, class traits>
  1227.   basic_ofstream<charT, traits>::~basic_ofstream()
  1228.   {
  1229.   }
  1230.  
  1231.   /*
  1232.    * basic_filebuf *rdbuf() const
  1233.    */
  1234.  
  1235.   template<class charT, class traits>
  1236.   basic_filebuf<charT, traits> *
  1237.   basic_ofstream<charT, traits>::rdbuf() const
  1238.   {
  1239.     return (basic_filebuf<charT, traits> *)&__fb;
  1240.   }
  1241.  
  1242.   /*
  1243.    * bool is_open()
  1244.    */
  1245.  
  1246.   template<class charT, class traits>
  1247.   bool basic_ofstream<charT, traits>::is_open()
  1248.   {
  1249.     return __fb.is_open();
  1250.   }
  1251.  
  1252.   /*
  1253.    * void open(const char *, ios_base::openmode)
  1254.    */
  1255.  
  1256.   template<class charT, class traits>
  1257.   void basic_ofstream<charT, traits>::open(const char *s,
  1258.                                            ios_base::openmode mode,
  1259.                                            long protection )
  1260.   {
  1261.     this->clear();
  1262.     mode |= ios_base::out;
  1263.  
  1264.     if ( !__fb.open(s, mode, protection) )
  1265.       this->setstate(ios_base::failbit);
  1266.   }
  1267.  
  1268.   /*
  1269.    * void close()
  1270.    */
  1271.  
  1272.   template<class charT, class traits>
  1273.   void basic_ofstream<charT, traits>::close()
  1274.   {
  1275.     if(!is_open())
  1276.       return;
  1277.  
  1278.     if(!__fb.close())
  1279.       this->setstate(ios_base::failbit);
  1280.     else
  1281.       this->clear();
  1282.   }
  1283.  
  1284.   /*
  1285.    * class basic_fstream : public basic_iostream
  1286.    */
  1287.  
  1288.   /*
  1289.    * basic_fstream()
  1290.    */
  1291.  
  1292.   template<class charT, class traits>
  1293.   basic_fstream<charT, traits>::basic_fstream()
  1294.   : basic_iostream<charT, traits>( )
  1295.   {
  1296.     init(&__fb);
  1297.   }
  1298.  
  1299.   /*
  1300.    * basic_fstream(const char *, ios_base::openmode, long)
  1301.    *
  1302.    * opens a filebuf for reading and writing
  1303.    */
  1304.  
  1305.   template<class charT, class traits>
  1306.   basic_fstream<charT, traits>::
  1307.   basic_fstream(const char *s, ios_base::openmode mode, long protection)
  1308.   : basic_iostream<charT, traits>( )
  1309.   {
  1310.     init(&__fb);
  1311.     open(s, mode, protection);
  1312.   }
  1313.  
  1314.   /*
  1315.    * basic_fstream(int fd)
  1316.    * opens a filebuf for reading and writing
  1317.    */
  1318. #ifndef _RWSTD_NO_EXTENSION
  1319.  
  1320.   template<class charT, class traits>
  1321.   basic_fstream<charT, traits>::
  1322.   basic_fstream(int fd)
  1323.   : basic_iostream<charT, traits>( )
  1324.   {
  1325.  
  1326.     init(&__fb);
  1327.  
  1328.     if ( !__fb.open(fd) ) 
  1329.       this->setstate(ios_base::failbit);
  1330.   }
  1331.  
  1332.   /*
  1333.    * basic_fstream(int fd, char_type *buf, int len)
  1334.    * opens a filebuf for reading and writing
  1335.    */
  1336.  
  1337.   template<class charT, class traits>
  1338.   basic_fstream<charT, traits>::
  1339.   basic_fstream(int fd, char_type *buf, int len)
  1340.   : basic_iostream<charT, traits>( )
  1341.   {
  1342.  
  1343.     init(&__fb);
  1344.  
  1345.     if ( ( buf!=0 ) && ( len>0 ) )
  1346.       __fb.pubsetbuf(buf,len);
  1347.  
  1348.     if ( !__fb.open(fd) ) 
  1349.       this->setstate(ios_base::failbit);
  1350.   }
  1351. #endif // _RWSTD_NO_EXTENSION
  1352.   /*
  1353.    * ~basic_fstream()
  1354.    */
  1355.  
  1356.   template<class charT, class traits>
  1357.   basic_fstream<charT, traits>::~basic_fstream()
  1358.   {
  1359.   }
  1360.  
  1361.   /*
  1362.    * basic_filebuf *rdbuf() const
  1363.    * returns the streambuf associated with this stream
  1364.    */
  1365.  
  1366.   template<class charT, class traits>
  1367.   basic_filebuf<charT, traits> *
  1368.   basic_fstream<charT, traits>::rdbuf() const
  1369.   {
  1370.     return (basic_filebuf<charT, traits> *)&__fb;
  1371.   }
  1372.  
  1373.   /*
  1374.    * bool is_open()
  1375.    */
  1376.  
  1377.   template<class charT, class traits>
  1378.   bool basic_fstream<charT, traits>::is_open()
  1379.   {
  1380.     return __fb.is_open();
  1381.   }
  1382.  
  1383.   /*
  1384.    * void open(const char *, ios_base::openmode, long)
  1385.    * opens up a file
  1386.    */
  1387.  
  1388.   template<class charT, class traits>
  1389.   void basic_fstream<charT, traits>::
  1390.   open(const char *s, ios_base::openmode mode, long protection)
  1391.   {
  1392.     this->clear();
  1393.     if ( !__fb.open(s, mode, protection) ) 
  1394.       this->setstate(ios_base::failbit);
  1395.   }
  1396.  
  1397.   /* 
  1398.    * void close()
  1399.    */
  1400.  
  1401.   template<class charT, class traits>
  1402.   void basic_fstream<charT, traits>::close()
  1403.   {
  1404.     if(!is_open())
  1405.       return;
  1406.   
  1407.     if(!__fb.close())
  1408.       this->setstate(ios_base::failbit);
  1409.     else
  1410.       this->clear();
  1411.   }
  1412.  
  1413. #ifndef _RWSTD_NO_NAMESPACE
  1414. }
  1415. #endif
  1416. #pragma option pop
  1417. #endif /* __FSTREAM_CC */
  1418.