_sstream.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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. #ifndef _STLP_SSTREAM_C
  19. #define _STLP_SSTREAM_C
  20. #ifndef _STLP_INTERNAL_SSTREAM
  21. # include <stl/_sstream.h>
  22. #endif
  23. #if defined ( _STLP_NESTED_TYPE_PARAM_BUG )
  24. // no wint_t is supported for this mode
  25. # define __BSB_int_type__ int
  26. # define __BSB_pos_type__ streampos
  27. #else
  28. # define __BSB_int_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::int_type
  29. # define __BSB_pos_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
  30. #endif
  31. _STLP_BEGIN_NAMESPACE
  32. //----------------------------------------------------------------------
  33. // Non-inline stringbuf member functions.
  34. // Constructors. Note that the base class constructor sets all of the
  35. // get and area pointers to null.
  36. template <class _CharT, class _Traits, class _Alloc>
  37. basic_stringbuf<_CharT, _Traits, _Alloc>
  38. ::basic_stringbuf(ios_base::openmode __mode)
  39. : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str()
  40. {}
  41. template <class _CharT, class _Traits, class _Alloc>
  42. basic_stringbuf<_CharT, _Traits, _Alloc>
  43. ::basic_stringbuf(const basic_string<_CharT, _Traits, _Alloc>& __s, ios_base::openmode __mode)
  44. : basic_streambuf<_CharT, _Traits>(), _M_mode(__mode), _M_str(__s)
  45. {
  46. _M_set_ptrs();
  47. }
  48. template <class _CharT, class _Traits, class _Alloc>
  49. basic_stringbuf<_CharT, _Traits, _Alloc>::~basic_stringbuf()
  50. {}
  51. // Set the underlying string to a new value.
  52. template <class _CharT, class _Traits, class _Alloc>
  53. void
  54. basic_stringbuf<_CharT, _Traits, _Alloc>::str(const basic_string<_CharT, _Traits, _Alloc>& __s)
  55. {
  56. _M_str = __s;
  57. _M_set_ptrs();
  58. }
  59. template <class _CharT, class _Traits, class _Alloc>
  60. void
  61. basic_stringbuf<_CharT, _Traits, _Alloc>::_M_set_ptrs()
  62. {
  63. _CharT* __data_ptr = _S_start(_M_str);
  64. _CharT* __data_end = _S_finish(_M_str);
  65. // The initial read position is the beginning of the string.
  66. if (_M_mode & ios_base::in) {
  67. this->setg(__data_ptr, (_M_mode & ios_base::ate) ? __data_end : __data_ptr, __data_end);
  68. }
  69. // The initial write position is the beginning of the string.
  70. if (_M_mode & ios_base::out) {
  71. if ( _M_mode & (ios_base::app | ios_base::ate) ) {
  72. this->setp( __data_end, __data_end );
  73. } else {
  74. this->setp( __data_ptr, __data_end );
  75. this->pbump((int)_M_str.size()); // initial write position, if we initialized with string
  76. }
  77. // this->setp((_M_mode & (ios_base::app | ios_base::ate))? __data_end : __data_ptr, __data_end);
  78. }
  79. }
  80. // Precondition: gptr() >= egptr(). Returns a character, if one is available.
  81. template <class _CharT, class _Traits, class _Alloc>
  82. __BSB_int_type__
  83. basic_stringbuf<_CharT, _Traits, _Alloc>::underflow() {
  84. return this->gptr() != this->egptr()
  85. ? _Traits::to_int_type(*this->gptr())
  86. : _Traits::eof();
  87. }
  88. // Precondition: gptr() >= egptr().
  89. template <class _CharT, class _Traits, class _Alloc>
  90. __BSB_int_type__
  91. basic_stringbuf<_CharT, _Traits, _Alloc>::uflow() {
  92. if (this->gptr() != this->egptr()) {
  93. int_type __c = _Traits::to_int_type(*this->gptr());
  94. this->gbump(1);
  95. return __c;
  96. }
  97. else
  98. return _Traits::eof();
  99. }
  100. template <class _CharT, class _Traits, class _Alloc>
  101. __BSB_int_type__
  102. basic_stringbuf<_CharT, _Traits, _Alloc>::pbackfail(int_type __c) {
  103. if (this->gptr() != this->eback()) {
  104. if (!_Traits::eq_int_type(__c, _Traits::eof())) {
  105. if (_Traits::eq(_Traits::to_char_type(__c), this->gptr()[-1])) {
  106. this->gbump(-1);
  107. return __c;
  108. }
  109. else if (_M_mode & ios_base::out) {
  110. this->gbump(-1);
  111. *this->gptr() = _Traits::to_char_type(__c);
  112. return __c;
  113. }
  114. else
  115. return _Traits::eof();
  116. }
  117. else {
  118. this->gbump(-1);
  119. return _Traits::not_eof(__c);
  120. }
  121. }
  122. else
  123. return _Traits::eof();
  124. }
  125. template <class _CharT, class _Traits, class _Alloc>
  126. __BSB_int_type__ basic_stringbuf<_CharT, _Traits, _Alloc>::overflow(int_type __c)
  127. {
  128. if (!_Traits::eq_int_type(__c, _Traits::eof())) {
  129. if (_M_mode & ios_base::out) {
  130. if ( this->pptr() < this->epptr() ) { // just put back in any case
  131. _M_str.push_back( _Traits::to_char_type(__c) );
  132. this->pbump(1);
  133. } else if ( _M_mode & ios_base::in ) {
  134. ptrdiff_t __offset = this->gptr() - this->eback();
  135. _M_str.push_back(_Traits::to_char_type(__c));
  136. _CharT* __data_ptr = _S_start(_M_str);
  137. this->setg(__data_ptr, __data_ptr + __offset, _S_finish(_M_str));
  138. this->setp(__data_ptr, _S_finish(_M_str));
  139. this->pbump((int)_M_str.size());
  140. } else {
  141. _M_str.push_back( _Traits::to_char_type(__c) );
  142. this->setp(_S_start(_M_str), _S_finish(_M_str));
  143. this->pbump((int)_M_str.size());
  144. }
  145. return __c;
  146. }
  147. return _Traits::eof(); // Overflow always fails if it's read-only
  148. }
  149. return _Traits::not_eof(__c); // __c is EOF, so we don't have to do anything
  150. }
  151. template <class _CharT, class _Traits, class _Alloc>
  152. streamsize
  153. basic_stringbuf<_CharT, _Traits, _Alloc>::xsputn(const char_type* __s,
  154. streamsize __n) {
  155. streamsize __nwritten = 0;
  156. if ((_M_mode & ios_base::out) && __n > 0) {
  157. // If the put pointer is somewhere in the middle of the string,
  158. // then overwrite instead of append.
  159. if ( !_M_str.empty() && this->pbase() == _S_start(_M_str)) {
  160. ptrdiff_t __avail = _S_finish(_M_str) - this->pptr();
  161. if (__avail > __n) {
  162. _Traits::copy(this->pptr(), __s, __STATIC_CAST(size_t, __n));
  163. this->pbump((int)__n);
  164. return __n;
  165. } else {
  166. _Traits::copy(this->pptr(), __s, __avail);
  167. __nwritten += __avail;
  168. __n -= __avail;
  169. __s += __avail;
  170. }
  171. }
  172. // At this point we know we're appending.
  173. _CharT* __data_ptr;
  174. if (_M_mode & ios_base::in) {
  175. ptrdiff_t __get_offset = this->gptr() - this->eback();
  176. _M_str.append(__s, __s + __STATIC_CAST(ptrdiff_t, __n));
  177. __data_ptr = _S_start(_M_str);
  178. this->setg(__data_ptr, __data_ptr + __get_offset, _S_finish(_M_str));
  179. } else {
  180. _M_str.append(__s, __s + __STATIC_CAST(ptrdiff_t, __n));
  181. __data_ptr = _S_start(_M_str);
  182. }
  183. this->setp(__data_ptr, _S_finish(_M_str));
  184. this->pbump((int)_M_str.size());
  185. __nwritten += __n;
  186. }
  187. return __nwritten;
  188. }
  189. template <class _CharT, class _Traits, class _Alloc>
  190. streamsize
  191. basic_stringbuf<_CharT, _Traits, _Alloc>::_M_xsputnc(char_type __c,
  192. streamsize __n) {
  193. streamsize __nwritten = 0;
  194. if ((_M_mode & ios_base::out) && __n > 0) {
  195. // If the put pointer is somewhere in the middle of the string,
  196. // then overwrite instead of append.
  197. if (this->pbase() == _S_start(_M_str)) {
  198. ptrdiff_t __avail = _S_finish(_M_str) - this->pptr();
  199. if (__avail > __n) {
  200. _Traits::assign(this->pptr(), __STATIC_CAST(size_t, __n), __c);
  201. this->pbump(__STATIC_CAST(int, __n));
  202. return __n;
  203. }
  204. else {
  205. _Traits::assign(this->pptr(), __avail, __c);
  206. __nwritten += __avail;
  207. __n -= __avail;
  208. }
  209. }
  210. // At this point we know we're appending.
  211. size_t __app_size = sizeof(streamsize) > sizeof(size_t) ? __STATIC_CAST(size_t, (min)(__n, __STATIC_CAST(streamsize, _M_str.max_size())))
  212. : __STATIC_CAST(size_t, __n);
  213. _CharT* __data_ptr;
  214. if (this->_M_mode & ios_base::in) {
  215. ptrdiff_t __get_offset = this->gptr() - this->eback();
  216. _M_str.append(__app_size, __c);
  217. __data_ptr = _S_start(_M_str);
  218. this->setg(__data_ptr, __data_ptr + __get_offset, _S_finish(_M_str));
  219. } else {
  220. _M_str.append(__app_size, __c);
  221. __data_ptr = _S_start(_M_str);
  222. }
  223. this->setp(__data_ptr, _S_finish(_M_str));
  224. this->pbump((int)_M_str.size());
  225. __nwritten += __app_size;
  226. }
  227. return __nwritten;
  228. }
  229. // According to the C++ standard the effects of setbuf are implementation
  230. // defined, except that setbuf(0, 0) has no effect. In this implementation,
  231. // setbuf(<anything>, n), for n > 0, calls reserve(n) on the underlying
  232. // string.
  233. template <class _CharT, class _Traits, class _Alloc>
  234. basic_streambuf<_CharT, _Traits>*
  235. basic_stringbuf<_CharT, _Traits, _Alloc>::setbuf(_CharT*, streamsize __n) {
  236. if (__n > 0) {
  237. bool __do_get_area = false;
  238. bool __do_put_area = false;
  239. ptrdiff_t __offg = 0;
  240. ptrdiff_t __offp = 0;
  241. if (this->pbase() == _S_start(_M_str)) {
  242. __do_put_area = true;
  243. __offp = this->pptr() - this->pbase();
  244. }
  245. if (this->eback() == _S_start(_M_str)) {
  246. __do_get_area = true;
  247. __offg = this->gptr() - this->eback();
  248. }
  249. _M_str.reserve(sizeof(streamsize) > sizeof(size_t) ? __STATIC_CAST(size_t, (min)(__n, __STATIC_CAST(streamsize, _M_str.max_size())))
  250. : __STATIC_CAST(size_t, __n));
  251. _CharT* __data_ptr = _S_start(_M_str);
  252. if (__do_get_area) {
  253. this->setg(__data_ptr, __data_ptr + __offg, _S_finish(_M_str));
  254. }
  255. if (__do_put_area) {
  256. this->setp(__data_ptr, _S_finish(_M_str));
  257. this->pbump((int)__offp);
  258. }
  259. }
  260. return this;
  261. }
  262. template <class _CharT, class _Traits, class _Alloc>
  263. __BSB_pos_type__
  264. basic_stringbuf<_CharT, _Traits, _Alloc>
  265. ::seekoff(off_type __off,
  266. ios_base::seekdir __dir,
  267. ios_base::openmode __mode) {
  268. __mode &= _M_mode;
  269. bool __imode = (__mode & ios_base::in) != 0;
  270. bool __omode = (__mode & ios_base::out) != 0;
  271. if ( !(__imode || __omode) )
  272. return pos_type(off_type(-1));
  273. if ( (__imode && (this->gptr() == 0)) || (__omode && (this->pptr() == 0)) )
  274. return pos_type(off_type(-1));
  275. streamoff __newoff;
  276. switch(__dir) {
  277. case ios_base::beg:
  278. __newoff = 0;
  279. break;
  280. case ios_base::end:
  281. __newoff = _M_str.size();
  282. break;
  283. case ios_base::cur:
  284. __newoff = __imode ? this->gptr() - this->eback() : this->pptr() - this->pbase();
  285. if ( __off == 0 ) {
  286. return pos_type(__newoff);
  287. }
  288. break;
  289. default:
  290. return pos_type(off_type(-1));
  291. }
  292. __off += __newoff;
  293. if (__imode) {
  294. ptrdiff_t __n = this->egptr() - this->eback();
  295. if (__off < 0 || __off > __n)
  296. return pos_type(off_type(-1));
  297. this->setg(this->eback(), this->eback() + __STATIC_CAST(ptrdiff_t, __off),
  298. this->eback() + __STATIC_CAST(ptrdiff_t, __n));
  299. }
  300. if (__omode) {
  301. ptrdiff_t __n = this->epptr() - this->pbase();
  302. if (__off < 0 || __off > __n)
  303. return pos_type(off_type(-1));
  304. this->setp(this->pbase(), this->pbase() + __n);
  305. this->pbump((int)__off);
  306. }
  307. return pos_type(__off);
  308. }
  309. template <class _CharT, class _Traits, class _Alloc>
  310. __BSB_pos_type__
  311. basic_stringbuf<_CharT, _Traits, _Alloc>
  312. ::seekpos(pos_type __pos, ios_base::openmode __mode) {
  313. __mode &= _M_mode;
  314. bool __imode = (__mode & ios_base::in) != 0;
  315. bool __omode = (__mode & ios_base::out) != 0;
  316. if ( !(__imode || __omode) )
  317. return pos_type(off_type(-1));
  318. if ( (__imode && (this->gptr() == 0)) || (__omode && (this->pptr() == 0)) )
  319. return pos_type(off_type(-1));
  320. const off_type __n = __pos - pos_type(off_type(0));
  321. if (__imode) {
  322. if (__n < 0 || __n > this->egptr() - this->eback())
  323. return pos_type(off_type(-1));
  324. this->setg(this->eback(), this->eback() + __STATIC_CAST(ptrdiff_t, __n), this->egptr());
  325. }
  326. if (__omode) {
  327. if (__n < 0 || size_t(__n) > _M_str.size())
  328. return pos_type(off_type(-1));
  329. this->setp(_S_start(_M_str), _S_finish(_M_str));
  330. this->pbump((int)__n);
  331. }
  332. return __pos;
  333. }
  334. //----------------------------------------------------------------------
  335. // Non-inline istringstream member functions.
  336. template <class _CharT, class _Traits, class _Alloc>
  337. basic_istringstream<_CharT, _Traits, _Alloc>
  338. ::basic_istringstream(ios_base::openmode __mode)
  339. : basic_istream<_CharT, _Traits>(0),
  340. _M_buf(__mode | ios_base::in) {
  341. this->init(&_M_buf);
  342. }
  343. template <class _CharT, class _Traits, class _Alloc>
  344. basic_istringstream<_CharT, _Traits, _Alloc>
  345. ::basic_istringstream(const _String& __str,ios_base::openmode __mode)
  346. : basic_istream<_CharT, _Traits>(0),
  347. _M_buf(__str, __mode | ios_base::in) {
  348. this->init(&_M_buf);
  349. }
  350. template <class _CharT, class _Traits, class _Alloc>
  351. basic_istringstream<_CharT, _Traits, _Alloc>::~basic_istringstream()
  352. {}
  353. //----------------------------------------------------------------------
  354. // Non-inline ostringstream member functions.
  355. template <class _CharT, class _Traits, class _Alloc>
  356. basic_ostringstream<_CharT, _Traits, _Alloc>
  357. ::basic_ostringstream(ios_base::openmode __mode)
  358. : basic_ostream<_CharT, _Traits>(0),
  359. _M_buf(__mode | ios_base::out) {
  360. this->init(&_M_buf);
  361. }
  362. template <class _CharT, class _Traits, class _Alloc>
  363. basic_ostringstream<_CharT, _Traits, _Alloc>
  364. ::basic_ostringstream(const _String& __str, ios_base::openmode __mode)
  365. : basic_ostream<_CharT, _Traits>(0),
  366. _M_buf(__str, __mode | ios_base::out) {
  367. this->init(&_M_buf);
  368. }
  369. template <class _CharT, class _Traits, class _Alloc>
  370. basic_ostringstream<_CharT, _Traits, _Alloc>::~basic_ostringstream()
  371. {}
  372. //----------------------------------------------------------------------
  373. // Non-inline stringstream member functions.
  374. template <class _CharT, class _Traits, class _Alloc>
  375. basic_stringstream<_CharT, _Traits, _Alloc>
  376. ::basic_stringstream(ios_base::openmode __mode)
  377. : basic_iostream<_CharT, _Traits>(0), _M_buf(__mode) {
  378. this->init(&_M_buf);
  379. }
  380. template <class _CharT, class _Traits, class _Alloc>
  381. basic_stringstream<_CharT, _Traits, _Alloc>
  382. ::basic_stringstream(const _String& __str, ios_base::openmode __mode)
  383. : basic_iostream<_CharT, _Traits>(0), _M_buf(__str, __mode) {
  384. this->init(&_M_buf);
  385. }
  386. template <class _CharT, class _Traits, class _Alloc>
  387. basic_stringstream<_CharT, _Traits, _Alloc>::~basic_stringstream()
  388. {}
  389. _STLP_END_NAMESPACE
  390. # undef __BSB_int_type__
  391. # undef __BSB_pos_type__
  392. #endif /* _STLP_SSTREAM_C */
  393. // Local Variables:
  394. // mode:C++
  395. // End: