Nginx——1

  • ngx_str_t定义

ngx_str_t是nginx中定义的类似于字符串的结构,其中包含了字符串的长度(不包含终止字符'\0')以及字符串的首地址,数据结构定义如下:

  1. typedef struct {  
  2.     size_t      len;  
  3.     u_char     *data;  
  4. } ngx_str_t;  
细心的人都会觉得,以首地址的方式指向一块内存,如果在改变ngx_str_t定义的字符串的时候,可能会出错。因为它指向的是一块内存的首地址,如果改变字符串内容,有可能使得指向内存的区域进入到别的字符串的区域,这样就会出现差错。所以,对于ngx_str_t最好的方式是以只读的方式进行。


  • 操作函数

1、初始化或赋值函数

  1. #define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }  
  2. #define ngx_null_string     { 0, NULL }  
  3. #define ngx_str_set(str, text)                                               \  
  4.     (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text  
  5. #define ngx_str_null(str)   (str)->len = 0; (str)->data = NULL  

  • ngx_string(str)用于接受一个常量字符串数据,然后将该字符串的长度以及首地址传给ngx_str_t的结构体。
  • ngx_null_string定义一个字符长度为0的结构体
  • ngx_str_set用于将结构体ngx_str_t的长度以及首地址赋值为text的长度以及首地址。
  • ngx_str_null(null)用于将结构体ngx_str_t初始化为长度为0,首地址为空的初始序列。
  • ngx_str_set传入的是结构体的地址,因为下面的引用成员变量的方式是以指针的方式进行的,ngx_str_null亦是如此。

  1. ngx_str_t s1=ngx_null_string;  
  2. ngx_str_t s2=ngx_string("hello nginx");  
  3. ngx_str_set(&s2,"hello again hello");  
  4. ngx_str_null(&s2);  

2、字符处理函数

很多是封装的c下面的string.h文件中的函数:

  1. #define ngx_tolower(c)      (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)    //转小写字符  
  2. #define ngx_toupper(c)      (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)  //转大写字符  
  3. void ngx_strlow(u_char *dst, u_char *src, size_t n);           //从src复制n个字符到dst中,同时将相应的字符转为小写字符  
  4. #define ngx_strncmp(s1, s2, n)  strncmp((const char *) s1, (const char *) s2, n)  //字符比较函数,只比较前面n个字符,大小写敏感  
  5. #define ngx_strcmp(s1, s2)  strcmp((const char *) s1, (const char *) s2)            //字符比较函数,一直到某个字符的终止位置,大小写敏感  
  6. #define ngx_strstr(s1, s2)  strstr((const char *) s1, (const char *) s2)             //查找子串  
  7. #define ngx_strlen(s)       strlen((const char *) s)                               //计算字符穿长度  
  8. #define ngx_strchr(s1, c)   strchr((const char *) s1, (int) c)                      //第一次出现c的位置  


自定义函数:

比较函数:

  1. ngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);  
  2. ngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n);  //以上两个函数类似与ngx_strcmp,ngx_strncmp,大小写不敏感  

格式打印函数:

  1. u_char * ngx_cdecl ngx_sprintf(u_char *buf, const char *fmt, ...);  
  2. u_char * ngx_cdecl ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...);  
  3. u_char * ngx_cdecl ngx_slprintf(u_char *buf, u_char *last, const char *fmt,  

ngx_cdecl是一个宏定义,原型为_cdecl,表示函数的参数从从右到左依次入账,是默认的函数调用方法,用到这个是因为以上三个参数用到了省略号参数,参数个数是可变的。以ngx_snprintf为例进行讲解:

  1. u_char * ngx_cdecl  
  2. ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)  
  3. {  
  4.     u_char   *p;  
  5.     va_list   args;  
  6.   
  7.     va_start(args, fmt);  
  8.     p = ngx_vslprintf(buf, buf + max, fmt, args);  
  9.     va_end(args);  
  10.   
  11.     return p;  
  12. }  

对于 va_listva_start以及 va_end的讲解,请参考改博客内容: http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html对于可变参数列表,一般有以下几个步骤:
  • 在调用参数表之前,定义一个 va_list 类型的变量,(假设va_list 类型变量被定义为ap);
  •  然后应该对ap 进行初始化,让它指向可变参数表里面的第一个参数,这是通过 va_start 来实现的,第一个参数是 ap 本身,第二个参数是在变参表前面紧挨着的一个变量,即“...”之前的那个参数;
  • 然后是获取参数,调用va_arg,它的第一个参数是ap,第二个参数是要获取的参数的指定类型,然后返回这个指定类型的值,并且把 ap 的位置指向变参表的下一个变量位置;
  •  获取所有的参数之后,我们有必要将这个 ap 指针关掉,以免发生危险,方法是调用 va_end,他是输入的参数 ap 置为 NULL,应该养成获取完参数表之后关闭指针的习惯。说白了,就是让我们的程序具有健壮性。通常va_start和va_end是成对出

ngx_snprintf中,fmt是可变参数,我们都知道,printf里面会有"%d%d%s"这种类似的格式,那么这里的fmt也是一样的。ngx_snprintf的格式参数包含:

  1. /* 
  2.  * supported formats: 
  3.  *    %[0][width][x][X]O        off_t 
  4.  *    %[0][width]T              time_t 
  5.  *    %[0][width][u][x|X]z      ssize_t/size_t 
  6.  *    %[0][width][u][x|X]d      int/u_int 
  7.  *    %[0][width][u][x|X]l      long 
  8.  *    %[0][width|m][u][x|X]i    ngx_int_t/ngx_uint_t 
  9.  *    %[0][width][u][x|X]D      int32_t/uint32_t 
  10.  *    %[0][width][u][x|X]L      int64_t/uint64_t 
  11.  *    %[0][width|m][u][x|X]A    ngx_atomic_int_t/ngx_atomic_uint_t 
  12.  *    %[0][width][.width]f      double, max valid number fits to %18.15f 
  13.  *    %P                        ngx_pid_t 
  14.  *    %M                        ngx_msec_t 
  15.  *    %r                        rlim_t 
  16.  *    %p                        void * 
  17.  *    %V                        ngx_str_t * 
  18.  *    %v                        ngx_variable_value_t * 
  19.  *    %s                        null-terminated string 
  20.  *    %*s                       length and string 
  21.  *    %Z                        '\0' 
  22.  *    %N                        '\n' 
  23.  *    %c                        char 
  24.  *    %%                        % 
  25.  * 
  26.  *  reserved: 
  27.  *    %t                        ptrdiff_t 
  28.  *    %S                        null-terminated wchar string 
  29.  *    %C                        wchar 
  30.  */  


ngx_snprintf的函数实现的是:将ngx_str_t的内容格式化输出到buf里面,最后还是通过调用printf实现输出。最后返回的u_char *指针输出的最后位置。

以上三个函数都调用了函数:

  1. u_char *ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args);  
它是实现最终的格式化输出到buf的函数。


复制函数

  1. u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n);  
  2. u_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src);  


使用例子:

  1. #include <ngx_config.h>  
  2. #include <ngx_core.h>  
  3. #include<ngx_string.h>  
  4. int main(int args,char *argv[])  
  5. {  
  6.     u_char *p;  
  7.     ngx_str_t str = ngx_null_string;  
  8.     unsigned char buffer[1024];  
  9.     printf("str長度爲:%d\n",(int)str.len);   
  10.     ngx_str_set(&str,"hello world");                 //注意是&str而不是str  
  11.     p=ngx_snprintf(buffer, str.len, "%V", &str);   //注意是&str而不是str  
  12.     buffer[str.len]='\0';  
  13.     printf("格式化str輸出爲:%s\n",buffer);  
  14.     printf("格式化長度爲:%d\n",(int)((p-buffer)/sizeof(char)));   //p返回的是最後輸出的位置,所以由此可以得出最後格式化的字符個數  
  15.     return 1;  
  16. }  

转自:http://blog.csdn.net/mao19931004/article/details/54341062

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值