代码:
ngx_array_t * ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size) { ngx_array_t *a; a = ngx_palloc(p, sizeof(ngx_array_t)); if (a == NULL) { return NULL; } a->elts = ngx_palloc(p, n * size); if (a->elts == NULL) { return NULL; } a->nelts = 0; a->size = size; a->nalloc = n; a->pool = p; return a; }
他先分配一个ngx_array_t大小的空间给a
然后再分配一个 n*size大小的空间地址头给a中的elts这个指针.
然后更新a中的nelts为0
size为size
nalloc为n
pool为p
然后返回a这个指针地址.
先判断sc->flushes的指针和具体的数值是否为空.
然后就利用ngx_array_create为*sc->flushes这个指针分配内存地址.
接着判断sc-length是否为空,为空就调用ngx_array_create分配内存.
这里还搞不懂为啥n的大小为
代码:
sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) + sizeof(ngx_http_script_var_code_t)) + sizeof(uintptr_t)
后面也是同样的手法来分配sc->values的内存空间.
还是不理解为啥这时候n是
代码:
(sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) + sizeof(ngx_http_script_var_code_t)) + sizeof(uintptr_t) + sc->source->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)
然后重置了sc->variables的值为0
-------------------------------------
这里花点时间说一下sc里面的几个东西的赋值情况
首先
代码:
value = cf->args->elts;
这个cf->args->elts是一个指针类型,至于指向什么具体类型没有定义.
value被定义成指向 ngx_str_t 这样的指针,
而随后的
代码:
sc.source = &value[1]
表示 value是一个包含 ngx_str_t指针的数组,也就是说,在这个函数里
cf->args->elts是一个包含ngx_str_t的数组,上面的语法说明 sc.source被分赋值成了 数组的第二个元素(ngx_str_t类型的元素)
代码:
vars_lengths = NULL; vars_values = NULL;
表示var_lengths和vars_values都被初始化成null了.
代码:
sc.cf = cf; sc.source = &value[1]; sc.lengths = &vars_lengths; sc.values = &vars_values; sc.complete_lengths = 1; sc.complete_values = 1;
分别是 cf这个ngx_conf_t被复制给了sc.cf
sc.source上面介绍过了
sc.lengths和sc.values都被赋值给 指向 ngx_array_t 指针的指针了.
sc.complete_lengths和sc.complete_values都被初始化成1了.
--------------------------------------------------------------------
接着就是一个for循环对 source里面的ngx_str_t类型的数据进行解析.
这个for循环是一个不完整的条件循环
代码:
for (i = 0; i < sc->source->len; /* void */ )
他先判断data部分的第一个char是否为$,如果是,就 ++i 看看是否到字串的尾部了,
看具体代码:
代码:
if (++i == sc->source->len) { goto invalid_variable; }
这样就巧妙的在程序的主体部分进行了字串位置的偏移,而不是在for部分,奇怪的做法
如果到尾部,就goto到 invalid_variable 部分.
接着看.
接着就判断后面的部分是不是1-9,如果是1-9,就把sc->source->data[i] - '0' 后赋值给 n
这里减字符0的做法有点费解,都比较了字符了,为啥还要减字符0,为了确保变成整数么.暂时先这么想吧.
接着用几行代码做了mask码的操作,我还不了解具体的mask的含义,先记着.
代码:
if (sc->captures_mask & (1 << n)) { sc->dup_capture = 1; } sc->captures_mask |= 1 << n;
然后 调用了一个新的函数
代码:
ngx_http_script_add_code(*sc->lengths, sizeof(ngx_http_script_copy_capture_code_t), NULL);
其中 ngx_http_script_copy_capture_code_t 数据结构的内部是这样的.
代码:
typedef struct { ngx_http_script_code_pt code; uintptr_t n; } ngx_http_script_copy_capture_code_t;
先来看看这个新的函数 ngx_http_script_add_code
------------------------------------------------------------------------
因为调用它的时候,第三个参数为NULL,所以函数内部主要只是做了一个动作
代码:
new = ngx_array_push_n(codes, size);
来看看 ngx_array_push_n 的内容...
首先他先计算一下 外面传递进来的size个数,和 已经分配内存空间的 ngx_array_t->size的乘积.
然后他判断
代码:
if (a->nelts + n > a->nalloc)
是说判断未使用的是否够n
如果不够,就看看这个pool里面是否还有多余的空间
代码:
if ((u_char *) a->elts + a->size * a->nalloc == p->d.last && p->d.last + size <= p->d.end)
如果还有空间,就移动d.last到size位置的偏移量,然后更新a->nalloc
如果没有空间,就分配新的
代码:
new = ngx_palloc(p, nalloc * a->size);
最后调用ngx_memcpy
代码:
ngx_memcpy(new, a->elts, a->nelts * a->size);
ngx_memcpy实际上是一个宏
代码:
#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)
然后更新 a里对应值
代码:
a->elts = new; a->nalloc = nalloc;
这里有个问题,就是原来的内存空间就浪费了,而且没法free,因为pool是一个链表结构,没法free,而只能是覆盖写然后偏移a->elts为具体的已经分配的array的大小
代码:
elt = (u_char *) a->elts + a->size * a->nelts;
同时更新a->nelts