📄 mcbxml.c
字号:
/**
****************************************************************************
* <P> McbXML.c - implementation file for basic XML parser written in ANSI C
* for portability.
* It works by using recursion and a node tree for breaking down the elements
* of an XML document. </P>
*
* @version V1.0
*
* @author Martyn C Brown
*
* @changeHistory
* 21st August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
/*
****************************************************************************
* Include all necessary include files
****************************************************************************
*/
#include "McbXML.h"
#include <malloc.h>
#include <memory.h>
#include <assert.h>
/*
****************************************************************************
* Enumeration used to decipher what type a token is
****************************************************************************
*/
typedef enum McbTokenType
{
eTokenText = 0,
eTokenQuotedText,
eTokenTagStart, /* "<" */
eTokenTagEnd, /* "</" */
eTokenCloseTag, /* ">" */
eTokenEquals, /* "=" */
eTokenDeclaration, /* "<?" */
eTokenShortHandClose, /* "/>" */
eTokenClear,
eTokenError
} McbTokenType;
/*
****************************************************************************
* Defines to dictate grow by value when adding nodes.
****************************************************************************
*/
#define McbGROWBY 5
#define McbINDENTCHAR _T('\t')
typedef struct McbClearTag
{
LPTSTR lpszOpen;
LPTSTR lpszClose;
} McbClearTag;
typedef struct McbNextToken
{
McbClearTag *pClr;
LPCTSTR pStr;
} McbNextToken;
/*
****************************************************************************
* Main structure used for parsing XML
****************************************************************************
*/
typedef struct McbXML
{
LPCTSTR lpXML;
int nIndex;
enum McbXMLError error;
LPCTSTR lpEndTag;
int cbEndTag;
LPCTSTR lpNewElement;
int cbNewElement;
int nFirst;
McbClearTag *pClrTags;
} McbXML;
/*
****************************************************************************
* Enumeration used when parsing attributes
****************************************************************************
*/
typedef enum McbAttrib
{
eAttribName = 0,
eAttribEquals,
eAttribValue
} McbAttrib;
/*
****************************************************************************
* Enumeration used when parsing elements to dictate whether we are currently
* inside a tag
****************************************************************************
*/
typedef enum McbStatus
{
eInsideTag = 0,
eOutsideTag
} McbStatus;
/*
****************************************************************************
* Structure used to obtain List.
****************************************************************************
*/
typedef struct List_ST{
struct List_ST *pNext;
struct List_ST *pPrev;
}List_st;
typedef struct{
List_st pList;
int iNum;
}ListHead_st;
/*
****************************************************************************
* Structure used to obtain List Node.
****************************************************************************
*/
#ifdef DYNAMIC_MEM
typedef struct{
List_st List;
LPTSTR lpszText;
}NodeText_st;
#else
typedef struct{
List_st List;
char lpszText[256];
}NodeText_st;
#endif
static ListHead_st g_StrList;
void InitList(ListHead_st *pListHead)
{
pListHead->pList.pNext = &(pListHead->pList);
pListHead->pList.pPrev = &(pListHead->pList);
pListHead->iNum = 0;
}/* InitList */
void AddToList(ListHead_st *pListHead,List_st *pListNode)
{
pListNode->pPrev = &(pListHead->pList);
pListNode->pNext = pListHead->pList.pNext;
pListHead->pList.pNext->pPrev = pListNode;
pListHead->pList.pNext = pListNode;
pListHead->iNum++;
}/* AddToList */
List_st *DeleteFromListTial(ListHead_st *pListHead)
{
List_st *pTemp;
//Empty List?
if(pListHead->pList.pPrev == &(pListHead->pList))
return 0;
pTemp = pListHead->pList.pPrev;
pTemp->pPrev->pNext = pTemp->pNext;
pTemp->pNext->pPrev = pTemp->pPrev;
pListHead->iNum--;
return pTemp;
}/* DeleteFromListTial */
void DeleteFromList(List_st *pList)
{
pList->pNext->pPrev = pList->pPrev;
pList->pPrev->pPrev = pList->pNext;
}/* DeleteFromList */
void FreeList(ListHead_st *pListHead)
{
List_st *pList;
NodeText_st *pNodeText;
//empty List
if(pListHead->pList.pNext == &(pListHead->pList))
return;
while(pListHead->iNum){
pList = DeleteFromListTial(pListHead);
pNodeText = ListEntry(pList,NodeText_st,List);
#ifdef DYNAMIC_MEM
free(pNodeText->lpszText);
#endif
free(pNodeText);
}
}/*FreeList*/
/**
****************************************************************************
* <P> Initialise an element. </P>
*
* @methodName McbInitElement
*
* @param *pEntry
* @param lpszName
*
* @return void
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 14th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
void McbInitElement(McbXMLElement *pEntry, McbXMLElement *pParent,
LPTSTR lpszName, int nIsDeclaration)
{
assert(pEntry);
pEntry->nMax = 0;
pEntry->nSize = 0;
pEntry->pEntries = NULL;
pEntry->pParent = pParent;
pEntry->nIsDeclaration = nIsDeclaration;
pEntry->lpszName = lpszName;
}/* McbInitElement */
/**
****************************************************************************
* <P> Create the root element. </P>
*
* @methodName * McbCreateRoot
*
* @param none
*
* @return McbXMLElement
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 1st February 2002 - (V1.0) Creation (MCB)
****************************************************************************
*/
McbXMLElement * McbCreateRoot()
{
McbXMLElement * pElement;
pElement = (McbXMLElement*)malloc(sizeof(McbXMLElement));
McbInitElement(pElement, NULL, 0, FALSE);
//Init the NodeName LinkList
//Toby add 2006/7/3/9:31
//InitList(&g_StrList);
return pElement;
}/* McbCreateRoot */
/**
****************************************************************************
* <P> Delete the root element and set it to NULL. </P>
*
* @methodName McbDeleteRoot
*
* @param ** ppElement
*
* @return void
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 1st February 2002 - (V1.0) Creation (MCB)
****************************************************************************
*/
void McbDeleteRoot(McbXMLElement * pElement)
{
McbDeleteElement(pElement);
free(pElement);
//FreeList(&g_StrList);
}/* McbDeleteRoot */
/**
****************************************************************************
* <P> Delete an attribute. </P>
*
* @methodName McbDeleteAttribute
*
* @param *pEntry
*
* @return void
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 14th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
void McbDeleteAttribute(McbXMLAttribute *pEntry)
{
assert(pEntry);
if (pEntry->lpszName)
{
free(pEntry->lpszName);
pEntry->lpszName = NULL;
}
if (pEntry->lpszValue)
{
free(pEntry->lpszValue);
pEntry->lpszValue= NULL;
}
}/* McbDeleteAttribute */
/**
****************************************************************************
* <P> Attach attributes from one list to another. </P>
*
* @methodName McbAttributeAttach
*
* @param *pDst
* @param *pSrc
* @param nNum
*
* @return void
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 14th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
void McbAttributeAttach(McbXMLAttribute *pDst, McbXMLAttribute *pSrc, int nNum)
{
int n;
for (n=0; n<nNum; n++)
{
pDst[n].lpszName = pSrc[n].lpszName;
pDst[n].lpszValue = pSrc[n].lpszValue;
pSrc[n].lpszName = NULL;
pSrc[n].lpszValue = NULL;
}
}/* McbAttributeAttach */
/**
****************************************************************************
* <P> Obtain the next character from the string. </P>
*
* @methodName McbGetNextChar
*
* @param *pXML
*
* @return TCHAR
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 17th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
TCHAR McbGetNextChar(McbXML *pXML)
{
TCHAR ch;
ch = pXML->lpXML[pXML->nIndex];
if (ch != 0) pXML->nIndex++;
return ch;
}/* McbGetNextChar */
/**
****************************************************************************
* <P> Find next non-white space character. </P>
*
* @methodName McbFindNonWhiteSpace
*
* @param *pXML
*
* @return TCHAR
*
* @exception none
*
* @author Martyn C Brown
*
* @changeHistory
* 18th August 2001 - (V1.0) Creation (MCB)
****************************************************************************
*/
TCHAR McbFindNonWhiteSpace(McbXML *pXML)
{
TCHAR ch;
LPCTSTR lpXML = pXML->lpXML;
int nExit = FALSE;
assert(pXML);
/*
*************************************************************************
* Iterate through characters in the string until we find a NULL or a
* non-white space character
*************************************************************************
*/
while((nExit == FALSE) && (ch = McbGetNextChar(pXML)))
{
switch(ch)
{
/*
*********************************************************************
* Ignore white space
*********************************************************************
*/
case _T('\n'):
case _T(' '):
case _T('\t'):
case _T('\r'):
continue;
default:
nExit = TRUE;
}
}
return ch;
}/* McbFindNonWhiteSpace */
/**
****************************************************************************
* <P> Duplicate a given string. </P>
*
* @methodName McbStrdup
*
* @param lpszData
* @param cbData
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -