wscan.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. wscan.c
  9. Abstract:
  10. This module implements wide string scanning functions.
  11. Author:
  12. Evan Green 27-Aug-2013
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "libcp.h"
  20. #include <errno.h>
  21. #include <limits.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. //
  25. // ---------------------------------------------------------------- Definitions
  26. //
  27. //
  28. // ------------------------------------------------------ Data Type Definitions
  29. //
  30. //
  31. // ----------------------------------------------- Internal Function Prototypes
  32. //
  33. BOOL
  34. ClpStreamScannerGetInputWide (
  35. PSCAN_INPUT Input,
  36. PWCHAR Character
  37. );
  38. //
  39. // -------------------------------------------------------------------- Globals
  40. //
  41. //
  42. // ------------------------------------------------------------------ Functions
  43. //
  44. LIBC_API
  45. int
  46. swscanf (
  47. const wchar_t *Input,
  48. const wchar_t *Format,
  49. ...
  50. )
  51. /*++
  52. Routine Description:
  53. This routine scans in a wide string and converts it to a number of arguments
  54. based on a format string.
  55. Arguments:
  56. Input - Supplies a pointer to the wide input string to scan.
  57. Format - Supplies the format wide string that specifies how to convert the
  58. input to the arguments.
  59. ... - Supplies the remaining pointer arguments where the scanned data will
  60. be returned.
  61. Return Value:
  62. Returns the number of successfully matched items on success. If the input
  63. ends before the first matching failure or conversion, EOF is returned. If
  64. a read error occurs, EOF shall be returned and errno shall be set to
  65. indicate the error.
  66. --*/
  67. {
  68. va_list ArgumentList;
  69. ULONG FormatLength;
  70. ULONG InputLength;
  71. ULONG ItemsScanned;
  72. int ReturnValue;
  73. KSTATUS Status;
  74. va_start(ArgumentList, Format);
  75. InputLength = MAX_ULONG;
  76. FormatLength = MAX_ULONG;
  77. Status = RtlStringScanVaListWide((PWSTR)Input,
  78. InputLength,
  79. (PWSTR)Format,
  80. FormatLength,
  81. CharacterEncodingDefault,
  82. &ItemsScanned,
  83. ArgumentList);
  84. if (!KSUCCESS(Status)) {
  85. ReturnValue = EOF;
  86. errno = ClConvertKstatusToErrorNumber(Status);
  87. if (Status != STATUS_END_OF_FILE) {
  88. if (ItemsScanned != 0) {
  89. ReturnValue = ItemsScanned;
  90. }
  91. }
  92. } else {
  93. ReturnValue = ItemsScanned;
  94. }
  95. va_end(ArgumentList);
  96. return ReturnValue;
  97. }
  98. LIBC_API
  99. int
  100. vswscanf (
  101. const wchar_t *String,
  102. const wchar_t *Format,
  103. va_list ArgumentList
  104. )
  105. /*++
  106. Routine Description:
  107. This routine scans in a wide string and converts it to a number of arguments
  108. based on a format string.
  109. Arguments:
  110. String - Supplies a pointer to the wide input string to scan.
  111. Format - Supplies the wide format string that specifies how to convert the
  112. input to the arguments.
  113. ArgumentList - Supplies the remaining arguments, which are all pointers to
  114. various types to be scanned.
  115. Return Value:
  116. Returns the number of successfully matched items on success. If the input
  117. ends before the first matching failure or conversion, EOF is returned. If
  118. a read error occurs, EOF shall be returned and errno shall be set to
  119. indicate the error.
  120. --*/
  121. {
  122. ULONG FormatLength;
  123. ULONG InputLength;
  124. ULONG ItemsScanned;
  125. int ReturnValue;
  126. KSTATUS Status;
  127. InputLength = MAX_ULONG;
  128. FormatLength = MAX_ULONG;
  129. Status = RtlStringScanVaListWide((PWSTR)String,
  130. InputLength,
  131. (PWSTR)Format,
  132. FormatLength,
  133. CharacterEncodingDefault,
  134. &ItemsScanned,
  135. ArgumentList);
  136. if (!KSUCCESS(Status)) {
  137. ReturnValue = EOF;
  138. errno = ClConvertKstatusToErrorNumber(Status);
  139. if (Status != STATUS_END_OF_FILE) {
  140. if (ItemsScanned != 0) {
  141. ReturnValue = ItemsScanned;
  142. }
  143. }
  144. } else {
  145. ReturnValue = ItemsScanned;
  146. }
  147. return ReturnValue;
  148. }
  149. LIBC_API
  150. int
  151. fwscanf (
  152. FILE *Stream,
  153. const wchar_t *Format,
  154. ...
  155. )
  156. /*++
  157. Routine Description:
  158. This routine scans in a string from a stream and converts it to a number
  159. of arguments based on a wide format string.
  160. Arguments:
  161. Stream - Supplies a pointer to the input stream.
  162. Format - Supplies the wide format string that specifies how to convert the
  163. input to the arguments.
  164. ... - Supplies the remaining arguments, which are all pointers to
  165. various types to be scanned.
  166. Return Value:
  167. Returns the number of successfully matched items on success. If the input
  168. ends before the first matching failure or conversion, EOF is returned. If
  169. a read error occurs, EOF shall be returned and errno shall be set to
  170. indicate the error.
  171. --*/
  172. {
  173. va_list ArgumentList;
  174. int Result;
  175. va_start(ArgumentList, Format);
  176. Result = vfwscanf(Stream, Format, ArgumentList);
  177. va_end(ArgumentList);
  178. return Result;
  179. }
  180. LIBC_API
  181. int
  182. vfwscanf (
  183. FILE *Stream,
  184. const wchar_t *Format,
  185. va_list ArgumentList
  186. )
  187. /*++
  188. Routine Description:
  189. This routine scans in a string from a stream and converts it to a number
  190. of arguments based on a format string.
  191. Arguments:
  192. Stream - Supplies a pointer to the input stream.
  193. Format - Supplies the wide format string that specifies how to convert the
  194. input to the arguments.
  195. ArgumentList - Supplies the remaining arguments, which are all pointers to
  196. various types to be scanned.
  197. Return Value:
  198. Returns the number of successfully matched items on success. If the input
  199. ends before the first matching failure or conversion, EOF is returned. If
  200. a read error occurs, EOF shall be returned and errno shall be set to
  201. indicate the error.
  202. --*/
  203. {
  204. int Result;
  205. ClpLockStream(Stream);
  206. Result = vfwscanf_unlocked(Stream, Format, ArgumentList);
  207. ClpUnlockStream(Stream);
  208. return Result;
  209. }
  210. LIBC_API
  211. int
  212. vfwscanf_unlocked (
  213. FILE *Stream,
  214. const wchar_t *Format,
  215. va_list ArgumentList
  216. )
  217. /*++
  218. Routine Description:
  219. This routine scans in a string from a stream and converts it to a number
  220. of arguments based on a format string. This routine does not acquire the
  221. stream's lock.
  222. Arguments:
  223. Stream - Supplies a pointer to the input stream.
  224. Format - Supplies the side format string that specifies how to convert the
  225. input to the arguments.
  226. ArgumentList - Supplies the remaining arguments, which are all pointers to
  227. various types to be scanned.
  228. Return Value:
  229. Returns the number of successfully matched items on success. If the input
  230. ends before the first matching failure or conversion, EOF is returned. If
  231. a read error occurs, EOF shall be returned and errno shall be set to
  232. indicate the error.
  233. --*/
  234. {
  235. SCAN_INPUT Input;
  236. ULONG ItemsScanned;
  237. int ReturnValue;
  238. KSTATUS Status;
  239. RtlZeroMemory(&Input, sizeof(SCAN_INPUT));
  240. Input.DataU.Context = Stream;
  241. Input.ReadU.GetInputWide = ClpStreamScannerGetInputWide;
  242. Status = RtlScanWide(&Input,
  243. (PWSTR)Format,
  244. MAX_ULONG,
  245. &ItemsScanned,
  246. ArgumentList);
  247. if (!KSUCCESS(Status)) {
  248. ReturnValue = EOF;
  249. errno = ClConvertKstatusToErrorNumber(Status);
  250. if (Status != STATUS_END_OF_FILE) {
  251. if (ItemsScanned != 0) {
  252. ReturnValue = ItemsScanned;
  253. }
  254. }
  255. } else {
  256. ReturnValue = ItemsScanned;
  257. }
  258. return ReturnValue;
  259. }
  260. LIBC_API
  261. int
  262. wscanf (
  263. const wchar_t *Format,
  264. ...
  265. )
  266. /*++
  267. Routine Description:
  268. This routine scans in a string from standard in and converts it to a number
  269. of arguments based on a format string.
  270. Arguments:
  271. Format - Supplies the wide format string that specifies how to convert the
  272. input to the arguments.
  273. ... - Supplies the remaining arguments, which are all pointers to
  274. various types to be scanned.
  275. Return Value:
  276. Returns the number of successfully matched items on success. If the input
  277. ends before the first matching failure or conversion, EOF is returned. If
  278. a read error occurs, EOF shall be returned and errno shall be set to
  279. indicate the error.
  280. --*/
  281. {
  282. va_list ArgumentList;
  283. int Result;
  284. va_start(ArgumentList, Format);
  285. Result = vwscanf(Format, ArgumentList);
  286. va_end(ArgumentList);
  287. return Result;
  288. }
  289. LIBC_API
  290. int
  291. vwscanf (
  292. const wchar_t *Format,
  293. va_list ArgumentList
  294. )
  295. /*++
  296. Routine Description:
  297. This routine scans in a string from standard in and converts it to a number
  298. of arguments based on a format string.
  299. Arguments:
  300. Format - Supplies the wide format string that specifies how to convert the
  301. input to the arguments.
  302. ArgumentList - Supplies the remaining arguments, which are all pointers to
  303. various types to be scanned.
  304. Return Value:
  305. Returns the number of successfully matched items on success. If the input
  306. ends before the first matching failure or conversion, EOF is returned. If
  307. a read error occurs, EOF shall be returned and errno shall be set to
  308. indicate the error.
  309. --*/
  310. {
  311. int Result;
  312. Result = vfwscanf(stdin, Format, ArgumentList);
  313. return Result;
  314. }
  315. LIBC_API
  316. float
  317. wcstof (
  318. const wchar_t *String,
  319. wchar_t **StringAfterScan
  320. )
  321. /*++
  322. Routine Description:
  323. This routine converts the initial portion of the given wide string into a
  324. float. This routine will scan past any whitespace at the beginning of
  325. the string.
  326. Arguments:
  327. String - Supplies a pointer to the null terminated wide string to convert
  328. to afloat.
  329. StringAfterScan - Supplies a pointer where a pointer will be returned
  330. representing the remaining portion of the string after the float was
  331. scanned. If the entire string is made up of whitespace or invalid
  332. characters, then this will point to the beginning of the given string
  333. (the scanner will not be advanced).
  334. Return Value:
  335. Returns the float representation of the string. If the value could not be
  336. converted, 0 is returned, and errno will be set to either EINVAL if the
  337. number could not be converted or ERANGE if the number is outside of the
  338. return type's expressible range.
  339. --*/
  340. {
  341. double Double;
  342. Double = wcstod(String, StringAfterScan);
  343. return (float)Double;
  344. }
  345. LIBC_API
  346. double
  347. wcstod (
  348. const wchar_t *String,
  349. wchar_t **StringAfterScan
  350. )
  351. /*++
  352. Routine Description:
  353. This routine converts the initial portion of the given wide string into a
  354. double. This routine will scan past any whitespace at the beginning of
  355. the string.
  356. Arguments:
  357. String - Supplies a pointer to the null terminated wide string to convert
  358. to a double.
  359. StringAfterScan - Supplies a pointer where a pointer will be returned
  360. representing the remaining portion of the wide string after the double
  361. was scanned. If the entire string is made up of whitespace or invalid
  362. characters, then this will point to the beginning of the given string
  363. (the scanner will not be advanced).
  364. Return Value:
  365. Returns the double representation of the wide string. If the value could
  366. not be converted, 0 is returned, and errno will be set to either EINVAL if
  367. the number could not be converted or ERANGE if the number is outside of the
  368. return type's expressible range.
  369. --*/
  370. {
  371. double Double;
  372. PCWSTR RemainingString;
  373. KSTATUS Status;
  374. ULONG StringLength;
  375. StringLength = MAX_ULONG;
  376. RemainingString = (PWSTR)String;
  377. Status = RtlStringScanDoubleWide(&RemainingString, &StringLength, &Double);
  378. if (StringAfterScan != NULL) {
  379. *StringAfterScan = (PWSTR)RemainingString;
  380. }
  381. if (!KSUCCESS(Status)) {
  382. errno = ClConvertKstatusToErrorNumber(Status);
  383. return 0;
  384. }
  385. return Double;
  386. }
  387. LIBC_API
  388. long double
  389. wcstold (
  390. const wchar_t *String,
  391. wchar_t **StringAfterScan
  392. )
  393. /*++
  394. Routine Description:
  395. This routine converts the initial portion of the given wide string into a
  396. long double. This routine will scan past any whitespace at the beginning of
  397. the string.
  398. Arguments:
  399. String - Supplies a pointer to the null terminated wide string to convert
  400. to a long double.
  401. StringAfterScan - Supplies a pointer where a pointer will be returned
  402. representing the remaining portion of the string after the long double
  403. was scanned. If the entire string is made up of whitespace or invalid
  404. characters, then this will point to the beginning of the given string
  405. (the scanner will not be advanced).
  406. Return Value:
  407. Returns the long double representation of the string. If the value could not
  408. be converted, 0 is returned, and errno will be set to either EINVAL if the
  409. number could not be converted or ERANGE if the number is outside of the
  410. return type's expressible range.
  411. --*/
  412. {
  413. double Double;
  414. Double = wcstod(String, StringAfterScan);
  415. return (long double)Double;
  416. }
  417. LIBC_API
  418. long
  419. wcstol (
  420. const wchar_t *String,
  421. wchar_t **StringAfterScan,
  422. int Base
  423. )
  424. /*++
  425. Routine Description:
  426. This routine converts the initial portion of the given wide string into an
  427. integer. This routine will scan past any whitespace at the beginning of
  428. the string. The string may have an optional plus or minus in front of the
  429. number to indicate sign.
  430. Arguments:
  431. String - Supplies a pointer to the null terminated wide string to convert
  432. to an integer.
  433. StringAfterScan - Supplies a pointer where a pointer will be returned
  434. representing the remaining portion of the wide string after the integer
  435. was scanned. If the entire string is made up of whitespace or invalid
  436. characters, then this will point to the beginning of the given string
  437. (the scanner will not be advanced).
  438. Base - Supplies the base system to interpret the number as. If zero is
  439. supplied, the base will be figured out based on the contents of the
  440. string. If the string begins with 0, it's treated as an octal (base 8)
  441. number. If the string begins with 1-9, it's treated as a decimal
  442. (base 10) number. And if the string begins with 0x or 0X, it's treated
  443. as a hexadecimal (base 16) number. Other base values must be specified
  444. explicitly here.
  445. Return Value:
  446. Returns the integer representation of the string. If the value could not be
  447. converted, 0 is returned, and errno will be set to either EINVAL if the
  448. number could not be converted or ERANGE if the number is outside of the
  449. return type's expressible range.
  450. --*/
  451. {
  452. LONGLONG Integer;
  453. PCWSTR RemainingString;
  454. KSTATUS Status;
  455. ULONG StringLength;
  456. StringLength = MAX_ULONG;
  457. RemainingString = (PWSTR)String;
  458. Status = RtlStringScanIntegerWide(&RemainingString,
  459. &StringLength,
  460. Base,
  461. TRUE,
  462. &Integer);
  463. if (StringAfterScan != NULL) {
  464. *StringAfterScan = (PWSTR)RemainingString;
  465. }
  466. if (!KSUCCESS(Status)) {
  467. errno = ClConvertKstatusToErrorNumber(Status);
  468. //
  469. // On integer overflow, set errno to ERANGE, but still return the
  470. // value, which will be a very extreme value.
  471. //
  472. if (Status == STATUS_INTEGER_OVERFLOW) {
  473. if (Integer == LLONG_MAX) {
  474. return LONG_MAX;
  475. }
  476. return LONG_MIN;
  477. } else {
  478. return 0;
  479. }
  480. }
  481. if (Integer > LONG_MAX) {
  482. errno = ERANGE;
  483. return LONG_MAX;
  484. } else if (Integer < LONG_MIN) {
  485. errno = ERANGE;
  486. return LONG_MIN;
  487. }
  488. return (LONG)Integer;
  489. }
  490. LIBC_API
  491. long long
  492. wcstoll (
  493. const wchar_t *String,
  494. wchar_t **StringAfterScan,
  495. int Base
  496. )
  497. /*++
  498. Routine Description:
  499. This routine converts the initial portion of the given wide string into an
  500. integer. This routine will scan past any whitespace at the beginning of
  501. the string. The string may have an optional plus or minus in front of the
  502. number to indicate sign.
  503. Arguments:
  504. String - Supplies a pointer to the null terminated wide string to convert
  505. to an integer.
  506. StringAfterScan - Supplies a pointer where a pointer will be returned
  507. representing the remaining portion of the wide string after the integer
  508. was scanned. If the entire string is made up of whitespace or invalid
  509. characters, then this will point to the beginning of the given string
  510. (the scanner will not be advanced).
  511. Base - Supplies the base system to interpret the number as. If zero is
  512. supplied, the base will be figured out based on the contents of the
  513. string. If the string begins with 0, it's treated as an octal (base 8)
  514. number. If the string begins with 1-9, it's treated as a decimal
  515. (base 10) number. And if the string begins with 0x or 0X, it's treated
  516. as a hexadecimal (base 16) number. Other base values must be specified
  517. explicitly here.
  518. Return Value:
  519. Returns the integer representation of the string. If the value could not be
  520. converted, 0 is returned, and errno will be set to EINVAL to indicate the
  521. number could not be converted.
  522. --*/
  523. {
  524. LONGLONG Integer;
  525. PCWSTR RemainingString;
  526. KSTATUS Status;
  527. ULONG StringLength;
  528. StringLength = MAX_ULONG;
  529. RemainingString = (PWSTR)String;
  530. Status = RtlStringScanIntegerWide(&RemainingString,
  531. &StringLength,
  532. Base,
  533. TRUE,
  534. &Integer);
  535. if (StringAfterScan != NULL) {
  536. *StringAfterScan = (PWSTR)RemainingString;
  537. }
  538. if (!KSUCCESS(Status)) {
  539. if (Status != STATUS_INTEGER_OVERFLOW) {
  540. Integer = 0;
  541. }
  542. errno = ClConvertKstatusToErrorNumber(Status);
  543. }
  544. return Integer;
  545. }
  546. LIBC_API
  547. long
  548. wcstoul (
  549. const wchar_t *String,
  550. wchar_t **StringAfterScan,
  551. int Base
  552. )
  553. /*++
  554. Routine Description:
  555. This routine converts the initial portion of the given wide string into an
  556. integer. This routine will scan past any whitespace at the beginning of
  557. the string. The string may have an optional plus or minus in front of the
  558. number to indicate sign.
  559. Arguments:
  560. String - Supplies a pointer to the null terminated wide string to convert
  561. to an integer.
  562. StringAfterScan - Supplies a pointer where a pointer will be returned
  563. representing the remaining portion of the wide string after the integer
  564. was scanned. If the entire string is made up of whitespace or invalid
  565. characters, then this will point to the beginning of the given string
  566. (the scanner will not be advanced).
  567. Base - Supplies the base system to interpret the number as. If zero is
  568. supplied, the base will be figured out based on the contents of the
  569. string. If the string begins with 0, it's treated as an octal (base 8)
  570. number. If the string begins with 1-9, it's treated as a decimal
  571. (base 10) number. And if the string begins with 0x or 0X, it's treated
  572. as a hexadecimal (base 16) number. Other base values must be specified
  573. explicitly here.
  574. Return Value:
  575. Returns the integer representation of the string. If the value could not be
  576. converted, 0 is returned, and errno will be set to either EINVAL if the
  577. number could not be converted or ERANGE if the number is outside of the
  578. return type's expressible range.
  579. --*/
  580. {
  581. LONGLONG Integer;
  582. PCWSTR RemainingString;
  583. KSTATUS Status;
  584. ULONG StringLength;
  585. StringLength = MAX_ULONG;
  586. RemainingString = (PWSTR)String;
  587. Status = RtlStringScanIntegerWide(&RemainingString,
  588. &StringLength,
  589. Base,
  590. FALSE,
  591. &Integer);
  592. if (StringAfterScan != NULL) {
  593. *StringAfterScan = (PWSTR)RemainingString;
  594. }
  595. if (!KSUCCESS(Status)) {
  596. errno = ClConvertKstatusToErrorNumber(Status);
  597. if (Status == STATUS_INTEGER_OVERFLOW) {
  598. return ULONG_MAX;
  599. } else {
  600. return 0;
  601. }
  602. }
  603. if ((ULONGLONG)Integer > ULONG_MAX) {
  604. errno = ERANGE;
  605. return ULONG_MAX;
  606. }
  607. return (ULONG)(ULONGLONG)Integer;
  608. }
  609. LIBC_API
  610. long long
  611. wcstoull (
  612. const wchar_t *String,
  613. wchar_t **StringAfterScan,
  614. int Base
  615. )
  616. /*++
  617. Routine Description:
  618. This routine converts the initial portion of the given wide string into an
  619. integer. This routine will scan past any whitespace at the beginning of
  620. the string. The string may have an optional plus or minus in front of the
  621. number to indicate sign.
  622. Arguments:
  623. String - Supplies a pointer to the null terminated wide string to convert
  624. to an integer.
  625. StringAfterScan - Supplies a pointer where a pointer will be returned
  626. representing the remaining portion of the wide string after the integer
  627. was scanned. If the entire string is made up of whitespace or invalid
  628. characters, then this will point to the beginning of the given string
  629. (the scanner will not be advanced).
  630. Base - Supplies the base system to interpret the number as. If zero is
  631. supplied, the base will be figured out based on the contents of the
  632. string. If the string begins with 0, it's treated as an octal (base 8)
  633. number. If the string begins with 1-9, it's treated as a decimal
  634. (base 10) number. And if the string begins with 0x or 0X, it's treated
  635. as a hexadecimal (base 16) number. Other base values must be specified
  636. explicitly here.
  637. Return Value:
  638. Returns the integer representation of the string. If the value could not be
  639. converted, 0 is returned, and errno will be set to EINVAL to indicate the
  640. number could not be converted.
  641. --*/
  642. {
  643. LONGLONG Integer;
  644. PCWSTR RemainingString;
  645. KSTATUS Status;
  646. ULONG StringLength;
  647. StringLength = MAX_ULONG;
  648. RemainingString = (PWSTR)String;
  649. Status = RtlStringScanIntegerWide(&RemainingString,
  650. &StringLength,
  651. Base,
  652. FALSE,
  653. &Integer);
  654. if (StringAfterScan != NULL) {
  655. *StringAfterScan = (PWSTR)RemainingString;
  656. }
  657. if (!KSUCCESS(Status)) {
  658. if (Status != STATUS_INTEGER_OVERFLOW) {
  659. Integer = 0;
  660. }
  661. errno = ClConvertKstatusToErrorNumber(Status);
  662. }
  663. return (ULONGLONG)Integer;
  664. }
  665. //
  666. // --------------------------------------------------------- Internal Functions
  667. //
  668. BOOL
  669. ClpStreamScannerGetInputWide (
  670. PSCAN_INPUT Input,
  671. PWCHAR Character
  672. )
  673. /*++
  674. Routine Description:
  675. This routine retrieves another byte of input from the input scanner for a
  676. stream based scanner.
  677. Arguments:
  678. Input - Supplies a pointer to the input scanner structure.
  679. Character - Supplies a pointer where the character will be returned on
  680. success.
  681. Return Value:
  682. TRUE if a character was read.
  683. FALSE if the end of the file or string was encountered.
  684. --*/
  685. {
  686. wint_t NewCharacter;
  687. NewCharacter = fgetwc_unlocked(Input->DataU.Context);
  688. if (NewCharacter == WEOF) {
  689. return FALSE;
  690. }
  691. *Character = (WCHAR)NewCharacter;
  692. Input->CharactersRead += 1;
  693. return TRUE;
  694. }