Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Stream buffer classes -*- C++ -*-
  2.  
  3. // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 2, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // You should have received a copy of the GNU General Public License along
  17. // with this library; see the file COPYING.  If not, write to the Free
  18. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  19. // USA.
  20.  
  21. // As a special exception, you may use this file as part of a free software
  22. // library without restriction.  Specifically, if other files instantiate
  23. // templates or use macros or inline functions from this file, or you compile
  24. // this file and link it with other files to produce an executable, this
  25. // file does not by itself cause the resulting executable to be covered by
  26. // the GNU General Public License.  This exception does not however
  27. // invalidate any other reasons why the executable file might be covered by
  28. // the GNU General Public License.
  29.  
  30. //
  31. // ISO C++ 14882: 27.5  Stream buffers
  32. //
  33.  
  34. #ifndef _CPP_BITS_STREAMBUF_TCC
  35. #define _CPP_BITS_STREAMBUF_TCC 1
  36.  
  37. namespace std {
  38.  
  39.   template<typename _CharT, typename _Traits>
  40.     basic_streambuf<_CharT, _Traits>::int_type
  41.     basic_streambuf<_CharT, _Traits>::
  42.     sbumpc()
  43.     {
  44.       int_type __ret;
  45.       if (_M_in_cur && _M_in_cur < _M_in_end)
  46.         {
  47.           char_type __c = *gptr();
  48.           _M_in_cur_move(1);
  49.           __ret = traits_type::to_int_type(__c);
  50.         }
  51.       else
  52.         __ret = this->uflow();
  53.       return __ret;
  54.     }
  55.  
  56.   template<typename _CharT, typename _Traits>
  57.     basic_streambuf<_CharT, _Traits>::int_type
  58.     basic_streambuf<_CharT, _Traits>::
  59.     sputbackc(char_type __c)
  60.     {
  61.       int_type __ret;
  62.       bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
  63.       bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]);
  64.       if (!__testpos || __testne)
  65.         __ret = pbackfail(traits_type::to_int_type(__c));
  66.       else
  67.         {
  68.           _M_in_cur_move(-1);
  69.           __ret = traits_type::to_int_type(*this->gptr());
  70.         }
  71.       return __ret;
  72.     }
  73.  
  74.   template<typename _CharT, typename _Traits>
  75.     basic_streambuf<_CharT, _Traits>::int_type
  76.     basic_streambuf<_CharT, _Traits>::
  77.     sungetc()
  78.     {
  79.       int_type __ret;
  80.       if (_M_in_cur && _M_in_beg < _M_in_cur)
  81.         {
  82.           _M_in_cur_move(-1);
  83.           __ret = traits_type::to_int_type(*_M_in_cur);
  84.         }
  85.       else
  86.         __ret = this->pbackfail();
  87.       return __ret;
  88.     }
  89.  
  90.   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
  91.   // allocated space, and on certain (rare but entirely legal)
  92.   // situations, there will be no allocated space yet the internal
  93.   // buffers will still be valid. (This happens if setp is used to set
  94.   // the internal buffer to say some externally-allocated sequence.)
  95.   template<typename _CharT, typename _Traits>
  96.     basic_streambuf<_CharT, _Traits>::int_type
  97.     basic_streambuf<_CharT, _Traits>::
  98.     sputc(char_type __c)
  99.     {
  100.       int_type __ret;
  101.       if (_M_out_buf_size())
  102.         {
  103.           *_M_out_cur = __c;
  104.           _M_out_cur_move(1);
  105.           __ret = traits_type::to_int_type(__c);
  106.         }
  107.       else
  108.         __ret = this->overflow(traits_type::to_int_type(__c));
  109.       return __ret;
  110.     }
  111.  
  112.   template<typename _CharT, typename _Traits>
  113.     streamsize
  114.     basic_streambuf<_CharT, _Traits>::
  115.     xsgetn(char_type* __s, streamsize __n)
  116.     {
  117.       streamsize __ret = 0;
  118.       while (__ret < __n)
  119.         {
  120.           size_t __buf_len = _M_in_end - _M_in_cur;
  121.           if (__buf_len > 0)
  122.             {
  123.               size_t __remaining = __n - __ret;
  124.               size_t __len = min(__buf_len, __remaining);
  125.               traits_type::copy(__s, _M_in_cur, __len);
  126.               __ret += __len;
  127.               __s += __len;
  128.               _M_in_cur_move(__len);
  129.             }
  130.          
  131.           if (__ret < __n)
  132.             {
  133.               int_type __c = this->uflow();  
  134.               if (__c != traits_type::eof())
  135.                 {
  136.                   traits_type::assign(*__s++, traits_type::to_char_type(__c));
  137.                   ++__ret;
  138.                 }
  139.               else
  140.                 break;
  141.             }
  142.         }
  143.       return __ret;
  144.     }
  145.  
  146.   // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
  147.   // allocated space, and on certain (rare but entirely legal)
  148.   // situations, there will be no allocated space yet the internal
  149.   // buffers will still be valid. (This happens if setp is used to set
  150.   // the internal buffer to say some externally-allocated sequence.)
  151.   template<typename _CharT, typename _Traits>
  152.     streamsize
  153.     basic_streambuf<_CharT, _Traits>::
  154.     xsputn(const char_type* __s, streamsize __n)
  155.     {
  156.       streamsize __ret = 0;
  157.       while (__ret < __n)
  158.         {
  159.           off_type __buf_len = _M_out_buf_size();
  160.           if (__buf_len > 0)
  161.             {
  162.               off_type __remaining = __n - __ret;
  163.               off_type __len = min(__buf_len, __remaining);
  164.               traits_type::copy(_M_out_cur, __s, __len);
  165.               __ret += __len;
  166.               __s += __len;
  167.               _M_out_cur_move(__len);
  168.             }
  169.  
  170.           if (__ret < __n)
  171.             {
  172.               int_type __c = this->overflow(traits_type::to_int_type(*__s));
  173.               if (__c != traits_type::eof())
  174.                 {
  175.                   ++__ret;
  176.                   ++__s;
  177.                 }
  178.               else
  179.                 break;
  180.             }
  181.         }
  182.       return __ret;
  183.     }
  184.  
  185.   // Conceivably, this could be used to implement buffer-to-buffer
  186.   // copies, if this was ever desired in an un-ambiguous way by the
  187.   // standard. If so, then checks for __ios being zero would be
  188.   // necessary.
  189.   template<typename _CharT, typename _Traits>
  190.     streamsize
  191.     __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
  192.                       basic_streambuf<_CharT, _Traits>* __sbin,
  193.                       basic_streambuf<_CharT, _Traits>* __sbout)
  194.   {
  195.       typedef typename _Traits::int_type        int_type;
  196.  
  197.       streamsize __ret = 0;
  198.       streamsize __bufsize = __sbin->in_avail();
  199.       streamsize __xtrct;
  200.       bool __testput = __sbout->_M_mode & ios_base::out;
  201.       try {
  202.         while (__testput && __bufsize != -1)
  203.           {
  204.             __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
  205.             __ret += __xtrct;
  206.             __sbin->_M_in_cur_move(__xtrct);
  207.             if (__xtrct == __bufsize)
  208.               {
  209.                 int_type __c = __sbin->sgetc();
  210.                 if (__c == _Traits::eof())
  211.                   {
  212.                     __ios.setstate(ios_base::eofbit);
  213.                     break;
  214.                   }
  215.                 __bufsize = __sbin->in_avail();
  216.               }
  217.             else
  218.               break;
  219.           }
  220.       }
  221.       catch(exception& __fail) {
  222.         if ((__ios.exceptions() & ios_base::failbit) != 0)
  223.           __throw_exception_again;
  224.       }
  225.       return __ret;
  226.     }
  227. } // namespace std
  228.  
  229. #endif // _CPP_BITS_STREAMBUF_TCC
  230.  
  231.