📄 jk_map.c
字号:
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* 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.
*/
/***************************************************************************
* Description: General purpose map object *
* Author: Gal Shachor <shachor@il.ibm.com> *
* Author: Mladen Turk <mturk@apache.org> *
* Version: $Revision: 300542 $ *
***************************************************************************/
#ifdef AS400
#include "apr_xlate.h"
#endif
#include "jk_global.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_map.h"
#include "jk_util.h"
#include "jk_shm.h"
#define CAPACITY_INC_SIZE (50)
#define LENGTH_OF_LINE (8192)
#ifdef AS400
#define CASE_MASK 0xbfbfbfbf
#else
#define CASE_MASK 0xdfdfdfdf
#endif
/* 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); \
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; \
} \
checksum &= CASE_MASK; \
}
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 && strcasecmp(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 && strcasecmp(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 && strcasecmp(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];
size_t len;
const char *rc;
int rv = 0;
sprintf(buf, "%d", def);
rc = jk_map_get_string(m, name, buf);
len = strlen(rc);
if (len) {
if (strcasecmp(rc, "true") == 0 ||
*rc == 'Y' || *rc == 'y' || *rc == '1') {
rv = 1;
}
}
return rv;
}
char **jk_map_get_string_list(jk_map_t *m,
const char *name,
unsigned *list_len, const char *def)
{
const char *l = jk_map_get_string(m, name, def);
char **ar = NULL;
#if defined(AS400) || defined(_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 "*"
*/
#if defined(AS400) || defined(_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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -