⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.cpp

📁 相当不错的入门程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "stdafx.h"
#include "xml.h"
//#include "./export/misc.h"
//#include "./export/md5.h"
//#include "./export/blowfish.h"
#include <io.h>
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>

CXML::CXML()
	: m_heapXmlNodes(1,128,sizeof(XMLNODE),TRUE)
	, m_heapXmlAttribs(1,128,sizeof(XMLATTRIB),TRUE)
	, m_heapXmlSmallStrs(1,128,sizeof(XMLSMALLSTR),TRUE)
	, m_pNodeLinks(NULL)
	, m_pNodeLinkLast(NULL)
	, m_pAttribLinks(NULL)
	, m_pAttribLinkLast(NULL)
{
}

CXML::~CXML()
{
	// 检查并释放当前XML文件
	FreeXml();
}

BOOL CXML::LoadXml(const char* lpszXmlFile)
{
	// 打开XML文件并进行读取
	FILE* fpXml=fopen(lpszXmlFile,"rb");
	if(fpXml==NULL) return FALSE;
	long nXmlLen=filelength(fileno(fpXml));
	if(nXmlLen<0)
	{	fclose(fpXml);
		return FALSE;
	}
	char* lpszXmls=(char*)malloc(nXmlLen+1);
	if(lpszXmls==NULL)
	{	fclose(fpXml);
		return FALSE;
	}
	memset(lpszXmls,0,nXmlLen+1);
	nXmlLen=fread(lpszXmls,1,nXmlLen,fpXml);
	fclose(fpXml);
	// 从缓冲区装载XML
	BOOL bLoadSuccess=LoadXml(lpszXmls,nXmlLen);
	if(lpszXmls!=NULL) free(lpszXmls);
	return bLoadSuccess;
}

BOOL CXML::SaveXml(const char* lpszXmlFile)
{
	// 打开XML文件并进行写入
	FILE* fpXml=fopen(lpszXmlFile,"wb");
	if(fpXml==NULL) return FALSE;

	// 从第一个子节点开始写入
	LPXMLNODE pChildNode=m_pNodeLinks;
	while(pChildNode!=NULL)
	{	SaveXmlNodeAndChilds(pChildNode,fpXml,0);
		pChildNode=(LPXMLNODE)pChildNode->m_pNext;
	}

	// 关闭XML文件
	fclose(fpXml);
	return TRUE;
}

BOOL CXML::SaveXml(char* lpszXmlBuf,LONG nXmlBufLen,LONG* pnUsedOrNeeded)
{
	// 检查默认输出,后面的参数可以为空,清除返回
	LONG nUsedOrNeeded=0;
	if(pnUsedOrNeeded==NULL) pnUsedOrNeeded=&nUsedOrNeeded;
	(*pnUsedOrNeeded)=0;

	// 从第一个子节点开始写入
	LPXMLNODE pChildNode=m_pNodeLinks;
	while(pChildNode!=NULL)
	{	SaveXmlNodeAndChilds(pChildNode,lpszXmlBuf,nXmlBufLen,pnUsedOrNeeded,0);
		pChildNode=(LPXMLNODE)pChildNode->m_pNext;
	}
	// 检查是否写完,还是只写了部分
	if((*pnUsedOrNeeded)>=nXmlBufLen)
	{	// 为已经写入的部分加入'\0'
		if(nXmlBufLen>0) lpszXmlBuf[nXmlBufLen-1]='\0';
		// 需要加上'\0'的长度
		(*pnUsedOrNeeded)++;
		// 返回失败
		return FALSE;
	}
	// 全部写入完成,为已经写入的部分加入'\0',并将实际使用长度加上补充的长度
	lpszXmlBuf[(*pnUsedOrNeeded)]='\0';
	(*pnUsedOrNeeded)++;
	return TRUE;
}

BOOL CXML::LoadXml(const char* lpszXml,LONG nXmlLen)
{
	// 检查参数
	if(lpszXml==NULL&&nXmlLen<=0) return FALSE;
	// 检查并释放当前XML文件
	FreeXml();
	// 从缓冲区加载XML,这里将执行预处理,去掉其中的回车换行
	char* lpszXmlTemps=TMALLOC(nXmlLen+1,char);
	memset(lpszXmlTemps,0,nXmlLen+1);
	memcpy(lpszXmlTemps,lpszXml,nXmlLen);
	// 分析XML格式
	if(!ParsingXml(lpszXmlTemps,nXmlLen))
	{	TFREE(lpszXmlTemps);
		FreeXml();
		return FALSE;
	}
	TFREE(lpszXmlTemps);
	return TRUE;
}

