mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 12:41:29 +00:00
Object-oriented implementation of charpool
This commit is contained in:
87
charpool.cc
87
charpool.cc
@@ -63,6 +63,8 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "nbase.h"
|
#include "nbase.h"
|
||||||
|
|
||||||
@@ -70,77 +72,56 @@
|
|||||||
#include "charpool.h"
|
#include "charpool.h"
|
||||||
#include "nmap_error.h"
|
#include "nmap_error.h"
|
||||||
|
|
||||||
static char *charpool[16];
|
static CharPool g_charpool (16384);
|
||||||
static int currentcharpool;
|
|
||||||
static size_t currentcharpoolsz;
|
const char *cp_strndup(const char *src, int len) {
|
||||||
static size_t nexti;
|
return g_charpool.dup(src, len);
|
||||||
|
}
|
||||||
|
const char *cp_strdup(const char *src) {
|
||||||
|
return g_charpool.dup(src);
|
||||||
|
}
|
||||||
|
void cp_free(void) {
|
||||||
|
return g_charpool.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocated blocks are allocated to multiples of ALIGN_ON. This is the
|
/* Allocated blocks are allocated to multiples of ALIGN_ON. This is the
|
||||||
definition used by the malloc in Glibc 2.7, which says that it "suffices for
|
definition used by the malloc in Glibc 2.7, which says that it "suffices for
|
||||||
nearly all current machines and C compilers." */
|
nearly all current machines and C compilers." */
|
||||||
#define ALIGN_ON (2 * sizeof(size_t))
|
#define ALIGN_ON (2 * sizeof(size_t))
|
||||||
|
|
||||||
static int cp_init(void) {
|
CharPool::CharPool(size_t init_sz) {
|
||||||
static int charpool_initialized = 0;
|
assert(init_sz >= 256);
|
||||||
if (charpool_initialized) return 0;
|
|
||||||
|
|
||||||
/* Create our char pool */
|
/* Create our char pool */
|
||||||
currentcharpool = 0;
|
currentbucketsz = init_sz;
|
||||||
currentcharpoolsz = 16384;
|
|
||||||
nexti = 0;
|
nexti = 0;
|
||||||
charpool[0] = (char *) safe_malloc(currentcharpoolsz);
|
char *b = (char *) safe_malloc(currentbucketsz);
|
||||||
charpool_initialized = 1;
|
buckets.push_back(b);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cp_free(void) {
|
void CharPool::clear(void) {
|
||||||
int ccp;
|
for (BucketList::iterator it=buckets.begin(); it != buckets.end(); it++) {
|
||||||
for(ccp=0; ccp <= currentcharpool; ccp++)
|
free(*it);
|
||||||
if(charpool[ccp]){
|
|
||||||
free(charpool[ccp]);
|
|
||||||
charpool[ccp] = NULL;
|
|
||||||
}
|
}
|
||||||
currentcharpool = 0;
|
buckets.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cp_grow(void) {
|
const char *CharPool::dup(const char *src, int len) {
|
||||||
/* Doh! We've got to make room */
|
int sz = len < 0 ? strlen(src) : len;
|
||||||
if (++currentcharpool > 15) {
|
char *p = buckets.back() + nexti;
|
||||||
fatal("Character Pool is out of buckets!");
|
|
||||||
}
|
|
||||||
currentcharpoolsz <<= 1;
|
|
||||||
|
|
||||||
nexti = 0;
|
|
||||||
charpool[currentcharpool] = (char *) safe_malloc(currentcharpoolsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *cp_alloc(int sz) {
|
|
||||||
char *p;
|
|
||||||
int modulus;
|
int modulus;
|
||||||
|
|
||||||
cp_init();
|
|
||||||
|
|
||||||
if ((modulus = sz % ALIGN_ON))
|
if ((modulus = sz % ALIGN_ON))
|
||||||
sz += ALIGN_ON - modulus;
|
sz += ALIGN_ON - modulus;
|
||||||
|
|
||||||
if (nexti + sz <= currentcharpoolsz) {
|
while (nexti + sz > currentbucketsz) {
|
||||||
p = charpool[currentcharpool] + nexti;
|
/* Doh! We've got to make room */
|
||||||
nexti += sz;
|
currentbucketsz <<= 1;
|
||||||
return p;
|
nexti = 0;
|
||||||
|
p = (char *) safe_malloc(currentbucketsz);
|
||||||
|
buckets.push_back(p);
|
||||||
}
|
}
|
||||||
/* Doh! We've got to make room */
|
|
||||||
cp_grow();
|
|
||||||
|
|
||||||
return cp_alloc(sz);
|
|
||||||
|
|
||||||
}
|
nexti += sz;
|
||||||
|
p[sz] = '\0';
|
||||||
const char *cp_strndup(const char *src, int len) {
|
return (const char *) memcpy(p, src, sz);
|
||||||
char *dst = (char *) cp_alloc(len + 1); // Additional byte for null terminator
|
|
||||||
dst[len] = '\0';
|
|
||||||
return (const char *) memcpy(dst, src, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *cp_strdup(const char *src) {
|
|
||||||
return cp_strndup(src, strlen(src));
|
|
||||||
}
|
}
|
||||||
|
|||||||
19
charpool.h
19
charpool.h
@@ -65,12 +65,29 @@
|
|||||||
#ifndef CHARPOOL_H
|
#ifndef CHARPOOL_H
|
||||||
#define CHARPOOL_H
|
#define CHARPOOL_H
|
||||||
|
|
||||||
void *cp_alloc(int sz);
|
#include <vector>
|
||||||
|
|
||||||
/* len does not include null terminator */
|
/* len does not include null terminator */
|
||||||
const char *cp_strndup(const char *src, int len);
|
const char *cp_strndup(const char *src, int len);
|
||||||
const char *cp_strdup(const char *src);
|
const char *cp_strdup(const char *src);
|
||||||
|
|
||||||
void cp_free(void);
|
void cp_free(void);
|
||||||
|
|
||||||
|
typedef std::vector<char *> BucketList;
|
||||||
|
|
||||||
|
class CharPool {
|
||||||
|
private:
|
||||||
|
BucketList buckets;
|
||||||
|
size_t currentbucketsz;
|
||||||
|
size_t nexti;
|
||||||
|
public:
|
||||||
|
CharPool(size_t init_sz=256);
|
||||||
|
~CharPool() { this->clear(); }
|
||||||
|
// Free all allocated buckets
|
||||||
|
void clear();
|
||||||
|
// if len < 0, strlen will be used to determine src length
|
||||||
|
const char *dup(const char *src, int len=-1);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user