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.

524 lines
15 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. #ifdef __FORCE_INSTANCE
  285. template class _CRTIMP2 basic_stringbuf<char,
  286. char_traits<char>, allocator<char> >;
  287. template class _CRTIMP2 basic_stringbuf<wchar_t,
  288. char_traits<wchar_t>, allocator<wchar_t> >;
  289. #ifdef _CRTBLD_NATIVE_WCHAR_T
  290. template class _CRTIMP2 basic_stringbuf<unsigned short,
  291. char_traits<unsigned short>, allocator<unsigned short> >;
  292. #endif
  293. #endif // __FORCE_INSTANCE
  294. #endif // _DLL_CPPLIB
  295. // TEMPLATE CLASS basic_istringstream
  296. template<class _Elem,
  297. class _Traits,
  298. class _Alloc>
  299. class basic_istringstream
  300. : public basic_istream<_Elem, _Traits>
  301. { // input stream associated with a character array
  302. public:
  303. typedef _Alloc allocator_type;
  304. typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
  305. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  306. explicit basic_istringstream(ios_base::openmode _Mode = ios_base::in)
  307. : basic_istream<_Elem, _Traits>(&_Stringbuffer),
  308. _Stringbuffer(_Mode | ios_base::in)
  309. { // construct empty readable character buffer
  310. }
  311. explicit basic_istringstream(const _Mystr& _Str,
  312. ios_base::openmode _Mode = ios_base::in)
  313. : basic_istream<_Elem, _Traits>(&_Stringbuffer),
  314. _Stringbuffer(_Str, _Mode | ios_base::in)
  315. { // construct readable character buffer from NTCS
  316. }
  317. virtual ~basic_istringstream()
  318. { // destroy the object
  319. }
  320. _Mysb *rdbuf() const
  321. { // return pointer to file buffer
  322. return ((_Mysb *)&_Stringbuffer);
  323. }
  324. _Mystr str() const
  325. { // return string copy of character array
  326. return (_Stringbuffer.str());
  327. }
  328. void str(const _Mystr& _Newstr)
  329. { // replace character array from string
  330. _Stringbuffer.str(_Newstr);
  331. }
  332. private:
  333. _Mysb _Stringbuffer; // the string buffer
  334. };
  335. #ifdef _DLL_CPPLIB
  336. #ifdef __FORCE_INSTANCE
  337. template class _CRTIMP2 basic_istringstream<char,
  338. char_traits<char>, allocator<char> >;
  339. template class _CRTIMP2 basic_istringstream<wchar_t,
  340. char_traits<wchar_t>, allocator<wchar_t> >;
  341. #ifdef _CRTBLD_NATIVE_WCHAR_T
  342. template class _CRTIMP2 basic_istringstream<unsigned short,
  343. char_traits<unsigned short>, allocator<unsigned short> >;
  344. #endif
  345. #endif // __FORCE_INSTANCE
  346. #endif // _DLL_CPPLIB
  347. // TEMPLATE CLASS basic_ostringstream
  348. template<class _Elem,
  349. class _Traits,
  350. class _Alloc>
  351. class basic_ostringstream
  352. : public basic_ostream<_Elem, _Traits>
  353. { // output stream associated with a character array
  354. public:
  355. typedef _Alloc allocator_type;
  356. typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
  357. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  358. explicit basic_ostringstream(ios_base::openmode _Mode = ios_base::out)
  359. : basic_ostream<_Elem, _Traits>(&_Stringbuffer),
  360. _Stringbuffer(_Mode | ios_base::out)
  361. { // construct empty writable character buffer
  362. }
  363. explicit basic_ostringstream(const _Mystr& _Str,
  364. ios_base::openmode _Mode = ios_base::out)
  365. : basic_ostream<_Elem, _Traits>(&_Stringbuffer),
  366. _Stringbuffer(_Str, _Mode | ios_base::out)
  367. { // construct writable character buffer from NTCS
  368. }
  369. virtual ~basic_ostringstream()
  370. { // destroy the object
  371. }
  372. _Mysb *rdbuf() const
  373. { // return pointer to buffer
  374. return ((_Mysb *)&_Stringbuffer);
  375. }
  376. _Mystr str() const
  377. { // return string copy of character array
  378. return (_Stringbuffer.str());
  379. }
  380. void str(const _Mystr& _Newstr)
  381. { // replace character array from string
  382. _Stringbuffer.str(_Newstr);
  383. }
  384. private:
  385. _Mysb _Stringbuffer; // the string buffer
  386. };
  387. #ifdef _DLL_CPPLIB
  388. #ifdef __FORCE_INSTANCE
  389. template class _CRTIMP2 basic_ostringstream<char,
  390. char_traits<char>, allocator<char> >;
  391. template class _CRTIMP2 basic_ostringstream<wchar_t,
  392. char_traits<wchar_t>, allocator<wchar_t> >;
  393. #ifdef _CRTBLD_NATIVE_WCHAR_T
  394. template class _CRTIMP2 basic_ostringstream<unsigned short,
  395. char_traits<unsigned short>, allocator<unsigned short> >;
  396. #endif
  397. #endif // __FORCE_INSTANCE
  398. #endif // _DLL_CPPLIB
  399. // TEMPLATE CLASS basic_stringstream
  400. template<class _Elem,
  401. class _Traits,
  402. class _Alloc>
  403. class basic_stringstream
  404. : public basic_iostream<_Elem, _Traits>
  405. { // input/output stream associated with a character array
  406. public:
  407. typedef _Elem char_type;
  408. typedef _Traits traits_type;
  409. typedef _Alloc allocator_type;
  410. typedef typename _Traits::int_type int_type;
  411. typedef typename _Traits::pos_type pos_type;
  412. typedef typename _Traits::off_type off_type;
  413. typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
  414. explicit basic_stringstream(ios_base::openmode _Mode =
  415. ios_base::in | ios_base::out)
  416. : basic_iostream<_Elem, _Traits>(&_Stringbuffer),
  417. _Stringbuffer(_Mode)
  418. { // construct empty character buffer
  419. }
  420. explicit basic_stringstream(const _Mystr& _Str,
  421. ios_base::openmode _Mode = ios_base::in | ios_base::out)
  422. : basic_iostream<_Elem, _Traits>(&_Stringbuffer),
  423. _Stringbuffer(_Str, _Mode)
  424. { // construct character buffer from NTCS
  425. }
  426. virtual ~basic_stringstream()
  427. { // destroy the object
  428. }
  429. basic_stringbuf<_Elem, _Traits, _Alloc> *rdbuf() const
  430. { // return pointer to buffer
  431. return ((basic_stringbuf<_Elem, _Traits, _Alloc> *)&_Stringbuffer);
  432. }
  433. _Mystr str() const
  434. { // return string copy of character array
  435. return (_Stringbuffer.str());
  436. }
  437. void str(const _Mystr& _Newstr)
  438. { // replace character array from string
  439. _Stringbuffer.str(_Newstr);
  440. }
  441. private:
  442. basic_stringbuf<_Elem, _Traits, _Alloc>
  443. _Stringbuffer; // the string buffer
  444. };
  445. #ifdef _DLL_CPPLIB
  446. #ifdef __FORCE_INSTANCE
  447. template class _CRTIMP2 basic_stringstream<char,
  448. char_traits<char>, allocator<char> >;
  449. template class _CRTIMP2 basic_stringstream<wchar_t,
  450. char_traits<wchar_t>, allocator<wchar_t> >;
  451. #ifdef _CRTBLD_NATIVE_WCHAR_T
  452. template class _CRTIMP2 basic_stringstream<unsigned short,
  453. char_traits<unsigned short>, allocator<unsigned short> >;
  454. #endif
  455. #endif // __FORCE_INSTANCE
  456. #endif // _DLL_CPPLIB
  457. _STD_END
  458. #pragma warning(default: 4251)
  459. #pragma warning(pop)
  460. #pragma pack(pop)
  461. #endif /* _SSTREAM_ */
  462. /*
  463. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  464. * Consult your license regarding permissions and restrictions.
  465. V3.10:0009 */