VOID CXML::FreeXml()
{
	// 释放节点
	LPXMLNODE pNodeLink=m_pNodeLinks;
	while(pNodeLink!=NULL)
	{	LPXMLNODE pNodeTemp=(LPXMLNODE)pNodeLink;
		pNodeLink=(LPXMLNODE)pNodeLink->m_pHeapLink;
		FreeXmlNode(pNodeTemp);
	}
	m_pNodeLinks=NULL;
	m_pNodeLinkLast=NULL;
	// 释放属性节点
	LPXMLATTRIB pAttribLink=m_pAttribLinks;
	while(pAttribLink!=NULL)
	{	LPXMLATTRIB pAttribTemp=(LPXMLATTRIB)pAttribLink;
		pAttribLink=(LPXMLATTRIB)pAttribLink->m_pHeapLink;
		FreeXmlAttrib(pAttribTemp);
	}
	m_pAttribLinks=NULL;
	m_pAttribLinkLast=NULL;
}


// 配置读取
INT CXML::GetXmlProfileInt(LPCSTR lpszKeyPath,INT nDefault)
{	LPCSTR pszValue=GetXmlValueWithPath(lpszKeyPath);
	if(pszValue!=NULL) return atol(pszValue);
	return nDefault;
}

DWORD CXML::GetXmlProfileString(LPCSTR lpszKeyPath,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize)
{	// 如果返回串地址空
	if(lpReturnedString==NULL) return 0;
	// 填写正确的返回内容
	LPCSTR pszValue=GetXmlValueWithPath(lpszKeyPath);
	if(pszValue!=NULL)
	{	nstrcpy(lpReturnedString,pszValue,nSize);
		return strlen(lpReturnedString);
	}
	// 填写默认的返回内容
	nstrcpy(lpReturnedString,lpDefault,nSize);
	return strlen(lpReturnedString);
}

LPCSTR CXML::GetXmlProfileString(LPCSTR lpszKeyPath,LPCSTR lpDefault)
{	LPCSTR pszValue=GetXmlValueWithPath(lpszKeyPath);
	if(pszValue!=NULL) return pszValue;
	return lpDefault;
}

LPCSTR CXML::GetXmlProfileSafeString(LPCSTR lpszKeyPath,LPCSTR lpDefault)
{	LPCSTR pszValue=GetXmlValueWithPath(lpszKeyPath);
	if(pszValue!=NULL) return pszValue;
	if(lpDefault!=NULL) return lpDefault;
	return "";
}

// 配置写入
BOOL CXML::SetXmlProfileInt(LPCSTR lpszKeyPath,INT nValue)
{	CHAR szBuffer[MAX_PATH]={0};
	nsprintf(szBuffer,sizeof(szBuffer),"%d",nValue);
	return SetXmlValueWithPath(lpszKeyPath,szBuffer);
}

BOOL CXML::SetXmlProfileString(LPCSTR lpszKeyPath,LPCSTR pszValue)
{	return SetXmlValueWithPath(lpszKeyPath,pszValue);
}

// 路径创建
LPXMLNODE CXML::CreateXmlWithPath(const char* lpszXmlPath,DWORD dwFlag)
{	return FindXmlWithPath(lpszXmlPath,TRUE,dwFlag);
}

BOOL CXML::SetXmlValueWithPath(const char* lpszXmlPath,const char* lpszValue)
{	LPXMLNODE pNode=CreateXmlWithPath(lpszXmlPath,XMLNODE_KEYSET);
	if(pNode==NULL) return FALSE;
	return SetXmlNodeValue(pNode,lpszValue);
}

BOOL CXML::SetXmlAttribValueWithPath(const char* lpszXmlPath,const char* pszName,const char* lpszValue)
{	LPXMLNODE pNode=FindXmlWithPath(lpszXmlPath);
	if(pNode==NULL) return FALSE;
	return SetXmlAttribValue(pNode,pszName,lpszValue);
}

