blob: 9ff088460ca915adeac52281393a0182fe871e47 [file] [log] [blame]
/*
* 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: Simple memory pool *
* Author: Gal Shachor <shachor@il.ibm.com> *
* Version: $Revision$ *
***************************************************************************/
#include "jk_pool.h"
#define DEFAULT_DYNAMIC 10
static void *jk_pool_dyn_alloc(jk_pool_t *p,
size_t size);
void jk_open_pool(jk_pool_t *p,
jk_pool_atom_t *buf,
unsigned size)
{
p->pos = 0;
p->size = size;
p->buf = (char *)buf;
p->dyn_pos = 0;
p->dynamic = NULL;
p->dyn_size = 0;
}
void jk_close_pool(jk_pool_t *p)
{
if(p) {
jk_reset_pool(p);
if(p->dynamic) {
free(p->dynamic);
}
}
}
void jk_reset_pool(jk_pool_t *p)
{
if(p && p->dyn_pos && p->dynamic) {
unsigned i;
for(i = 0 ; i < p->dyn_pos ; i++) {
if(p->dynamic[i]) {
free(p->dynamic[i]);
}
}
}
p->dyn_pos = 0;
p->pos = 0;
}
void *jk_pool_alloc(jk_pool_t *p,
size_t size)
{
void *rc = NULL;
if(p && size > 0) {
/* Round size to the upper mult of 8 (or 16 on iSeries) */
size--;
#ifdef AS400
size /= 16;
size = (size + 1) * 16;
#else
size /= 8;
size = (size + 1) * 8;
#endif
if((p->size - p->pos) >= size) {
rc = &(p->buf[p->pos]);
p->pos += size;
} else {
rc = jk_pool_dyn_alloc(p, size);
}
}
return rc;
}
void *jk_pool_realloc(jk_pool_t *p,
size_t sz,
const void *old,
size_t old_sz)
{
void *rc;
if(!p || (!old && old_sz)) {
return NULL;
}
rc = jk_pool_alloc(p, sz);
if(rc) {
memcpy(rc, old, old_sz);
}
return rc;
}
void *jk_pool_strdup(jk_pool_t *p,
const char *s)
{
char *rc = NULL;
if(s && p) {
size_t size = strlen(s);
if(!size) {
return "";
}
size++;
rc = jk_pool_alloc(p, size);
if(rc) {
memcpy(rc, s, size);
}
}
return rc;
}
void jk_dump_pool(jk_pool_t *p,
FILE *f)
{
fprintf(f, "Dumping for pool [%x]\n", p);
fprintf(f, "size [%d]\n", p->size);
fprintf(f, "pos [%d]\n", p->pos);
fprintf(f, "buf [%x]\n", p->buf);
fprintf(f, "dyn_size [%d]\n", p->dyn_size);
fprintf(f, "dyn_pos [%d]\n", p->dyn_pos);
fprintf(f, "dynamic [%x]\n", p->dynamic);
fflush(f);
}
static void *jk_pool_dyn_alloc(jk_pool_t *p,
size_t size)
{
void *rc = NULL;
if(p->dyn_size == p->dyn_pos) {
unsigned new_dyn_size = p->dyn_size + DEFAULT_DYNAMIC;
void **new_dynamic = (void **)malloc(new_dyn_size * sizeof(void *));
if(new_dynamic) {
if(p->dynamic) {
memcpy(new_dynamic,
p->dynamic,
p->dyn_size * sizeof(void *));
free(p->dynamic);
}
p->dynamic = new_dynamic;
p->dyn_size = new_dyn_size;
} else {
return NULL;
}
}
rc = p->dynamic[p->dyn_pos] = malloc(size);
if(p->dynamic[p->dyn_pos]) {
p->dyn_pos ++;
}
return rc;
}