Leaked source code of windows server 2003
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.

505 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. parsers.cxx
  5. Abstract:
  6. Common text parsing functions (generally moved here from other protocols)
  7. Contents:
  8. ExtractWord
  9. ExtractDword
  10. ExtractInt
  11. SkipWhitespace
  12. SkipSpaces
  13. SkipLine
  14. FindToken
  15. NiceNum
  16. Author:
  17. Richard L Firth (rfirth) 03-Jul-1996
  18. Revision History:
  19. 03-Jul-1996 rfirth
  20. Created
  21. --*/
  22. #include <wininetp.h>
  23. //
  24. // functions
  25. //
  26. BOOL
  27. ExtractWord(
  28. IN OUT LPSTR* pString,
  29. IN DWORD NumberLength,
  30. OUT LPWORD pConvertedNumber
  31. )
  32. /*++
  33. Routine Description:
  34. pulls a <NumberLength> character number out of a string.
  35. Assumes: 1. The number to be converted is an unsigned short
  36. 2. A whole number is contained within *pString
  37. Arguments:
  38. pString - pointer to pointer to string from which to get number
  39. NumberLength - number of characters that comprise number string, if
  40. not equal to 0, else if 0, we don't know the length
  41. of the number string a priori
  42. pConvertedNumber - pointer to variable where converted number written
  43. Return Value:
  44. BOOL
  45. TRUE - number converted OK
  46. FALSE - one of the characters in the number is not a digit
  47. --*/
  48. {
  49. WORD number;
  50. BOOL exact;
  51. LPSTR string;
  52. //
  53. // if the caller doesn't know how many characters comprise the number, then
  54. // we will convert until the next non-digit character, or until we have
  55. // converted the maximum number of digits that can comprise an unsigned
  56. // short value
  57. //
  58. if (NumberLength == 0) {
  59. NumberLength = sizeof("65535") - 1;
  60. exact = FALSE;
  61. } else {
  62. exact = TRUE;
  63. }
  64. number = 0;
  65. string = *pString;
  66. while (NumberLength && isdigit(*string)) {
  67. number = number * 10 + (WORD)((BYTE)(*string++) - (BYTE)'0');
  68. --NumberLength;
  69. }
  70. *pConvertedNumber = number;
  71. *pString = string;
  72. //
  73. // if we were asked to convert a certain number of characters but failed
  74. // because we hit a non-digit character, then return FALSE. Anything else
  75. // (we converted required number of characters, or the caller didn't know
  76. // how many characters comprised the number) is TRUE
  77. //
  78. return (exact && (NumberLength != 0)) ? FALSE : TRUE;
  79. }
  80. BOOL
  81. ExtractDword(
  82. IN OUT LPSTR* pString,
  83. IN DWORD NumberLength,
  84. OUT LPDWORD pConvertedNumber
  85. )
  86. /*++
  87. Routine Description:
  88. pulls a <NumberLength> character number out of a string.
  89. Assumes: 1. The number to be converted is an unsigned long
  90. 2. A whole number is contained within *pString
  91. Arguments:
  92. pString - pointer to pointer to string from which to get number
  93. NumberLength - number of characters that comprise number string, if
  94. not equal to 0, else if 0, we don't know the length
  95. of the number string a priori
  96. pConvertedNumber - pointer to variable where converted number written
  97. Return Value:
  98. BOOL
  99. TRUE - number converted OK
  100. FALSE - one of the characters in the number is not a digit
  101. --*/
  102. {
  103. DWORD number;
  104. BOOL exact;
  105. //
  106. // if the caller doesn't know how many characters comprise the number, then
  107. // we will convert until the next non-digit character, or until we have
  108. // converted the maximum number of digits that can comprise an unsigned
  109. // short value
  110. //
  111. if (NumberLength == 0) {
  112. NumberLength = sizeof("4294967295") - 1;
  113. exact = FALSE;
  114. } else {
  115. exact = TRUE;
  116. }
  117. for (number = 0; isdigit(**pString) && NumberLength--; ) {
  118. number = number * 10 + (DWORD)((BYTE)*((*pString)++) - (BYTE)'0');
  119. }
  120. *pConvertedNumber = number;
  121. //
  122. // if we were asked to convert a certain number of characters but failed
  123. // because we hit a non-digit character, then return FALSE. Anything else
  124. // (we converted required number of characters, or the caller didn't know
  125. // how many characters comprised the number) is TRUE
  126. //
  127. return (exact && (NumberLength != 0)) ? FALSE : TRUE;
  128. }
  129. BOOL
  130. ExtractInt(
  131. IN OUT LPSTR* pString,
  132. IN DWORD NumberLength,
  133. OUT LPINT pConvertedNumber
  134. )
  135. /*++
  136. Routine Description:
  137. pulls a <NumberLength> character number out of a string.
  138. Assumes: 1. The number to be converted is an signed integer (32-bits)
  139. Arguments:
  140. pString - pointer to pointer to string from which to get number
  141. NumberLength - number of characters that comprise number string, if
  142. not equal to 0, else if 0, we don't know the length
  143. of the number string a priori
  144. pConvertedNumber - pointer to variable where converted number written
  145. Return Value:
  146. BOOL
  147. TRUE - number converted OK
  148. FALSE - one of the characters in the number is not a digit
  149. --*/
  150. {
  151. int number;
  152. int sign;
  153. BOOL exact;
  154. if ((**pString == '-') || (**pString == '+')) {
  155. sign = (**pString == '-') ? -1 : +1;
  156. if (NumberLength) {
  157. --NumberLength;
  158. }
  159. ++*pString;
  160. } else {
  161. sign = 1;
  162. }
  163. //
  164. // if the caller doesn't know how many characters comprise the number, then
  165. // we will convert until the next non-digit character, or until we have
  166. // converted the maximum number of digits that can comprise an unsigned
  167. // short value
  168. //
  169. if (NumberLength == 0) {
  170. NumberLength = sizeof("2147483647") - 1;
  171. exact = FALSE;
  172. } else {
  173. exact = TRUE;
  174. }
  175. for (number = 0; isdigit(**pString) && NumberLength; ) {
  176. number = number * 10 + (INT)(((BYTE)**pString) - (BYTE)'0');
  177. ++*pString;
  178. --NumberLength;
  179. }
  180. *pConvertedNumber = number * sign;
  181. //
  182. // if we were asked to convert a certain number of characters but failed
  183. // because we hit a non-digit character, then return FALSE. Anything else
  184. // (we converted required number of characters, or the caller didn't know
  185. // how many characters comprised the number) is TRUE
  186. //
  187. return (exact && (NumberLength != 0)) ? FALSE : TRUE;
  188. }
  189. BOOL
  190. SkipWhitespace(
  191. IN OUT LPSTR* lpBuffer,
  192. IN OUT LPDWORD lpBufferLength
  193. )
  194. /*++
  195. Routine Description:
  196. Skips any whitespace characters
  197. Arguments:
  198. lpBuffer - pointer to pointer to buffer
  199. lpBufferLength - pointer to remaining buffer length
  200. Return Value:
  201. BOOL
  202. Success - TRUE
  203. Failure - FALSE. No more data left in buffer
  204. --*/
  205. {
  206. while ((*lpBufferLength != 0) && isspace(**lpBuffer)) {
  207. ++*lpBuffer;
  208. --*lpBufferLength;
  209. }
  210. return *lpBufferLength != 0;
  211. }
  212. BOOL
  213. SkipSpaces(
  214. IN OUT LPSTR* lpBuffer,
  215. IN OUT LPDWORD lpBufferLength
  216. )
  217. /*++
  218. Routine Description:
  219. Skips any space characters. We only look for the actual space character
  220. Arguments:
  221. lpBuffer - pointer to pointer to buffer
  222. lpBufferLength - pointer to remaining buffer length
  223. Return Value:
  224. BOOL
  225. Success - TRUE
  226. Failure - FALSE. No more data left in buffer
  227. --*/
  228. {
  229. while ((*lpBufferLength != 0) && (**lpBuffer == ' ')) {
  230. ++*lpBuffer;
  231. --*lpBufferLength;
  232. }
  233. return *lpBufferLength != 0;
  234. }
  235. BOOL
  236. SkipLine(
  237. IN OUT LPSTR* lpBuffer,
  238. IN OUT LPDWORD lpBufferLength
  239. )
  240. /*++
  241. Routine Description:
  242. Positions text pointer at start of next non-empty line
  243. Arguments:
  244. lpBuffer - pointer to string. Updated on output
  245. lpBufferLength - pointer to remaining length of string. Updated on output
  246. Return Value:
  247. BOOL
  248. TRUE - found start of next non-empty line
  249. FALSE - ran out of buffer
  250. --*/
  251. {
  252. while ((*lpBufferLength != 0) && (**lpBuffer != '\r') && (**lpBuffer != '\n')) {
  253. ++*lpBuffer;
  254. --*lpBufferLength;
  255. }
  256. while ((*lpBufferLength != 0) && ((**lpBuffer == '\r') || (**lpBuffer == '\n'))) {
  257. ++*lpBuffer;
  258. --*lpBufferLength;
  259. }
  260. return *lpBufferLength != 0;
  261. }
  262. #undef isspace
  263. #define isspace(ch) ((ch==0x20) || ((ch >= 0x09) && (ch <= 0x0d)))
  264. BOOL
  265. FindToken(
  266. IN OUT LPSTR* lpBuffer,
  267. IN OUT LPDWORD lpBufferLength
  268. )
  269. /*++
  270. Routine Description:
  271. Moves over the current token, past any spaces, and to the start of the next
  272. token
  273. Arguments:
  274. lpBuffer - pointer to pointer to buffer
  275. lpBufferLength - pointer to remaining buffer length
  276. Return Value:
  277. BOOL
  278. Success - TRUE
  279. Failure - FALSE. No more data left in buffer
  280. --*/
  281. {
  282. while ((*lpBufferLength != 0) && !isspace(**lpBuffer)) {
  283. ++*lpBuffer;
  284. --*lpBufferLength;
  285. }
  286. while ((*lpBufferLength != 0) && isspace(**lpBuffer)) {
  287. ++*lpBuffer;
  288. --*lpBufferLength;
  289. }
  290. return *lpBufferLength != 0;
  291. }
  292. LPSTR
  293. NiceNum(
  294. OUT LPSTR Buffer,
  295. IN SIZE_T Number,
  296. IN int FieldWidth
  297. )
  298. /*++
  299. Routine Description:
  300. Converts a number to a string. The string is very human-sensible (i.e.
  301. 1,234,567 instead of 1234567. Sometimes its hard to make out these numbers
  302. when your salary is so large)
  303. Arguments:
  304. Buffer - place to put resultant string
  305. Number - to convert
  306. FieldWidth - maximum width of the field, or 0 for "don't care"
  307. Return Value:
  308. LPSTR
  309. pointer to Buffer
  310. --*/
  311. {
  312. int i;
  313. if (Number == 0) {
  314. if (FieldWidth == 0) {
  315. Buffer[0] = '0';
  316. Buffer[1] = '\0';
  317. } else {
  318. memset(Buffer, ' ', FieldWidth);
  319. Buffer[FieldWidth - 1] = '0';
  320. Buffer[FieldWidth] = '\0';
  321. }
  322. } else {
  323. //
  324. // if the caller specified zero for the field width then work out how
  325. // many characters the string will occupy
  326. //
  327. if (FieldWidth == 0) {
  328. SIZE_T n;
  329. n = Number;
  330. ++FieldWidth;
  331. while (n >= 10) {
  332. n /= 10;
  333. ++FieldWidth;
  334. }
  335. FieldWidth += (FieldWidth / 3) - (((FieldWidth % 3) == 0) ? 1 : 0);
  336. }
  337. //
  338. // now create the representation
  339. //
  340. Buffer[FieldWidth] = '\0';
  341. Buffer += FieldWidth;
  342. i = 0;
  343. while (Number && FieldWidth) {
  344. *--Buffer = (char)((Number % 10) + '0');
  345. --FieldWidth;
  346. Number /= 10;
  347. if ((++i == 3) && FieldWidth) {
  348. if (Number) {
  349. *--Buffer = ',';
  350. --FieldWidth;
  351. i = 0;
  352. }
  353. }
  354. }
  355. while (FieldWidth--) {
  356. *--Buffer = ' ';
  357. }
  358. }
  359. return Buffer;
  360. }