📄 cxml.c
字号:
/*-------------------------------------------------------------------------*/
/*XML解释模块,师鹏超设计,支持W3C 1.0版本 */
/*此不支持DTD,支持实体引用,但不支持节点间的注内的注释 */
/*此种注释被当成数据来对待 */
/* 师鹏超 */
/* 2005年06月24日 */
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
#include "CXml.h"
#include "CCode.h"
BYTE nCharType;
/*-------------------------------------------------------------------------*/
/*常用内部函数说明*/
PXMLNODE STDCALL XML_AllocNode( IN LPCSTR pszName, IN LPCSTR pszData, IN PCNODEPROPERTY pProp );
RESULT STDCALL XML_FreeNode( IN PXMLNODE pNode );
void STDCALL XML_TransValue( IN LPCSTR pszMsg, OUT LPSTR pszVal );
RESULT STDCALL XML_ValueTrans( IN LPCSTR pszMsg, IN UINT nLen, OUT LPSTR pszVal );
RESULT STDCALL XML_GetInfoFromMsg( \
IN OUT LPSTR *ppszMsg, /*输入的节点的数据缓冲区,返回子节点的超始位置*/\
IN OUT UINT *pnMsgLen, /*输入缓冲区的长度,输出此节点数据体的长度*/\
OUT LPSTR pszName, /*节点名*/\
OUT LPSTR pszData, /*节点数据*/\
OUT PNODEPROPERTY pProp, /*节点的属性*/\
OUT BOOL *pbIsParent, /*是否有子节点*/\
OUT LPSTR *ppszNextNode /*下一节点的位置,如果返回为空,下一节点不存在*/\
);
void STDCALL TrimLast( IN OUT LPSTR pszStr );
void STDCALL TrimSpace( IN OUT LPSTR pszStr );
RESULT STDCALL GetPriorPath( IN LPCSTR pszPath, OUT LPSTR pszPriorPath );
RESULT STDCALL GetLastName( IN LPCSTR pszPath, OUT LPSTR pszName );
RESULT STDCALL GetLeavePath( IN LPCSTR pszPath, OUT LPSTR pszLeavePath );
RESULT STDCALL GetRootName( IN LPCSTR pszPath, OUT LPSTR pszName );
RESULT STDCALL MakeEndName( IN LPCSTR pszName, OUT LPSTR pszEndName );
UINT STDCALL Calu_Var_Chgs( IN LPCSTR pszData );
RESULT STDCALL XML_ConvertPath( IN LPCSTR pszPath, OUT LPSTR pszFormatPath, IN OUT UINT *pnFormatLen );
DWORD STDCALL Ustrlen( unsigned short *pnzStr );
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_AllocProperty( IN OUT PNODEPROPERTY pProp, IN UINT nPropertyCount )
{
/*为节点分配属性内存*/
UINT nSize;
DETECT_NULL( pProp );
if ( nPropertyCount ) {
nSize = nPropertyCount * sizeof( PROPER );
ASSERT_NULL( pProp->pVal = ( PPROPER )AllocMemory( nSize ) );
}
pProp->nCount = nPropertyCount;
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_FreeProperty( IN OUT PNODEPROPERTY pProp )
{
/*释放属性信息*/
DETECT_NULL( pProp );
DETECT_NULL( pProp->pVal );
FreeMemory( ( LPVOID )pProp->pVal );
/*置属性的值*/
pProp->pVal = NULL;
pProp->nCount = 0;
return NORMAL;
}
/*-------------------------------------------------------------------------*/
PXMLNODE STDCALL XML_AllocNode( IN LPCSTR pszName, IN LPCSTR pszData, IN PCNODEPROPERTY pProp )
{
/*为XML的节点分配内存*/
PXMLNODE pNode;
LPSTR pszInsData = NULL;
/*判断节点名及数据的长度有效性*/
if ( pszName != NULL ) {
if ( !VERIFY( strlen( pszName ) <= XML_NAME_LEN ) ) {
return NULL;
}
}
/*判断值是否为空 ------> ""是否为空串呢?*/
if ( ( pszData != NULL ) && ( strlen( pszData ) > 0 ) ) {
if ( VERIFY_NULL( pszInsData = ( LPSTR )AllocMemory( ( UINT )strlen( pszData ) + 3 ) ) )
strcpy( pszInsData, pszData );
else
return NULL;
}
pNode = ( PXMLNODE )AllocMemory( sizeof( XMLNODE ) );
if ( VERIFY_NULL( pNode ) ) {
/*如果你输入一个为空的节点名或数据,
那么新的节点名为空或节点数据为空。*/
memset( pNode, 0, sizeof( XMLNODE ) );
if ( pszName != NULL )
strcpy( pNode->szName, pszName );
else
strcpy( pNode->szName, "<>" );
pNode->pszData = pszInsData;
/*置节点属性的值*/
if ( pProp != NULL ) {
if ( VERIFY_NORMAL( XML_AllocProperty( &( pNode->nProperty ), pProp->nCount ) ) ) {
memcpy( pNode->nProperty.pVal, pProp->pVal, pProp->nCount * sizeof( PROPER ) );
}
}
return pNode;
}
if ( pszInsData != NULL )
FreeMemory( ( LPVOID )pszInsData );
return NULL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_FreeNode( IN PXMLNODE pNode )
{
/*释放XML节点内存*/
DETECT_NULL( pNode );
XML_FreeProperty( &( pNode->nProperty ) );
FreeMemory( ( LPVOID )pNode );
return NORMAL;
}
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_Create( \
IN OUT PXMLSTRUCT pXml, /*XML结构指针*/\
IN LPCSTR pszName, /*XML根节点名*/\
IN LPCSTR pszData, /*XML根节点的值*/\
IN PCNODEPROPERTY pProp /*XML根节点的属性*/\
)
{
/*初始化XML结构及数据*/
char szName[XML_NAME_LEN + 1];
DETECT_NULL( pXml );
DETECT( pszName == NULL || strlen( pszName ) <= XML_NAME_LEN );
DETECT( pszData == NULL || ( strlen( pszData ) + Calu_Var_Chgs( pszData ) * 4 ) <= XML_DATA_LEN );
/*置默认根节点*/
if ( pszName == NULL || ( strlen( pszName ) == 0 ) ) {
#ifndef _WIN32
sprintf( szName, "<ROOT>" );
#else
wsprintf( szName, "<ROOT>" );
#endif
}
else {
ASSERT_NORMAL( GetRootName( pszName, szName ) );
}
XML_Delete( pXml );
memset( pXml, 0, sizeof( XMLSTRUCT ) ); /*XML结构清零*/
pXml->nMaxLen = 0x02000000; /*最大为32M的XML文件缓冲区*/
TREE_Init( &(pXml->nTree) );
ASSERT_NORMAL( XML_InsertRoot( pXml, ( LPCSTR )szName, pszData, pProp ) );
nCharType = GB2312; /*设置编码类型,默认为GB2312*/
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_Delete( IN OUT PXMLSTRUCT pXml )
{
/*释放XML内存*/
DETECT_NULL( pXml );
if ( pXml->nTree.nRootPos != NULL ) XML_DelNodeByPos( pXml, pXml->nTree.nRootPos );
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_SetRootName( IN OUT PXMLSTRUCT pXml, IN LPCSTR pszName )
{
/*设置XML的名字*/
UINT nSize, nLen;
char tmpName[33];
PXMLNODE pNode;
DETECT_NULL( pXml );
DETECT_NULL( pXml->nTree.nRootPos );
DETECT_NULL( pszName );
DETECT( strlen( pszName ) > 0 );
/*取根节点名*/
ASSERT_NORMAL( GetRootName( pszName, tmpName ) );
/*取根节点的值*/
TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
DETECT_NULL( pNode );
/*测试长度*/
nLen = ( UINT )strlen( tmpName );
DETECT( nLen <= XML_NAME_LEN );
nSize = ( UINT )strlen( pNode->szName );
strcpy( pNode->szName, tmpName );
/*更改XML的长度*/
pXml->nLen += ( 2 * nLen - 2 * nSize );
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_GetRootName( IN PCXMLSTRUCT pXml, IN OUT LPSTR pszName, IN OUT UINT *pnNameLen )
{
/*取根节点的节点名,如果pszName为NULL,则返回名字的长度*/
PXMLNODE pNode;
UINT nLen;
DETECT_NULL( pXml );
DETECT_NULL( pXml->nTree.nRootPos );
/*取根节点的值*/
TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
DETECT_NULL( pNode );
nLen = ( UINT )strlen( ( const char * )( pNode->szName ) );
if ( pszName == NULL ) {
*pnNameLen = nLen;
return NORMAL;
}
DETECT( *pnNameLen > nLen );
*pnNameLen = nLen;
strcpy( pszName, pNode->szName );
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_SetRootProperty( IN OUT PXMLSTRUCT pXml, IN PCNODEPROPERTY pProp )
{
/*设置根节点的属性*/
PXMLNODE pNode;
UINT nSize, nPropertySize, nLoop;
DETECT_NULL( pXml );
DETECT_NULL( pXml->nTree.nRootPos );
/*取根节点的值*/
TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
DETECT_NULL( pNode );
/*计算原属性的大小*/
nSize = 0;
for( nLoop = 0; nLoop < pNode->nProperty.nCount; nLoop ++ ) {
nSize += ( UINT )( strlen( pNode->nProperty.pVal[nLoop].szName ) + 2 \
+ strlen( pNode->nProperty.pVal[nLoop].szData ) \
+ Calu_Var_Chgs( pNode->nProperty.pVal[nLoop].szData ) * 4 + 2 );
}
XML_FreeProperty( &( pNode->nProperty ) );
pXml->nLen -= nSize;
if ( pProp != NULL ) {
nPropertySize = 0;
for( nLoop = 0; nLoop < pProp->nCount; nLoop ++ ) {
nPropertySize += ( UINT )( strlen( pProp->pVal[nLoop].szName ) + 2 \
+ strlen( pProp->pVal[nLoop].szData ) \
+ Calu_Var_Chgs( pProp->pVal[nLoop].szData ) * 4 + 2 );
}
if ( pProp->nCount ) {
ASSERT_NORMAL( XML_AllocProperty( &( pNode->nProperty ), pProp->nCount ) );
memcpy( pNode->nProperty.pVal, pProp->pVal, pProp->nCount * sizeof( PROPER ) );
pXml->nLen += nPropertySize;
}
}
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_GetRootProperty( IN PCXMLSTRUCT pXml, OUT PNODEPROPERTY pProp )
{
/*取根节点的属性*/
PXMLNODE pNode;
DETECT_NULL( pXml );
DETECT_NULL( pXml->nTree.nRootPos );
/*取根节点的值*/
TREE_GetVal( &( pXml->nTree ), pXml->nTree.nRootPos, ( LPVOID * )&pNode );
DETECT_NULL( pNode );
/*判断输出属性的指针是否有效*/
DETECT_NULL( pProp );
XML_FreeProperty( pProp );
/*分配属性内存*/
ASSERT_NORMAL( XML_AllocProperty( pProp, pNode->nProperty.nCount ) );
memcpy( pProp->pVal, pNode->nProperty.pVal, pNode->nProperty.nCount * sizeof( PROPER ) );
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_DelNodeByPos( IN OUT PXMLSTRUCT pXml, IN POS nPos )
{
/*按位置删除节点,此函数是一个递归函数*/
POS nPosDel, nPosChild, nPosParent;
PXMLNODE pNode;
UINT nDataLen, nDepth, nProperLen, iLoop;
/*有效性判断*/
DETECT_NULL( pXml );
DETECT( TREE_NodeIsValid( &( pXml->nTree ), nPos ) );
/*先删除节点的子孙节点*/
nPosChild = nPos;
TREE_GetChildHead( &( pXml->nTree ), &nPosChild );
while( nPosChild != NULL ) {
nPosDel = nPosChild;
TREE_GetNext( &( pXml->nTree ), &nPosChild );
XML_DelNodeByPos( pXml, nPosDel );
}
TREE_GetVal( &( pXml->nTree ), nPos, ( LPVOID * )&pNode );
/*对于空串的判断,可以在此处不修改*/
nDataLen = ( pNode->pszData == NULL ) ? 0 : ( UINT )strlen( pNode->pszData ) + Calu_Var_Chgs( ( LPCSTR )( pNode->pszData ) ) * 4;
nDepth = TREE_GetDepth( &pXml->nTree, nPos );
/*计算属性的长度*/
nProperLen = 0;
for( iLoop = 0; iLoop < pNode->nProperty.nCount; iLoop ++ ) {
nProperLen += ( UINT )( strlen( pNode->nProperty.pVal[iLoop].szName ) + 2 \
+ strlen( pNode->nProperty.pVal[iLoop].szData ) \
+ Calu_Var_Chgs( pNode->nProperty.pVal[iLoop].szData ) * 4 + 2 );
}
/*计算XML的长度*/
pXml->nLen -= ( ( UINT )( 2 * strlen( pNode->szName ) ) + 1 + nDataLen + nDepth + nProperLen );
/*对其父节点的处理*/
nPosParent = nPos;
TREE_GetParent( &( pXml->nTree ), &nPosParent );
/*如果是最后一个子节点*/
if ( ( nPosParent != NULL ) && ( TREE_GetChildCount( &( pXml->nTree ), nPosParent ) == 1 ) )
pXml->nLen -= ( nDepth - 1 );
if ( pNode->pszData != NULL ) FreeMemory( ( LPVOID )pNode->pszData );
/*删除节点*/
XML_FreeNode( pNode );
/*在树中删除节点*/
TREE_DeleteNode( &( pXml->nTree ), nPos );
return NORMAL;
}
/*-------------------------------------------------------------------------*/
RESULT STDCALL XML_DeleteNode( IN OUT PXMLSTRUCT pXml, IN LPCSTR pszPath )
{
/*在XML中删除第一个路径名为pszPath的节点*/
POS nPos;
DETECT_NULL( pXml );
DETECT_NULL( pXml->nTree.nRootPos );
DETECT_NULL( pszPath );
DETECT( strlen( pszPath ) <= XML_PATH_LEN );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -