c++编写json解析类

      好久没有更新博客了,今天就将我之前写的一些代码陆续发上来。

json.h

#include<iostream>
#include <string>
using namespace std;

class CJson
{
public:
	enum TYPE{STRING,LONG,ARRAY,OBJECT,BOOL,NAMEDOBG,STRINGA,LONGA,ARRAYA,OBJECTA,BOOLA,NAMEDOBGA};
	typedef struct _NODE
	{
		friend CJson;
		string m_key;
		TYPE type;
		string m_strVal;
		bool m_boolVal;
		long m_longVal;
		string m_objVal;
		_NODE(){memset(this,0,sizeof(_NODE));}
		_NODE* GetChild(){return m_child;}
		_NODE* GetNext(){return m_next;}
		_NODE* GetParent(){return m_parent;}
		_NODE* Get(int index)
		{
			NODE* n=m_child;
			for(int i=0;i<index;i++)
			{
				if(n==0)
				{
					return 0;
				}
				n=n->m_next;
			}
			return n;
		}
		_NODE* Get(char* key)
		{
			NODE* n=m_child;
			while(n)
			{
				if(n->m_key==key)
				{
					return n;
				}
				n=n->m_next;
			}
			return 0;
		}
		_NODE* Append(TYPE type,char* key,char* sVal,long nVal)
		{
			NODE *node=new NODE;
			node->type=type;
			if(type==STRING)
			{
				node->m_key=key;
				node->m_strVal=sVal;
			}
			else if (type==LONG)
			{
				node->m_key=key;
				node->m_longVal=nVal;
			}
			else if(type==OBJECT)
			{
				node->m_key=key;
			}
			else if (type==ARRAY)
			{
				node->m_key=key;
			}
			else if(type==STRINGA)
			{
				node->m_strVal=sVal;
			}
			else if (type==LONGA)
			{
				node->m_longVal=nVal;
			}
			else if(type==OBJECTA)
			{

			}
			else if (type==ARRAYA)
			{

			}
			if(!m_child)
			{
				m_child=node;
				node->m_parent=this;
			}
			else
			{
				NODE* n=m_child;
				while (n->m_next)
				{
					n=n->m_next;
				}
				n->m_next=node;
				node->m_parent=this;
			}
			return node;
		}
		_NODE* Remove(_NODE* node)     //remove  child 
		{
			if(!node)
			{
				return 0;
			}
			NODE* nNext=node->m_next,*n=m_child;
			if(node==n)
			{
				delete[] m_child;
				m_child=0;
			}
			else
			{
				while(n->m_next!=node)
				{
					n=n->m_next;
				}
				n->m_next=node->m_next;
				delete node;
			}
			return nNext;
		}
		_NODE* Remove(int index)    //remove  array  child
		{
			if(index<0)
				return 0;
			NODE* n=m_child,*n1;
			if(index==0)
			{
				NODE* n=m_child;
				m_child=m_child->m_next;
				delete n;
				return m_child;
			}
			for(int i=0;i<index;i++)
			{
				n1=n;
				n=n->m_next;
			}
			n1->m_next=n->m_next;
			delete n;
			return n1->m_next;
		}
		_NODE* Remove(CJson* oCj)         //remove self
		{
			if(!oCj)
			{
				return 0;
			}
			NODE* nNext=m_next;
			if(!m_parent)
			{
				if(!oCj->m_root)
				{
					return 0;
				}
				if(oCj->m_root==this)
				{
					oCj->m_root=nNext;
					delete this;
				}
				else
				{
					NODE *n=oCj->m_root;
					while(n->m_next!=this)
					{
						n=n->m_next;
					}
					NODE* n1=n->m_next;
					n->m_next=n1->m_next;
					delete n1;
				}
			}
			else
			{
				if(!m_parent->m_child)
				{
					return 0;
				}
				if(m_parent->m_child==this)
				{
					m_parent->m_child=nNext;
					delete this;
				}
				else
				{
					NODE *n=m_parent->m_child;
					while(n->m_next!=this)
					{
						n=n->m_next;
					}
					NODE* n1=n->m_next;
					n->m_next=n1->m_next;
					delete n1;
				}
			}
			return nNext;
		}
		_NODE* Insert(_NODE* node,int index)
		{
			if(!node)
			{
				return 0;
			}
			if(!m_child)
			{
				m_child=node;
				return node;
			}
			NODE* n=m_child;
			for(int i=0;i<index-1;i++)
			{
				if(!n->m_next)
				{
					break;
				}
				n=n->m_next;
			}
			node->m_next=n->m_next;
			n->m_next=node;
			node->m_parent=this;
			return node;
		}
		_NODE* Copy()
		{
			_NODE* n=new _NODE;
			*n=*this;
			n->m_child=0;
			n->m_parent=0;
			n->m_child=0;
			return n;
		}
	private:
		_NODE *m_child;
		_NODE *m_next;
		_NODE *m_parent;
	}NODE;
	CJson();
	~CJson();
	friend _NODE;
	bool Load(char*);
	NODE* GetRoot();
	string GetJsonString();
	NODE* Get(char*);
	NODE* Append(TYPE,char*,char*,long);
	NODE* Remove(NODE*);         //return next node
	NODE* Insert(NODE*,int);
private:
	void Release(NODE*);
	void output(NODE *);
	inline string GetTab(int num){
		string tab;
		for(int i=0;i<num;i++)
		{
			tab+="\t";
		}
		return tab;
	}
	char* m_str;
	NODE *m_root;
	string m_strOutput;

};
typedef CJson::NODE JsonNode;


