nginx源码分析 –数据类型

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 nginx源码分析 –数据类型,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

1.数据类型

1.1基本数据

Nginx主要使用了三个标准整数类型: size_t、 u_char和off_t。

size_t用于计算数据的长度,是C/C++标准里定义的一个类型,是 sizeof 操作符的结果类型,相当于unsigned_long。在64位的系统里宽度是8字节:

u_char表示一个字节,虽然它也是一个标准整数类型,但并不是C/C++标准,而是“系统标准”,是在<sys/types.h>里的一个typedef:

typedef unsigned char u_char

1.2自定义

Nginx依据C/C++标准重新定义了三个整数类型来代替标准里的int/long 等类型,编译都能获得一致的结果。这些类型是:


typedef intptr_t        ngx_int_t;
typedef uintptr_t       ngx_uint_t;
typedef intptr_t        ngx_flag_t;

 还有很多在其他模块。

我们在开发 Nginx 块编写代码时应该尽量使用这些 Nginx 专有的整数类型,不仅是为

了与 Ngin 保持风格的一致,更重要的是保证代码的跨平台兼容

1.3无效值

变量的初始化是编程语言里一个重要但又常常会被忽略的问题。在C/C++中,整数类型属于POD类型,初始值是“未定义”的,也就是说初始值可能是任意数值,存在安全隐患。
Lua/Python等语言有Nil/None 的概念,一个变量如果未初始化,那么它的值就是Nil或者None。Nginx采用了类似思路的“UNSET”值,使用“-1”表示未初始化。
由于C/C++是强类型语言,单纯的整数-1不能直接与其他类型比较,需要做类型转换,所以Nginx为-1定义了不同类型转换的宏:
#define NGX_CONF_UNSET       -1                    //通用无效值
#define NGX_CONF_UNSET_UINT  (ngx_uint_t) -1       //无符号整数
#define NGX_CONF_UNSET_PTR   (void *) -1           //指针
#define NGX_CONF_UNSET_SIZE  (size_t) -1          //size_t 类型的无效值
#define NGX_CONF_UNSET_MSEC  (ngx_msec_t) -1      //毫秒的无效值



#define ngx_conf_init_value(conf, default)                                   \
    if (conf == NGX_CONF_UNSET) {                                            \
        conf = default;                                                      \
    }

#define ngx_conf_init_ptr_value(conf, default)                               \
    if (conf == NGX_CONF_UNSET_PTR) {                                        \
        conf = default;                                                      \
    }

#define ngx_conf_init_uint_value(conf, default)                              \
    if (conf == NGX_CONF_UNSET_UINT) {                                       \
        conf = default;                                                      \
    }

#define ngx_conf_init_size_value(conf, default)                              \
    if (conf == NGX_CONF_UNSET_SIZE) {                                       \
        conf = default;                                                      \
    }

#define ngx_conf_init_msec_value(conf, default)                              \
    if (conf == NGX_CONF_UNSET_MSEC) {                                       \
        conf = default;                                                      \
    }

2.c++封装数据类型

2.1封装无效值

class NgxUnsetValue final
{
    public:
    template<typename T>
    operator T()const
    {
        return static_cast<T>(-1);
    }
    //指针和整数之间的转换
    template<typename T>
    operator T*()const
    {
        return reinterpret_cast<T*>(-1);
    }
    //
    //NgxUnsetvalue应该是个单件
    //,可以实现一个静态成员函数
    //,提供一个全局访问点:
    public:
    static const NgxUnsetValue&get()
    {
        static NgxUnsetValue const v={};//空类
        return v;
    }
    
} ;

解析1

1.首先利用模板技术比宏安全(建议参考这篇文章宏与模板的区分)实现了任意封装类型的无效值。

2.NgxUnsetvalue应该是个单件,可以实现一个静态成员函数,提供一个全局访问点:

auto &&ngx_nil=NgxUnsetValue::get()

2.2操作函数封装

2.1.1判断是否无效

    public:
    template<typename T,typename ... Args>
    static void unset(T&v,Args ... arg)
    {
        v=NgxUnsetValue::get();
        unset(arg...);
    }
    void unset(){};
    public:
    template<typename T>
    static bool invaild(const T&v)
    {
        return v==static_cast<T>(NgxUnsetValue::get());
    }
    template<typename T,typename U>
    static void init(T&x,const U&v)
    {
        if(invaild(x))
        {
            return x=v;
        }
    }

    public:
    template<typename T,typename U,typename V>
    static void merge(T&c,const U&p,const V&d)
    {
        if(invaild(c))
        {
            c=invaild(p)?d:p;
        }
    }

思想

1.先判断是否为有效值

2.采用参数系列,使用递归来判断多个值;

3.单个值是否有效,在初始化一个值

4.一个值是否有效,再初始化两个值

2.2.2重载

 namespace cwr {
        auto &&ngx_nil=NgxUnsetValue::get();
    };
    template <typename T>
    bool operator==(const T&x,const NgxUnsetValue&)
    {
        return NgxValue::invalid(x);
    }
    template<class T>
    bool operator!=(const T&x,const NgxUnsetValue&)
    {
        return !NgxValue::invaild(x);
    }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129640.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!