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.

341 lines
7.1 KiB

  1. /*
  2. * X S E A R C H . C P P
  3. *
  4. * XML push model parsing for MS-SEARCH requests
  5. *
  6. * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  7. */
  8. #include "_xml.h"
  9. #include <align.h>
  10. // class CNFSearch -------------------------------------------------------------
  11. //
  12. SCODE
  13. CNFSearch::ScCompleteAttribute (void)
  14. {
  15. SCODE sc = S_OK;
  16. switch (m_state)
  17. {
  18. case ST_RANGE_TYPE:
  19. // Find the range type.
  20. //
  21. m_state = ST_RANGE;
  22. if (0 == wcsncmp (m_sb.PContents(), L"row", m_sb.CchSize()))
  23. m_uRT = RANGE_ROW;
  24. else if (0 == wcsncmp (m_sb.PContents(), L"url", m_sb.CchSize()))
  25. m_uRT = RANGE_URL;
  26. else if (0 == wcsncmp (m_sb.PContents(), L"find", m_sb.CchSize()))
  27. m_uRT = RANGE_FIND;
  28. else
  29. m_uRT = RANGE_UNKNOWN;
  30. m_sb.Reset();
  31. break;
  32. case ST_RANGE_ROWS:
  33. // Find the number of rows to retrieve
  34. //
  35. m_state = ST_RANGE;
  36. m_sb.Append (sizeof(WCHAR), L"");
  37. m_lcRows = wcstol (m_sb.PContents(), NULL, 10 /* base 10 only */);
  38. m_sb.Reset();
  39. break;
  40. }
  41. return sc;
  42. }
  43. SCODE
  44. CNFSearch::ScCompleteChildren (
  45. /* [in] */ BOOL fEmptyNode,
  46. /* [in] */ DWORD dwType,
  47. /* [in] */ const WCHAR __RPC_FAR *pwcText,
  48. /* [in] */ ULONG ulLen)
  49. {
  50. SCODE sc = S_OK;
  51. switch (m_state)
  52. {
  53. case ST_SEARCH:
  54. Assert (dwType == XML_ELEMENT);
  55. m_state = ST_NODOC;
  56. break;
  57. // Exiting the base repl node
  58. //
  59. case ST_REPL:
  60. Assert (dwType == XML_ELEMENT);
  61. m_state = ST_SEARCH;
  62. break;
  63. case ST_QUERY:
  64. Assert (dwType == XML_ELEMENT);
  65. m_state = ST_SEARCH;
  66. // Set the search text into the context
  67. //
  68. m_sb.Append (sizeof(WCHAR), L"");
  69. sc = m_csc.ScSetSQL (this, m_sb.PContents());
  70. if (FAILED (sc))
  71. goto ret;
  72. break;
  73. case ST_QUERYENTITY:
  74. m_state = ST_QUERY;
  75. break;
  76. case ST_REPLCOLLBLOB:
  77. Assert (dwType == XML_ELEMENT);
  78. m_state = ST_REPL;
  79. // Set the collblob text into the context
  80. //
  81. m_sb.Append (sizeof(WCHAR), L"");
  82. sc = m_csc.ScSetCollBlob (m_sb.PContents());
  83. if (FAILED (sc))
  84. goto ret;
  85. break;
  86. case ST_REPLRESTAGLIST:
  87. Assert (dwType == XML_ELEMENT);
  88. m_state = ST_REPL;
  89. break;
  90. case ST_REPLRESTAGADD:
  91. Assert (dwType == XML_ELEMENT);
  92. m_state = ST_REPLRESTAGLIST;
  93. // Set the restag text into the context
  94. //
  95. m_sb.Append (sizeof(WCHAR), L"");
  96. sc = m_csc.ScSetResTagAdds (m_sb.PContents());
  97. if (FAILED (sc))
  98. goto ret;
  99. break;
  100. case ST_RANGE:
  101. Assert (XML_ELEMENT == dwType);
  102. m_state = ST_SEARCH;
  103. // Add the range to the list
  104. //
  105. m_sb.Append (sizeof(WCHAR), L"");
  106. sc = m_csc.ScAddRange (m_uRT, m_sb.PContents(), m_lcRows);
  107. if (FAILED (sc))
  108. goto ret;
  109. // Clear all range elements
  110. //
  111. m_uRT = RANGE_UNKNOWN;
  112. m_lcRows = 0;
  113. break;
  114. case ST_GROUP_EXPANSION:
  115. Assert (XML_ELEMENT == dwType);
  116. m_state = ST_SEARCH;
  117. // Add the expansion level to the context
  118. //
  119. m_sb.Append (sizeof(WCHAR), L"");
  120. sc = m_csc.ScSetExpansion (wcstol(m_sb.PContents(), NULL, 10));
  121. if (FAILED (sc))
  122. goto ret;
  123. break;
  124. }
  125. ret:
  126. return sc;
  127. }
  128. SCODE
  129. CNFSearch::ScHandleNode (
  130. /* [in] */ DWORD dwType,
  131. /* [in] */ DWORD dwSubType,
  132. /* [in] */ BOOL fTerminal,
  133. /* [in] */ const WCHAR __RPC_FAR *pwcText,
  134. /* [in] */ ULONG ulLen,
  135. /* [in] */ ULONG ulNamespaceLen,
  136. /* [in] */ const WCHAR __RPC_FAR *pwcNamespace,
  137. /* [in] */ const ULONG ulNsPrefixLen)
  138. {
  139. CStackBuffer<WCHAR> wsz;
  140. LPCWSTR pwszTag;
  141. SCODE sc = S_FALSE;
  142. UINT cch;
  143. switch (dwType)
  144. {
  145. case XML_ELEMENT:
  146. // Construct the full name of the node
  147. //
  148. cch = ulNamespaceLen + ulLen;
  149. pwszTag = wsz.resize(CbSizeWsz(cch));
  150. if (NULL == pwszTag)
  151. {
  152. sc = E_OUTOFMEMORY;
  153. goto ret;
  154. }
  155. wcsncpy (wsz.get(), pwcNamespace, ulNamespaceLen);
  156. wcsncpy (wsz.get() + ulNamespaceLen, pwcText, ulLen);
  157. *(wsz.get() + cch) = 0;
  158. switch (m_state)
  159. {
  160. case ST_NODOC:
  161. // If this is the topmost node in a propSearch request,
  162. // transition to the next state. Since there is no parent
  163. // node to provide scoping, FIsTag() cannot be used here!
  164. //
  165. if (!wcscmp (pwszTag, gc_wszSearchRequest))
  166. {
  167. m_state = ST_SEARCH;
  168. sc = S_OK;
  169. }
  170. break;
  171. case ST_SEARCH:
  172. // Look for our well know node types
  173. //
  174. if (FIsTag (pwszTag, gc_wszSql))
  175. {
  176. m_state = ST_QUERY;
  177. m_sb.Reset();
  178. sc = S_OK;
  179. }
  180. // Check for our top-level repl node.
  181. // All repl items should appear inside this node.
  182. // Tell our caller this is a REPL request, and
  183. // switch our state to ST_REPL.
  184. //
  185. else if (FIsTag (pwszTag, gc_wszReplNode))
  186. {
  187. m_state = ST_REPL;
  188. sc = m_csc.ScSetReplRequest (TRUE);
  189. if (FAILED (sc))
  190. goto ret;
  191. }
  192. else if (FIsTag (pwszTag, gc_wszRange))
  193. {
  194. m_state = ST_RANGE;
  195. m_sb.Reset();
  196. sc = S_OK;
  197. }
  198. else if (FIsTag (pwszTag, gc_wszExpansion))
  199. {
  200. m_state = ST_GROUP_EXPANSION;
  201. m_sb.Reset();
  202. sc = S_OK;
  203. }
  204. break;
  205. case ST_REPL:
  206. // Handle the nodes under the top-level repl node.
  207. //
  208. if (FIsTag (pwszTag, gc_wszReplCollBlob))
  209. {
  210. m_sb.Reset();
  211. m_state = ST_REPLCOLLBLOB;
  212. sc = S_OK;
  213. }
  214. else if (FIsTag (pwszTag, gc_wszReplResTagList))
  215. {
  216. m_sb.Reset();
  217. m_state = ST_REPLRESTAGLIST;
  218. sc = S_OK;
  219. }
  220. break;
  221. case ST_REPLRESTAGLIST:
  222. // Handle the restag nodes under the restaglist node.
  223. //
  224. if (FIsTag (pwszTag, gc_wszReplResTagItem))
  225. {
  226. m_sb.Reset();
  227. m_state = ST_REPLRESTAGADD;
  228. sc = S_OK;
  229. }
  230. break;
  231. }
  232. break;
  233. case XML_ATTRIBUTE:
  234. if (ST_RANGE == m_state)
  235. {
  236. // Construct the full name of the node
  237. //
  238. cch = ulNamespaceLen + ulLen;
  239. pwszTag = wsz.resize(CbSizeWsz(cch));
  240. if (NULL == pwszTag)
  241. {
  242. sc = E_OUTOFMEMORY;
  243. goto ret;
  244. }
  245. wcsncpy (wsz.get(), pwcNamespace, ulNamespaceLen);
  246. wcsncpy (wsz.get() + ulNamespaceLen, pwcText, ulLen);
  247. *(wsz.get() + cch) = 0;
  248. // There are two attributes node for the DAV:range
  249. // node. DAV:type, and DAV:rows.
  250. //
  251. if (FIsTag (pwszTag, gc_wszRangeType))
  252. {
  253. m_state = ST_RANGE_TYPE;
  254. sc = S_OK;
  255. }
  256. else if (FIsTag (pwszTag, gc_wszRangeRows))
  257. {
  258. m_state = ST_RANGE_ROWS;
  259. sc = S_OK;
  260. }
  261. break;
  262. }
  263. break;
  264. case XML_PCDATA:
  265. // If this is SQL query data, or repl collblob data,
  266. // repl resourcetag data, or any of the range items,
  267. // then remember it in our buffer.
  268. //
  269. if ((m_state == ST_QUERY)
  270. || (m_state == ST_REPLCOLLBLOB)
  271. || (m_state == ST_REPLRESTAGADD)
  272. || (m_state == ST_RANGE_TYPE)
  273. || (m_state == ST_RANGE_ROWS)
  274. || (m_state == ST_RANGE)
  275. || (m_state == ST_GROUP_EXPANSION))
  276. {
  277. // Append the current bits to the buffer
  278. //
  279. m_sb.Append (ulLen * sizeof(WCHAR), pwcText);
  280. sc = S_OK;
  281. }
  282. break;
  283. }
  284. ret:
  285. return sc;
  286. }