// 路径查找
LPXMLNODE CXML::FindXmlWithPath(const char* lpszXmlPath,BOOL bCreate,DWORD dwFlag)
{
	// 判断并复制出路径
	if(lpszXmlPath==NULL) return NULL;
	char* pszTemp=(char*)alloca(strlen(lpszXmlPath)+1);
	strcpy(pszTemp,lpszXmlPath);
	// 查找路径,例如/root/version/或者root/version
	LPXMLNODE pParentNode=NULL;
	BOOL bParentIsCreated=FALSE;
	for(;;)
	{	// 得到关键字的头部
		while((*pszTemp)=='/'||(*pszTemp)==' '||(*pszTemp)=='\t') pszTemp++;
		if((*pszTemp)=='\0') break;
		char* pszKey=pszTemp;
		// 得到关键字的尾部
		while((*pszTemp)!='\0'&&(*pszTemp)!='/') pszTemp++;
		char* pszKeyEnd=pszTemp;
		if((*pszTemp)!='\0') pszTemp++;
		// 截取字段并进行查找
		pszKeyEnd--;
		while((*pszKeyEnd)==' '||(*pszKeyEnd)=='\t') pszKeyEnd--;
		pszKeyEnd++;
		(*pszKeyEnd)='\0';
		LPXMLNODE pXmlNode=FindXmlNode(pParentNode,pszKey);
		if(pXmlNode==NULL)
		{	if(!bCreate) return NULL;
			// 如果不是创建的第一个节点,那么修正刚才创建的节点类型
			if(bParentIsCreated) pParentNode->m_dwFlag=XMLNODE_KEYSET;
			bParentIsCreated=TRUE;
			// 判断父类型是否能够创建子类型
			if(pParentNode!=NULL&&pParentNode->m_dwFlag!=XMLNODE_KEYSET) return NULL;
			// 创建当前类型的节点
			pXmlNode=AllocXmlNodeAtTail(pParentNode);
			pXmlNode->m_Key=AllocXmlStr(pszKey,strlen(pszKey));
			pXmlNode->m_dwFlag=dwFlag;
		}
		pParentNode=pXmlNode;
	}
	return pParentNode;
}

const char* CXML::GetXmlValueWithPath(const char* lpszXmlPath)
{	LPXMLNODE pNode=FindXmlWithPath(lpszXmlPath);
	if(pNode==NULL) return NULL;
	return GetXmlNodeValue(pNode);
}

const char* CXML::GetXmlAttribValueWithPath(const char* lpszXmlPath,const char* pszName)
{	LPXMLNODE pNode=FindXmlWithPath(lpszXmlPath);
	if(pNode==NULL) return NULL;
	return GetXmlAttribValue(pNode,pszName);
}

const char* CXML::GetXmlNodeValue(LPXMLNODE pNode)
{	if(pNode==NULL) return NULL;
	LPXMLNODE pChild=(LPXMLNODE)pNode->m_pChild;
	if(pChild==NULL||pChild->m_dwFlag!=XMLNODE_VALUE) return NULL;
	return pChild->m_Key.m_pStr;
}

LPXMLNODE CXML::FindXmlNode(LPXMLNODE pParent,const char* pszKey)
{
	LPXMLNODE pNode=GetFirstChildXmlNode(pParent);
	while(pNode!=NULL)
	{	if(stricmp(pNode->m_Key.m_pStr,pszKey)==0)
			return pNode;
		pNode=GetNextXmlNode(pNode);
	}
	return NULL;
}

LPXMLNODE CXML::GetFirstChildXmlNode(LPXMLNODE pParent)
{
	// 如果父节点为空,表明取根节点的子节点,按照分配的逻辑应该是链表的第一个
	if(pParent==NULL) return m_pNodeLinks;
	// 否则返回指定节点的第一个节点
	return (LPXMLNODE)pParent->m_pChild;
}

LPXMLNODE CXML::GetNextXmlNode(LPXMLNODE pNode)
{	if(pNode==NULL) return NULL;
	return (LPXMLNODE)pNode->m_pNext;
}

BOOL CXML::SetXmlNodeValue(LPXMLNODE pNode,const char* pszValue)
{	// 检查参数是否合法
	if(pNode==NULL||pszValue==NULL) return FALSE;
	// 得到或创建子节点
	LPXMLNODE pChild=(LPXMLNODE)pNode->m_pChild;
	if(pChild==NULL)
	{	pChild=AllocXmlNodeAtTail(pNode);
		pChild->m_dwFlag=XMLNODE_VALUE;
	}
	// 判断子节点类型
	if(pChild->m_dwFlag!=XMLNODE_VALUE) return FALSE;
	// 更新子节点数据
	FreeXmlStr(pChild->m_Key);
	pChild->m_Key=AllocXmlStr(pszValue,strlen(pszValue));
	return TRUE;
}

// 通过名称获取属性值
const char* CXML::GetXmlAttribValue(LPXMLNODE pNode,const char* pszName)
{	LPXMLATTRIB pAttrib=FindXmlAttrib(pNode,pszName);
	if(pAttrib==NULL) return NULL;
	return pAttrib->m_Value.m_pStr;
}

// 通过名称查找属性
LPXMLATTRIB CXML::FindXmlAttrib(LPXMLNODE pNode,const char* pszName)
{	LPXMLATTRIB pAttrib=GetFirstXmlAttrib(pNode);
	while(pAttrib!=NULL)
	{	if(stricmp(pAttrib->m_Name.m_pStr,pszName)==0)
			return pAttrib;
		pAttrib=GetNextXmlAttrib(pAttrib);
	}
	return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -