1
0
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:
dmiller
2022-09-16 01:10:20 +00:00
parent b7c76ea08a
commit 631d163fb2
2 changed files with 52 additions and 54 deletions

View File

@@ -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));
} }

View File

@@ -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