Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Input streams -*- C++ -*-
  2.  
  3. // Copyright (C) 2004-2015 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 3, 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. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. //
  26. // ISO C++ 14882: 27.6.1  Input streams
  27. //
  28.  
  29. #include <istream>
  30.  
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34.  
  35.   template<>
  36.     basic_istream<char>&
  37.     basic_istream<char>::
  38.     getline(char_type* __s, streamsize __n, char_type __delim)
  39.     {
  40.       _M_gcount = 0;
  41.       ios_base::iostate __err = ios_base::goodbit;
  42.       sentry __cerb(*this, true);
  43.       if (__cerb)
  44.         {
  45.           __try
  46.             {
  47.               const int_type __idelim = traits_type::to_int_type(__delim);
  48.               const int_type __eof = traits_type::eof();
  49.               __streambuf_type* __sb = this->rdbuf();
  50.               int_type __c = __sb->sgetc();
  51.              
  52.               while (_M_gcount + 1 < __n
  53.                      && !traits_type::eq_int_type(__c, __eof)
  54.                      && !traits_type::eq_int_type(__c, __idelim))
  55.                 {
  56.                   streamsize __size = std::min(streamsize(__sb->egptr()
  57.                                                           - __sb->gptr()),
  58.                                                streamsize(__n - _M_gcount
  59.                                                           - 1));
  60.                   if (__size > 1)
  61.                     {
  62.                       const char_type* __p = traits_type::find(__sb->gptr(),
  63.                                                                __size,
  64.                                                                __delim);
  65.                       if (__p)
  66.                         __size = __p - __sb->gptr();
  67.                       traits_type::copy(__s, __sb->gptr(), __size);
  68.                       __s += __size;
  69.                       __sb->__safe_gbump(__size);
  70.                       _M_gcount += __size;
  71.                       __c = __sb->sgetc();
  72.                     }
  73.                   else
  74.                     {
  75.                       *__s++ = traits_type::to_char_type(__c);
  76.                       ++_M_gcount;
  77.                       __c = __sb->snextc();
  78.                     }
  79.                 }
  80.  
  81.               if (traits_type::eq_int_type(__c, __eof))
  82.                 __err |= ios_base::eofbit;
  83.               else if (traits_type::eq_int_type(__c, __idelim))
  84.                 {
  85.                   ++_M_gcount;           
  86.                   __sb->sbumpc();
  87.                 }
  88.               else
  89.                 __err |= ios_base::failbit;
  90.             }
  91.           __catch(__cxxabiv1::__forced_unwind&)
  92.             {
  93.               this->_M_setstate(ios_base::badbit);
  94.               __throw_exception_again;
  95.             }
  96.           __catch(...)
  97.             { this->_M_setstate(ios_base::badbit); }
  98.         }
  99.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  100.       // 243. get and getline when sentry reports failure.
  101.       if (__n > 0)
  102.         *__s = char_type();
  103.       if (!_M_gcount)
  104.         __err |= ios_base::failbit;
  105.       if (__err)
  106.         this->setstate(__err);
  107.       return *this;
  108.     }
  109.  
  110.   template<>
  111.     basic_istream<char>&
  112.     basic_istream<char>::
  113.     ignore(streamsize __n, int_type __delim)
  114.     {
  115.       if (traits_type::eq_int_type(__delim, traits_type::eof()))
  116.         return ignore(__n);
  117.  
  118.       _M_gcount = 0;
  119.       sentry __cerb(*this, true);
  120.       if (__n > 0 && __cerb)
  121.         {
  122.           ios_base::iostate __err = ios_base::goodbit;
  123.           __try
  124.             {
  125.               const char_type __cdelim = traits_type::to_char_type(__delim);
  126.               const int_type __eof = traits_type::eof();
  127.               __streambuf_type* __sb = this->rdbuf();
  128.               int_type __c = __sb->sgetc();
  129.  
  130.               bool __large_ignore = false;
  131.               while (true)
  132.                 {
  133.                   while (_M_gcount < __n
  134.                          && !traits_type::eq_int_type(__c, __eof)
  135.                          && !traits_type::eq_int_type(__c, __delim))
  136.                     {
  137.                       streamsize __size = std::min(streamsize(__sb->egptr()
  138.                                                               - __sb->gptr()),
  139.                                                    streamsize(__n - _M_gcount));
  140.                       if (__size > 1)
  141.                         {
  142.                           const char_type* __p = traits_type::find(__sb->gptr(),
  143.                                                                    __size,
  144.                                                                    __cdelim);
  145.                           if (__p)
  146.                             __size = __p - __sb->gptr();
  147.                           __sb->__safe_gbump(__size);
  148.                           _M_gcount += __size;
  149.                           __c = __sb->sgetc();
  150.                         }
  151.                       else
  152.                         {
  153.                           ++_M_gcount;
  154.                           __c = __sb->snextc();
  155.                         }
  156.                     }
  157.                   if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
  158.                       && !traits_type::eq_int_type(__c, __eof)
  159.                       && !traits_type::eq_int_type(__c, __delim))
  160.                     {
  161.                       _M_gcount =
  162.                         __gnu_cxx::__numeric_traits<streamsize>::__min;
  163.                       __large_ignore = true;
  164.                     }
  165.                   else
  166.                     break;
  167.                 }
  168.  
  169.               if (__large_ignore)
  170.                 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
  171.  
  172.               if (traits_type::eq_int_type(__c, __eof))
  173.                 __err |= ios_base::eofbit;
  174.               else if (traits_type::eq_int_type(__c, __delim))
  175.                 {
  176.                   if (_M_gcount
  177.                       < __gnu_cxx::__numeric_traits<streamsize>::__max)
  178.                     ++_M_gcount;
  179.                   __sb->sbumpc();
  180.                 }
  181.             }
  182.           __catch(__cxxabiv1::__forced_unwind&)
  183.             {
  184.               this->_M_setstate(ios_base::badbit);
  185.               __throw_exception_again;
  186.             }
  187.           __catch(...)
  188.             { this->_M_setstate(ios_base::badbit); }
  189.           if (__err)
  190.             this->setstate(__err);
  191.         }
  192.       return *this;
  193.     }
  194.  
  195.   template<>
  196.     basic_istream<char>&
  197.     operator>>(basic_istream<char>& __in, char* __s)
  198.     {
  199.       typedef basic_istream<char>               __istream_type;
  200.       typedef __istream_type::int_type          __int_type;
  201.       typedef __istream_type::char_type         __char_type;
  202.       typedef __istream_type::traits_type       __traits_type;
  203.       typedef __istream_type::__streambuf_type  __streambuf_type;
  204.       typedef __istream_type::__ctype_type      __ctype_type;
  205.  
  206.       streamsize __extracted = 0;
  207.       ios_base::iostate __err = ios_base::goodbit;
  208.       __istream_type::sentry __cerb(__in, false);
  209.       if (__cerb)
  210.         {
  211.           __try
  212.             {
  213.               // Figure out how many characters to extract.
  214.               streamsize __num = __in.width();
  215.               if (__num <= 0)
  216.                 __num = __gnu_cxx::__numeric_traits<streamsize>::__max;
  217.  
  218.               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
  219.  
  220.               const __int_type __eof = __traits_type::eof();
  221.               __streambuf_type* __sb = __in.rdbuf();
  222.               __int_type __c = __sb->sgetc();
  223.  
  224.               while (__extracted < __num - 1
  225.                      && !__traits_type::eq_int_type(__c, __eof)
  226.                      && !__ct.is(ctype_base::space,
  227.                                  __traits_type::to_char_type(__c)))
  228.                 {
  229.                   streamsize __size = std::min(streamsize(__sb->egptr()
  230.                                                           - __sb->gptr()),
  231.                                                streamsize(__num - __extracted
  232.                                                           - 1));
  233.                   if (__size > 1)
  234.                     {
  235.                       __size = (__ct.scan_is(ctype_base::space,
  236.                                              __sb->gptr() + 1,
  237.                                              __sb->gptr() + __size)
  238.                                 - __sb->gptr());
  239.                       __traits_type::copy(__s, __sb->gptr(), __size);
  240.                       __s += __size;
  241.                       __sb->__safe_gbump(__size);
  242.                       __extracted += __size;
  243.                       __c = __sb->sgetc();
  244.                     }
  245.                   else
  246.                     {
  247.                       *__s++ = __traits_type::to_char_type(__c);
  248.                       ++__extracted;
  249.                       __c = __sb->snextc();
  250.                     }
  251.                 }
  252.  
  253.               if (__traits_type::eq_int_type(__c, __eof))
  254.                 __err |= ios_base::eofbit;
  255.  
  256.               // _GLIBCXX_RESOLVE_LIB_DEFECTS
  257.               // 68.  Extractors for char* should store null at end
  258.               *__s = __char_type();
  259.               __in.width(0);
  260.             }
  261.           __catch(__cxxabiv1::__forced_unwind&)
  262.             {
  263.               __in._M_setstate(ios_base::badbit);
  264.               __throw_exception_again;
  265.             }
  266.           __catch(...)
  267.             { __in._M_setstate(ios_base::badbit); }
  268.         }
  269.       if (!__extracted)
  270.         __err |= ios_base::failbit;
  271.       if (__err)
  272.         __in.setstate(__err);
  273.       return __in;
  274.     }
  275.  
  276. #ifdef _GLIBCXX_USE_WCHAR_T
  277.   template<>
  278.     basic_istream<wchar_t>&
  279.     basic_istream<wchar_t>::
  280.     getline(char_type* __s, streamsize __n, char_type __delim)
  281.     {
  282.       _M_gcount = 0;
  283.       ios_base::iostate __err = ios_base::goodbit;
  284.       sentry __cerb(*this, true);
  285.       if (__cerb)
  286.         {
  287.           __try
  288.             {
  289.               const int_type __idelim = traits_type::to_int_type(__delim);
  290.               const int_type __eof = traits_type::eof();
  291.               __streambuf_type* __sb = this->rdbuf();
  292.               int_type __c = __sb->sgetc();
  293.              
  294.               while (_M_gcount + 1 < __n
  295.                      && !traits_type::eq_int_type(__c, __eof)
  296.                      && !traits_type::eq_int_type(__c, __idelim))
  297.                 {
  298.                   streamsize __size = std::min(streamsize(__sb->egptr()
  299.                                                           - __sb->gptr()),
  300.                                                streamsize(__n - _M_gcount
  301.                                                           - 1));
  302.                   if (__size > 1)
  303.                     {
  304.                       const char_type* __p = traits_type::find(__sb->gptr(),
  305.                                                                __size,
  306.                                                                __delim);
  307.                       if (__p)
  308.                         __size = __p - __sb->gptr();
  309.                       traits_type::copy(__s, __sb->gptr(), __size);
  310.                       __s += __size;
  311.                       __sb->__safe_gbump(__size);
  312.                       _M_gcount += __size;
  313.                       __c = __sb->sgetc();
  314.                     }
  315.                   else
  316.                     {
  317.                       *__s++ = traits_type::to_char_type(__c);
  318.                       ++_M_gcount;
  319.                       __c = __sb->snextc();
  320.                     }
  321.                 }
  322.  
  323.               if (traits_type::eq_int_type(__c, __eof))
  324.                 __err |= ios_base::eofbit;
  325.               else if (traits_type::eq_int_type(__c, __idelim))
  326.                 {
  327.                   ++_M_gcount;           
  328.                   __sb->sbumpc();
  329.                 }
  330.               else
  331.                 __err |= ios_base::failbit;
  332.             }
  333.           __catch(__cxxabiv1::__forced_unwind&)
  334.             {
  335.               this->_M_setstate(ios_base::badbit);
  336.               __throw_exception_again;
  337.             }
  338.           __catch(...)
  339.             { this->_M_setstate(ios_base::badbit); }
  340.         }
  341.       // _GLIBCXX_RESOLVE_LIB_DEFECTS
  342.       // 243. get and getline when sentry reports failure.
  343.       if (__n > 0)
  344.         *__s = char_type();
  345.       if (!_M_gcount)
  346.         __err |= ios_base::failbit;
  347.       if (__err)
  348.         this->setstate(__err);
  349.       return *this;
  350.     }
  351.  
  352.   template<>
  353.     basic_istream<wchar_t>&
  354.     basic_istream<wchar_t>::
  355.     ignore(streamsize __n, int_type __delim)
  356.     {
  357.       if (traits_type::eq_int_type(__delim, traits_type::eof()))
  358.         return ignore(__n);
  359.  
  360.       _M_gcount = 0;
  361.       sentry __cerb(*this, true);
  362.       if (__n > 0 && __cerb)
  363.         {
  364.           ios_base::iostate __err = ios_base::goodbit;
  365.           __try
  366.             {
  367.               const char_type __cdelim = traits_type::to_char_type(__delim);
  368.               const int_type __eof = traits_type::eof();
  369.               __streambuf_type* __sb = this->rdbuf();
  370.               int_type __c = __sb->sgetc();
  371.  
  372.               bool __large_ignore = false;
  373.               while (true)
  374.                 {
  375.                   while (_M_gcount < __n
  376.                          && !traits_type::eq_int_type(__c, __eof)
  377.                          && !traits_type::eq_int_type(__c, __delim))
  378.                     {
  379.                       streamsize __size = std::min(streamsize(__sb->egptr()
  380.                                                               - __sb->gptr()),
  381.                                                    streamsize(__n - _M_gcount));
  382.                       if (__size > 1)
  383.                         {
  384.                           const char_type* __p = traits_type::find(__sb->gptr(),
  385.                                                                    __size,
  386.                                                                    __cdelim);
  387.                           if (__p)
  388.                             __size = __p - __sb->gptr();
  389.                           __sb->__safe_gbump(__size);
  390.                           _M_gcount += __size;
  391.                           __c = __sb->sgetc();
  392.                         }
  393.                       else
  394.                         {
  395.                           ++_M_gcount;
  396.                           __c = __sb->snextc();
  397.                         }
  398.                     }
  399.                   if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
  400.                       && !traits_type::eq_int_type(__c, __eof)
  401.                       && !traits_type::eq_int_type(__c, __delim))
  402.                     {
  403.                       _M_gcount =
  404.                         __gnu_cxx::__numeric_traits<streamsize>::__min;
  405.                       __large_ignore = true;
  406.                     }
  407.                   else
  408.                     break;
  409.                 }
  410.  
  411.               if (__large_ignore)
  412.                 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
  413.  
  414.               if (traits_type::eq_int_type(__c, __eof))
  415.                 __err |= ios_base::eofbit;
  416.               else if (traits_type::eq_int_type(__c, __delim))
  417.                 {
  418.                   if (_M_gcount
  419.                       < __gnu_cxx::__numeric_traits<streamsize>::__max)
  420.                     ++_M_gcount;
  421.                   __sb->sbumpc();
  422.                 }
  423.             }
  424.           __catch(__cxxabiv1::__forced_unwind&)
  425.             {
  426.               this->_M_setstate(ios_base::badbit);
  427.               __throw_exception_again;
  428.             }
  429.           __catch(...)
  430.             { this->_M_setstate(ios_base::badbit); }
  431.           if (__err)
  432.             this->setstate(__err);
  433.         }
  434.       return *this;
  435.     }
  436. #endif
  437.  
  438.  
  439. _GLIBCXX_END_NAMESPACE_VERSION
  440. } // namespace
  441.