home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / stlport / stl / _string_io.c < prev    next >
C/C++ Source or Header  |  2002-02-02  |  8KB  |  331 lines

  1. #ifndef _STLP_STRING_IO_C
  2. #define _STLP_STRING_IO_C
  3.  
  4. #ifndef _STLP_STRING_IO_H
  5. # include <stl/_string_io.h>
  6. #endif
  7.  
  8. # ifdef _STLP_DEBUG
  9. #  define basic_string _Nondebug_string
  10. # endif
  11.  
  12. _STLP_BEGIN_NAMESPACE
  13.  
  14. # if defined (_STLP_OWN_IOSTREAMS)
  15. #  define _STLP_USING_IO
  16. # else
  17. #  define _STLP_USING_IO _STLP_USING_VENDOR_STD
  18. # endif
  19.  
  20. #if defined (_STLP_USE_NEW_IOSTREAMS)
  21.  
  22. template <class _CharT, class _Traits>
  23. bool _STLP_CALL
  24. __stlp_string_fill(basic_ostream<_CharT, _Traits>& __os,
  25.                   basic_streambuf<_CharT, _Traits>* __buf,
  26.                   size_t __n)
  27. {
  28.   _CharT __f = __os.fill();
  29.   size_t __i;
  30.   bool __ok = true;
  31.  
  32.   for (__i = 0; __i < __n; ++__i)
  33.     __ok = __ok && !_Traits::eq_int_type(__buf->sputc(__f), _Traits::eof());
  34.   return __ok;
  35. }
  36.  
  37. template <class _CharT, class _Traits, class _Alloc>
  38. basic_ostream<_CharT, _Traits>& _STLP_CALL
  39. operator<<(basic_ostream<_CharT, _Traits>& __os, 
  40.            const basic_string<_CharT,_Traits,_Alloc>& __s)
  41. {
  42.  
  43.   _STLP_USING_IO
  44.   typedef basic_ostream<_CharT, _Traits> __ostream;
  45.   typename __ostream::sentry __sentry(__os);
  46.   bool __ok = false;
  47.  
  48.   if (__sentry) {
  49.     __ok = true;
  50.     size_t __n = __s.size();
  51.     size_t __pad_len = 0;
  52.     const bool __left = (__os.flags() & __ostream::left) != 0;
  53.     const size_t __w = __os.width(0);
  54.     basic_streambuf<_CharT, _Traits>* __buf = __os.rdbuf();
  55.  
  56.     if (__n < __w) {
  57.       __pad_len = __w - __n;
  58.     }
  59.     
  60.     if (!__left)
  61.       __ok = __stlp_string_fill(__os, __buf, __pad_len);    
  62.  
  63.     __ok = __ok && (__buf->sputn(__s.data(), streamsize(__n)) == streamsize(__n));
  64.  
  65.     if (__left)
  66.       __ok = __ok && __stlp_string_fill(__os, __buf, __pad_len);
  67.   }
  68.  
  69.   if (!__ok)
  70.     __os.setstate(__ostream::failbit);
  71.  
  72.   return __os;
  73. }
  74.  
  75. template <class _CharT, class _Traits, class _Alloc>
  76. basic_istream<_CharT, _Traits>& _STLP_CALL 
  77. operator>>(basic_istream<_CharT, _Traits>& __is,
  78.            basic_string<_CharT,_Traits, _Alloc>& __s)
  79. {
  80.   _STLP_USING_IO
  81.   typedef basic_istream<_CharT, _Traits> __istream;
  82.   typename __istream::sentry __sentry(__is);
  83.  
  84.   if (__sentry) {
  85.     basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
  86.     typedef ctype<_CharT> _C_type;
  87.  
  88. #ifdef _STLP_OWN_IOSTREAMS
  89.     //    const _C_type& _Ctype = use_facet<_C_type>(__loc);
  90.     const _C_type& _Ctype = *(const _C_type*)__is._M_ctype_facet();
  91. #else
  92. # if defined (_STLP_MSVC) && (_STLP_MSVC <= 1200 ) || defined (__ICL)
  93.     const locale& __loc = __is.getloc();
  94.     const _C_type& _Ctype = use_facet(__loc , ( _C_type * ) 0, true);
  95. # elif defined (__SUNPRO_CC)
  96.     const locale& __loc = __is.getloc();
  97.     const _C_type& _Ctype = use_facet(__loc , ( _C_type * ) 0);
  98. # else
  99.     const locale& __loc = __is.getloc();
  100.     const _C_type& _Ctype = use_facet<_C_type>(__loc);
  101. # endif
  102. #endif
  103.     __s.clear();
  104.     size_t __n = __is.width(0);
  105.     if (__n == 0)
  106.       __n = __STATIC_CAST(size_t,-1);
  107.     else
  108.       __s.reserve(__n);
  109.     
  110.  
  111.     while (__n-- > 0) {
  112.       typename _Traits::int_type __c1 = __buf->sbumpc();
  113.       if (_Traits::eq_int_type(__c1, _Traits::eof())) {
  114.         __is.setstate(__istream::eofbit);
  115.         break;
  116.       }
  117.       else {
  118.         _CharT __c = _Traits::to_char_type(__c1);
  119.  
  120.         if (_Ctype.is(_C_type::space, __c)) {
  121.           if (_Traits::eq_int_type(__buf->sputbackc(__c), _Traits::eof()))
  122.             __is.setstate(__istream::failbit);
  123.           break;
  124.         }
  125.         else
  126.           __s.push_back(__c);
  127.       }
  128.     }
  129.     
  130.     // If we have read no characters, then set failbit.
  131.     if (__s.size() == 0)
  132.       __is.setstate(__istream::failbit);
  133.   }
  134.   else
  135.     __is.setstate(__istream::failbit);
  136.  
  137.   return __is;
  138. }
  139.  
  140. template <class _CharT, class _Traits, class _Alloc>    
  141. basic_istream<_CharT, _Traits>& _STLP_CALL 
  142. getline(basic_istream<_CharT, _Traits>& __is,
  143.         basic_string<_CharT,_Traits,_Alloc>& __s,
  144.         _CharT __delim)
  145. {
  146.   _STLP_USING_IO
  147.   typedef basic_istream<_CharT, _Traits> __istream;
  148.   size_t __nread = 0;
  149.   typename basic_istream<_CharT, _Traits>::sentry __sentry(__is, true);
  150.   if (__sentry) {
  151.     basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
  152.     __s.clear();
  153.  
  154.     while (__nread < __s.max_size()) {
  155.       int __c1 = __buf->sbumpc();
  156.       if (_Traits::eq_int_type(__c1, _Traits::eof())) {
  157.         __is.setstate(__istream::eofbit);
  158.         break;
  159.       }
  160.       else {
  161.         ++__nread;
  162.         _CharT __c = _Traits::to_char_type(__c1);
  163.         if (!_Traits::eq(__c, __delim)) 
  164.           __s.push_back(__c);
  165.         else
  166.           break;              // Character is extracted but not appended.
  167.       }
  168.     }
  169.   }
  170.   if (__nread == 0 || __nread >= __s.max_size())
  171.     __is.setstate(__istream::failbit);
  172.  
  173.   return __is;
  174. }
  175.  
  176. #elif ! defined ( _STLP_USE_NO_IOSTREAMS )
  177.  
  178. // (reg) For Watcom IO, _OSTREAM_DLL tells if ostream class is in .exe or in .dll
  179.  
  180. template <class _CharT, class _Traits, class _Alloc>
  181. _OSTREAM_DLL&  _STLP_CALL operator<<(_OSTREAM_DLL& __os, 
  182.                     const basic_string<_CharT,_Traits,_Alloc>& __s)
  183. {
  184.   _STLP_USING_IO
  185.   streambuf* __buf = __os.rdbuf();
  186.   if (__buf) {
  187.     size_t __n = __s.size();
  188.     size_t __pad_len = 0;
  189.     const bool __left = (__os.flags() & ios::left) !=0;
  190.     const size_t __w = __os.width();
  191.  
  192.     if (__n < __w) { 
  193.       __pad_len = __w - __n; 
  194.     } 
  195.     
  196.     if (!__left)
  197.       __stlp_string_fill(__os, __buf, __pad_len);
  198.   
  199.     const size_t __nwritten = __buf->sputn(__s.data(), __n);
  200.  
  201.     if (__left)
  202.       __stlp_string_fill(__os, __buf, __pad_len);
  203.  
  204.     if (__nwritten != __n)
  205.       __os.clear(__os.rdstate() | ios::failbit);
  206.  
  207.     __os.width(0);
  208.   }
  209.   else
  210.     __os.clear(__os.rdstate() | ios::badbit);
  211.  
  212.   return __os;
  213. }
  214.  
  215. template <class _CharT, class _Traits, class _Alloc>
  216. _ISTREAM_DLL& _STLP_CALL operator>>(_ISTREAM_DLL& __is, basic_string<_CharT,_Traits,_Alloc>& __s)
  217. {
  218.   _STLP_USING_IO
  219.   if (!__is)
  220.     return __is;
  221.  
  222.   streambuf* __buf = __is.rdbuf();
  223.   if (__buf) {
  224.  
  225.     if (__is.flags() & ios::skipws) {
  226.       //      _CharT __c;
  227.       int __c;
  228.       do {
  229.         __c = __buf->sbumpc();
  230.       }
  231.       while (__c != EOF && isspace((unsigned char)__c));
  232.  
  233.       if (__c == EOF) {
  234.         __is.clear(__is.rdstate() | ios::eofbit | ios::failbit);
  235.       }
  236.       else {
  237.     if (__buf->sputbackc(__c) == EOF)
  238.       __is.clear(__is.rdstate() | ios::failbit);
  239.       }
  240.     }
  241.  
  242.     // If we arrive at end of file (or fail for some other reason) while
  243.     // still discarding whitespace, then we don't try to read the string.
  244.     if (__is) {
  245.       __s.clear();
  246.  
  247.       size_t __n = __is.width();
  248.       if (__n == 0)
  249.         __n = __STATIC_CAST(size_t,-1);
  250.       else
  251.         __s.reserve(__n);
  252.  
  253.       while (__n-- > 0) {
  254.         int __c1 = __buf->sbumpc();
  255.         if (__c1 == EOF) {
  256.           __is.clear(__is.rdstate() | ios::eofbit);
  257.           break;
  258.         }
  259.         else {
  260.           _CharT __c = _Traits::to_char_type(__c1);
  261.  
  262.           if (isspace((unsigned char) __c)) {
  263.             if (__buf->sputbackc(__c) == EOF)
  264.               __is.clear(__is.rdstate() | ios::failbit);
  265.             break;
  266.           }
  267.           else
  268.             __s.push_back(__c);
  269.         }
  270.       }
  271.     
  272.       // If we have read no characters, then set failbit.
  273.       if (__s.size() == 0)
  274.         __is.clear(__is.rdstate() | ios::failbit);
  275.     }
  276.  
  277.     __is.width(0);
  278.   }
  279.   else                          // We have no streambuf.
  280.     __is.clear(__is.rdstate() | ios::badbit);
  281.  
  282.   return __is;
  283. }
  284.  
  285. template <class _CharT, class _Traits, class _Alloc>    
  286. _ISTREAM_DLL& _STLP_CALL getline(_ISTREAM_DLL& __is,
  287.                  basic_string<_CharT,_Traits,_Alloc>& __s,
  288.                  _CharT __delim)
  289. {
  290.   _STLP_USING_IO
  291.   streambuf* __buf = __is.rdbuf();
  292.   if (__buf) {
  293.     size_t __nread = 0;
  294.     if (__is) {
  295.       __s.clear();
  296.  
  297.       while (__nread < __s.max_size()) {
  298.         int __c1 = __buf->sbumpc();
  299.         if (__c1 == EOF) {
  300.           __is.clear(__is.rdstate() | ios::eofbit);
  301.           break;
  302.         }
  303.         else {
  304.           ++__nread;
  305.           _CharT __c = _Traits::to_char_type(__c1);
  306.           if (!_Traits::eq(__c, __delim)) 
  307.             __s.push_back(__c);
  308.           else
  309.             break;              // Character is extracted but not appended.
  310.         }
  311.       }
  312.     }
  313.  
  314.     if (__nread == 0 || __nread >= __s.max_size())
  315.       __is.clear(__is.rdstate() | ios::failbit);
  316.   }
  317.   else
  318.     __is.clear(__is.rdstate() | ios::badbit);
  319.  
  320.   return __is;
  321. }
  322.  
  323. # endif /* _STLP_NEW_IOSTREAMS */
  324.  
  325. _STLP_END_NAMESPACE
  326.  
  327. // # undef _STLP_USING_IO
  328. # undef basic_string
  329.  
  330. #endif
  331.