Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

500 lines
14 KiB

  1. // sstream standard header
  2. #pragma once
  3. #ifndef _SSTREAM_
  4. #define _SSTREAM_
  5. #include <string>
  6. #pragma pack(push,8)
  7. #pragma warning(push,3)
  8. #pragma warning(disable: 4251)
  9. _STD_BEGIN
  10. // TEMPLATE CLASS basic_stringbuf
  11. template<class _Elem,
  12. class _Traits,
  13. class _Alloc>
  14. class basic_stringbuf
  15. : public basic_streambuf<_Elem, _Traits>
  16. { // stream buffer maintaining an allocated character array
  17. public:
  18. typedef _Alloc allocator_type;
  19. typedef basic_streambuf<_Elem, _Traits> _Mysb;
  20. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  21. explicit basic_stringbuf(ios_base::openmode _Mode =
  22. ios_base::in | ios_base::out)
  23. { // construct empty character buffer from mode
  24. _Init(0, 0, _Getstate(_Mode));
  25. }
  26. explicit basic_stringbuf(const _Mystr& _Str,
  27. ios_base::openmode _Mode = ios_base::in | ios_base::out)
  28. { // construct character buffer from string, mode
  29. _Init(_Str.c_str(), _Str.size(), _Getstate(_Mode));
  30. }
  31. virtual ~basic_stringbuf()
  32. { // destroy the object
  33. _Tidy();
  34. }
  35. enum
  36. { // constants for bits in stream state
  37. _Allocated = 1, // set if character array storage has been allocated
  38. _Constant = 2, // set if character array nonmutable
  39. _Noread = 4}; // set if character array cannot be read
  40. typedef int _Strstate;
  41. typedef typename _Traits::int_type int_type;
  42. typedef typename _Traits::pos_type pos_type;
  43. typedef typename _Traits::off_type off_type;
  44. _Mystr str() const
  45. { // return string copy of character array
  46. if (!(_Mystate & _Constant) && _Mysb::pptr() != 0)
  47. { // writable, make string from write buffer
  48. _Mystr _Str(_Mysb::pbase(), (_Seekhigh < _Mysb::pptr()
  49. ? _Mysb::pptr() : _Seekhigh) - _Mysb::pbase());
  50. return (_Str);
  51. }
  52. else if (!(_Mystate & _Noread) && _Mysb::gptr() != 0)
  53. { // readable, make string from read buffer
  54. _Mystr _Str(_Mysb::eback(), _Mysb::egptr() - _Mysb::eback());
  55. return (_Str);
  56. }
  57. else
  58. { // inaccessible, return empty string
  59. _Mystr _Nul;
  60. return (_Nul);
  61. }
  62. }
  63. void str(const _Mystr& _Newstr)
  64. { // replace character array from string
  65. _Tidy();
  66. _Init(_Newstr.c_str(), _Newstr.size(), _Mystate);
  67. }
  68. protected:
  69. virtual int_type overflow(int_type _Meta = _Traits::eof())
  70. { // put an element to stream
  71. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  72. return (_Traits::not_eof(_Meta)); // EOF, return success code
  73. else if (_Mysb::pptr() != 0
  74. && _Mysb::pptr() < _Mysb::epptr())
  75. { // room in buffer, store it
  76. *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
  77. return (_Meta);
  78. }
  79. else if (_Mystate & _Constant)
  80. return (_Traits::eof()); // array nonmutable, fail
  81. else
  82. { // grow buffer and store element
  83. size_t _Oldsize = _Mysb::pptr() == 0
  84. ? 0 : _Mysb::epptr() - _Mysb::eback();
  85. size_t _Newsize = _Oldsize;
  86. size_t _Inc = _Newsize / 2 < _MINSIZE
  87. ? _MINSIZE : _Newsize / 2; // grow by 50 per cent
  88. _Elem *_Ptr = 0;
  89. while (0 < _Inc && INT_MAX - _Inc < _Newsize)
  90. _Inc /= 2; // increment causes overflow, halve it
  91. if (0 < _Inc)
  92. { // finite increment, allocate new character array
  93. _Newsize += _Inc;
  94. _Ptr = _Al.allocate(_Newsize, (void *)0);
  95. }
  96. if (0 < _Oldsize)
  97. _Traits::copy(_Ptr, _Mysb::eback(), _Oldsize);
  98. if (_Mystate & _Allocated)
  99. _Al.deallocate(_Mysb::eback(), _Oldsize);
  100. _Mystate |= _Allocated;
  101. if (_Oldsize == 0)
  102. { // first growth, set up pointers
  103. _Seekhigh = _Ptr;
  104. _Mysb::setp(_Ptr, _Ptr + _Newsize);
  105. if (_Mystate & _Noread)
  106. _Mysb::setg(_Ptr, 0, _Ptr);
  107. else
  108. _Mysb::setg(_Ptr, _Ptr, _Ptr + 1);
  109. }
  110. else
  111. { // not first growth, adjust pointers
  112. _Seekhigh = _Seekhigh - _Mysb::eback() + _Ptr;
  113. _Mysb::setp(_Mysb::pbase() - _Mysb::eback() + _Ptr,
  114. _Mysb::pptr() - _Mysb::eback() + _Ptr, _Ptr + _Newsize);
  115. if (_Mystate & _Noread)
  116. _Mysb::setg(_Ptr, 0, _Ptr);
  117. else
  118. _Mysb::setg(_Ptr,
  119. _Mysb::gptr() - _Mysb::eback() + _Ptr,
  120. _Mysb::pptr() + 1);
  121. }
  122. *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
  123. return (_Meta);
  124. }
  125. }
  126. virtual int_type pbackfail(int_type _Meta = _Traits::eof())
  127. { // put an element back to stream
  128. if (_Mysb::gptr() == 0
  129. || _Mysb::gptr() <= _Mysb::eback()
  130. || !_Traits::eq_int_type(_Traits::eof(), _Meta)
  131. && !_Traits::eq(_Traits::to_char_type(_Meta), _Mysb::gptr()[-1])
  132. && _Mystate & _Constant)
  133. return (_Traits::eof()); // can't put back, fail
  134. else
  135. { // back up one position and store put-back character
  136. _Mysb::gbump(-1);
  137. if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
  138. *_Mysb::gptr() = _Traits::to_char_type(_Meta);
  139. return (_Traits::not_eof(_Meta));
  140. }
  141. }
  142. virtual int_type underflow()
  143. { // get an element from stream, but don't point past it
  144. if (_Mysb::gptr() == 0)
  145. return (_Traits::eof()); // no character buffer, fail
  146. else if (_Mysb::gptr() < _Mysb::egptr())
  147. return (_Traits::to_int_type(*_Mysb::gptr())); // return buffered
  148. else if (_Mystate & _Noread || _Mysb::pptr() == 0
  149. || _Mysb::pptr() <= _Mysb::gptr() && _Seekhigh <= _Mysb::gptr())
  150. return (_Traits::eof()); // can't read, fail
  151. else
  152. { // extend read buffer into written area, then return buffered
  153. if (_Seekhigh < _Mysb::pptr())
  154. _Seekhigh = _Mysb::pptr();
  155. _Mysb::setg(_Mysb::eback(), _Mysb::gptr(), _Seekhigh);
  156. return (_Traits::to_int_type(*_Mysb::gptr()));
  157. }
  158. }
  159. virtual pos_type seekoff(off_type _Off, ios_base::seekdir _Way,
  160. ios_base::openmode _Which = ios_base::in | ios_base::out)
  161. { // change position by _Off, according to _Way, _Mode
  162. if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
  163. _Seekhigh = _Mysb::pptr(); // update high-water pointer
  164. if (_Which & ios_base::in && _Mysb::gptr() != 0)
  165. { // position within read buffer
  166. if (_Way == ios_base::end)
  167. _Off += off_type(_Seekhigh - _Mysb::eback());
  168. else if (_Way == ios_base::cur
  169. && (_Which & ios_base::out) == 0)
  170. _Off += off_type(_Mysb::gptr() - _Mysb::eback());
  171. else if (_Way != ios_base::beg)
  172. _Off = _BADOFF;
  173. if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
  174. { // change read position
  175. _Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
  176. if (_Which & ios_base::out && _Mysb::pptr() != 0)
  177. _Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
  178. _Mysb::epptr()); // change write position to match
  179. }
  180. else
  181. _Off = _BADOFF;
  182. }
  183. else if (_Which & ios_base::out && _Mysb::pptr() != 0)
  184. { // position within write buffer
  185. if (_Way == ios_base::end)
  186. _Off += off_type(_Seekhigh - _Mysb::eback());
  187. else if (_Way == ios_base::cur)
  188. _Off += off_type(_Mysb::pptr() - _Mysb::eback());
  189. else if (_Way != ios_base::beg)
  190. _Off = _BADOFF;
  191. if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
  192. _Mysb::pbump((int)(_Mysb::eback()
  193. - _Mysb::pptr() + _Off)); // change write position
  194. else
  195. _Off = _BADOFF;
  196. }
  197. else
  198. _Off = _BADOFF; // neither read nor write buffer selected, fail
  199. return (pos_type(_Off));
  200. }
  201. virtual pos_type seekpos(pos_type _Ptr,
  202. ios_base::openmode _Mode = ios_base::in | ios_base::out)
  203. { // change position to _Pos, according to _Mode
  204. streamoff _Off = (streamoff)_Ptr;
  205. if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
  206. _Seekhigh = _Mysb::pptr(); // update high-water pointer
  207. if (_Off == _BADOFF)
  208. ;
  209. else if (_Mode & ios_base::in && _Mysb::gptr() != 0)
  210. { // position within read buffer
  211. if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
  212. { // change read position
  213. _Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
  214. if (_Mode & ios_base::out && _Mysb::pptr() != 0)
  215. _Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
  216. _Mysb::epptr()); // change write position to match
  217. }
  218. else
  219. _Off = _BADOFF;
  220. }
  221. else if (_Mode & ios_base::out && _Mysb::pptr() != 0)
  222. { // position within write buffer
  223. if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
  224. _Mysb::pbump((int)(_Mysb::eback()
  225. - _Mysb::pptr() + _Off)); // change write position
  226. else
  227. _Off = _BADOFF;
  228. }
  229. else
  230. _Off = _BADOFF;
  231. return (streampos(_Off));
  232. }
  233. void _Init(const _Elem *_Ptr, size_t _Count, _Strstate _State)
  234. { // initialize buffer to [_Ptr, _Ptr + _Count), set state
  235. _Seekhigh = 0;
  236. _Mystate = _State;
  237. if (_Count != 0
  238. && (_Mystate & (_Noread | _Constant)) != (_Noread | _Constant))
  239. { // finite buffer that can be read or written, set it up
  240. _Elem *_Pnew = _Al.allocate(_Count, (void *)0);
  241. _Traits::copy(_Pnew, _Ptr, _Count);
  242. _Seekhigh = _Pnew + _Count;
  243. if (!(_Mystate & _Noread))
  244. _Mysb::setg(_Pnew, _Pnew,
  245. _Pnew + _Count); // setup read buffer
  246. if (!(_Mystate & _Constant))
  247. { // setup write buffer, and maybe read buffer
  248. _Mysb::setp(_Pnew, _Pnew + _Count);
  249. if (_Mysb::gptr() == 0)
  250. _Mysb::setg(_Pnew, 0, _Pnew);
  251. }
  252. _Mystate |= _Allocated;
  253. }
  254. }
  255. void _Tidy()
  256. { // discard any allocated buffer and clear pointers
  257. if (_Mystate & _Allocated)
  258. _Al.deallocate(_Mysb::eback(),
  259. (_Mysb::pptr() != 0 ? _Mysb::epptr()
  260. : _Mysb::egptr()) - _Mysb::eback());
  261. _Mysb::setg(0, 0, 0);
  262. _Mysb::setp(0, 0);
  263. _Seekhigh = 0;
  264. _Mystate &= ~_Allocated;
  265. }
  266. private:
  267. enum
  268. { // constant for minimum buffer size
  269. _MINSIZE = 32};
  270. _Strstate _Getstate(ios_base::openmode _Mode)
  271. { // convert open mode to stream state bits
  272. _Strstate _State = (_Strstate)0;
  273. if (!(_Mode & ios_base::in))
  274. _State |= _Noread;
  275. if (!(_Mode & ios_base::out))
  276. _State |= _Constant;
  277. return (_State);
  278. }
  279. _Elem *_Seekhigh; // the high-water pointer in character array
  280. _Strstate _Mystate; // the stream state
  281. allocator_type _Al; // the allocator object
  282. };
  283. #ifdef _DLL_CPPLIB
  284. template class _CRTIMP2 basic_stringbuf<char,
  285. char_traits<char>, allocator<char> >;
  286. template class _CRTIMP2 basic_stringbuf<wchar_t,
  287. char_traits<wchar_t>, allocator<wchar_t> >;
  288. #endif // _DLL_CPPLIB
  289. // TEMPLATE CLASS basic_istringstream
  290. template<class _Elem,
  291. class _Traits,
  292. class _Alloc>
  293. class basic_istringstream
  294. : public basic_istream<_Elem, _Traits>
  295. { // input stream associated with a character array
  296. public:
  297. typedef _Alloc allocator_type;
  298. typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
  299. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  300. explicit basic_istringstream(ios_base::openmode _Mode = ios_base::in)
  301. : basic_istream<_Elem, _Traits>(&_Stringbuffer),
  302. _Stringbuffer(_Mode | ios_base::in)
  303. { // construct empty readable character buffer
  304. }
  305. explicit basic_istringstream(const _Mystr& _Str,
  306. ios_base::openmode _Mode = ios_base::in)
  307. : basic_istream<_Elem, _Traits>(&_Stringbuffer),
  308. _Stringbuffer(_Str, _Mode | ios_base::in)
  309. { // construct readable character buffer from NTCS
  310. }
  311. virtual ~basic_istringstream()
  312. { // destroy the object
  313. }
  314. _Mysb *rdbuf() const
  315. { // return pointer to file buffer
  316. return ((_Mysb *)&_Stringbuffer);
  317. }
  318. _Mystr str() const
  319. { // return string copy of character array
  320. return (_Stringbuffer.str());
  321. }
  322. void str(const _Mystr& _Newstr)
  323. { // replace character array from string
  324. _Stringbuffer.str(_Newstr);
  325. }
  326. private:
  327. _Mysb _Stringbuffer; // the string buffer
  328. };
  329. #ifdef _DLL_CPPLIB
  330. template class _CRTIMP2 basic_istringstream<char,
  331. char_traits<char>, allocator<char> >;
  332. template class _CRTIMP2 basic_istringstream<wchar_t,
  333. char_traits<wchar_t>, allocator<wchar_t> >;
  334. #endif // _DLL_CPPLIB
  335. // TEMPLATE CLASS basic_ostringstream
  336. template<class _Elem,
  337. class _Traits,
  338. class _Alloc>
  339. class basic_ostringstream
  340. : public basic_ostream<_Elem, _Traits>
  341. { // output stream associated with a character array
  342. public:
  343. typedef _Alloc allocator_type;
  344. typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
  345. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  346. explicit basic_ostringstream(ios_base::openmode _Mode = ios_base::out)
  347. : basic_ostream<_Elem, _Traits>(&_Stringbuffer),
  348. _Stringbuffer(_Mode | ios_base::out)
  349. { // construct empty writable character buffer
  350. }
  351. explicit basic_ostringstream(const _Mystr& _Str,
  352. ios_base::openmode _Mode = ios_base::out)
  353. : basic_ostream<_Elem, _Traits>(&_Stringbuffer),
  354. _Stringbuffer(_Str, _Mode | ios_base::out)
  355. { // construct writable character buffer from NTCS
  356. }
  357. virtual ~basic_ostringstream()
  358. { // destroy the object
  359. }
  360. _Mysb *rdbuf() const
  361. { // return pointer to buffer
  362. return ((_Mysb *)&_Stringbuffer);
  363. }
  364. _Mystr str() const
  365. { // return string copy of character array
  366. return (_Stringbuffer.str());
  367. }
  368. void str(const _Mystr& _Newstr)
  369. { // replace character array from string
  370. _Stringbuffer.str(_Newstr);
  371. }
  372. private:
  373. _Mysb _Stringbuffer; // the string buffer
  374. };
  375. #ifdef _DLL_CPPLIB
  376. template class _CRTIMP2 basic_ostringstream<char,
  377. char_traits<char>, allocator<char> >;
  378. template class _CRTIMP2 basic_ostringstream<wchar_t,
  379. char_traits<wchar_t>, allocator<wchar_t> >;
  380. #endif // _DLL_CPPLIB
  381. // TEMPLATE CLASS basic_stringstream
  382. template<class _Elem,
  383. class _Traits,
  384. class _Alloc>
  385. class basic_stringstream
  386. : public basic_iostream<_Elem, _Traits>
  387. { // input/output stream associated with a character array
  388. public:
  389. typedef _Elem char_type;
  390. typedef _Traits traits_type;
  391. typedef _Alloc allocator_type;
  392. typedef typename _Traits::int_type int_type;
  393. typedef typename _Traits::pos_type pos_type;
  394. typedef typename _Traits::off_type off_type;
  395. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  396. explicit basic_stringstream(ios_base::openmode _Mode =
  397. ios_base::in | ios_base::out)
  398. : basic_iostream<_Elem, _Traits>(&_Stringbuffer),
  399. _Stringbuffer(_Mode)
  400. { // construct empty character buffer
  401. }
  402. explicit basic_stringstream(const _Mystr& _Str,
  403. ios_base::openmode _Mode = ios_base::in | ios_base::out)
  404. : basic_iostream<_Elem, _Traits>(&_Stringbuffer),
  405. _Stringbuffer(_Str, _Mode)
  406. { // construct character buffer from NTCS
  407. }
  408. virtual ~basic_stringstream()
  409. { // destroy the object
  410. }
  411. basic_stringbuf<_Elem, _Traits, _Alloc> *rdbuf() const
  412. { // return pointer to buffer
  413. return ((basic_stringbuf<_Elem, _Traits, _Alloc> *)&_Stringbuffer);
  414. }
  415. _Mystr str() const
  416. { // return string copy of character array
  417. return (_Stringbuffer.str());
  418. }
  419. void str(const _Mystr& _Newstr)
  420. { // replace character array from string
  421. _Stringbuffer.str(_Newstr);
  422. }
  423. private:
  424. basic_stringbuf<_Elem, _Traits, _Alloc>
  425. _Stringbuffer; // the string buffer
  426. };
  427. #ifdef _DLL_CPPLIB
  428. template class _CRTIMP2 basic_stringstream<char,
  429. char_traits<char>, allocator<char> >;
  430. template class _CRTIMP2 basic_stringstream<wchar_t,
  431. char_traits<wchar_t>, allocator<wchar_t> >;
  432. #endif // _DLL_CPPLIB
  433. _STD_END
  434. #pragma warning(default: 4251)
  435. #pragma warning(pop)
  436. #pragma pack(pop)
  437. #endif /* _SSTREAM_ */
  438. /*
  439. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  440. * Consult your license regarding permissions and restrictions.
  441. V3.10:0009 */