📄 mcbxml.c
字号:
* @methodName * McbAddClear
*
* @param *pEntry
* @param lpszValue
* @param nGrowBy
*
* @return McbXMLClear
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 20th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
McbXMLClear * McbAddClear(McbXMLElement *pEntry, LPTSTR lpszValue,
McbClearTag *pClear, int nGrowBy)
{
McbXMLNode *pNode;
McbXMLClear *pNewClear;
assert(pEntry);
assert(nGrowBy > 0);
/*
*************************************************************************
* Check we have enough storage
*************************************************************************
*/
if (pEntry->nSize == pEntry->nMax)
{
McbAllocNodes(pEntry, nGrowBy);
}
/*
*************************************************************************
* Obtain the new node, set the type and initialise it.
*************************************************************************
*/
pNode = &pEntry->pEntries[pEntry->nSize];
pNode->type = eNodeClear;
pNewClear = malloc(sizeof(McbXMLClear));
pNode->node.pClear = pNewClear;
pNewClear->lpszValue = lpszValue;
pNewClear->lpszOpenTag = pClear->lpszOpen;
pNewClear->lpszCloseTag = pClear->lpszClose;
/*
*************************************************************************
* Increment the number of contained nodes
*************************************************************************
*/
pEntry->nSize++;
/*
*************************************************************************
* Return the new attribute.
*************************************************************************
*/
return pNewClear;
}/* McbAddClear */
/**
****************************************************************************
* <P> Enumerate nodes in the list. </P>
*
* @methodName McbEnumNodes
*
* @param *pEntry
* @param *pnIndex
*
* @return McbXMLNode
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 20th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
McbXMLNode * McbEnumNodes(McbXMLElement *pEntry, int *pnIndex)
{
McbXMLNode * pResult = NULL;
assert(pnIndex);
assert(pEntry);
if (*pnIndex < pEntry->nSize)
{
pResult = &pEntry->pEntries[*pnIndex];
(*pnIndex)++;
}
return pResult;
}/* McbEnumNodes */
/**
****************************************************************************
* <P> Enumerate elements on a base element. </P>
*
* @methodName McbEnumElements
*
* @param *pEntry
* @param *pnIndex
*
* @return McbXMLNode
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 20th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
McbXMLElement * McbEnumElements(McbXMLElement *pEntry, int *pnIndex)
{
McbXMLElement * pResult = NULL;
int nIndex;
assert(pnIndex);
assert(pEntry);
nIndex = *pnIndex;
for (;nIndex < pEntry->nSize && !pResult; nIndex++)
{
if (pEntry->pEntries[nIndex].type == eNodeElement)
{
pResult = pEntry->pEntries[nIndex].node.pElement;
}
}
*pnIndex = nIndex;
return pResult;
}/* McbEnumElements */
/**
****************************************************************************
* <P> Enumerate attributes on a base element. </P>
*
* @methodName McbEnumAttributes
*
* @param *pEntry
* @param *pnIndex
*
* @return McbXMLNode
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 20th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
McbXMLAttribute * McbEnumAttributes(McbXMLElement *pEntry, int *pnIndex)
{
McbXMLAttribute * pResult = NULL;
int nIndex;
assert(pnIndex);
assert(pEntry);
nIndex = *pnIndex;
for (;nIndex < pEntry->nSize && !pResult; nIndex++)
{
if (pEntry->pEntries[nIndex].type == eNodeAttribute)
{
pResult = pEntry->pEntries[nIndex].node.pAttrib;
}
}
*pnIndex = nIndex;
return pResult;
}/* McbEnumAttributes */
/**
****************************************************************************
* <P> Trim the end of the text to remove white space characters. </P>
*
* @methodName McbFindEndOfText
*
* @param lpszToken
* @param *pcbText
*
* @return void
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 20th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
void McbFindEndOfText(LPCTSTR lpszToken, int *pcbText)
{
TCHAR ch;
int cbText;
assert(lpszToken);
assert(pcbText);
cbText = (*pcbText)-1;
while(TRUE)
{
assert(cbText >= 0);
ch = lpszToken[cbText];
switch(ch)
{
case _T('\r'):
case _T('\n'):
case _T('\t'):
case _T(' '):
cbText--;
break;
default:
*pcbText = cbText+1;
return;
}
}
}/* McbFindEndOfText */
/**
****************************************************************************
* <P> Parse a clear (unformatted) type node. </P>
*
* @methodName McbParseClearTag
*
* @param *pXML
* @param *pElement
* @param lpszClose
* @param lpszToken
*
* @return int
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 26th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
int McbParseClearTag(McbXML *pXML, McbXMLElement *pElement, McbClearTag * pClear)
{
int cbTemp = 0;
LPTSTR lpszTemp;
LPCTSTR lpszXML = &pXML->lpXML[pXML->nIndex];
/*
*************************************************************************
* Find the closing tag
*************************************************************************
*/
lpszTemp = _tcsstr(lpszXML, pClear->lpszClose);
/*
*************************************************************************
* Iterate through the tokens until we find the closing tag.
*************************************************************************
*/
if (lpszTemp)
{
/*
*********************************************************************
* Cache the size and increment the index
*********************************************************************
*/
cbTemp = lpszTemp - lpszXML;
pXML->nIndex += cbTemp;
pXML->nIndex += _tcslen(pClear->lpszClose);
/*
*********************************************************************
* Add the clear node to the current element
*********************************************************************
*/
lpszTemp = McbStrdup(lpszXML, cbTemp);
McbAddClear(pElement, lpszTemp, pClear, McbGROWBY);
#ifdef McbSTOREOFFSETS
pElement->pEntries[pElement->nSize-1].nStringOffset = (lpszXML -
_tcslen(pClear->lpszOpen)) - pXML->lpXML;
#endif /* McbSTOREOFFSETS */
return TRUE;
}
/*
*************************************************************************
* If we failed to find the end tag
*************************************************************************
*/
else
{
pXML->error = eXMLErrorUnmatchedEndTag;
return FALSE;
}
}/* McbParseClearTag */
/**
****************************************************************************
* <P> Recursively parse an XML element. </P>
*
* @methodName McbParseXMLElement
*
* @param *pXML
* @param * pElement
*
* @return int
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 19th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
int McbParseXMLElement(McbXML *pXML, McbXMLElement * pElement)
{
LPCTSTR lpszToken;
int cbToken;
enum McbTokenType type;
McbNextToken token;
LPCTSTR lpszTemp;
int cbTemp;
int nDeclaration;
LPCTSTR lpszText = NULL;
McbXMLElement *pNew;
enum McbStatus status;
enum McbAttrib attrib = eAttribName;
assert(pXML);
assert(pElement);
/*
*************************************************************************
* If this is the first call to the function
*************************************************************************
*/
if (pXML->nFirst)
{
/*
*********************************************************************
* Assume we are outside of a tag definition
*********************************************************************
*/
pXML->nFirst = FALSE;
status = eOutsideTag;
}
/*
*************************************************************************
* If this is not the first call then we should only be called when inside
* a tag.
*************************************************************************
*/
else
{
status = eInsideTag;
}
/*
*************************************************************************
* Iterate through the tokens in the document
*************************************************************************
*/
while(TRUE)
{
/*
*********************************************************************
* Obtain the next token
*********************************************************************
*/
token = McbGetNextToken(pXML, &cbToken, &type);
if (type != eTokenError)
{
/*
*****************************************************************
* Check the current status
*****************************************************************
*/
switch(status)
{
/*
*****************************************************************
* If we outside of a tag definition
*****************************************************************
*/
case eOutsideTag:
/*
*************************************************************
* Check what type of token we obtained
*************************************************************
*/
switch(type)
{
/*
*************************************************************
* If we have found text or quoted text
*************************************************************
*/
case eTokenText:
case eTokenQuotedText:
case eTokenEquals:
if (!lpszText)
{
lpszText = token.pStr;
}
break;
/*
*************************************************************
* If we found a start tag '<' and declarations '<?'
*************************************************************
*/
case eTokenTagStart:
case eTokenDeclaration:
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -