_string_io.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #ifndef _STLP_STRING_IO_C
  2. #define _STLP_STRING_IO_C
  3. #ifndef _STLP_STRING_IO_H
  4. # include <stl/_string_io.h>
  5. #endif
  6. #ifndef _STLP_INTERNAL_CTYPE_H
  7. # include <stl/_ctype.h>
  8. #endif
  9. _STLP_BEGIN_NAMESPACE
  10. template <class _CharT, class _Traits>
  11. bool _STLP_CALL
  12. __stlp_string_fill(basic_ostream<_CharT, _Traits>& __os,
  13. basic_streambuf<_CharT, _Traits>* __buf,
  14. streamsize __n) {
  15. _CharT __f = __os.fill();
  16. for (streamsize __i = 0; __i < __n; ++__i) {
  17. if (_Traits::eq_int_type(__buf->sputc(__f), _Traits::eof()))
  18. return false;
  19. }
  20. return true;
  21. }
  22. template <class _CharT, class _Traits, class _Alloc>
  23. basic_ostream<_CharT, _Traits>& _STLP_CALL
  24. operator << (basic_ostream<_CharT, _Traits>& __os,
  25. const basic_string<_CharT,_Traits,_Alloc>& __s) {
  26. typedef basic_ostream<_CharT, _Traits> __ostream;
  27. typedef typename basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
  28. // The hypothesis of this implementation is that size_type is unsigned:
  29. _STLP_STATIC_ASSERT(__STATIC_CAST(size_type, -1) > 0)
  30. typename __ostream::sentry __sentry(__os);
  31. bool __ok = false;
  32. if (__sentry) {
  33. __ok = true;
  34. size_type __n = __s.size();
  35. const bool __left = (__os.flags() & __ostream::left) != 0;
  36. const streamsize __w = __os.width(0);
  37. basic_streambuf<_CharT, _Traits>* __buf = __os.rdbuf();
  38. const bool __need_pad = (((sizeof(streamsize) > sizeof(size_t)) && (__STATIC_CAST(streamsize, __n) < __w)) ||
  39. ((sizeof(streamsize) <= sizeof(size_t)) && (__n < __STATIC_CAST(size_t, __w))));
  40. streamsize __pad_len = __need_pad ? __w - __n : 0;
  41. if (!__left)
  42. __ok = __stlp_string_fill(__os, __buf, __pad_len);
  43. __ok = __ok && (__buf->sputn(__s.data(), streamsize(__n)) == streamsize(__n));
  44. if (__left)
  45. __ok = __ok && __stlp_string_fill(__os, __buf, __pad_len);
  46. }
  47. if (!__ok)
  48. __os.setstate(__ostream::failbit);
  49. return __os;
  50. }
  51. template <class _CharT, class _Traits, class _Alloc>
  52. basic_istream<_CharT, _Traits>& _STLP_CALL
  53. operator >> (basic_istream<_CharT, _Traits>& __is,
  54. basic_string<_CharT,_Traits, _Alloc>& __s) {
  55. typedef basic_istream<_CharT, _Traits> __istream;
  56. typedef typename basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
  57. // The hypothesis of this implementation is that size_type is unsigned:
  58. _STLP_STATIC_ASSERT(__STATIC_CAST(size_type, -1) > 0)
  59. typename __istream::sentry __sentry(__is);
  60. if (__sentry) {
  61. basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
  62. typedef ctype<_CharT> _C_type;
  63. const locale& __loc = __is.getloc();
  64. const _C_type& _Ctype = use_facet<_C_type>(__loc);
  65. __s.clear();
  66. streamsize __width = __is.width(0);
  67. size_type __n;
  68. if (__width <= 0)
  69. __n = __s.max_size();
  70. /* __width can only overflow size_type if sizeof(streamsize) > sizeof(size_type)
  71. * because here we know that __width is positive and the stattic assertion check
  72. * that size_type is unsigned.
  73. */
  74. else if (sizeof(streamsize) > sizeof(size_type) &&
  75. (__width > __STATIC_CAST(streamsize, __s.max_size())))
  76. __n = 0;
  77. else {
  78. __n = __STATIC_CAST(size_type, __width);
  79. __s.reserve(__n);
  80. }
  81. while (__n-- > 0) {
  82. typename _Traits::int_type __c1 = __buf->sbumpc();
  83. if (_Traits::eq_int_type(__c1, _Traits::eof())) {
  84. __is.setstate(__istream::eofbit);
  85. break;
  86. }
  87. else {
  88. _CharT __c = _Traits::to_char_type(__c1);
  89. if (_Ctype.is(_C_type::space, __c)) {
  90. if (_Traits::eq_int_type(__buf->sputbackc(__c), _Traits::eof()))
  91. __is.setstate(__istream::failbit);
  92. break;
  93. }
  94. else
  95. __s.push_back(__c);
  96. }
  97. }
  98. // If we have read no characters, then set failbit.
  99. if (__s.empty())
  100. __is.setstate(__istream::failbit);
  101. }
  102. else
  103. __is.setstate(__istream::failbit);
  104. return __is;
  105. }
  106. template <class _CharT, class _Traits, class _Alloc>
  107. basic_istream<_CharT, _Traits>& _STLP_CALL
  108. getline(basic_istream<_CharT, _Traits>& __is,
  109. basic_string<_CharT,_Traits,_Alloc>& __s,
  110. _CharT __delim) {
  111. typedef basic_istream<_CharT, _Traits> __istream;
  112. typedef typename basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
  113. size_type __nread = 0;
  114. typename basic_istream<_CharT, _Traits>::sentry __sentry(__is, true);
  115. if (__sentry) {
  116. basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
  117. __s.clear();
  118. while (__nread < __s.max_size()) {
  119. int __c1 = __buf->sbumpc();
  120. if (_Traits::eq_int_type(__c1, _Traits::eof())) {
  121. __is.setstate(__istream::eofbit);
  122. break;
  123. }
  124. else {
  125. ++__nread;
  126. _CharT __c = _Traits::to_char_type(__c1);
  127. if (!_Traits::eq(__c, __delim))
  128. __s.push_back(__c);
  129. else
  130. break; // Character is extracted but not appended.
  131. }
  132. }
  133. }
  134. if (__nread == 0 || __nread >= __s.max_size())
  135. __is.setstate(__istream::failbit);
  136. return __is;
  137. }
  138. _STLP_END_NAMESPACE
  139. #endif
  140. // Local Variables:
  141. // mode:C++
  142. // End: