- typedef struct {
- size_t len;
- u_char *data;
- } ngx_str_t;
-
Nginx提供两个初始化函数宏:ngx_string()使用字符串初始化,ngx_null_string ()初始化为一个空字符串,因为它们使用了{...}的形式,所以只能用于赋值初始化:
- #define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
- #define ngx_null_string { 0, NULL }
设置内容:
运行时设置字符串内容可以使用下面两个函数宏,功能是相同的,注意参数str必须是指针:
- #define ngx_str_set(str, text) \
- (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
- #define ngx_str_null(str) (str)->len = 0; (str)->data = NULL
ngx_string ()和 ngx_str_set()内部使用了sizeof计算字符串长度,所以参数必须是一个编译期的字符串“字面值”,而不能是一个字符串指针,否则sizeof 会计算得到指针的长度(8字节),而不是字符串的实际长度。
用法示例:
- ngx_str_t s1=ngx_null_string;
- ngx_str_t s2=ngx_string("matrix");
-
- ngx_str_set(&s1,"reload");
- ngx_str_null(&s2);
转化大小写
- #define ngx_tolower(c) (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
- #define ngx_toupper(c) (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)
大小比较
ngx_str_t 只是个普通的字符串,所以标准的c字符串函数都能够使用(需要转型为const char*),处理它的data成员就可以了,但Nginx也实现了一些特有的操作函数。
下面是一些常用的字符串操作函数,但需要注意有的参数类型不是ngx_str_t,而是u _char* :
- #define ngx_strncmp(s1, s2, n) strncmp((const char *) s1, (const char *) s2, n)
-
-
- /* msvc and icc7 compile strcmp() to inline loop */
- #define ngx_strcmp(s1, s2) strcmp((const char *) s1, (const char *) s2)
-
-
- #define ngx_strstr(s1, s2) strstr((const char *) s1, (const char *) s2)
-
格式化函数
- _char * ngx_cdecl
- ngx_sprintf(u_char *buf, const char *fmt, ...)
- {
- u_char *p;
- va_list args;
-
- va_start(args, fmt);
- p = ngx_vslprintf(buf, (void *) -1, fmt, args);
- va_end(args);
-
- return p;
- }
- u_char * ngx_cdecl
- ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
- {
- u_char *p;
- va_list args;
-
- va_start(args, fmt);
- p = ngx_vslprintf(buf, buf + max, fmt, args);
- va_end(args);
-
- return p;
- }
-
-
- u_char * ngx_cdecl
- ngx_slprintf(u_char *buf, u_char *last, const char *fmt, ...)
- {
- u_char *p;
- va_list args;
-
- va_start(args, fmt);
- p = ngx_vslprintf(buf, last, fmt, args);
- va_end(args);
-
- return p;
- }
ngx_sprintf ( )直接向buf输出格式化内容,不检查缓冲区的有效性,存在缓冲区溢出危险,通常不建议使用。后两个函数比较安全,参数max和 last指明了缓冲区的结束位置,所以格式化的结果只会填满缓冲区为止。
- #define typed_ngx_string(str) ngx_str_t ngx_string(str)
- #define typed_ngx_null_string ngx_str_t ngx_null_string
-
-
- public:
- typedef NgxWrapper<ngx_str_t> super_type;
- typedef NgxString this_type;
-
- typedef boost::string_ref string_ref_type;
-
- public:
- NgxString(ngx_str_t& str):
- super_type(str)
- {}
-
- // enable convert const object
- NgxString(const ngx_str_t& str):
- super_type(const_cast<ngx_str_t&>(str))
- {}
-
- // disable temporary object
- NgxString(ngx_str_t&& str) = delete;
-
- ~NgxString() = default;
1.NgxWrapper相当于一个基本的模块类型(封装各种各样的数据结构)
2.有一个新特性 const_cast
:const_cast
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;
二、常量引用被转换成非常量的引用,并且仍然指向原来的对象;
三、const_cast一般用于修改底指针。如const char *p形式。
3. 有一个巧妙设计 NgxString(ngx_str_t&& str) = delete;
将对象转化成str!!!
- public:
- const char* data() const
- {
- return reinterpret_cast<const char*>(get()->data);
- }
-
- std::size_t size() const
- {
- return get()->len;
- }
-
- bool empty() const
- {
- return !get()->data || !get()->len;
- }
-
- string_ref_type str() const
- {
- return string_ref_type(data(), size());
- }
- }
- public:
- // nagetive means error
- operator ngx_int_t () const
- {
- return ngx_atoi(get()->data, get()->len);
- }
1.首先提供data()和size()提供访问
2.判断空和转换char-》int
- public:
- // range concept
- typedef u_char char_type;
- typedef u_char* iterator;
- typedef iterator const_iterator;
- typedef boost::iterator_difference
difference_type; - public:
- const_iterator begin() const
- {
- return get()->data;
- }
-
- const_iterator end() const
- {
- return get()->data + get()->len;
- }
-
- public:
- const char_type& front() const
- {
- return *begin();
- }
- const char_type& back() const
- {
- //return *std::prev(end());
- return *boost::prior(end());
- }
- public:
- bool contains(const this_type& x) const
- {
- return boost::contains(*this, x);
- }
1.理解u_char 和u_char*
1.指针传递,就是把改变的地址传过去了,你在第一个函数里修改里地址里的内容,所以a改变了
2.值传递,值传递只是拷贝了一份,作为参数,不影响原来的值
3.引用是原变量的一个别名,跟原来的变量实质上是同一个东西。
- int a = 996;
- int *p = &a; // p是指针, &在此是求地址运算
- int &r = a; // r是引用, &在此起标识作用
总结就是一个是返回变量值,一个是内存值
- public:
- template<typename T>
- friend T& operator<<(T& o, const this_type& s)
- {
- o.write(s.data(), s.size());
- return o;
- }
-
- public:
- template<typename T>
- friend T& operator<<(T& o, const this_type& s)
- {
- o.write(s.data(), s.size());
- return o;
- }
-
- template<typename T>
- friend T& operator<<(T& o, const ngx_str_t& s)
- {
- o.write(reinterpret_cast<const char*>(s.data), s.len);
- return o;
- }
-
- template<typename T>
- friend T& operator<<(T& o, const volatile ngx_str_t& s)
- {
- o.write(reinterpret_cast<const char*>(s.data), s.len);
- return o;
- }
-
-
- public:
- template<typename ... Args>
- void printf(const Args& ... args) const
- {
- auto p = ngx_snprintf(get()->data, get()->len, args ...);
- get()->len = static_cast
size_t>(p - get()->data); - }
- };
1.重载<<(c++cin<<)相似
2.重载两种类型
volatile的本意是“易变的”,volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
const就不多说啦
3.printf相同!!!借鉴啦上面的ngx_snprintf