jk_map.c

来自「以便Apache与其他服务进行整合 Mod_JK安装」· C语言 代码 · 共 855 行 · 第 1/2 页

C
855
字号
/* *  Licensed to the Apache Software Foundation (ASF) under one or more *  contributor license agreements.  See the NOTICE file distributed with *  this work for additional information regarding copyright ownership. *  The ASF licenses this file to You 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. *//*************************************************************************** * Description: General purpose map object                                 * * Author:      Gal Shachor <shachor@il.ibm.com>                           * * Author:      Mladen Turk <mturk@apache.org>                             * * Version:     $Revision: 550239 $                                          * ***************************************************************************/#if defined(AS400) && !defined(AS400_UTF8)#include "apr_xlate.h"#endif#include "jk_global.h"#include "jk_pool.h"#include "jk_util.h"#include "jk_map.h"#define CAPACITY_INC_SIZE   (50)#define LENGTH_OF_LINE      (8192)#define JK_MAP_RECURSION    (20)#define JK_MAP_REFERENCE    (".reference")#define JK_MAP_REFERENCE_SZ (strlen(JK_MAP_REFERENCE))/* Compute the "checksum" for a key, consisting of the first * 4 bytes, 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 strcmp */#define COMPUTE_KEY_CHECKSUM(key, checksum)    \{                                              \    const char *k = (key);                     \    unsigned int c = (unsigned int)*k;         \    (checksum) = c;                            \    (checksum) <<= 8;                          \    if (c) {                                   \        c = (unsigned int)*++k;                \        checksum |= c;                         \    }                                          \    (checksum) <<= 8;                          \    if (c) {                                   \        c = (unsigned int)*++k;                \        checksum |= c;                         \    }                                          \    (checksum) <<= 8;                          \    if (c) {                                   \        c = (unsigned int)*++k;                \        checksum |= c;                         \    }                                          \}struct jk_map{    jk_pool_t p;    jk_pool_atom_t buf[SMALL_POOL_SIZE];    const char **names;    const void **values;    unsigned int *keys;    unsigned int capacity;    unsigned int size;};static void trim_prp_comment(char *prp);static size_t trim(char *s);static int map_realloc(jk_map_t *m);int jk_map_alloc(jk_map_t **m){    if (m) {        return jk_map_open(*m = (jk_map_t *)malloc(sizeof(jk_map_t)));    }    return JK_FALSE;}int jk_map_free(jk_map_t **m){    int rc = JK_FALSE;    if (m && *m) {        jk_map_close(*m);        free(*m);        *m = NULL;    }    return rc;}int jk_map_open(jk_map_t *m){    int rc = JK_FALSE;    if (m) {        jk_open_pool(&m->p, m->buf, sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE);        m->capacity = 0;        m->size = 0;        m->keys  = NULL;        m->names = NULL;        m->values = NULL;        rc = JK_TRUE;    }    return rc;}int jk_map_close(jk_map_t *m){    int rc = JK_FALSE;    if (m) {        jk_close_pool(&m->p);        rc = JK_TRUE;    }    return rc;}void *jk_map_get(jk_map_t *m, const char *name, const void *def){    const void *rc = (void *)def;    if (m && name) {        unsigned int i;        unsigned int key;        COMPUTE_KEY_CHECKSUM(name, key)        for (i = 0; i < m->size; i++) {            if (m->keys[i] == key && strcmp(m->names[i], name) == 0) {                rc = m->values[i];                break;            }        }    }    return (void *)rc;          /* DIRTY */}int jk_map_get_id(jk_map_t *m, const char *name){    int rc = -1;    if (m && name) {        unsigned int i;        unsigned int key;        COMPUTE_KEY_CHECKSUM(name, key)        for (i = 0; i < m->size; i++) {            if (m->keys[i] == key && strcmp(m->names[i], name) == 0) {                rc = i;                break;            }        }    }    return rc;}const char *jk_map_get_string(jk_map_t *m, const char *name, const char *def){    const char *rc = def;    if (m && name) {        unsigned int i;        unsigned int key;        COMPUTE_KEY_CHECKSUM(name, key)        for (i = 0; i < m->size; i++) {            if (m->keys[i] == key && strcmp(m->names[i], name) == 0) {                rc = m->values[i];                break;            }        }    }    return rc;}int jk_map_get_int(jk_map_t *m, const char *name, int def){    char buf[100];    const char *rc;    size_t len;    int int_res;    int multit = 1;    sprintf(buf, "%d", def);    rc = jk_map_get_string(m, name, buf);    len = strlen(rc);    if (len) {        char *lastchar = &buf[0] + len - 1;        strcpy(buf, rc);        if ('m' == *lastchar || 'M' == *lastchar) {            *lastchar = '\0';            multit = 1024 * 1024;        }        else if ('k' == *lastchar || 'K' == *lastchar) {            *lastchar = '\0';            multit = 1024;        }        int_res = atoi(buf);    }    else        int_res = def;    return int_res * multit;}double jk_map_get_double(jk_map_t *m, const char *name, double def){    char buf[100];    const char *rc;    sprintf(buf, "%f", def);    rc = jk_map_get_string(m, name, buf);    return atof(rc);}int jk_map_get_bool(jk_map_t *m, const char *name, int def){    char buf[100];    const char *rc;    sprintf(buf, "%d", def);    rc = jk_map_get_string(m, name, buf);    return jk_get_bool_code(rc, def);}char **jk_map_get_string_list(jk_map_t *m,                              const char *name,                              unsigned int *list_len, const char *def){    const char *l = jk_map_get_string(m, name, def);    char **ar = NULL;#ifdef _REENTRANT    char *lasts;#endif    *list_len = 0;    if (l) {        unsigned capacity = 0;        unsigned idex = 0;        char *p;        char *v = jk_pool_strdup(&m->p, l);        if (!v) {            return NULL;        }        /*         * GS, in addition to VG's patch, we now need to         * strtok also by a "*"         */#ifdef _REENTRANT        for (p = strtok_r(v, " \t,", &lasts);             p; p = strtok_r(NULL, " \t,", &lasts))#else        for (p = strtok(v, " \t,"); p; p = strtok(NULL, " \t,"))#endif        {            if (idex == capacity) {                ar = jk_pool_realloc(&m->p,                                     sizeof(char *) * (capacity + 5),                                     ar, sizeof(char *) * capacity);                if (!ar) {                    return JK_FALSE;                }                capacity += 5;            }            ar[idex] = jk_pool_strdup(&m->p, p);            idex++;        }        *list_len = idex;    }    return ar;}int jk_map_get_int_list(jk_map_t *m,                        const char *name,                        int *list,                        unsigned int list_len,                        const char *def){    const char *l = jk_map_get_string(m, name, def);#ifdef _REENTRANT    char *lasts;#endif    if (!list_len)        return 0;    if (l) {        unsigned int capacity = list_len;        unsigned int index = 0;        char *p;        char *v = jk_pool_strdup(&m->p, l);        if (!v) {            return 0;        }        /*         * GS, in addition to VG's patch, we now need to         * strtok also by a "*"         */#ifdef _REENTRANT        for (p = strtok_r(v, " \t,", &lasts);             p; p = strtok_r(NULL, " \t,", &lasts))#else        for (p = strtok(v, " \t,"); p; p = strtok(NULL, " \t,"))#endif        {            if (index < capacity) {                list[index] = atoi(p);                index++;            }            else                break;        }        return index;    }    return 0;}int jk_map_add(jk_map_t *m, const char *name, const void *value){    int rc = JK_FALSE;    if (m && name) {        unsigned int key;        COMPUTE_KEY_CHECKSUM(name, key)        map_realloc(m);        if (m->size < m->capacity) {            m->values[m->size] = value;            m->names[m->size] = jk_pool_strdup(&m->p, name);            m->keys[m->size] = key;            m->size++;            rc = JK_TRUE;        }    }    return rc;}int jk_map_put(jk_map_t *m, const char *name, const void *value, void **old){    int rc = JK_FALSE;    if (m && name) {        unsigned int i;        unsigned int key;        COMPUTE_KEY_CHECKSUM(name, key)        for (i = 0; i < m->size; i++) {            if (m->keys[i] == key && strcmp(m->names[i], name) == 0) {                break;            }        }        if (i < m->size) {            if (old)                *old = (void *)m->values[i];        /* DIRTY */            m->values[i] = value;            rc = JK_TRUE;        }        else {            rc = jk_map_add(m, name, value);        }    }    return rc;}static int jk_map_validate_property(char *prp, jk_logger_t *l){    int off = (int)strlen(prp) - (int)JK_MAP_REFERENCE_SZ;    /* check the worker properties */    if (off <= 0 || strncmp(&prp[off], JK_MAP_REFERENCE, JK_MAP_REFERENCE_SZ) ) {        if (!jk_is_valid_property(prp)) {            jk_log(l, JK_LOG_ERROR,                   "The attribute '%s' is not supported - please check"                   " the documentation for the supported attributes.",                   prp);            return JK_FALSE;        }        if (jk_is_deprecated_property(prp)) {            jk_log(l, JK_LOG_WARNING,                   "The attribute '%s' is deprecated - please check"                   " the documentation for the correct replacement.",                   prp);        }    }    return JK_TRUE;}static int jk_map_handle_duplicates(jk_map_t *m, const char *prp, char **v,                                    int treatment, jk_logger_t *l){    const char *oldv = jk_map_get_string(m, prp, NULL);    if (oldv) {        if ((treatment == JK_MAP_HANDLE_DUPLICATES)            && jk_is_unique_property(prp) == JK_FALSE) {            char *tmpv = jk_pool_alloc(&m->p,

⌨️ 快捷键说明

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