home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / src / strstream.cpp < prev    next >
C/C++ Source or Header  |  2001-01-26  |  10KB  |  426 lines

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