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.

690 lines
9.9 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name :
  4. parse.hxx
  5. Abstract:
  6. Simple parser class for extrapolating HTTP headers information
  7. Author:
  8. John Ludeman (JohnL) 18-Jan-1995
  9. Project:
  10. HTTP server
  11. Revision History:
  12. --*/
  13. #include "precomp.hxx"
  14. ODBC_PARSER::ODBC_PARSER(
  15. CHAR * pszStart
  16. )
  17. /*++
  18. Routine Description:
  19. Sets the initial position of the buffer for parsing
  20. Arguments:
  21. pszStart - start of character buffer
  22. pszEnd - End of buffer
  23. Return Value:
  24. --*/
  25. : m_fListMode ( FALSE ),
  26. m_pszPos ( pszStart ),
  27. m_pszTokenTerm( NULL ),
  28. m_pszLineTerm ( NULL )
  29. {
  30. DBG_ASSERT( pszStart );
  31. //
  32. // Chew up any initial white space at the beginning of the buffer
  33. // and terminate the first token in the string.
  34. //
  35. EatWhite();
  36. TerminateToken();
  37. }
  38. ODBC_PARSER::~ODBC_PARSER(
  39. VOID
  40. )
  41. /*++
  42. Routine Description:
  43. Restores any changes we made to the string while parsing
  44. Arguments:
  45. --*/
  46. {
  47. RestoreBuffer();
  48. }
  49. CHAR *
  50. ODBC_PARSER::QueryPos(
  51. VOID
  52. )
  53. /*++
  54. Routine Description:
  55. Removes the terminators and returns the current parser position
  56. Arguments:
  57. Return Value:
  58. Zero terminated string if we've reached the end of the buffer
  59. --*/
  60. {
  61. RestoreToken();
  62. RestoreLine();
  63. return m_pszPos;
  64. }
  65. VOID
  66. ODBC_PARSER::SetPtr(
  67. CHAR * pch
  68. )
  69. /*++
  70. Routine Description:
  71. Sets the parser to point at a new location
  72. Arguments:
  73. pch - New position for parser to start parsing from
  74. Return Value:
  75. --*/
  76. {
  77. RestoreToken();
  78. RestoreLine();
  79. m_pszPos = pch;
  80. }
  81. CHAR *
  82. ODBC_PARSER::QueryToken(
  83. VOID
  84. )
  85. /*++
  86. Routine Description:
  87. Returns a pointer to the current zero terminated token
  88. If list mode is on, then a comma is considered a delimiter.
  89. Arguments:
  90. Return Value:
  91. Zero terminated string if we've reached the end of the buffer
  92. --*/
  93. {
  94. if ( !m_pszTokenTerm )
  95. {
  96. TerminateToken( m_fListMode ? ',' : '\0' );
  97. }
  98. return m_pszPos;
  99. }
  100. CHAR *
  101. ODBC_PARSER::QueryLine(
  102. VOID
  103. )
  104. /*++
  105. Routine Description:
  106. Returns a pointer to the current zero terminated line
  107. Arguments:
  108. Return Value:
  109. Zero terminated string if we've reached the end of the buffer
  110. --*/
  111. {
  112. RestoreToken();
  113. if ( !m_pszLineTerm )
  114. {
  115. TerminateLine();
  116. }
  117. return m_pszPos;
  118. }
  119. HRESULT
  120. ODBC_PARSER::CopyToken(
  121. STRA * pStr,
  122. BOOL fAdvanceToken
  123. )
  124. /*++
  125. Routine Description:
  126. Copies the token at the current position to *pStr
  127. Arguments:
  128. pStr - Receives token
  129. fAdvanceToken - True if we should advance to the next token
  130. Return Value:
  131. TRUE if successful, FALSE otherwise
  132. --*/
  133. {
  134. HRESULT hr;
  135. DBG_ASSERT( pStr );
  136. if ( !m_pszTokenTerm )
  137. {
  138. TerminateToken();
  139. }
  140. hr = pStr->Copy( m_pszPos );
  141. if ( fAdvanceToken )
  142. {
  143. NextToken();
  144. }
  145. return hr;
  146. }
  147. HRESULT
  148. ODBC_PARSER::CopyToEOL(
  149. STRA * pstr,
  150. BOOL fAdvance
  151. )
  152. /*++
  153. Routine Description:
  154. Copies the token at the current character position
  155. Arguments:
  156. --*/
  157. {
  158. HRESULT hr;
  159. RestoreToken();
  160. if ( !m_pszLineTerm )
  161. {
  162. TerminateLine();
  163. }
  164. hr = pstr->Copy( m_pszPos );
  165. if ( fAdvance )
  166. {
  167. NextLine();
  168. }
  169. return hr;
  170. }
  171. HRESULT
  172. ODBC_PARSER::AppendToEOL(
  173. STRA * pstr,
  174. BOOL fAdvance
  175. )
  176. /*++
  177. Routine Description:
  178. Same as CopyToEOL except the text from the current line is appended to
  179. pstr
  180. Arguments:
  181. --*/
  182. {
  183. HRESULT hr;
  184. RestoreToken();
  185. if ( !m_pszLineTerm )
  186. {
  187. TerminateLine();
  188. }
  189. hr = pstr->Append( m_pszPos );
  190. if ( fAdvance )
  191. {
  192. NextLine();
  193. }
  194. return hr;
  195. }
  196. CHAR *
  197. ODBC_PARSER::NextLine(
  198. VOID
  199. )
  200. /*++
  201. Routine Description:
  202. Sets the current position to the first non-white character after the
  203. next '\n' (or terminating '\0').
  204. --*/
  205. {
  206. RestoreToken();
  207. RestoreLine();
  208. m_pszPos = AuxSkipTo( '\n' );
  209. if ( *m_pszPos )
  210. {
  211. m_pszPos++;
  212. }
  213. return EatWhite();
  214. }
  215. CHAR *
  216. ODBC_PARSER::NextToken(
  217. VOID
  218. )
  219. /*++
  220. Routine Description:
  221. Sets the current position to the next non-white character after the
  222. current token
  223. --*/
  224. {
  225. //
  226. // Make sure the line is terminated so a '\0' will be returned after
  227. // the last token is found on this line
  228. //
  229. RestoreToken();
  230. if ( !m_pszLineTerm )
  231. {
  232. TerminateLine();
  233. }
  234. //
  235. // Skip the current token
  236. //
  237. EatNonWhite();
  238. EatWhite();
  239. TerminateToken();
  240. return m_pszPos;
  241. }
  242. CHAR *
  243. ODBC_PARSER::NextToken(
  244. CHAR ch
  245. )
  246. /*++
  247. Routine Description:
  248. Advances the position to the next token after ch (stopping
  249. at the end of the line)
  250. --*/
  251. {
  252. //
  253. // Make sure the line is terminated so a '\0' will be returned after
  254. // the last token is found on this line
  255. //
  256. RestoreToken();
  257. if ( !m_pszLineTerm )
  258. {
  259. TerminateLine();
  260. }
  261. //
  262. // Look for the specified character (generally ',' or ';')
  263. //
  264. SkipTo( ch );
  265. if ( *m_pszPos )
  266. {
  267. m_pszPos++;
  268. }
  269. EatWhite();
  270. TerminateToken( ch );
  271. return m_pszPos;
  272. }
  273. CHAR *
  274. ODBC_PARSER::SkipTo(
  275. CHAR ch
  276. )
  277. /*++
  278. Routine Description:
  279. Skips to the specified character or returns a null terminated string
  280. if the end of the line is reached
  281. --*/
  282. {
  283. //
  284. // Make sure the line is terminated so a '\0' will be returned after
  285. // the last token is found on this line
  286. //
  287. RestoreToken();
  288. if ( !m_pszLineTerm )
  289. {
  290. TerminateLine();
  291. }
  292. m_pszPos = AuxSkipTo( ch );
  293. return m_pszPos;
  294. }
  295. VOID
  296. ODBC_PARSER::SetListMode(
  297. BOOL fListMode
  298. )
  299. /*++
  300. Routine Description:
  301. Resets the parser mode to list mode or non-list mode
  302. Arguments:
  303. --*/
  304. {
  305. RestoreToken();
  306. if ( !m_pszLineTerm )
  307. {
  308. TerminateLine();
  309. }
  310. m_fListMode = fListMode;
  311. }
  312. VOID
  313. ODBC_PARSER::TerminateToken(
  314. CHAR ch
  315. )
  316. /*++
  317. Routine Description:
  318. Zero terminates after the white space of the current token
  319. Arguments:
  320. --*/
  321. {
  322. DBG_ASSERT( !m_pszTokenTerm );
  323. m_pszTokenTerm = AuxEatNonWhite( ch );
  324. m_chTokenTerm = *m_pszTokenTerm;
  325. *m_pszTokenTerm = '\0';
  326. }
  327. VOID
  328. ODBC_PARSER::RestoreToken(
  329. VOID
  330. )
  331. /*++
  332. Routine Description:
  333. Restores the character replaced by the zero terminator
  334. Arguments:
  335. --*/
  336. {
  337. if ( m_pszTokenTerm )
  338. {
  339. *m_pszTokenTerm = m_chTokenTerm;
  340. m_pszTokenTerm = NULL;
  341. }
  342. }
  343. VOID
  344. ODBC_PARSER::TerminateLine(
  345. VOID
  346. )
  347. /*++
  348. Routine Description:
  349. Zero terminates at the end of this line
  350. Arguments:
  351. --*/
  352. {
  353. DBG_ASSERT( !m_pszLineTerm );
  354. m_pszLineTerm = AuxSkipTo( '\n' );
  355. //
  356. // Now trim any trailing white space on the line
  357. //
  358. if ( m_pszLineTerm > m_pszPos )
  359. {
  360. m_pszLineTerm--;
  361. while ( m_pszLineTerm >= m_pszPos &&
  362. ISWHITEA( *m_pszLineTerm ) )
  363. {
  364. m_pszLineTerm--;
  365. }
  366. }
  367. //
  368. // Go forward one (trimming found the last non-white
  369. // character)
  370. //
  371. if ( *m_pszLineTerm &&
  372. *m_pszLineTerm != '\n' &&
  373. !ISWHITEA( *m_pszLineTerm ))
  374. {
  375. m_pszLineTerm++;
  376. }
  377. m_chLineTerm = *m_pszLineTerm;
  378. *m_pszLineTerm = '\0';
  379. }
  380. VOID
  381. ODBC_PARSER::RestoreLine(
  382. VOID
  383. )
  384. /*++
  385. Routine Description:
  386. Restores the character replaced by the zero terminator
  387. Arguments:
  388. --*/
  389. {
  390. if ( m_pszLineTerm )
  391. {
  392. *m_pszLineTerm = m_chLineTerm;
  393. m_pszLineTerm = NULL;
  394. }
  395. }
  396. CHAR *
  397. ODBC_PARSER::AuxEatNonWhite(
  398. CHAR ch
  399. )
  400. /*++
  401. Routine Description:
  402. In non list mode returns the first white space character after
  403. the current parse position
  404. In list mode returns the first delimiter ( "';\n" ) character after
  405. the current parse position
  406. Arguments:
  407. ch - Optional character that is considered white space (such as ',' or ';'
  408. when doing list processing).
  409. --*/
  410. {
  411. CHAR * psz = m_pszPos;
  412. //
  413. // Note that ISWHITEA includes '\r'. In list mode, comma and semi-colon
  414. // are considered delimiters
  415. //
  416. if ( !m_fListMode )
  417. {
  418. while ( *psz &&
  419. *psz != '\n' &&
  420. !ISWHITEA(*psz)&&
  421. *psz != ch )
  422. {
  423. psz++;
  424. }
  425. return psz;
  426. }
  427. else
  428. {
  429. while ( *psz &&
  430. *psz != '\n' &&
  431. *psz != ',' &&
  432. *psz != ';' &&
  433. *psz != ch )
  434. {
  435. psz++;
  436. }
  437. return psz;
  438. }
  439. }
  440. CHAR *
  441. ODBC_PARSER::AuxEatWhite(
  442. VOID
  443. )
  444. /*++
  445. Routine Description:
  446. Returns the first non-white space character after the current parse
  447. position
  448. Arguments:
  449. --*/
  450. {
  451. CHAR * psz = m_pszPos;
  452. //
  453. // Note that ISWHITEA includes '\r'
  454. //
  455. while ( *psz &&
  456. *psz != '\n' &&
  457. ISWHITEA(*psz))
  458. {
  459. psz++;
  460. }
  461. return psz;
  462. }
  463. CHAR *
  464. ODBC_PARSER::AuxSkipTo(
  465. CHAR ch
  466. )
  467. /*++
  468. Routine Description:
  469. Skips to the specified character or returns a null terminated string
  470. if the end of the line is reached
  471. --*/
  472. {
  473. CHAR * psz = m_pszPos;
  474. while ( *psz &&
  475. *psz != '\n' &&
  476. *psz != ch )
  477. {
  478. psz++;
  479. }
  480. return psz;
  481. }