Jsonajax领域很流行,记得当时看过它的介绍后很兴奋,网上找了一些解析jsonc

 

c++代码,不过没有找到特别好的,有的写得不错不过要依赖于boost,有的用c写的不大好用,好在json语法简单,参考了一些c/c++json解析代码做了一个json类,最近又把去年写的json类修改为unicode下使用,增了一些功能,现在CJsonw可以解析const char *型输入,也可解析const wchar_t *型输入,可解析ansi编码、unicode编码、utf8编码的json文件。看看我的CJsonw定义:

 

        JsonwType type;                     //Json类型, true false null直接由类型表示了

        DWORD tag;                            //tag,用户自用值,默认为0

        union

        {

                struct{

                        wchar_t *cstring;//字符串型值

                        int clen;            //cstring按照字符计算的分配个数,包括可能的0

                };

                double dvalue;          //double

                struct

                {

                        int ivalue;         //int

                        DWORD dwhigh;       //高部

                };

                __int64 i64value;        //int64

                OBJS *objs;                     //对象型值

                ARRAYS *arrays;             //数组型值

        };

Sizeof(CJsonw) == 16

OBJS类型描述无序的key-value型数据,ARRAYS描述 array型有序数据,定义如下:

        typedef CHashiW<CJsonw *, CJsonw *> OBJS;

        typedef std::vector<CJsonw *> ARRAYS;

支持以下构造函数:

        CJsonw(JsonwType t=json_null);

        CJsonw(int value);

        CJsonw(__int64 value);

        CJsonw(float value);

        CJsonw(double value);

        CJsonw(const wchar_t *value);

        //数组型构造函数

        CJsonw(int *numbers, int count);

        CJsonw(__int64 *numbers, int count);

        CJsonw(float *numbers, int count);

        CJsonw(double *numbers, int count);

        CJsonw(const wchar_t **strings, int count);

支持以下赋值函数:

        bool setnull();

        bool set(bool value);

        bool set(int value);

        bool set(__int64 value);

        bool set(float value);

        bool set(double value);

        bool set(const wchar_t *value);

        bool set(int *numbers, int count);

        bool set(__int64 *numbers, int count);

        bool set(float *numbers, int count);

        bool set(double *numbers, int count);

        bool set(const wchar_t **strings, int count);

       

        //修改常规值,就是true, false, int, real, string

        bool setbystring(const wchar_t *value);

 

支持以下输入:

        bool parse(const char *string);

        bool parse(const wchar_t *string);

        bool parsefile(FILE *fp);

        bool parsefile(LPCTSTR filename);

文件可以ansi编码、unicode编码、或者utf8编码

 

支持以下wchar_t型输出:

        //dump,默认为unicode编码

        //uunicode表示字符串中的unicode字符是否按照\uxxxx格式输出

        //bDisptrue按照友好格式显示,会输出\t换行等方便阅读

        //bDispfalse按照紧凑模式显示,没有多余字符,方便网络传输等场合

        bool dump(CBlockBuffer *pbk, bool bNameQuotes=true, bool uunicode=false, bool bDisp=true);

        //跟上面的dump一样,但如果成功会在buf里面插入一个'\0'字符

        bool dump0(CBlockBuffer *pbk, bool bNameQuotes=true, bool uunicode=false, bool bDisp=true);

        bool save(LPCTSTR filename);

        bool save(FILE *fp);

保存到文件默认为UNICODE格式

 

支持以下ANSI型输出:

        //a系列dumpansi编码输出

        //bDisptrue按照友好格式显示,会输出\t换行等方便阅读

        //bDispfalse按照紧凑模式显示,没有多余字符,方便网络传输等场合

        bool dumpa(CBlockBuffer *pbk, bool bNameQuotes=true, bool uunicode=true, bool bDisp=true);

        //跟上面的dump一样,但如果成功会在buf里面插入一个'\0'字符

        bool dumpa0(CBlockBuffer *pbk, bool bNameQuotes=true, bool uunicode=true, bool bDisp=true);

ANSI型输出主要用在节省网络带宽或者和其他系统交换数据的情况下。

 

支持以下类型判别函数:

        //类型判别函数

        bool IsArray() const { return type==json_array; }

        bool IsObject() const { return type==json_object; }

        bool IsInt() const { return type==json_int; }

        bool IsReal() const { return type==json_real; }

        bool IsNumber() const { return IsInt()||IsReal(); }

        bool IsNull() const { return type==json_null; }

        bool IsTrue() const { return type==json_true; }

        bool IsFalse() const { return type==json_false; }

        bool IsString() const { return type==json_string; }

 

