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.

1095 lines
28 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. #ifdef __FORCE_INSTANCE
  668. template class _CRTIMP2 basic_istream<char, char_traits<char> >;
  669. template class _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >;
  670. #ifdef _CRTBLD_NATIVE_WCHAR_T
  671. template class _CRTIMP2 basic_istream<unsigned short, char_traits<unsigned short> >;
  672. #endif
  673. #endif // __FORCE_INSTANCE
  674. #endif // _DLL_CPPLIB
  675. // TEMPLATE CLASS basic_iostream
  676. template<class _Elem,
  677. class _Traits>
  678. class basic_iostream
  679. : public basic_istream<_Elem, _Traits>,
  680. public basic_ostream<_Elem, _Traits>
  681. { // control insertions and extractions from a stream buffer
  682. public:
  683. explicit basic_iostream(basic_streambuf<_Elem, _Traits> *_Strbuf)
  684. : basic_istream<_Elem, _Traits>(_Strbuf, false, true),
  685. basic_ostream<_Elem, _Traits>(_Strbuf)
  686. { // construct from stream buffer pointer
  687. }
  688. virtual ~basic_iostream()
  689. { // destroy the object
  690. }
  691. };
  692. #ifdef _DLL_CPPLIB
  693. #ifdef __FORCE_INSTANCE
  694. template class _CRTIMP2 basic_iostream<char, char_traits<char> >;
  695. template class _CRTIMP2 basic_iostream<wchar_t, char_traits<wchar_t> >;
  696. #ifdef _CRTBLD_NATIVE_WCHAR_T
  697. template class _CRTIMP2 basic_iostream<unsigned short, char_traits<unsigned short> >;
  698. #endif
  699. #endif // __FORCE_INSTANCE
  700. #endif // _DLL_CPPLIB
  701. // EXTRACTORS
  702. template<class _Elem,
  703. class _Traits> inline
  704. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  705. basic_istream<_Elem, _Traits>& _Istr, _Elem *_Str)
  706. { // extract NTBS
  707. typedef basic_istream<_Elem, _Traits> _Myis;
  708. typedef ctype<_Elem> _Ctype;
  709. ios_base::iostate _State = ios_base::goodbit;
  710. _Elem *_Str0 = _Str;
  711. const typename _Myis::sentry _Ok(_Istr);
  712. if (_Ok)
  713. { // state okay, extract characters
  714. const _Ctype& _Facet = _USE(_Istr.getloc(), _Ctype);
  715. _TRY_IO_BEGIN
  716. streamsize _Count = 0 < _Istr.width() ? _Istr.width() : INT_MAX;
  717. typename _Myis::int_type _Meta = _Istr.rdbuf()->sgetc();
  718. _Elem _Ch;
  719. for (; 0 < --_Count; _Meta = _Istr.rdbuf()->snextc())
  720. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  721. { // end of file, quit
  722. _State |= ios_base::eofbit;
  723. break;
  724. }
  725. else if (_Facet.is(_Ctype::space,
  726. _Ch = _Traits::to_char_type(_Meta))
  727. || _Ch == _Elem())
  728. break; // whitespace or nul, quit
  729. else
  730. *_Str++ = _Traits::to_char_type(_Meta); // add it to string
  731. _CATCH_IO_(_Istr)
  732. }
  733. *_Str = _Elem(); // add terminating null character
  734. _Istr.width(0);
  735. _Istr.setstate(_Str == _Str0 ? _State | ios_base::failbit : _State);
  736. return (_Istr);
  737. }
  738. template<class _Elem,
  739. class _Traits> inline
  740. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  741. basic_istream<_Elem, _Traits>& _Istr, _Elem& _Ch)
  742. { // extract a character
  743. typedef basic_istream<_Elem, _Traits> _Myis;
  744. typename _Myis::int_type _Meta;
  745. ios_base::iostate _State = ios_base::goodbit;
  746. const typename _Myis::sentry _Ok(_Istr);
  747. if (_Ok)
  748. { // state okay, extract characters
  749. _TRY_IO_BEGIN
  750. _Meta = _Istr.rdbuf()->sbumpc();
  751. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  752. _State |= ios_base::eofbit | ios_base::failbit; // end of file
  753. else
  754. _Ch = _Traits::to_char_type(_Meta); // got a character
  755. _CATCH_IO_(_Istr)
  756. }
  757. _Istr.setstate(_State);
  758. return (_Istr);
  759. }
  760. template<class _Elem,
  761. class _Traits> inline
  762. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  763. basic_istream<_Elem, _Traits>& _Istr, signed char *_Str)
  764. { // extract a signed char NTBS
  765. return (_Istr >> (char *)_Str);
  766. }
  767. template<class _Elem,
  768. class _Traits> inline
  769. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  770. basic_istream<_Elem, _Traits>& _Istr, signed char& _Ch)
  771. { // extract a signed char
  772. return (_Istr >> (char&)_Ch);
  773. }
  774. template<class _Elem,
  775. class _Traits> inline
  776. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  777. basic_istream<_Elem, _Traits>& _Istr, unsigned char *_Str)
  778. { // extract an unsigned char NTBS
  779. return (_Istr >> (char *)_Str);
  780. }
  781. template<class _Elem,
  782. class _Traits> inline
  783. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  784. basic_istream<_Elem, _Traits>& _Istr, unsigned char& _Ch)
  785. { // extract an unsigned char
  786. return (_Istr >> (char&)_Ch);
  787. }
  788. template<class _Elem,
  789. class _Traits> inline
  790. basic_istream<_Elem, _Traits>& __cdecl operator>>(
  791. basic_istream<_Elem, _Traits>& _Istr, signed short * _Str)
  792. { // extract a wide character NTBS
  793. return (_Istr >> (wchar_t *)_Str);
  794. }
  795. #ifdef _DLL_CPPLIB
  796. #ifndef CRTDLL2
  797. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  798. operator>>(basic_istream<char, char_traits<char> >&, char *);
  799. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  800. operator>>(basic_istream<char, char_traits<char> >&, char&);
  801. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  802. operator>>(basic_istream<char, char_traits<char> >&, signed char *);
  803. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  804. operator>>(basic_istream<char, char_traits<char> >&, signed char&);
  805. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  806. operator>>(basic_istream<char, char_traits<char> >&, unsigned char *);
  807. template _CRTIMP2 basic_istream<char, char_traits<char> >& __cdecl
  808. operator>>(basic_istream<char, char_traits<char> >&, unsigned char&);
  809. template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >& __cdecl
  810. operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, wchar_t *);
  811. template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >& __cdecl
  812. operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&, wchar_t&);
  813. #ifdef _CRTBLD_NATIVE_WCHAR_T
  814. template _CRTIMP2 basic_istream<unsigned short, char_traits<unsigned short> >& __cdecl
  815. operator>>(basic_istream<unsigned short, char_traits<unsigned short> >&, unsigned short *);
  816. template _CRTIMP2 basic_istream<unsigned short, char_traits<unsigned short> >& __cdecl
  817. operator>>(basic_istream<unsigned short, char_traits<unsigned short> >&, unsigned short&);
  818. #endif
  819. #endif // CRTDLL2
  820. #endif // _DLL_CPPLIB
  821. // MANIPULATORS
  822. template<class _Elem,
  823. class _Traits> inline
  824. basic_istream<_Elem, _Traits>&
  825. __cdecl ws(basic_istream<_Elem, _Traits>& _Istr)
  826. { // consume whitespace
  827. typedef basic_istream<_Elem, _Traits> _Myis;
  828. typedef ctype<_Elem> _Ctype;
  829. ios_base::iostate _State = ios_base::goodbit;
  830. const typename _Myis::sentry _Ok(_Istr, true);
  831. if (_Ok)
  832. { // state okay, extract characters
  833. const _Ctype& _Facet = _USE(_Istr.getloc(), _Ctype);
  834. _TRY_IO_BEGIN
  835. for (typename _Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  836. _Meta = _Istr.rdbuf()->snextc())
  837. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  838. { // end of file, quit
  839. _State |= ios_base::eofbit;
  840. break;
  841. }
  842. else if (!_Facet.is(_Ctype::space,
  843. _Traits::to_char_type(_Meta)))
  844. break; // not whitespace, quit
  845. _CATCH_IO_(_Istr)
  846. }
  847. _Istr.setstate(_State);
  848. return (_Istr);
  849. }
  850. _CRTIMP2 inline basic_istream<char, char_traits<char> >&
  851. __cdecl ws(basic_istream<char, char_traits<char> >& _Istr)
  852. { // consume whitespace
  853. typedef char _Elem;
  854. typedef char_traits<_Elem> _Traits;
  855. ios_base::iostate _State = ios_base::goodbit;
  856. const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
  857. if (_Ok)
  858. { // state okay, use facet to extract
  859. const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
  860. _TRY_IO_BEGIN
  861. for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  862. _Meta = _Istr.rdbuf()->snextc())
  863. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  864. { // end of file, quit
  865. _State |= ios_base::eofbit;
  866. break;
  867. }
  868. else if (!_Facet.is(ctype<_Elem>::space,
  869. _Traits::to_char_type(_Meta)))
  870. break; // not whitespace, quit
  871. _CATCH_IO_(_Istr)
  872. }
  873. _Istr.setstate(_State);
  874. return (_Istr);
  875. }
  876. _CRTIMP2 inline basic_istream<wchar_t, char_traits<wchar_t> >&
  877. __cdecl ws(basic_istream<wchar_t, char_traits<wchar_t> >& _Istr)
  878. { // consume whitespace
  879. typedef wchar_t _Elem;
  880. typedef char_traits<_Elem> _Traits;
  881. ios_base::iostate _State = ios_base::goodbit;
  882. const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
  883. if (_Ok)
  884. { // state okay, use facet to extract
  885. const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
  886. _TRY_IO_BEGIN
  887. for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  888. _Meta = _Istr.rdbuf()->snextc())
  889. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  890. { // end of file, quit
  891. _State |= ios_base::eofbit;
  892. break;
  893. }
  894. else if (!_Facet.is(ctype<_Elem>::space,
  895. _Traits::to_char_type(_Meta)))
  896. break; // not whitespace, quit
  897. _CATCH_IO_(_Istr)
  898. }
  899. _Istr.setstate(_State);
  900. return (_Istr);
  901. }
  902. #ifdef _CRTBLD_NATIVE_WCHAR_T
  903. _CRTIMP2 inline basic_istream<unsigned short, char_traits<unsigned short> >&
  904. __cdecl ws(basic_istream<unsigned short, char_traits<unsigned short> >& _Istr)
  905. { // consume whitespace
  906. typedef unsigned short _Elem;
  907. typedef char_traits<_Elem> _Traits;
  908. ios_base::iostate _State = ios_base::goodbit;
  909. const basic_istream<_Elem, _Traits>::sentry _Ok(_Istr, true);
  910. if (_Ok)
  911. { // state okay, use facet to extract
  912. const ctype<_Elem>& _Facet = _USE(_Istr.getloc(), ctype<_Elem>);
  913. _TRY_IO_BEGIN
  914. for (_Traits::int_type _Meta = _Istr.rdbuf()->sgetc(); ;
  915. _Meta = _Istr.rdbuf()->snextc())
  916. if (_Traits::eq_int_type(_Traits::eof(), _Meta))
  917. { // end of file, quit
  918. _State |= ios_base::eofbit;
  919. break;
  920. }
  921. else if (!_Facet.is(ctype<_Elem>::space,
  922. _Traits::to_char_type(_Meta)))
  923. break; // not whitespace, quit
  924. _CATCH_IO_(_Istr)
  925. }
  926. _Istr.setstate(_State);
  927. return (_Istr);
  928. }
  929. #endif
  930. _STD_END
  931. #pragma warning(pop)
  932. #pragma pack(pop)
  933. #endif /* _ISTREAM_ */
  934. /*
  935. * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
  936. * Consult your license regarding permissions and restrictions.
  937. V3.10:0009 */