好久沒有更新博客了,今天就將我之前寫的一些代碼陸續發上來。
json.h
[cpp]
#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
[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;
}