text: 
  /*
   * Copyright (C) Igor Sysoev
   * Copyright (C) Nginx, Inc.
   */
  
  
  #include <ngx_config.h>
  #include <ngx_core.h>
  
  
  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;
      }
  
      if (ngx_array_init(a, p, n, size) != NGX_OK) {
          return NULL;
      }
  
      return a;
  }
  
  
  void
  ngx_array_destroy(ngx_array_t *a)
  {
      ngx_pool_t  *p;
  
      p = a->pool;
  
      if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
          p->d.last -= a->size * a->nalloc;
      }
  
      if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
          p->d.last = (u_char *) a;
      }
  }
  
  
  void *
  ngx_array_push(ngx_array_t *a)
  {
      void        *elt, *new;
      size_t       size;
      ngx_pool_t  *p;
  
      if (a->nelts == a->nalloc) { //数据空间已满
  
          /* the array is full */
  
          size = a->size * a->nalloc;
  
          p = a->pool;
  
          //当前数组位于内存池最尾部，且内存池足够分配一个新元素空间
          if ((u_char *) a->elts + size == p->d.last
              && p->d.last + a->size <= p->d.end)
          {
              /*
               * the array allocation is the last in the pool
               * and there is space for new allocation
               */
  
              p->d.last += a->size;
              a->nalloc++;
  
          } else { 
              /* allocate a new array */
              //将数组容量扩大一倍
              new = ngx_palloc(p, 2 * size);
              if (new == NULL) {
                  return NULL;
              }
              //将旧数组的元素copy到新数组中
              ngx_memcpy(new, a->elts, size);
              a->elts = new;
              a->nalloc *= 2;
          }
      }
      //获取新元素的地址
      elt = (u_char *) a->elts + a->size * a->nelts;
      //数组元素个数+1
      a->nelts++;
  
      return elt;
  }
  
  
  void *
  ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
  {
      void        *elt, *new;
      size_t       size;
      ngx_uint_t   nalloc;
      ngx_pool_t  *p;
  
      size = n * a->size;
  
      if (a->nelts + n > a->nalloc) {
  
          /* the array is full */
  
          p = a->pool;
  
          if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
              && p->d.last + size <= p->d.end)
          {
              /*
               * the array allocation is the last in the pool
               * and there is space for new allocation
               */
  
              p->d.last += size;
              a->nalloc += n;
  
          } else {
              /* allocate a new array */
  
              nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
  
              new = ngx_palloc(p, nalloc * a->size);
              if (new == NULL) {
                  return NULL;
              }
  
              ngx_memcpy(new, a->elts, a->nelts * a->size);
              a->elts = new;
              a->nalloc = nalloc;
          }
      }
  
      elt = (u_char *) a->elts + a->size * a->nelts;
      a->nelts += n;
  
      return elt;
  }
  