⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apr_tables.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <stdio.h>/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * Resource allocation code... the code here is responsible for making * sure that nothing leaks. * * rst --- 4/95 --- 6/95 */#include "apr_private.h"#include "apr_general.h"#include "apr_pools.h"#include "apr_tables.h"#include "apr_strings.h"#include "apr_lib.h"#if APR_HAVE_STDLIB_H#include <stdlib.h>#endif#if APR_HAVE_STRING_H#include <string.h>#endif#if APR_HAVE_STRINGS_H#include <strings.h>#endif/***************************************************************** * This file contains array and apr_table_t functions only. *//***************************************************************** * * The 'array' functions... */static void make_array_core(apr_array_header_t *res, apr_pool_t *p,			    int nelts, int elt_size, int clear){    /*     * Assure sanity if someone asks for     * array of zero elts.     */    if (nelts < 1) {        nelts = 1;    }    if (clear) {        res->elts = apr_pcalloc(p, nelts * elt_size);    }    else {        res->elts = apr_palloc(p, nelts * elt_size);    }    res->pool = p;    res->elt_size = elt_size;    res->nelts = 0;		/* No active elements yet... */    res->nalloc = nelts;	/* ...but this many allocated */}APR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a){    return ((a == NULL) || (a->nelts == 0));}APR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p,						int nelts, int elt_size){    apr_array_header_t *res;    res = (apr_array_header_t *) apr_palloc(p, sizeof(apr_array_header_t));    make_array_core(res, p, nelts, elt_size, 1);    return res;}APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr){    if (apr_is_empty_array(arr)) {        return NULL;    }       return arr->elts + (arr->elt_size * (--arr->nelts));}APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr){    if (arr->nelts == arr->nalloc) {        int new_size = (arr->nalloc <= 0) ? 1 : arr->nalloc * 2;        char *new_data;        new_data = apr_palloc(arr->pool, arr->elt_size * new_size);        memcpy(new_data, arr->elts, arr->nalloc * arr->elt_size);        memset(new_data + arr->nalloc * arr->elt_size, 0,               arr->elt_size * (new_size - arr->nalloc));        arr->elts = new_data;        arr->nalloc = new_size;    }    ++arr->nelts;    return arr->elts + (arr->elt_size * (arr->nelts - 1));}static void *apr_array_push_noclear(apr_array_header_t *arr){    if (arr->nelts == arr->nalloc) {        int new_size = (arr->nalloc <= 0) ? 1 : arr->nalloc * 2;        char *new_data;        new_data = apr_palloc(arr->pool, arr->elt_size * new_size);        memcpy(new_data, arr->elts, arr->nalloc * arr->elt_size);        arr->elts = new_data;        arr->nalloc = new_size;    }    ++arr->nelts;    return arr->elts + (arr->elt_size * (arr->nelts - 1));}APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst,			       const apr_array_header_t *src){    int elt_size = dst->elt_size;    if (dst->nelts + src->nelts > dst->nalloc) {	int new_size = (dst->nalloc <= 0) ? 1 : dst->nalloc * 2;	char *new_data;	while (dst->nelts + src->nelts > new_size) {	    new_size *= 2;	}	new_data = apr_pcalloc(dst->pool, elt_size * new_size);	memcpy(new_data, dst->elts, dst->nalloc * elt_size);	dst->elts = new_data;	dst->nalloc = new_size;    }    memcpy(dst->elts + dst->nelts * elt_size, src->elts,	   elt_size * src->nelts);    dst->nelts += src->nelts;}APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p,						const apr_array_header_t *arr){    apr_array_header_t *res =        (apr_array_header_t *) apr_palloc(p, sizeof(apr_array_header_t));    make_array_core(res, p, arr->nalloc, arr->elt_size, 0);    memcpy(res->elts, arr->elts, arr->elt_size * arr->nelts);    res->nelts = arr->nelts;    memset(res->elts + res->elt_size * res->nelts, 0,           res->elt_size * (res->nalloc - res->nelts));    return res;}/* This cute function copies the array header *only*, but arranges * for the data section to be copied on the first push or arraycat. * It's useful when the elements of the array being copied are * read only, but new stuff *might* get added on the end; we have the * overhead of the full copy only where it is really needed. */static APR_INLINE void copy_array_hdr_core(apr_array_header_t *res,					   const apr_array_header_t *arr){    res->elts = arr->elts;    res->elt_size = arr->elt_size;    res->nelts = arr->nelts;    res->nalloc = arr->nelts;	/* Force overflow on push */}APR_DECLARE(apr_array_header_t *)    apr_array_copy_hdr(apr_pool_t *p,		       const apr_array_header_t *arr){    apr_array_header_t *res;    res = (apr_array_header_t *) apr_palloc(p, sizeof(apr_array_header_t));    res->pool = p;    copy_array_hdr_core(res, arr);    return res;}/* The above is used here to avoid consing multiple new array bodies... */APR_DECLARE(apr_array_header_t *)    apr_array_append(apr_pool_t *p,		      const apr_array_header_t *first,		      const apr_array_header_t *second){    apr_array_header_t *res = apr_array_copy_hdr(p, first);    apr_array_cat(res, second);    return res;}/* apr_array_pstrcat generates a new string from the apr_pool_t containing * the concatenated sequence of substrings referenced as elements within * the array.  The string will be empty if all substrings are empty or null, * or if there are no elements in the array. * If sep is non-NUL, it will be inserted between elements as a separator. */APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p,				     const apr_array_header_t *arr,				     const char sep){    char *cp, *res, **strpp;    apr_size_t len;    int i;    if (arr->nelts <= 0 || arr->elts == NULL) {    /* Empty table? */        return (char *) apr_pcalloc(p, 1);    }    /* Pass one --- find length of required string */    len = 0;    for (i = 0, strpp = (char **) arr->elts; ; ++strpp) {        if (strpp && *strpp != NULL) {            len += strlen(*strpp);        }        if (++i >= arr->nelts) {            break;	}        if (sep) {            ++len;	}    }    /* Allocate the required string */    res = (char *) apr_palloc(p, len + 1);    cp = res;    /* Pass two --- copy the argument strings into the result space */    for (i = 0, strpp = (char **) arr->elts; ; ++strpp) {        if (strpp && *strpp != NULL) {            len = strlen(*strpp);            memcpy(cp, *strpp, len);            cp += len;        }        if (++i >= arr->nelts) {            break;	}        if (sep) {            *cp++ = sep;	}    }    *cp = '\0';    /* Return the result string */    return res;}/***************************************************************** * * The "table" functions. */#if APR_CHARSET_EBCDIC#define CASE_MASK 0xbfbfbfbf#else#define CASE_MASK 0xdfdfdfdf#endif#define TABLE_HASH_SIZE 32#define TABLE_INDEX_MASK 0x1f#define TABLE_HASH(key)  (TABLE_INDEX_MASK & *(unsigned char *)(key))#define TABLE_INDEX_IS_INITIALIZED(t, i) ((t)->index_initialized & (1 << (i)))#define TABLE_SET_INDEX_INITIALIZED(t, i) ((t)->index_initialized |= (1 << (i)))/* Compute the "checksum" for a key, consisting of the first * 4 bytes, normalized for case-insensitivity and packed into * an int...this checksum allows us to do a single integer * comparison as a fast check to determine whether we can * skip a strcasecmp */#define COMPUTE_KEY_CHECKSUM(key, checksum)    \{                                              \    const char *k = (key);                     \    apr_uint32_t c = (apr_uint32_t)*k;         \    (checksum) = c;                            \    (checksum) <<= 8;                          \    if (c) {                                   \        c = (apr_uint32_t)*++k;                \        checksum |= c;                         \    }                                          \    (checksum) <<= 8;                          \    if (c) {                                   \        c = (apr_uint32_t)*++k;                \        checksum |= c;                         \    }                                          \    (checksum) <<= 8;                          \    if (c) {                                   \        c = (apr_uint32_t)*++k;                \        checksum |= c;                         \    }                                          \    checksum &= CASE_MASK;                     \}/** The opaque string-content table type */struct apr_table_t {    /* This has to be first to promote backwards compatibility with     * older modules which cast a apr_table_t * to an apr_array_header_t *...     * they should use the apr_table_elts() function for most of the     * cases they do this for.     */    /** The underlying array for the table */    apr_array_header_t a;#ifdef MAKE_TABLE_PROFILE    /** Who created the array. */    void *creator;#endif    /* An index to speed up table lookups.  The way this works is:     *   - Take the requested key and compute its checksum     *   - Hash the checksum into the index:     *     - index_first[TABLE_HASH(checksum)] is the offset within     *       the table of the first entry with that key checksum     *     - index_last[TABLE_HASH(checksum)] is the offset within     *       the table of the first entry with that key checksum     *   - If (and only if) there is no entry in the table whose     *     checksum hashes to index element i, then the i'th bit     *     of index_initialized will be zero.  (Check this before     *     trying to use index_first[i] or index_last[i]!)     */    apr_uint32_t index_initialized;    int index_first[TABLE_HASH_SIZE];    int index_last[TABLE_HASH_SIZE];};/* * NOTICE: if you tweak this you should look at is_empty_table()  * and table_elts() in alloc.h */#ifdef MAKE_TABLE_PROFILEstatic apr_table_entry_t *table_push(apr_table_t *t){    if (t->a.nelts == t->a.nalloc) {        return NULL;    }    return (apr_table_entry_t *) apr_array_push_noclear(&t->a);}#else /* MAKE_TABLE_PROFILE */#define table_push(t)	((apr_table_entry_t *) apr_array_push_noclear(&(t)->a))#endif /* MAKE_TABLE_PROFILE */APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t){    return (const apr_array_header_t *)t;}APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t){    return ((t == NULL) || (t->a.nelts == 0));}APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts){    apr_table_t *t = apr_palloc(p, sizeof(apr_table_t));    make_array_core(&t->a, p, nelts, sizeof(apr_table_entry_t), 0);#ifdef MAKE_TABLE_PROFILE    t->creator = __builtin_return_address(0);#endif    t->index_initialized = 0;    return t;}APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p, const apr_table_t *t){    apr_table_t *new = apr_palloc(p, sizeof(apr_table_t));#ifdef POOL_DEBUG    /* we don't copy keys and values, so it's necessary that t->a.pool     * have a life span at least as long as p     */    if (!apr_pool_is_ancestor(t->a.pool, p)) {	fprintf(stderr, "copy_table: t's pool is not an ancestor of p\n");	abort();    }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -