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

/*
* X S E A R C H . C P P
*
* XML push model parsing for MS-SEARCH requests
*
* Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
*/
#include "_xml.h"
#include <align.h>
// class CNFSearch -------------------------------------------------------------
//
SCODE
CNFSearch::ScCompleteAttribute (void)
{
SCODE sc = S_OK;
switch (m_state)
{
case ST_RANGE_TYPE:
// Find the range type.
//
m_state = ST_RANGE;
if (0 == wcsncmp (m_sb.PContents(), L"row", m_sb.CchSize()))
m_uRT = RANGE_ROW;
else if (0 == wcsncmp (m_sb.PContents(), L"url", m_sb.CchSize()))
m_uRT = RANGE_URL;
else if (0 == wcsncmp (m_sb.PContents(), L"find", m_sb.CchSize()))
m_uRT = RANGE_FIND;
else
m_uRT = RANGE_UNKNOWN;
m_sb.Reset();
break;
case ST_RANGE_ROWS:
// Find the number of rows to retrieve
//
m_state = ST_RANGE;
m_sb.Append (sizeof(WCHAR), L"");
m_lcRows = wcstol (m_sb.PContents(), NULL, 10 /* base 10 only */);
m_sb.Reset();
break;
}
return sc;
}
SCODE
CNFSearch::ScCompleteChildren (
/* [in] */ BOOL fEmptyNode,
/* [in] */ DWORD dwType,
/* [in] */ const WCHAR __RPC_FAR *pwcText,
/* [in] */ ULONG ulLen)
{
SCODE sc = S_OK;
switch (m_state)
{
case ST_SEARCH:
Assert (dwType == XML_ELEMENT);
m_state = ST_NODOC;
break;
// Exiting the base repl node
//
case ST_REPL:
Assert (dwType == XML_ELEMENT);
m_state = ST_SEARCH;
break;
case ST_QUERY:
Assert (dwType == XML_ELEMENT);
m_state = ST_SEARCH;
// Set the search text into the context
//
m_sb.Append (sizeof(WCHAR), L"");
sc = m_csc.ScSetSQL (this, m_sb.PContents());
if (FAILED (sc))
goto ret;
break;
case ST_QUERYENTITY:
m_state = ST_QUERY;
break;
case ST_REPLCOLLBLOB:
Assert (dwType == XML_ELEMENT);
m_state = ST_REPL;
// Set the collblob text into the context
//
m_sb.Append (sizeof(WCHAR), L"");
sc = m_csc.ScSetCollBlob (m_sb.PContents());
if (FAILED (sc))
goto ret;
break;
case ST_REPLRESTAGLIST:
Assert (dwType == XML_ELEMENT);
m_state = ST_REPL;
break;
case ST_REPLRESTAGADD:
Assert (dwType == XML_ELEMENT);
m_state = ST_REPLRESTAGLIST;
// Set the restag text into the context
//
m_sb.Append (sizeof(WCHAR), L"");
sc = m_csc.ScSetResTagAdds (m_sb.PContents());
if (FAILED (sc))
goto ret;
break;
case ST_RANGE:
Assert (XML_ELEMENT == dwType);
m_state = ST_SEARCH;
// Add the range to the list
//
m_sb.Append (sizeof(WCHAR), L"");
sc = m_csc.ScAddRange (m_uRT, m_sb.PContents(), m_lcRows);
if (FAILED (sc))
goto ret;
// Clear all range elements
//
m_uRT = RANGE_UNKNOWN;
m_lcRows = 0;
break;
case ST_GROUP_EXPANSION:
Assert (XML_ELEMENT == dwType);
m_state = ST_SEARCH;
// Add the expansion level to the context
//
m_sb.Append (sizeof(WCHAR), L"");
sc = m_csc.ScSetExpansion (wcstol(m_sb.PContents(), NULL, 10));
if (FAILED (sc))
goto ret;
break;
}
ret:
return sc;
}
SCODE
CNFSearch::ScHandleNode (
/* [in] */ DWORD dwType,
/* [in] */ DWORD dwSubType,
/* [in] */ BOOL fTerminal,
/* [in] */ const WCHAR __RPC_FAR *pwcText,
/* [in] */ ULONG ulLen,
/* [in] */ ULONG ulNamespaceLen,
/* [in] */ const WCHAR __RPC_FAR *pwcNamespace,
/* [in] */ const ULONG ulNsPrefixLen)
{
CStackBuffer<WCHAR> wsz;
LPCWSTR pwszTag;
SCODE sc = S_FALSE;
UINT cch;
switch (dwType)
{
case XML_ELEMENT:
// Construct the full name of the node
//
cch = ulNamespaceLen + ulLen;
pwszTag = wsz.resize(CbSizeWsz(cch));
if (NULL == pwszTag)
{
sc = E_OUTOFMEMORY;
goto ret;
}
wcsncpy (wsz.get(), pwcNamespace, ulNamespaceLen);
wcsncpy (wsz.get() + ulNamespaceLen, pwcText, ulLen);
*(wsz.get() + cch) = 0;
switch (m_state)
{
case ST_NODOC:
// If this is the topmost node in a propSearch request,
// transition to the next state. Since there is no parent
// node to provide scoping, FIsTag() cannot be used here!
//
if (!wcscmp (pwszTag, gc_wszSearchRequest))
{
m_state = ST_SEARCH;
sc = S_OK;
}
break;
case ST_SEARCH:
// Look for our well know node types
//
if (FIsTag (pwszTag, gc_wszSql))
{
m_state = ST_QUERY;
m_sb.Reset();
sc = S_OK;
}
// Check for our top-level repl node.
// All repl items should appear inside this node.
// Tell our caller this is a REPL request, and
// switch our state to ST_REPL.
//
else if (FIsTag (pwszTag, gc_wszReplNode))
{
m_state = ST_REPL;
sc = m_csc.ScSetReplRequest (TRUE);
if (FAILED (sc))
goto ret;
}
else if (FIsTag (pwszTag, gc_wszRange))
{
m_state = ST_RANGE;
m_sb.Reset();
sc = S_OK;
}
else if (FIsTag (pwszTag, gc_wszExpansion))
{
m_state = ST_GROUP_EXPANSION;
m_sb.Reset();
sc = S_OK;
}
break;
case ST_REPL:
// Handle the nodes under the top-level repl node.
//
if (FIsTag (pwszTag, gc_wszReplCollBlob))
{
m_sb.Reset();
m_state = ST_REPLCOLLBLOB;
sc = S_OK;
}
else if (FIsTag (pwszTag, gc_wszReplResTagList))
{
m_sb.Reset();
m_state = ST_REPLRESTAGLIST;
sc = S_OK;
}
break;
case ST_REPLRESTAGLIST:
// Handle the restag nodes under the restaglist node.
//
if (FIsTag (pwszTag, gc_wszReplResTagItem))
{
m_sb.Reset();
m_state = ST_REPLRESTAGADD;
sc = S_OK;
}
break;
}
break;
case XML_ATTRIBUTE:
if (ST_RANGE == m_state)
{
// Construct the full name of the node
//
cch = ulNamespaceLen + ulLen;
pwszTag = wsz.resize(CbSizeWsz(cch));
if (NULL == pwszTag)
{
sc = E_OUTOFMEMORY;
goto ret;
}
wcsncpy (wsz.get(), pwcNamespace, ulNamespaceLen);
wcsncpy (wsz.get() + ulNamespaceLen, pwcText, ulLen);
*(wsz.get() + cch) = 0;
// There are two attributes node for the DAV:range
// node. DAV:type, and DAV:rows.
//
if (FIsTag (pwszTag, gc_wszRangeType))
{
m_state = ST_RANGE_TYPE;
sc = S_OK;
}
else if (FIsTag (pwszTag, gc_wszRangeRows))
{
m_state = ST_RANGE_ROWS;
sc = S_OK;
}
break;
}
break;
case XML_PCDATA:
// If this is SQL query data, or repl collblob data,
// repl resourcetag data, or any of the range items,
// then remember it in our buffer.
//
if ((m_state == ST_QUERY)
|| (m_state == ST_REPLCOLLBLOB)
|| (m_state == ST_REPLRESTAGADD)
|| (m_state == ST_RANGE_TYPE)
|| (m_state == ST_RANGE_ROWS)
|| (m_state == ST_RANGE)
|| (m_state == ST_GROUP_EXPANSION))
{
// Append the current bits to the buffer
//
m_sb.Append (ulLen * sizeof(WCHAR), pwcText);
sc = S_OK;
}
break;
}
ret:
return sc;
}