• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

luatable与json的之间的互相转换高性能c++实现

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

请自行约束两种语言数据结构语法上的不同,避开如下问题:

1、json本身不约束key是否符合一个编程语言中的变量名,所以编写用于和编程语言数据结构交互的json代码时应该注意key是否正确。

2、lua没有数组,利用哈希表实现的逻辑上的数组,在中间可以存在不连续的情况时json将无法识别。

3、lua的字符串key可以和数字key共存,这对于json来说,是不允许的。

 

 这些代码我已经用了很久了,所以暂时不多解释了,依赖c++11以上的版本,

代码挺多,有需求可以直接复制,这么多代码的目的也就是更高性能,单纯的在C++里面跑,比谷歌的实现稍微快一点点。

好了,废话不多说,上代码

#pragma once
#include <string>
#include <functional>
#include <setjmp.h>
#include <fstream>
#include <vector>

namespace aqx {

#ifndef jsize_t
    typedef unsigned int jsize_t;
#endif

#ifndef jnumber_t
    typedef double jnumber_t;
#endif

    static short constexpr jsvt_null{ 0 };
    static short constexpr jsvt_string{ 1 };
    static short constexpr jsvt_number{ 2 };
    static short constexpr jsvt_boolean{ 3 };
    static short constexpr jsvt_object{ 4 };
    static short constexpr jsvt_group{ 5 };

    namespace aqx_internal {
#ifndef __AQX_UTF8_CHAR_LEN
#define __AQX_UTF8_CHAR_LEN
        static unsigned char utf8_char_len[] = {
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
            2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
            2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
            3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
            4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
        };
#endif

        static unsigned int json_char_state[] = {
            0,0,0,0,0,0,0,0,0,32,96,0,0,96,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            32,0,640,0,0,0,0,0,0,0,0,1048576,65536,8192,131072,512,
            3072,3072,3072,3072,3072,3072,3072,3072,3072,3072,16,0,0,0,0,0,
            0,1024,1024,1024,1024,5120,1024,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,4,768,8,0,0,
            0,17408,1024,1024,1024,21504,50176,0,0,0,0,0,278528,0,524800,0,
            0,0,16896,16384,49664,279040,0,0,0,0,0,1,0,2,0,0
        };

        static int u16c2u8c(unsigned long u16c, unsigned char *u8c) {
            if (u16c <= 0x0000007F) {
                u8c[0] = u16c & 0x7F;
                return 1;
            }
            else if (u16c >= 0x00000080 && u16c <= 0x000007FF) {
                u8c[1] = (u16c & 0x3F) | 0x80;
                u8c[0] = ((u16c >> 6) & 0x1F) | 0xC0;
                return 2;
            }
            else if (u16c >= 0x00000800 && u16c <= 0x0000FFFF)
            {
                u8c[2] = (u16c & 0x3F) | 0x80;
                u8c[1] = ((u16c >> 6) & 0x3F) | 0x80;
                u8c[0] = ((u16c >> 12) & 0x0F) | 0xE0;
                return 3;
            }
            else if (u16c >= 0x00010000 && u16c <= 0x001FFFFF)
            {
                u8c[3] = (u16c & 0x3F) | 0x80;
                u8c[2] = ((u16c >> 6) & 0x3F) | 0x80;
                u8c[1] = ((u16c >> 12) & 0x3F) | 0x80;
                u8c[0] = ((u16c >> 18) & 0x07) | 0xF0;
                return 4;
            }
            else if (u16c >= 0x00200000 && u16c <= 0x03FFFFFF)
            {
                u8c[4] = (u16c & 0x3F) | 0x80;
                u8c[3] = ((u16c >> 6) & 0x3F) | 0x80;
                u8c[2] = ((u16c >> 12) & 0x3F) | 0x80;
                u8c[1] = ((u16c >> 18) & 0x3F) | 0x80;
                u8c[0] = ((u16c >> 24) & 0x03) | 0xF8;
                return 5;
            }
            else if (u16c >= 0x04000000 && u16c <= 0x7FFFFFFF)
            {
                u8c[5] = (u16c & 0x3F) | 0x80;
                u8c[4] = ((u16c >> 6) & 0x3F) | 0x80;
                u8c[3] = ((u16c >> 12) & 0x3F) | 0x80;
                u8c[2] = ((u16c >> 18) & 0x3F) | 0x80;
                u8c[1] = ((u16c >> 24) & 0x3F) | 0x80;
                u8c[0] = ((u16c >> 30) & 0x01) | 0xFC;
                return 6;
            }

            return 0;
        }