json.cpp

#include "json.h"
CJson::CJson()
{
	m_str=0;
	m_root=0;
}
CJson::~CJson()
{
	Release(m_root);
	if(m_str)
	{
		delete[] m_str;
		m_str=0;
	}
}
void CJson::Release(NODE* node)
{
	if(node)
	{
		Release(node->m_child);
		Release(node->m_next);
		delete node;
	}

}
JsonNode* CJson::GetRoot()
{
	return m_root;
}
bool CJson::Load(char* str)
{
	NODE* CurNode;
#define CHECKBLANK(ch) (ch==' ' || ch=='\t' || ch=='\r' || ch=='\n')
	if(str==0 || *str==0)
	{
		return false;
	}
	m_str=new char[strlen(str)+1];
	strcpy(m_str,str);
	int i=0;
	while(m_str[i]!='{')
	{
		i++;
	}
	i++;
	NODE *m_par=0,*m_cur=0;
	bool bInKey=true;
	while(m_str[i])
	{
		if(!CHECKBLANK(m_str[i]))
		{
			if(m_str[i]==',')
			{
				bInKey=true;
			}
			else if(m_str[i]==':')
			{
				bInKey=false;
			}
			else if(m_str[i]=='[')
			{
				if(!bInKey)
				{

					m_cur->type=ARRAY;
					m_par=m_cur;
					bInKey=true;

				}
				else
				{
					NODE *node=new NODE;
					memset(node,0,sizeof(NODE));
					node->type=ARRAYA;
					node->m_parent=m_par;
					m_cur=node;
					if(m_par->m_child==0)
					{
						m_par->m_child=node;
					}
					else
					{
						NODE *n=m_par->m_child;
						while(n->m_next)
						{
							n=n->m_next;
						}
						n->m_next=node;
					}
					m_par=node;
				}

			}
			else if(m_str[i]==']')
			{
				if(m_par)
				{
					m_par=m_par->m_parent;
				}
				bInKey=true;
			}
			else if(m_str[i]=='{')
			{
				if(!bInKey)
				{

					m_cur->type=OBJECT;
					m_par=m_cur;
					bInKey=true;

				}
				else
				{
					NODE *node=new NODE;
					memset(node,0,sizeof(NODE));
					node->type=OBJECTA;
					node->m_parent=m_par;
					m_cur=node;
					if(m_par->m_child==0)
					{
						m_par->m_child=node;
					}
					else
					{
						NODE *n=m_par->m_child;
						while(n->m_next)
						{
							n=n->m_next;
						}
						n->m_next=node;
					}
					m_par=node;
				}
			}
			else if(m_str[i]=='}')
			{
				if(m_par)
				{
					m_par=m_par->m_parent;
				}
				bInKey=true;
			}
			else if(m_str[i]=='\"')
			{
				if(!bInKey)
				{
					i++;
					m_cur->type=STRING;
					while(m_str[i]!='\"' ||(m_str[i]=='\"' && m_str[i-1]=='\\'))
					{
						m_cur->m_strVal+=m_str[i];
						i++;
					}
					while(m_str[i]!=','&& m_str[i]!=']' && m_str[i]!='}')
					{
						i++;
					}
					i--;
				}
				else
				{
					i++;
					NODE *node=new NODE;
					memset(node,0,sizeof(NODE));
					while(m_str[i]!='\"' ||(m_str[i]=='\"' && m_str[i-1]=='\\'))
					{					
						node->m_key+=m_str[i];		
						i++;
					}
					if(m_par && (m_par->type==ARRAY || m_par->type==ARRAYA))
					{
						node->m_strVal=node->m_key;
						node->type=STRINGA;
						while(m_str[i]!=',' && m_str[i]!=']')
						{
							i++;
						}
						i--;
					}
					else
					{
						while(m_str[i]!=':')
						{
							i++;
						}
						i--;
					}

					if(m_root==0)
					{
						m_root=node;
						m_cur=node;
					}
					else
					{
						m_cur=node;
						node->m_parent=m_par;
						if(m_par)
						{
							if(m_par->m_child==0)
							{
								m_par->m_child=node;
							}
							else
							{
								NODE *n=m_par->m_child;
								while(n->m_next)
								{
									n=n->m_next;
								}
								n->m_next=node;
							}
						}
						else
						{
							NODE *n=m_root;
							while(n->m_next)
							{
								n=n->m_next;
							}
							n->m_next=node;
						}

					}
				}
			}
			else if(m_str[i]>='1' && m_str[i]<='9')
			{
				if(m_par && (m_par->type==ARRAY || m_par->type==ARRAYA))
				{
					NODE *node=new NODE;
					memset(node,0,sizeof(NODE));
					node->type=LONGA;
					node->m_parent=m_par;
					m_cur=node;
					if(m_par->m_child==0)
					{
						m_par->m_child=node;
					}
					else
					{
						NODE *n=m_par->m_child;
						while(n->m_next)
						{
							n=n->m_next;
						}
						n->m_next=node;
					}
					if(m_str[i-1]=='-')
					{
						node->m_strVal+=m_str[i-1];
					}
					while(m_str[i]!=','&& m_str[i]!=']')
					{	
						if(!CHECKBLANK(m_str[i]))
						{
							node->m_strVal+=m_str[i];
						}
						node->m_longVal=atoi(node->m_strVal.data());
						i++;
					}
					i--;

				}
				else
				{
					m_cur->type=LONG;
					if(m_str[i-1]=='-')
					{
						m_cur->m_strVal+=m_str[i-1];
					}
					while(m_str[i]!=','&& m_str[i]!=']' && m_str[i]!='}')
					{	
						if(!CHECKBLANK(m_str[i]))
						{
							m_cur->m_strVal+=m_str[i];
						}
						m_cur->m_longVal=atoi(m_cur->m_strVal.data());
						i++;
					}
					i--;

				}

			}
			else if((m_str[i]>='a' && m_str[i]<='z') || (m_str[i]>='A' && m_str[i]<='Z'))
			{
				if(m_par && (m_par->type==ARRAY || m_par->type==ARRAYA))
				{
					NODE *node=new NODE;
					memset(node,0,sizeof(NODE));
					node->m_parent=m_par;
					m_cur=node;
					if(m_par->m_child==0)
					{
						m_par->m_child=node;
					}
					else
					{
						NODE *n=m_par->m_child;
						while(n->m_next)
						{
							n=n->m_next;
						}
						n->m_next=node;
					}
					bool bInQ=false;
					while(bInQ ||(m_str[i]!=','&& m_str[i]!=']'))
					{	
						if(!CHECKBLANK(m_str[i]))
						{
							if(m_str[i]=='\"' || m_str[i]=='\'')
							{
								bInQ=!bInQ;
							}
							node->m_objVal+=m_str[i];
						}
						i++;
					}
					i--;
					if(m_cur->m_objVal=="true"  || m_cur->m_objVal=="false")
					{
						node->type=BOOLA;
					}
					else
					{
						node->type=NAMEDOBGA;
					}
				}
				else
				{
					bool bInQ=false;
					while(1)
					{
						if(m_str[i]=='\"' || m_str[i]=='\'')
						{
							bInQ=!bInQ;
							m_cur->m_objVal+=m_str[i];
						}
						else if(CHECKBLANK(m_str[i]))
						{
							i++;
							continue;
						}
						else if(!bInQ && (m_str[i]==',' || m_str[i]==']' ||m_str[i]=='}'))
						{
							i--;
							break;
						}
						else
						{
							m_cur->m_objVal+=m_str[i];
						}
						i++;
					}
					if(m_cur->m_objVal=="true"  || m_cur->m_objVal=="false")
					{
						m_cur->type=BOOL;
					}
					else
					{
						m_cur->type=NAMEDOBG;
					}
				}
			}

		}
		i++;
	}
	return true;
}
string CJson::GetJsonString()
{
	m_strOutput="";
	output(m_root);
	m_strOutput="{\n"+m_strOutput+"\n}";
	return m_strOutput;
}
void CJson::output(NODE *n)
{
	static int nTab=1;
	if(n)
	{
		if(n->m_parent)
		{
			if(n!=n->m_parent->m_child)
			{
				m_strOutput+=",\n";
			}
		}
		else
		{
			if(n!=m_root)
			{
				m_strOutput+=",\n";
			}
		}
		if(n->type==ARRAY)
		{
			m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";
			m_strOutput+="\n"+GetTab(nTab)+"[\n";
			nTab++;
			output(n->m_child);
			nTab--;
			m_strOutput+="\n"+GetTab(nTab)+"]";
		}
		else if(n->type==OBJECT)
		{

			m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";
			m_strOutput+="\n"+GetTab(nTab)+"{\n";
			nTab++;
			output(n->m_child);
			nTab--;
			m_strOutput+="\n"+GetTab(nTab)+"}";
		}
		else if(n->type==OBJECTA)
		{

			m_strOutput+=GetTab(nTab)+"{\n";
			nTab++;
			output(n->m_child);
			nTab--;
			m_strOutput+="\n"+GetTab(nTab)+"}";
		}
		else if(n->type==ARRAYA)
		{

			m_strOutput+=GetTab(nTab)+"[\n";
			nTab++;
			output(n->m_child);
			nTab--;
			m_strOutput+="\n"+GetTab(nTab)+"]";
		}
		else if(n->type==STRINGA)
		{
			m_strOutput+=GetTab(nTab)+"\""+n->m_strVal+"\"";
		}
		else if(n->type==LONGA)
		{
			if(atoi(n->m_strVal.data())!=n->m_longVal)
			{
				char str[100]={0};
				itoa(n->m_longVal,str,10);
				n->m_strVal=str;
			}
			m_strOutput+=GetTab(nTab)+n->m_strVal;
		}
		else if(n->type==LONG)
		{
			char str[100]={0};
			itoa(n->m_longVal,str,10);
			n->m_strVal=str;
			m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";
			m_strOutput=m_strOutput+n->m_strVal;
		}
		else if(n->type==STRING)
		{
			m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";
			m_strOutput=m_strOutput+"\""+n->m_strVal+"\"";
		}
		else if(n->type==BOOL || n->type==NAMEDOBG)
		{
			m_strOutput=m_strOutput+GetTab(nTab)+"\""+n->m_key+"\":";
			m_strOutput=m_strOutput+n->m_objVal;
		}
		else if(n->type==BOOLA || n->type==NAMEDOBGA)
		{
			m_strOutput+=GetTab(nTab)+n->m_objVal;
		}
		output(n->m_next);
	}
}
JsonNode* CJson::Get(char* key)
{
	if(m_root)
	{
		NODE* n=m_root;
		while(n)
		{
			if(n->m_key==key)
			{
				return n;
			}
			n=n->m_next;
		}
	}

	return 0;

}
JsonNode* CJson::Append(TYPE type,char* key,char* sVal,long nVal)
{
	NODE *node=new NODE;
	node->type=type;
	if(type==STRING)
	{
		node->m_key=key;
		node->m_strVal=sVal;
	}
	else if (type==LONG)
	{
		node->m_key=key;
		node->m_longVal=nVal;
	}
	else if(type==OBJECT)
	{
		node->m_key=key;
	}
	else if (type==ARRAY)
	{
		node->m_key=key;
	}
	else if(type==STRINGA)
	{
		node->m_strVal=sVal;
	}
	else if (type==LONGA)
	{
		node->m_longVal=nVal;
	}
	else if(type==OBJECTA)
	{

	}
	else if (type==ARRAYA)
	{

	}
	if(!m_root)
	{
		m_root=node;
	}
	else
	{
		NODE* n=m_root;
		while (n->m_next)
		{
			n=n->m_next;
		}
		n->m_next=node;
	}
	return node;
}
JsonNode* CJson::Insert(NODE* node,int index)
{
	if(!node)
	{
		return 0;
	}
	if(!m_root)
	{
		m_root=node;
		return node;
	}
	NODE* n=m_root;
	for(int i=0;i<index-1;i++)
	{
		if(!n->m_next)
		{
			break;
		}
		n=n->m_next;
	}
	node->m_next=n->m_next;
	n->m_next=node;
	node->m_parent=0;
	return node;
}
JsonNode* CJson::Remove(NODE* node)
{
	if(!node)
	{
		return 0;
	}
	NODE* nNext=node->m_next,*n=m_root;
	if(node==n)
	{
		delete[] m_root;
		m_root=0;
	}
	else
	{
		while(n->m_next!=node)
		{
			n=n->m_next;
		}
		n->m_next=node->m_next;
		delete node;
	}
	return nNext;
}
int main()
{
	FILE *f=fopen("d:\\json.txt","rb");
	fseek(f,0,SEEK_END);
	long n=ftell(f);
	fseek(f,0,SEEK_SET);
	char *b=new char[n+1];
	b[n]=0;
	fread(b,1,n,f);
	fclose(f);
	CJson j;
	j.Load(b);
	//JsonNode* nn=j.Get("a")->Get(2)->Get(0);
	//	JsonNode* nnn=nn->Copy();
	//j.Append(CJson::STRING,"qq","123",0);
	//j.Append(CJson::ARRAY,"qq1",0,0)->Append(CJson::ARRAYA,0,0,0)->Append(CJson::OBJECTA,0,0,0)->Append(CJson::STRING,"2","23",0);
	//nn->Remove(&j);
	//j.Get("a")->Insert(nnn,1);
	//j.Get("a")->Remove(0);
	cout<<j.GetJsonString()<<endl;
	delete[] b;
}


        这个解析类的数据结构是二叉树,左子树是节点的兄弟节点的nextnode,右子树是节点的子节点的firstchild。

      文章不足之处还望大家多多指正。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值