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.

1046 lines
26 KiB

  1. // istream standard header
  2. #pragma once
  3. #ifndef _ISTREAM_
  4. #define _ISTREAM_
  5. #include <ostream>
  6. #pragma pack(push,8)
  7. #pragma warning(push,3)
  8. _STD_BEGIN
  9. // TEMPLATE CLASS basic_istream
  10. template<class _Elem,
  11. class _Traits>
  12. class basic_istream
  13. : virtual public basic_ios<_Elem, _Traits>
  14. { // control extractions from a stream buffer
  15. public:
  16. typedef basic_istream<_Elem, _Traits> _Myt;
  17. typedef basic_ios<_Elem, _Traits> _Myios;
  18. typedef basic_streambuf<_Elem, _Traits> _Mysb;
  19. typedef istreambuf_iterator<_Elem, _Traits> _Iter;
  20. typedef ctype<_Elem> _Ctype;
  21. typedef num_get<_Elem, _Iter> _Nget;
  22. explicit basic_istream(_Mysb *_Strbuf, bool _Isstd = false,
  23. bool _Noinit = false)
  24. : _Chcount(0)
  25. { // construct from stream buffer pointer
  26. if (!_Noinit)
  27. _Myios::init(_Strbuf, _Isstd);
  28. }
  29. basic_istream(_Uninitialized)
  30. { // construct uninitialized
  31. ios_base::_Addstd();
  32. }
  33. virtual ~basic_istream()
  34. { // destroy the object
  35. }
  36. typedef typename _Traits::int_type int_type;
  37. typedef typename _Traits::pos_type pos_type;
  38. typedef typename _Traits::off_type off_type;
  39. // TEMPLATE CLASS sentry
  40. class _Sentry_base
  41. { // stores thread lock and reference to input stream
  42. public:
  43. _Sentry_base(_Myt& _Istr)
  44. : _Myistr(_Istr)
  45. { // lock the stream buffer, if there
  46. if (_Myistr.rdbuf() != 0)
  47. _Myistr.rdbuf()->_Lock();
  48. }
  49. ~_Sentry_base()
  50. { // destroy after unlocking
  51. if (_Myistr.rdbuf() != 0)
  52. _Myistr.rdbuf()->_Unlock();
  53. }
  54. _Myt& _Myistr; // the input stream, for _Unlock call at destruction
  55. };
  56. class sentry
  57. : public _Sentry_base
  58. { // stores thread lock and result of _Ipfx call
  59. public:
  60. explicit sentry(_Myt& _Istr, bool _Noskip = false)
  61. : _Sentry_base(_Istr)
  62. { // construct locking and calling _Ipfx
  63. _Ok = _Myistr._Ipfx(_Noskip);
  64. }
  65. operator bool() const
  66. { // test if _Ipfx succeeded
  67. return (_Ok);
  68. }
  69. private:
  70. sentry(const sentry&); // not defined
  71. sentry& operator=(const sentry&); // not defined
  72. bool _Ok; // true if _Ipfx succeeded at construction
  73. };
  74. bool _Ipfx(bool _Noskip = false)
  75. { // test stream state and skip whitespace as needed
  76. if (ios_base::good())
  77. { // state okay, flush tied stream and skip whitespace
  78. if (_Myios::tie() != 0)
  79. _Myios::tie()->flush();
  80. if (!_Noskip && ios_base::flags() & ios_base::skipws)
  81. { // skip whitespace
  82. const _Ctype& _Facet = _USE(ios_base::getloc(), _Ctype);
  83. _TRY_IO_BEGIN
  84. int_type _Meta = _Myios::rdbuf()->sgetc();
  85. for (; ; _Meta = _Myios::rdbuf()->snextc())
  86. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  87. { // end of file, quit
  88. _Myios::setstate(ios_base::eofbit);
  89. break;
  90. }
  91. else if (!_Facet.is(_Ctype::space,
  92. _Traits::to_char_type(_Meta)))
  93. break; // not whitespace, quit
  94. _CATCH_IO_END
  95. }
  96. if (ios_base::good())
  97. return (true);
  98. }
  99. _Myios::setstate(ios_base::failbit);
  100. return (false);
  101. }
  102. bool ipfx(bool _Noskip = false)
  103. { // test stream state and skip whitespace as needed (retained)
  104. return _Ipfx(_Noskip);
  105. }
  106. void isfx()
  107. { // perform any wrapup (retained)
  108. }
  109. _Myt& operator>>(_Myt& (__cdecl *_Pfn)(_Myt&))
  110. { // call basic_istream manipulator
  111. return ((*_Pfn)(*this));
  112. }
  113. _Myt& operator>>(_Myios& (__cdecl *_Pfn)(_Myios&))
  114. { // call basic_ios manipulator
  115. (*_Pfn)(*(_Myios *)this);
  116. return (*this);
  117. }
  118. _Myt& operator>>(ios_base& (__cdecl *_Pfn)(ios_base&))
  119. { // call ios_base manipulator
  120. (*_Pfn)(*(ios_base *)this);
  121. return (*this);
  122. }
  123. _Myt& operator>>(_Bool& _Val)
  124. { // extract a boolean
  125. ios_base::iostate _State = ios_base::goodbit;
  126. const sentry _Ok(*this);
  127. if (_Ok)
  128. { // state okay, use facet to extract
  129. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  130. _TRY_IO_BEGIN
  131. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  132. *this, _State, _Val);
  133. _CATCH_IO_END
  134. }
  135. _Myios::setstate(_State);
  136. return (*this);
  137. }
  138. _Myt& operator>>(short& _Val)
  139. { // extract a short
  140. ios_base::iostate _State = ios_base::goodbit;
  141. const sentry _Ok(*this);
  142. if (_Ok)
  143. { // state okay, use facet to extract
  144. long _Tmp = 0;
  145. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  146. _TRY_IO_BEGIN
  147. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  148. *this, _State, _Tmp);
  149. _CATCH_IO_END
  150. if (_State & ios_base::failbit
  151. || _Tmp < SHRT_MIN || SHRT_MAX < _Tmp)
  152. _State |= ios_base::failbit;
  153. else
  154. _Val = (short)_Tmp;
  155. }
  156. _Myios::setstate(_State);
  157. return (*this);
  158. }
  159. _Myt& operator>>(unsigned short& _Val)
  160. { // extract an unsigned short
  161. ios_base::iostate _State = ios_base::goodbit;
  162. const sentry _Ok(*this);
  163. if (_Ok)
  164. { // state okay, use facet to extract
  165. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  166. _TRY_IO_BEGIN
  167. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  168. *this, _State, _Val);
  169. _CATCH_IO_END
  170. }
  171. _Myios::setstate(_State);
  172. return (*this);
  173. }
  174. _Myt& operator>>(int& _Val)
  175. { // extract an int
  176. ios_base::iostate _State = ios_base::goodbit;
  177. const sentry _Ok(*this);
  178. if (_Ok)
  179. { // state okay, use facet to extract
  180. long _Tmp = 0;
  181. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  182. _TRY_IO_BEGIN
  183. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  184. *this, _State, _Tmp);
  185. _CATCH_IO_END
  186. if (_State & ios_base::failbit
  187. || _Tmp < INT_MIN || INT_MAX < _Tmp)
  188. _State |= ios_base::failbit;
  189. else
  190. _Val = _Tmp;
  191. }
  192. _Myios::setstate(_State);
  193. return (*this);
  194. }
  195. _Myt& operator>>(unsigned int& _Val)
  196. { // extract an unsigned int
  197. ios_base::iostate _State = ios_base::goodbit;
  198. const sentry _Ok(*this);
  199. if (_Ok)
  200. { // state okay, use facet to extract
  201. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  202. _TRY_IO_BEGIN
  203. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  204. *this, _State, _Val);
  205. _CATCH_IO_END
  206. }
  207. _Myios::setstate(_State);
  208. return (*this);
  209. }
  210. _Myt& operator>>(long& _Val)
  211. { // extract a long
  212. ios_base::iostate _State = ios_base::goodbit;
  213. const sentry _Ok(*this);
  214. if (_Ok)
  215. { // state okay, use facet to extract
  216. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  217. _TRY_IO_BEGIN
  218. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  219. *this, _State, _Val);
  220. _CATCH_IO_END
  221. }
  222. _Myios::setstate(_State);
  223. return (*this);
  224. }
  225. _Myt& operator>>(unsigned long& _Val)
  226. { // extract an unsigned long
  227. ios_base::iostate _State = ios_base::goodbit;
  228. const sentry _Ok(*this);
  229. if (_Ok)
  230. { // state okay, use facet to extract
  231. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  232. _TRY_IO_BEGIN
  233. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  234. *this, _State, _Val);
  235. _CATCH_IO_END
  236. }
  237. _Myios::setstate(_State);
  238. return (*this);
  239. }
  240. #ifdef _LONGLONG
  241. _Myt& operator>>(_LONGLONG& _Val)
  242. { // extract a long long
  243. ios_base::iostate _State = ios_base::goodbit;
  244. const sentry _Ok(*this);
  245. if (_Ok)
  246. { // state okay, use facet to extract
  247. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  248. _TRY_IO_BEGIN
  249. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  250. *this, _State, _Val);
  251. _CATCH_IO_END
  252. }
  253. _Myios::setstate(_State);
  254. return (*this);
  255. }
  256. _Myt& operator>>(_ULONGLONG& _Val)
  257. { // extract an unsigned long long
  258. ios_base::iostate _State = ios_base::goodbit;
  259. const sentry _Ok(*this);
  260. if (_Ok)
  261. { // state okay, use facet to extract
  262. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  263. _TRY_IO_BEGIN
  264. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  265. *this, _State, _Val);
  266. _CATCH_IO_END
  267. }
  268. _Myios::setstate(_State);
  269. return (*this);
  270. }
  271. #endif /* _LONGLONG */
  272. _Myt& operator>>(float& _Val)
  273. { // extract a float
  274. ios_base::iostate _State = ios_base::goodbit;
  275. const sentry _Ok(*this);
  276. if (_Ok)
  277. { // state okay, use facet to extract
  278. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  279. _TRY_IO_BEGIN
  280. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  281. *this, _State, _Val);
  282. _CATCH_IO_END
  283. }
  284. _Myios::setstate(_State);
  285. return (*this);
  286. }
  287. _Myt& operator>>(double& _Val)
  288. { // extract a double
  289. ios_base::iostate _State = ios_base::goodbit;
  290. const sentry _Ok(*this);
  291. if (_Ok)
  292. { // state okay, use facet to extract
  293. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  294. _TRY_IO_BEGIN
  295. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  296. *this, _State, _Val);
  297. _CATCH_IO_END
  298. }
  299. _Myios::setstate(_State);
  300. return (*this);
  301. }
  302. _Myt& operator>>(long double& _Val)
  303. { // extract a long double
  304. ios_base::iostate _State = ios_base::goodbit;
  305. const sentry _Ok(*this);
  306. if (_Ok)
  307. { // state okay, use facet to extract
  308. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  309. _TRY_IO_BEGIN
  310. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  311. *this, _State, _Val);
  312. _CATCH_IO_END
  313. }
  314. _Myios::setstate(_State);
  315. return (*this);
  316. }
  317. _Myt& operator>>(void *& _Val)
  318. { // extract a void pointer
  319. ios_base::iostate _State = ios_base::goodbit;
  320. const sentry _Ok(*this);
  321. if (_Ok)
  322. { // state okay, use facet to extract
  323. const _Nget& _Facet = _USE(ios_base::getloc(), _Nget);
  324. _TRY_IO_BEGIN
  325. _Facet.get(_Iter(_Myios::rdbuf()), _Iter(0),
  326. *this, _State, _Val);
  327. _CATCH_IO_END
  328. }
  329. _Myios::setstate(_State);
  330. return (*this);
  331. }
  332. _Myt& operator>>(_Mysb *_Strbuf)
  333. { // extract until end-of-file into a stream buffer
  334. ios_base::iostate _State = ios_base::goodbit;
  335. bool _Copied = false;
  336. const sentry _Ok(*this);
  337. if (_Ok && _Strbuf != 0)
  338. { // state okay, extract characters
  339. _TRY_IO_BEGIN
  340. int_type _Meta = _Myios::rdbuf()->sgetc();
  341. for (; ; _Meta = _Myios::rdbuf()->snextc())
  342. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  343. { // end of file, quit
  344. _State |= ios_base::eofbit;
  345. break;
  346. }
  347. else
  348. { // got a character, insert it into buffer
  349. _TRY_BEGIN
  350. if (_Traits::eq_int_type(_Traits::eof(),
  351. _Strbuf->sputc(_Traits::to_char_type(_Meta))))
  352. break;
  353. _CATCH_ALL
  354. break;
  355. _CATCH_END
  356. _Copied = true;
  357. }
  358. _CATCH_IO_END
  359. }
  360. _Myios::setstate(!_Copied ? _State | ios_base::failbit : _State);
  361. return (*this);
  362. }
  363. int_type get()
  364. { // extract a metacharacter
  365. int_type _Meta = 0;
  366. ios_base::iostate _State = ios_base::goodbit;
  367. _Chcount = 0;
  368. const sentry _Ok(*this, true);
  369. if (!_Ok)
  370. _Meta = _Traits::eof(); // state not okay, return EOF
  371. else
  372. { // state okay, extract a character
  373. _TRY_IO_BEGIN
  374. _Meta = _Myios::rdbuf()->sbumpc();
  375. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  376. _State |= ios_base::eofbit | ios_base::failbit; // end of file
  377. else
  378. ++_Chcount; // got a character, count it
  379. _CATCH_IO_END
  380. }
  381. _Myios::setstate(_State);
  382. return (_Meta);
  383. }
  384. _Myt& get(_Elem *_Str, streamsize _Count)
  385. { // get up to _Count characters into NTCS
  386. return (get(_Str, _Count, _Myios::widen('\n')));
  387. }
  388. _Myt& get(_Elem *_Str, streamsize _Count, _Elem _Delim)
  389. { // get up to _Count characters into NTCS, stop before _Delim
  390. ios_base::iostate _State = ios_base::goodbit;
  391. _Chcount = 0;
  392. const sentry _Ok(*this, true);
  393. if (_Ok && 0 < _Count)
  394. { // state okay, extract characters
  395. _TRY_IO_BEGIN
  396. int_type _Meta = _Myios::rdbuf()->sgetc();
  397. for (; 0 < --_Count; _Meta = _Myios::rdbuf()->snextc())
  398. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  399. { // end of file, quit
  400. _State |= ios_base::eofbit;
  401. break;
  402. }
  403. else if (_Traits::to_char_type(_Meta) == _Delim)
  404. break; // got a delimiter, quit
  405. else
  406. { // got a character, add it to string
  407. *_Str++ = _Traits::to_char_type(_Meta);
  408. ++_Chcount;
  409. }
  410. _CATCH_IO_END
  411. }
  412. _Myios::setstate(_Chcount == 0
  413. ? _State | ios_base::failbit : _State);
  414. *_Str = _Elem(); // add terminating null character
  415. return (*this);
  416. }
  417. _Myt& get(_Elem& _Ch)
  418. { // get a character
  419. int_type _Meta = get();
  420. if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
  421. _Ch = _Traits::to_char_type(_Meta);
  422. return (*this);
  423. }
  424. _Myt& get(_Mysb& _Strbuf)
  425. { // extract up to newline and insert into stream buffer
  426. return (get(_Strbuf, _Myios::widen('\n')));
  427. }
  428. _Myt& get(_Mysb& _Strbuf, _Elem _Delim)
  429. { // extract up to delimiter and insert into stream buffer
  430. ios_base::iostate _State = ios_base::goodbit;
  431. _Chcount = 0;
  432. const sentry _Ok(*this, true);
  433. if (_Ok)
  434. { // state okay, use facet to extract
  435. _TRY_IO_BEGIN
  436. int_type _Meta = _Myios::rdbuf()->sgetc();
  437. for (; ; _Meta = _Myios::rdbuf()->snextc())
  438. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  439. { // end of file, quit
  440. _State |= ios_base::eofbit;
  441. break;
  442. }
  443. else
  444. { // got a character, insert it into stream buffer
  445. _TRY_BEGIN
  446. _Elem _Ch = _Traits::to_char_type(_Meta);
  447. if (_Ch == _Delim
  448. || _Traits::eq_int_type(_Traits::eof(),
  449. _Strbuf.sputc(_Ch)))
  450. break;
  451. _CATCH_ALL
  452. break;
  453. _CATCH_END
  454. ++_Chcount;
  455. }
  456. _CATCH_IO_END
  457. }
  458. if (_Chcount == 0)
  459. _State |= ios_base::failbit;
  460. _Myios::setstate(_State);
  461. return (*this);
  462. }
  463. _Myt& getline(_Elem *_Str, streamsize _Count)
  464. { // get up to _Count characters into NTCS, discard newline
  465. return (getline(_Str, _Count, _Myios::widen('\n')));
  466. }
  467. _Myt& getline(_Elem *_Str, streamsize _Count, _Elem _Delim)
  468. { // get up to _Count characters into NTCS, discard _Delim
  469. ios_base::iostate _State = ios_base::goodbit;
  470. _Chcount = 0;
  471. const sentry _Ok(*this, true);
  472. if (_Ok && 0 < _Count)
  473. { // state okay, use facet to extract
  474. int_type _Metadelim = _Traits::to_int_type(_Delim);
  475. _TRY_IO_BEGIN
  476. int_type _Meta = _Myios::rdbuf()->sgetc();
  477. for (; ; _Meta = _Myios::rdbuf()->snextc())
  478. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  479. { // end of file, quit
  480. _State |= ios_base::eofbit;
  481. break;
  482. }
  483. else if (_Meta == _Metadelim)
  484. { // got a delimiter, discard it and quit
  485. ++_Chcount;
  486. _Myios::rdbuf()->sbumpc();
  487. break;
  488. }
  489. else if (--_Count <= 0)
  490. { // buffer full, quit
  491. _State |= ios_base::failbit;
  492. break;
  493. }
  494. else
  495. { // got a character, add it to string
  496. ++_Chcount;
  497. *_Str++ = _Traits::to_char_type(_Meta);
  498. }
  499. _CATCH_IO_END
  500. }
  501. *_Str = _Elem(); // add terminating null character
  502. _Myios::setstate(_Chcount == 0 ? _State | ios_base::failbit : _State);
  503. return (*this);
  504. }
  505. _Myt& ignore(streamsize _Count = 1, int_type _Metadelim = _Traits::eof())
  506. { // ignore up to _Count characters, discarding delimiter
  507. ios_base::iostate _State = ios_base::goodbit;
  508. _Chcount = 0;
  509. const sentry _Ok(*this, true);
  510. if (_Ok && 0 < _Count)
  511. { // state okay, use facet to extract
  512. _TRY_IO_BEGIN
  513. for (; ; )
  514. { // get a metacharacter if more room in buffer
  515. int_type _Meta;
  516. if (_Count != INT_MAX && --_Count < 0)
  517. break; // buffer full, quit
  518. else if (_Traits::eq_int_type(_Traits::eof(),
  519. _Meta = _Myios::rdbuf()->sbumpc()))
  520. { // end of file, quit
  521. _State |= ios_base::eofbit;
  522. break;
  523. }
  524. else
  525. { // got a character, count it
  526. ++_Chcount;
  527. if (_Meta == _Metadelim)
  528. break; // got a delimiter, quit
  529. }
  530. }
  531. _CATCH_IO_END
  532. }
  533. _Myios::setstate(_State);
  534. return (*this);
  535. }
  536. _Myt& read(_Elem *_Str, streamsize _Count)
  537. { // read up to _Count characters into buffer
  538. ios_base::iostate _State = ios_base::goodbit;
  539. _Chcount = 0;
  540. const sentry _Ok(*this, true);
  541. if (_Ok)
  542. { // state okay, use facet to extract
  543. _TRY_IO_BEGIN
  544. const streamsize _Num = _Myios::rdbuf()->sgetn(_Str, _Count);
  545. _Chcount += _Num;
  546. if (_Num != _Count)
  547. _State |= ios_base::eofbit | ios_base::failbit; // short read
  548. _CATCH_IO_END
  549. }
  550. _Myios::setstate(_State);
  551. return (*this);
  552. }
  553. streamsize readsome(_Elem *_Str, streamsize _Count)
  554. { // read up to _Count characters into buffer, without blocking
  555. ios_base::iostate _State = ios_base::goodbit;
  556. _Chcount = 0;
  557. const sentry _Ok(*this, true);
  558. streamsize _Num;
  559. if (!_Ok)
  560. _State |= ios_base::failbit; // no buffer, fail
  561. else if ((_Num = _Myios::rdbuf()->in_avail()) < 0)
  562. _State |= ios_base::eofbit; // no characters available
  563. else if (0 < _Num)
  564. read(_Str, _Num < _Count ? _Num : _Count); // read available
  565. _Myios::setstate(_State);
  566. return (gcount());
  567. }
  568. int_type peek()
  569. { // return next character, unconsumed
  570. ios_base::iostate _State = ios_base::goodbit;
  571. _Chcount = 0;
  572. int_type _Meta = 0;
  573. const sentry _Ok(*this, true);
  574. if (!_Ok)
  575. _Meta = _Traits::eof(); // state not okay, return EOF
  576. else
  577. { // state okay, read a character
  578. _TRY_IO_BEGIN
  579. if (_Traits::eq_int_type(_Traits::eof(),
  580. _Meta = _Myios::rdbuf()->sgetc()))
  581. _State |= ios_base::eofbit;
  582. _CATCH_IO_END
  583. }
  584. _Myios::setstate(_State);
  585. return (_Meta);
  586. }
  587. _Myt& putback(_Elem _Ch)
  588. { // put back a character
  589. ios_base::iostate _State = ios_base::goodbit;
  590. _Chcount = 0;
  591. const sentry _Ok(*this, true);
  592. if (_Ok)
  593. { // state okay, put character back
  594. _TRY_IO_BEGIN
  595. if (_Traits::eq_int_type(_Traits::eof(),
  596. _Myios::rdbuf()->sputbackc(_Ch)))
  597. _State |= ios_base::badbit;
  598. _CATCH_IO_END
  599. }
  600. _Myios::setstate(_State);
  601. return (*this);
  602. }
  603. _Myt& unget()
  604. { // put back last read character
  605. ios_base::iostate _State = ios_base::goodbit;
  606. _Chcount = 0;
  607. const sentry _Ok(*this, true);
  608. if (_Ok)
  609. { // state okay, use facet to extract
  610. _TRY_IO_BEGIN
  611. if (_Traits::eq_int_type(_Traits::eof(),
  612. _Myios::rdbuf()->sungetc()))
  613. _State |= ios_base::badbit;
  614. _CATCH_IO_END
  615. }
  616. _Myios::setstate(_State);
  617. return (*this);
  618. }
  619. streamsize gcount() const
  620. { // get count from last extraction
  621. return (_Chcount);
  622. }
  623. int sync()
  624. { // synchronize with input source
  625. ios_base::iostate _State = ios_base::goodbit;
  626. int _Ans;
  627. if (_Myios::rdbuf() == 0)
  628. _Ans = -1; // no buffer, fail
  629. else if (_Myios::rdbuf()->pubsync() == -1)
  630. { // stream buffer sync failed, fail
  631. _State |= ios_base::badbit;
  632. _Ans = -1;
  633. }
  634. else
  635. _Ans = 0; // success
  636. _Myios::setstate(_State);
  637. return (_Ans);
  638. }
  639. _Myt& seekg(pos_type _Pos)
  640. { // set input stream position to _Pos
  641. if (!ios_base::fail()
  642. && (off_type)_Myios::rdbuf()->pubseekpos(_Pos,
  643. ios_base::in) == _BADOFF)
  644. _Myios::setstate(ios_base::failbit);
  645. return (*this);
  646. }
  647. _Myt& seekg(off_type _Off, ios_base::seekdir _Way)
  648. { // change input stream position by _Off, according to _Way
  649. if (!ios_base::fail()
  650. && (off_type)_Myios::rdbuf()->pubseekoff(_Off, _Way,
  651. ios_base::in) == _BADOFF)
  652. _Myios::setstate(ios_base::failbit);
  653. return (*this);
  654. }
  655. pos_type tellg()
  656. { // return input stream position
  657. if (!ios_base::fail())
  658. return (_Myios::rdbuf()->pubseekoff(0,
  659. ios_base::cur, ios_base::in));
  660. else
  661. return (pos_type(_BADOFF));
  662. }
  663. private:
  664. streamsize _Chcount; // the character count
  665. };
  666. #ifdef _DLL_CPPLIB
  667. template class _CRTIMP2 basic_istream<char, char_traits<char> >;
  668. template class _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >;
  669. #endif // _DLL_CPPLIB
  670. // TEMPLATE CLASS basic_iostream
  671. template<class _Elem,
  672. class _Traits>
  673. class basic_iostream
  674. : public basic_istream<_Elem, _Traits>,
  675. public basic_ostream<_Elem, _Traits>
  676. { // control insertions and extractions from a stream buffer
  677. public:
  678. explicit basic_iostream(basic_streambuf<_Elem, _Traits> *_Strbuf)
  679. : basic_istream<_Elem, _Traits>(_Strbuf, false, true),
  680. basic_ostream<_Elem, _Traits>(_Strbuf)
  681. { // construct from stream buffer pointer
  682. }
  683. virtual ~basic_iostream()
  684. { // destroy the object
  685. }
  686. };
  687. #ifdef _DLL_CPPLIB
  688. template class _CRTIMP2 basic_iostream<char, char_traits<char> >;
  689. template class _CRTIMP2 basic_iostream<wchar_t, char_traits<wchar_t> >;
  690. #endif // _DLL_CPPLIB
  691. // EXTRACTORS
  692. template<class _Elem,
  693. class _Traits> inline
  694. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  695. basic_istream<_Elem, _Traits>& _Istr, _Elem *_Str)
  696. { // extract NTBS
  697. typedef basic_istream<_Elem, _Traits> _Myis;
  698. typedef ctype<_Elem> _Ctype;
  699. ios_base::iostate _State = ios_base::goodbit;
  700. _Elem *_Str0 = _Str;
  701. const typename _Myis::sentry _Ok(_Istr);
  702. if (_Ok)
  703. { // state okay, extract characters
  704. const _Ctype& _Facet = _USE(_Istr.getloc(), _Ctype);
  705. _TRY_IO_BEGIN
  706. streamsize _Count = 0 < _Istr.width() ? _Istr.width() : INT_MAX;
  707. typename _Myis::int_type _Meta = _Istr.rdbuf()->sgetc();
  708. _Elem _Ch;
  709. for (; 0 < --_Count; _Meta = _Istr.rdbuf()->snextc())
  710. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  711. { // end of file, quit
  712. _State |= ios_base::eofbit;
  713. break;
  714. }
  715. else if (_Facet.is(_Ctype::space,
  716. _Ch = _Traits::to_char_type(_Meta))
  717. || _Ch == _Elem())
  718. break; // whitespace or nul, quit
  719. else
  720. *_Str++ = _Traits::to_char_type(_Meta); // add it to string
  721. _CATCH_IO_(_Istr)
  722. }
  723. *_Str = _Elem(); // add terminating null character
  724. _Istr.width(0);
  725. _Istr.setstate(_Str == _Str0 ? _State | ios_base::failbit : _State);
  726. return (_Istr);
  727. }
  728. template<class _Elem,
  729. class _Traits> inline
  730. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  731. basic_istream<_Elem, _Traits>& _Istr, _Elem& _Ch)
  732. { // extract a character
  733. typedef basic_istream<_Elem, _Traits> _Myis;
  734. typename _Myis::int_type _Meta;
  735. ios_base::iostate _State = ios_base::goodbit;
  736. const typename _Myis::sentry _Ok(_Istr);
  737. if (_Ok)
  738. { // state okay, extract characters
  739. _TRY_IO_BEGIN
  740. _Meta = _Istr.rdbuf()->sbumpc();
  741. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  742. _State |= ios_base::eofbit | ios_base::failbit; // end of file
  743. else
  744. _Ch = _Traits::to_char_type(_Meta); // got a character
  745. _CATCH_IO_(_Istr)
  746. }
  747. _Istr.setstate(_State);
  748. return (_Istr);
  749. }
  750. template<class _Elem,
  751. class _Traits> inline
  752. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  753. basic_istream<_Elem, _Traits>& _Istr, signed char *_Str)
  754. { // extract a signed char NTBS
  755. return (_Istr >> (char *)_Str);
  756. }
  757. template<class _Elem,
  758. class _Traits> inline
  759. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  760. basic_istream<_Elem, _Traits>& _Istr, signed char& _Ch)
  761. { // extract a signed char
  762. return (_Istr >> (char&)_Ch);
  763. }
  764. template<class _Elem,
  765. class _Traits> inline
  766. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  767. basic_istream<_Elem, _Traits>& _Istr, unsigned char *_Str)
  768. { // extract an unsigned char NTBS
  769. return (_Istr >> (char *)_Str);
  770. }
  771. template<class _Elem,
  772. class _Traits> inline
  773. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  774. basic_istream<_Elem, _Traits>& _Istr, unsigned char& _Ch)
  775. { // extract an unsigned char
  776. return (_Istr >> (char&)_Ch);
  777. }
  778. template<class _Elem,
  779. class _Traits> inline
  780. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  781. basic_istream<_Elem, _Traits>& _Istr, signed short * _Str)
  782. { // extract a wide character NTBS
  783. return (_Istr >> (wchar_t *)_Str);
  784. }
  785. #ifdef _DLL_CPPLIB
  786. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  787. operator>>(basic_istream<char, char_traits<char> >&, char *);
  788. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  789. operator>>(basic_istream<char, char_traits<char> >&, char&);
  790. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  791. operator>>(basic_istream<char, char_traits<char> >&, signed char *);
  792. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  793. operator>>(basic_istream<char, char_traits<char> >&, signed char&);
  794. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  795. operator>>(basic_istream<char, char_traits<char> >&, unsigned char *);
  796. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  797. operator>>(basic_istream<char, char_traits<char> >&, unsigned char&);
  798. template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >& __cdecl
  799. operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, wchar_t *);
  800. template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >& __cdecl
  801. operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, wchar_t&);
  802. #endif // _DLL_CPPLIB
  803. // MANIPULATORS
  804. template<class _Elem,
  805. class _Traits> inline
  806. basic_istream<_Elem, _Traits>&
  807. __cdecl ws(basic_istream<_Elem, _Traits>& _Istr)
  808. { // consume whitespace
  809. typedef basic_istream<_Elem, _Traits> _Myis;
  810. typedef ctype<_Elem> _Ctype;
  811. ios_base::iostate _State = ios_base::goodbit;
  812. const typename _Myis::sentry _Ok(_Istr, true);
  813. if (_Ok)
  814. { // state okay, extract characters
  815. const _Ctype& _Facet = _USE(_Istr.getloc(), _Ctype);
  816. _TRY_IO_BEGIN
  817. for (typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  818. _Meta = _Istr.rdbuf()->snextc())
  819. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  820. { // end of file, quit
  821. _State |= ios_base::eofbit;
  822. break;
  823. }
  824. else if (!_Facet.is(_Ctype::space,
  825. _Traits::to_char_type(_Meta)))
  826. break; // not whitespace, quit
  827. _CATCH_IO_(_Istr)
  828. }
  829. _Istr.setstate(_State);
  830. return (_Istr);
  831. }
  832. _CRTIMP2 inline basic_istream<char, char_traits<char> >&
  833. __cdecl ws(basic_istream<char, char_traits<char> >& _Istr)
  834. { // consume whitespace
  835. typedef char _Elem;
  836. typedef char_traits<_Elem> _Traits;
  837. ios_base::iostate _State = ios_base::goodbit;
  838. const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
  839. if (_Ok)
  840. { // state okay, use facet to extract
  841. const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
  842. _TRY_IO_BEGIN
  843. for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  844. _Meta = _Istr.rdbuf()->snextc())
  845. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  846. { // end of file, quit
  847. _State |= ios_base::eofbit;
  848. break;
  849. }
  850. else if (!_Facet.is(ctype<_Elem>::space,
  851. _Traits::to_char_type(_Meta)))
  852. break; // not whitespace, quit
  853. _CATCH_IO_(_Istr)
  854. }
  855. _Istr.setstate(_State);
  856. return (_Istr);
  857. }
  858. _CRTIMP2 inline basic_istream<wchar_t, char_traits<wchar_t> >&
  859. __cdecl ws(basic_istream<wchar_t, char_traits<wchar_t> >& _Istr)
  860. { // consume whitespace
  861. typedef wchar_t _Elem;
  862. typedef char_traits<_Elem> _Traits;
  863. ios_base::iostate _State = ios_base::goodbit;
  864. const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
  865. if (_Ok)
  866. { // state okay, use facet to extract
  867. const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
  868. _TRY_IO_BEGIN
  869. for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  870. _Meta = _Istr.rdbuf()->snextc())
  871. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  872. { // end of file, quit
  873. _State |= ios_base::eofbit;
  874. break;
  875. }
  876. else if (!_Facet.is(ctype<_Elem>::space,
  877. _Traits::to_char_type(_Meta)))
  878. break; // not whitespace, quit
  879. _CATCH_IO_(_Istr)
  880. }
  881. _Istr.setstate(_State);
  882. return (_Istr);
  883. }
  884. _STD_END
  885. #pragma warning(pop)
  886. #pragma pack(pop)
  887. #endif /* _ISTREAM_ */
  888. /*
  889. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  890. * Consult your license regarding permissions and restrictions.
  891. V3.10:0009 */