        namespace JSON_SYNTAX {
            static constexpr auto _T_OBJECT_BEGIN{ static_cast<unsigned int>(0x01) };            // {
            static constexpr auto _T_OBJECT_END{ static_cast<unsigned int>(0x02) };            // }
            static constexpr auto _T_GROUP_BEGIN{ static_cast<unsigned int>(0x04) };            // [
            static constexpr auto _T_GROUP_END{ static_cast<unsigned int>(0x08) };            // ]
            static constexpr auto _T_VALUE{ static_cast<unsigned int>(0x10) };                // :
            static constexpr auto _T_SPACE{ static_cast<unsigned int>(0x20) };                // 4个空白字符" \t\r\n"
            static constexpr auto _T_ENDL{ static_cast<unsigned int>(0x40) };                    // 2个换行符"\r\n"
            static constexpr auto _T_TEXT{ static_cast<unsigned int>(0x80) };                    // "
            static constexpr auto _T_ESCAPE_BEGIN{ static_cast<unsigned int>(0x100) };            // 转义符开始 '\\'
            static constexpr auto _T_ESCAPE_TYPE{ static_cast<unsigned int>(0x200) };            // 转义符类型 "nrtbfu\\"
            static constexpr auto _T_HEX{ static_cast<unsigned int>(0x400) };                    // \u之后UTF16的4字符HEX,"abcdefABCDEF"
            static constexpr auto _T_NUMBER{ static_cast<unsigned int>(0x800) };                // 数字"0-9"
            static constexpr auto _T_E{ static_cast<unsigned int>(0x1000) };                    // 科学计数法 e或E
            static constexpr auto _T_NEGATIVE{ static_cast<unsigned int>(0x2000) };            // 负数 -
            static constexpr auto _T_BOOL{ static_cast<unsigned int>(0x4000) };                // true false
            static constexpr auto _T_BOOL_BEGIN{ static_cast<unsigned int>(0x8000) };            // t f
            static constexpr auto _T_NEXT{ static_cast<unsigned int>(0x10000) };                // ,
            static constexpr auto _T_DECIMAL{ static_cast<unsigned int>(0x20000) };            // 小数点 .
            static constexpr auto _T_NULL{ static_cast<unsigned int>(0x40000) };                // null
            static constexpr auto _T_NULL_BEGIN{ static_cast<unsigned int>(0x80000) };            // n
            static constexpr auto _T_POSITIVE{ static_cast<unsigned int>(0x100000) };                // +
        }


        static constexpr auto _jnf{ static_cast<jsize_t>(-1) };


        template<typename _Ty> class _json_parser;

        class _jts_base {
        public:
            _jts_base() {
                text = nullptr;
            }

            void init(const char *_Text, int _Size) {
                text = _Text;
                size = _Size;
                instr = false;
                flags = 0;
                index = 0;
            }

            jsize_t open_instr() {
                instr = true;
                jsize_t _Result = flags;
                flags = 0;
                return _Result;
            }

            void close_instr(jsize_t _Flags) {
                instr = false;
                flags = _Flags;
            }

            jsize_t set_flags(jsize_t _Flags) {
                auto _Result = flags;
                flags = _Flags;
                return _Result;
            }

            long subhextol(int left, int len) {
                long _Result = 0;
                int rlen = len;
                for (int i = 0; i < len; i++) {
                    char c = text[--rlen];
                    long _Tmp;
                    switch (c) {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        _Tmp = c - '0';
                        break;
                    case 'a':
                    case 'b':
                    case 'c':
                    case 'd':
                    case 'e':
                    case 'f':
                        _Tmp = c - 'a' + 10;
                        break;
                    case 'A':
                    case 'B':
                    case 'C':
                    case 'D':
                    case 'E':
                    case 'F':
                        _Tmp = c - 'A' + 10;
                        break;
                    default:
                        return 0;
                    }
                    _Result += (_Tmp << (i << 2));
                }
                return _Result;
            }

        protected:
            const char *text;
            jsize_t size;
            unsigned int s;
            char c;
            unsigned char cl;
            bool instr;
            unsigned int flags;
            jsize_t index;
            std::string tmp;
        };

        class _jts_utf8 : public _jts_base
        {
        public:
            int operator++() {


                c = text[index];
                cl = utf8_char_len[(unsigned char)c];
                if (cl != 1) {
                    if (flags == JSON_SYNTAX::_T_ESCAPE_TYPE || !instr)
                        return -1;
                    do {
                        index += cl;
                        c = text[index];
                        cl = utf8_char_len[(unsigned char)c];
                    } while (cl != 1);
                }
                s = json_char_state[c];
                if (flags & s) {
                    index += cl;
                    return 0;
                }

                if (instr) {
                    if (s & JSON_SYNTAX::_T_ENDL)
                        return -1;

                    index += cl;
                    return 0;
                }

                return -1;
            }

        private:
            friend class _json_parser<_jts_utf8>;
        };

        class _jts_gbk : public _jts_base
        {
        public:
            int operator++() {
                c = text[index];
                cl = ((unsigned char)c & 0x80) ? 2 : 1;
                if (cl != 1) {
                    if (flags == JSON_SYNTAX::_T_ESCAPE_TYPE || !instr)
                        return -1;
                    do {
                        index += cl;
                        c = text[index];
                        cl = ((unsigned char)c & 0x80) ? 2 : 1;
                    } while (cl != 1);
                }
                s = json_char_state[c];
                if (flags & s) {
                    index += cl;
                    return 0;
                }

                if (instr) {
                    if (s & JSON_SYNTAX::_T_ENDL)
                        return -1;

                    index += cl;
                    return 0;
                }

                return -1;
            }

        private:
            friend class _json_parser<_jts_gbk>;
        };

        class _json_tree {
        public:
            class node {
            public:
                node() {
                    _Size = 0;
                    _Bgn = _Parent = _jnf;
                }

                node(jsize_t _Pa) {
                    _Size = 0;
                    _Parent = _Pa;
                    _Bgn = _jnf;
                }

                jsize_t size() {
                    return _Size;
                }

                jsize_t begin() {
                    return _Bgn;
                }

            private:
                friend class _json_parser<_jts_utf8>;
                friend class _json_parser<_jts_gbk>;
                friend class _json_tree;
                jsize_t _Size, _Bgn, _End, _Parent;
            };

            class var {
            public:

                var() {
                    Key = _jnf;
                    Next = _jnf;
                    Kty = 1;
                    Type = 0;
                }

                var(short _KTy, jsize_t _Key) {
                    Next = _jnf;
                    Kty = _KTy;
                    Key = _Key;
                    Type = 0;
                }

                var(short _KTy, jsize_t _Key, short
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
c++调用lua之HelloWorld发布时间:2022-07-22
下一篇:
lua方法点(.)调用和冒号(:)调用区别:发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap