Nginx源码分析 - 基础数据结构篇 - 字符串结构 ngx_string.c(08)

简介:

       想要了解nginx,还需要从源码入手,在看代码的同时,抽离出其中具体的数据结构,并单独运行查看效果,字符串比较简单

一、数据结构定义
1. ngx_str_t 字符串结构

/**
 * 字符串结构
 */
typedef struct {
    size_t      len; //字符串长度
    u_char     *data; //具体的指针地址
} ngx_str_t;

2. ngx_keyval_t 字符串K V结构

下面这种结构主要用在如下配置中

/**
 * 字符串的K V结构
 */
typedef struct {
    ngx_str_t   key;
    ngx_str_t   value;
} ngx_keyval_t;

一、数据结构图

三、具体函数实现


1. 初始化一个字符串 ngx_string

//初始化一个字符串
#define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }

2. 设置字符串

//将一个字符串设置为NULL
#define ngx_null_string     { 0, NULL }
//设置一个字符串
#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

四、具体例子

代码目录结构:

 



/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>

#ifndef _NGX_STRING_H_INCLUDED_
#define _NGX_STRING_H_INCLUDED_

typedef struct {
    size_t      len;
    u_char     *data;
} ngx_str_t;


typedef struct {
    ngx_str_t   key;
    ngx_str_t   value;
} ngx_keyval_t;


typedef struct {
    unsigned    len:28;

    unsigned    valid:1;
    unsigned    no_cacheable:1;
    unsigned    not_found:1;
    unsigned    escape:1;

    u_char     *data;
} ngx_variable_value_t;


#define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string     { 0, NULL }
#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


#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)
#define ngx_strstr(s1, s2)  strstr((const char *) s1, (const char *) s2)
#define ngx_strlen(s)       strlen((const char *) s)


#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)

size_t ngx_strnlen(u_char *p, size_t n);

size_t ngx_strnlen(u_char *p, size_t n);
void ngx_strlow(u_char *dst, u_char *src, size_t n);
#endif /* _NGX_STRING_H_INCLUDED_ */



#include "nginx_string.h"


void ngx_strlow(u_char *dst, u_char *src, size_t n)
{
    while (n) {
        *dst = ngx_tolower(*src);
        dst++;
        src++;
        n--;
    }
}

// 求所给字符串的长度
size_t ngx_strnlen(u_char *p, size_t n)
{
    size_t  i;

    for (i = 0; i < n; i++) {

        if (p[i] == '\0') {
            return i;
        }
    }

    return n;
}



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "nginx_string.h"

int main()
{
    //1. 初始化
    ngx_str_t  name = ngx_string("deamon");
    printf("name->len:%ld, name->data:%s\n",name.len,name.data);
    //2. 初始化为空
    ngx_str_t  name1 = ngx_null_string;
    printf("name1->len:%ld, name1->data:%s\n",name1.len,name1.data);
    //3.  set函数赋值
    ngx_str_set(&name1, "hello alpha");
    printf("name1->len:%ld, name1->data:%s\n",name1.len,name1.data);
    //4.  设置为空
    ngx_str_null(&name1);
    printf("name1->len:%ld, name1->data:%s\n",name1.len,name1.data);
    //5.  单个字符转换为小写
    u_char c_l = 'L';  u_char c_h = 'H'; u_char c1; u_char c2;
    printf("c_l:%c,c_h:%c\n",c_l,c_h);
    c1 = ngx_tolower(c_l); c2 = ngx_tolower(c_h);
    printf("c_l:%c,c_h:%c\n",c1,c2);
    //6.  单个字符转换为大写   
    u_char cc_l = 'l';  u_char cc_h = 'h'; u_char cc1; u_char cc2;
    printf("c_l:%c,c_h:%c\n",cc_l,cc_h);
    cc1 = ngx_toupper(c_l); cc2 = ngx_toupper(c_h);
    printf("c_l:%c,c_h:%c\n",cc1,cc2);

    //7. 将大写转换为小写
    ngx_str_t  name3 = ngx_string("DEAMON");
    printf("name3->len:%ld, name3->data:%s\n",name3.len,name3.data);
    #define NGX_MAXHOSTNAMELEN  256
    char  hostname[NGX_MAXHOSTNAMELEN];
    if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
        printf("gethostname failed\n");
        return -1;
    }
    printf("origin-hostname:%s\n",hostname);
    hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
    ngx_str_t   str_hostname;
    size_t len = ngx_strlen(hostname);
    str_hostname.len =  len;
    str_hostname.data  = malloc(str_hostname.len);
    ngx_strlow(str_hostname.data, (u_char *) hostname, len);
    printf("str_hostname->len:%ld, str_hostname->data:%s\n",str_hostname.len,str_hostname.data);


    //8. 字符串比较 比较前n个  比较所有
    if( ngx_strncmp(str_hostname.data, "vm-0-17-ubuntu",3) == 0 ){
        printf("compare result  str_hostname.data:%s, vm-0-17-ubuntu,3  \n",str_hostname.data);
    }
    if(ngx_strcmp(str_hostname.data, "vm-0-17-ubuntu") == 0){
        printf("compare result  str_hostname.data:%s,vm-0-17-ubuntu \n",str_hostname.data);
    }


    //9.nginx中的字符数组 -- 中的k-v结构
    static ngx_keyval_t  ngx_http_scgi_cache_headers[] = {
    { ngx_string("HTTP_IF_MODIFIED_SINCE"),ngx_string("$upstream_cache_last_modified") },
    { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
    { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("$upstream_cache_etag") },
    { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
    { ngx_string("HTTP_RANGE"), ngx_string("") },
    { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
    { ngx_null_string, ngx_null_string }
    };
    for(size_t index = 0; index < sizeof(ngx_http_scgi_cache_headers)/sizeof(ngx_keyval_t); index ++){
            printf("index:%2ld | key->len:%2ld| key is %24s | value->len:%2ld | value is %24s\n",
            index,(ngx_http_scgi_cache_headers[index].key.len),
            (ngx_http_scgi_cache_headers[index].key.data),
            (ngx_http_scgi_cache_headers[index].value.len),
            (ngx_http_scgi_cache_headers[index].value.data));
    }





    free(str_hostname.data);
    return 0;
}

执行效果;

 

参考文章:

1.https://initphp.blog.csdn.net/article/details/50682163

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值