Subversion Repositories Kolibri OS

Rev

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

  1. // strstream definitions -*- C++ -*-
  2.  
  3. // Copyright (C) 2001-2013 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.  * Copyright (c) 1998
  27.  * Silicon Graphics Computer Systems, Inc.
  28.  *
  29.  * Permission to use, copy, modify, distribute and sell this software
  30.  * and its documentation for any purpose is hereby granted without fee,
  31.  * provided that the above copyright notice appear in all copies and
  32.  * that both that copyright notice and this permission notice appear
  33.  * in supporting documentation.  Silicon Graphics makes no
  34.  * representations about the suitability of this software for any
  35.  * purpose.  It is provided "as is" without express or implied warranty.
  36.  */
  37.  
  38. // Implementation of the classes in header <strstream>.
  39. // WARNING: The classes defined in <strstream> are DEPRECATED.  This
  40. // header is defined in section D.7.1 of the C++ standard, and it
  41. // MAY BE REMOVED in a future standard revision.  You should use the
  42. // header <sstream> instead.
  43.  
  44. #include <strstream>
  45. #include <algorithm>
  46. #include <new>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <limits.h>
  50.  
  51. namespace std _GLIBCXX_VISIBILITY(default)
  52. {
  53. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  54.  
  55.   strstreambuf::strstreambuf(streamsize initial_capacity)
  56.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(true),
  57.     _M_frozen(false), _M_constant(false)
  58.   {
  59.     streamsize n = std::max(initial_capacity, streamsize(16));
  60.    
  61.     char* buf = _M_alloc(n);
  62.     if (buf)
  63.       {
  64.         setp(buf, buf + n);
  65.         setg(buf, buf, buf);
  66.       }
  67.   }
  68.  
  69.   strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
  70.   : _Base(), _M_alloc_fun(alloc_f), _M_free_fun(free_f), _M_dynamic(true),
  71.     _M_frozen(false), _M_constant(false)
  72.   {
  73.     streamsize n = 16;
  74.  
  75.     char* buf = _M_alloc(n);
  76.     if (buf)
  77.       {
  78.         setp(buf, buf + n);
  79.         setg(buf, buf, buf);
  80.       }
  81.   }
  82.  
  83.   strstreambuf::strstreambuf(char* get, streamsize n, char* put) throw ()
  84.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
  85.     _M_frozen(false), _M_constant(false)
  86.   { _M_setup(get, put, n); }
  87.  
  88.   strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put) throw ()
  89.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
  90.   _M_frozen(false), _M_constant(false)
  91.   { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
  92.  
  93.   strstreambuf::strstreambuf(unsigned char* get, streamsize n,
  94.                              unsigned char* put) throw ()
  95.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
  96.     _M_frozen(false), _M_constant(false)
  97.   { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
  98.  
  99.   strstreambuf::strstreambuf(const char* get, streamsize n) throw ()
  100.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
  101.     _M_frozen(false), _M_constant(true)
  102.   { _M_setup(const_cast<char*>(get), 0, n); }
  103.  
  104.   strstreambuf::strstreambuf(const signed char* get, streamsize n) throw ()
  105.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
  106.     _M_frozen(false), _M_constant(true)
  107.   { _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n); }
  108.  
  109.   strstreambuf::strstreambuf(const unsigned char* get, streamsize n) throw ()
  110.   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
  111.     _M_frozen(false), _M_constant(true)
  112.   { _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n); }
  113.  
  114.   strstreambuf::~strstreambuf()
  115.   {
  116.     if (_M_dynamic && !_M_frozen)
  117.       _M_free(eback());
  118.   }
  119.  
  120.   void
  121.   strstreambuf::freeze(bool frozenflag) throw ()
  122.   {
  123.     if (_M_dynamic)
  124.       _M_frozen = frozenflag;
  125.   }
  126.  
  127.   char*
  128.   strstreambuf::str() throw ()
  129.   {
  130.     freeze(true);
  131.     return eback();
  132.   }
  133.  
  134.   int
  135.   strstreambuf::pcount() const throw ()
  136.   { return pptr() ? pptr() - pbase() : 0; }
  137.  
  138.   strstreambuf::int_type
  139.   strstreambuf::overflow(int_type c)
  140.   {
  141.     if (c == traits_type::eof())
  142.       return traits_type::not_eof(c);
  143.    
  144.     // Try to expand the buffer.
  145.     if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant)
  146.       {
  147.         ptrdiff_t old_size = epptr() - pbase();
  148.         ptrdiff_t new_size = std::max(ptrdiff_t(2 * old_size), ptrdiff_t(1));
  149.        
  150.         char* buf = _M_alloc(new_size);
  151.         if (buf)
  152.           {
  153.             memcpy(buf, pbase(), old_size);
  154.             char* old_buffer = pbase();
  155.             bool reposition_get = false;
  156.             ptrdiff_t old_get_offset;
  157.             if (gptr() != 0)
  158.               {
  159.                 reposition_get = true;
  160.                 old_get_offset = gptr() - eback();
  161.               }
  162.            
  163.             setp(buf, buf + new_size);
  164.             __safe_pbump(old_size);
  165.  
  166.             if (reposition_get)
  167.               setg(buf, buf + old_get_offset, buf +
  168.                    std::max(old_get_offset, old_size));
  169.  
  170.             _M_free(old_buffer);
  171.           }
  172.       }
  173.    
  174.     if (pptr() != epptr())
  175.       {
  176.         *pptr() = c;
  177.         pbump(1);
  178.         return c;
  179.       }
  180.     else
  181.       return traits_type::eof();
  182.   }
  183.  
  184.   strstreambuf::int_type
  185.   strstreambuf::pbackfail(int_type c)
  186.   {
  187.     if (gptr() != eback())
  188.       {
  189.       if (c == _Traits::eof())
  190.         {
  191.           gbump(-1);
  192.           return _Traits::not_eof(c);
  193.         }
  194.       else if (c == _Traits::to_int_type(gptr()[-1]))
  195.         {  // KLUDGE
  196.           gbump(-1);
  197.           return c;
  198.         }
  199.       else if (!_M_constant)
  200.         {
  201.           gbump(-1);
  202.           *gptr() = c;
  203.           return c;
  204.         }
  205.     }
  206.     return _Traits::eof();
  207.   }
  208.  
  209.   strstreambuf::int_type
  210.   strstreambuf::underflow()
  211.   {
  212.     if (gptr() == egptr() && pptr() && pptr() > egptr())
  213.       setg(eback(), gptr(), pptr());
  214.    
  215.     if (gptr() != egptr())
  216.       return (unsigned char) *gptr();
  217.     else
  218.       return _Traits::eof();
  219.   }
  220.  
  221.   basic_streambuf<char, char_traits<char> >*
  222.   strstreambuf::setbuf(char*, streamsize)
  223.   { return this; }
  224.  
  225.   strstreambuf::pos_type
  226.   strstreambuf::seekoff(off_type off, ios_base::seekdir dir,
  227.                         ios_base::openmode mode)
  228.   {
  229.     bool do_get = false;
  230.     bool do_put = false;
  231.  
  232.     if ((mode & (ios_base::in | ios_base::out))
  233.         == (ios_base::in | ios_base::out) &&
  234.         (dir == ios_base::beg || dir == ios_base::end))
  235.       do_get = do_put = true;
  236.     else if (mode & ios_base::in)
  237.       do_get = true;
  238.     else if (mode & ios_base::out)
  239.       do_put = true;
  240.  
  241.     // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
  242.     // area is undefined if there is no get area.
  243.     if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
  244.       return pos_type(off_type(-1));
  245.  
  246.     char* seeklow  = eback();
  247.     char* seekhigh = epptr() ? epptr() : egptr();
  248.  
  249.     off_type newoff;
  250.     switch (dir)
  251.       {
  252.       case ios_base::beg:
  253.         newoff = 0;
  254.         break;
  255.       case ios_base::end:
  256.         newoff = seekhigh - seeklow;
  257.         break;
  258.       case ios_base::cur:
  259.         newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
  260.         break;
  261.       default:
  262.         return pos_type(off_type(-1));
  263.       }
  264.    
  265.     off += newoff;
  266.     if (off < 0 || off > seekhigh - seeklow)
  267.       return pos_type(off_type(-1));
  268.  
  269.     if (do_put)
  270.       {
  271.         if (seeklow + off < pbase())
  272.           {
  273.             setp(seeklow, epptr());
  274.             __safe_pbump(off);
  275.           }
  276.         else
  277.           {
  278.             setp(pbase(), epptr());
  279.             __safe_pbump(off - (pbase() - seeklow));
  280.           }
  281.       }
  282.     if (do_get)
  283.       {
  284.         if (off <= egptr() - seeklow)
  285.           setg(seeklow, seeklow + off, egptr());
  286.         else if (off <= pptr() - seeklow)
  287.           setg(seeklow, seeklow + off, pptr());
  288.         else
  289.           setg(seeklow, seeklow + off, epptr());
  290.       }
  291.     return pos_type(newoff);
  292.   }
  293.  
  294.   strstreambuf::pos_type
  295.   strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
  296.   { return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode); }
  297.  
  298.   char*
  299.   strstreambuf::_M_alloc(size_t n)
  300.   {
  301.     if (_M_alloc_fun)
  302.       return static_cast<char*>(_M_alloc_fun(n));
  303.     else
  304.       return new char[n];
  305.   }
  306.  
  307.   void
  308.   strstreambuf::_M_free(char* p)
  309.   {
  310.     if (p)
  311.       {
  312.         if (_M_free_fun)
  313.           _M_free_fun(p);
  314.         else
  315.           delete[] p;
  316.       }
  317.   }
  318.  
  319.   void
  320.   strstreambuf::_M_setup(char* get, char* put, streamsize n) throw ()
  321.   {
  322.     if (get)
  323.       {
  324.         size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
  325.        
  326.         if (put)
  327.           {
  328.             setg(get, get, put);
  329.             setp(put, put + N);
  330.           }
  331.         else
  332.           setg(get, get, get + N);
  333.       }
  334.   }
  335.  
  336.   istrstream::istrstream(char* s)
  337.   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
  338.   { basic_ios<char>::init(&_M_buf); }
  339.  
  340.   istrstream::istrstream(const char* s)
  341.   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
  342.   { basic_ios<char>::init(&_M_buf); }
  343.  
  344.   istrstream::istrstream(char* s, streamsize n)
  345.   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
  346.   { basic_ios<char>::init(&_M_buf); }
  347.  
  348.   istrstream::istrstream(const char* s, streamsize n)
  349.   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
  350.   { basic_ios<char>::init(&_M_buf); }
  351.  
  352.   istrstream::~istrstream() { }
  353.  
  354.   strstreambuf*
  355.   istrstream::rdbuf() const throw ()
  356.   { return const_cast<strstreambuf*>(&_M_buf); }
  357.  
  358.   char*
  359.   istrstream::str() throw ()
  360.   { return _M_buf.str(); }
  361.  
  362.   ostrstream::ostrstream()
  363.   : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
  364.   { basic_ios<char>::init(&_M_buf); }
  365.  
  366.   ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
  367.   : basic_ios<char>(), basic_ostream<char>(0),
  368.     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
  369.   { basic_ios<char>::init(&_M_buf); }
  370.  
  371.   ostrstream::~ostrstream() {}
  372.  
  373.   strstreambuf*
  374.   ostrstream::rdbuf() const throw ()
  375.   { return const_cast<strstreambuf*>(&_M_buf); }
  376.  
  377.   void
  378.   ostrstream::freeze(bool freezeflag) throw ()
  379.   { _M_buf.freeze(freezeflag); }
  380.  
  381.   char*
  382.   ostrstream::str() throw ()
  383.   { return _M_buf.str(); }
  384.  
  385.   int
  386.   ostrstream::pcount() const throw ()
  387.   { return _M_buf.pcount(); }
  388.  
  389.   strstream::strstream()
  390.   : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
  391.   { basic_ios<char>::init(&_M_buf); }
  392.  
  393.   strstream::strstream(char* s, int n, ios_base::openmode mode)
  394.   : basic_ios<char>(), basic_iostream<char>(0),
  395.     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
  396.   { basic_ios<char>::init(&_M_buf); }
  397.  
  398.   strstream::~strstream() { }
  399.  
  400.   strstreambuf*
  401.   strstream::rdbuf() const throw ()
  402.   { return const_cast<strstreambuf*>(&_M_buf); }
  403.  
  404.   void
  405.   strstream::freeze(bool freezeflag) throw ()
  406.   { _M_buf.freeze(freezeflag); }
  407.  
  408.   int
  409.   strstream::pcount() const throw ()
  410.   { return _M_buf.pcount(); }
  411.  
  412.   char*
  413.   strstream::str() throw ()
  414.   { return _M_buf.str(); }
  415.  
  416. _GLIBCXX_END_NAMESPACE_VERSION
  417. } // namespace
  418.