支持以下一些直接取值函数:

        const wchar_t *getordef(const wchar_t *strdef)

        int getordef(int idef)

        __int64 getordef(__int64 idef)

        double getordef(double ddef)

        bool getordef(bool bdef)

        //array的元素

        CJsonw *get(int n)

        CJsonw *operator[](int n) const

        //obj的元素

        CJsonw *get(const wchar_t *name)

        CJsonw *operator[](const wchar_t *name) const

 

支持以下取array型子元素数据的函数:

        const wchar_t *getordef(int n, const wchar_t *strdef)

        int getordef(int n, int idef)

        __int64 getordef(int n, __int64 idef)

        double getordef(int n, double ddef)

        bool getordef(int n, bool bdef)

 

支持以下取obj型子元素数据的函数:

        const wchar_t *getordef(const wchar_t *name, const wchar_t *strdef)

        int getordef(const wchar_t *name, int idef)

        __int64 getordef(const wchar_t *name, __int64 idef)

        double getordef(const wchar_t *name, double ddef)

        bool getordef(const wchar_t *name, bool bdef)

 

支持以下obj遍历函数:

        //遍历函数,最常见写法:

        //for(CJsonw::OBJIT *p=xxx.FirstObj(); p; p=p->next())...

        OBJIT *firstobj()

 

        //arrayobject元素个数,string类型返回分配的字符个数(包括可能的),其他类型都返回

        int size() const

 

另外支持一些增加array子元素函数:

        bool add(CJsonw *pnode)

        bool del(int n, bool bfree=true)

        bool addnull(){ return add(new CJsonw(json_null)); }

        bool addtrue(){ return add(new CJsonw(json_true)); }

        bool addfalse(){ return add(new CJsonw(json_false)); }

        bool add(int value){ return add(new CJsonw(value)); }

        bool add(__int64 value){ return add(new CJsonw(value)); }

        bool add(float value){ return add(new CJsonw(value)); }

        bool add(double value){ return add(new CJsonw(value)); }

        bool add(const wchar_t *value){ return add(new CJsonw(value)); }

 

也支持obj增加删除子对象函数:

        bool addobj(const wchar_t *name, CJsonw *pnode)

        bool delobj(const wchar_t *name, bool bfree=true)

        bool addobjnull(const wchar_t *name){ return addobj(name, new CJsonw(json_null)); }

        bool addobjtrue(const wchar_t *name){ return addobj(name, new CJsonw(json_true)); }

        bool addobjfalse(const wchar_t *name){ return addobj(name, new CJsonw(json_false)); }

        bool addobj(const wchar_t *name, int value){ return addobj(name, new CJsonw(value)); }

        bool addobj(const wchar_t *name, __int64 value){ return addobj(name, new CJsonw(value)); }

        bool addobj(const wchar_t *name, float value){ return addobj(name, new CJsonw(value)); }

        bool addobj(const wchar_t *name, double value){ return addobj(name, new CJsonw(value)); }

        bool addobj(const wchar_t *name, const wchar_t *value){ return addobj(name, new CJsonw(value)); }

 

还有一些特殊函数:

        //计算整个树的crc

        DWORD calccrc();

        //计算整个树的md5,要求md5不少于个字节

        byte *calcmd5(byte *md5);

        //计算hex表示的md5,不写尾部,要求md5hex不少于个字符

        char *calcmd5hex(char *md5hex, const byte x='x');

        //计算hex表示的md5,写尾部,要求md5hex不少于个字符

        char *calcmd5hex0(char *md5hex, const byte x='x');

 

 

json类上花了较多时间,主要是觉得这个类很有用,可以描述任意对象,易保存易传输易构造,对速度要求不苛刻的应用程序用json作为基本数据结构很合适,配合json里面的data自定义字段理论上支持描述任意对象,配合使用一些cache可扩大json类的使用范围,用它取代ini xml等配置简直是大材小用,用json类来做stringtable简直就是小菜一碟,而且还是hash级高效率,丝毫不比手工做一个hash_map<,>表差。

在实际应用中,去年有一个网络验证的项目就大量使用了这个类,配置、帮助都是json格式,应用中管理大量对象的内存数据库也是用了json类,编码后直接网上传输,server内部也是一个json对象直接管理了大量用户的信息,非常方便,可以说用json类使得这个程序少写了大量代码,也使得整个项目只用了1个月时间就做出来了,还部署成master – master- slave(N)模式稳定运行了将近1年时间。

在另一些网络应用中,俺将json格式数据作为变长包使用,前面俺写过一篇短文介绍了变长包最常见的几种格式,分别是:

1、 key\0value\0…

2、 json格式

3、 xml格式

使用json格式作为变长包现在很流行,这也是大量ajax所采用所依赖的技术,qq种菜,google搜索预列表都是采用json格式的。

Posted on 2010-10-03 14:17 袁斌 阅读(887) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理