mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
optimize dns_rdatatype_fromtext()
This commit is contained in:
108
lib/dns/gen.c
108
lib/dns/gen.c
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: gen.c,v 1.38 2000/04/19 18:33:09 explorer Exp $ */
|
||||
/* $Id: gen.c,v 1.39 2000/04/25 19:09:06 explorer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -136,6 +136,7 @@ struct ttnam {
|
||||
char typename[11];
|
||||
char macroname[11];
|
||||
char attr[256];
|
||||
unsigned int sorted;
|
||||
} typenames[256];
|
||||
|
||||
char * upper(char *);
|
||||
@@ -318,6 +319,7 @@ insert_into_typenames(int type, char *typename, char *attr)
|
||||
exit(1);
|
||||
}
|
||||
strcpy(ttn->attr, attr);
|
||||
ttn->sorted = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -420,6 +422,19 @@ sd(int rdclass, char *classname, char *dirname, char filetype) {
|
||||
end_directory(&dir);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
HASH(char *string)
|
||||
{
|
||||
unsigned int n;
|
||||
unsigned char a, b;
|
||||
|
||||
n = strlen(string);
|
||||
a = tolower(string[0]);
|
||||
b = tolower(string[n - 1]);
|
||||
|
||||
return ((a + n) * b) % 256;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
char buf[256]; /* XXX Should be max path length */
|
||||
@@ -428,7 +443,8 @@ main(int argc, char **argv) {
|
||||
char classname[11];
|
||||
struct tt *tt;
|
||||
struct cc *cc;
|
||||
struct ttnam *ttn;
|
||||
struct ttnam *ttn, *ttn2;
|
||||
unsigned int hash;
|
||||
struct tm *tm;
|
||||
time_t now;
|
||||
char year[11];
|
||||
@@ -437,7 +453,7 @@ main(int argc, char **argv) {
|
||||
int class_enum = 0;
|
||||
int type_enum = 0;
|
||||
int structs = 0;
|
||||
int c, i;
|
||||
int c, i, j;
|
||||
char buf1[11];
|
||||
char filetype = 'c';
|
||||
FILE *fd;
|
||||
@@ -517,19 +533,6 @@ main(int argc, char **argv) {
|
||||
fprintf(stdout, copyright, year);
|
||||
|
||||
if (code) {
|
||||
#if 0
|
||||
dodecl("isc_result_t", "fromtext", FROMTEXTDECL);
|
||||
dodecl("isc_result_t", "totext", TOTEXTDECL);
|
||||
dodecl("isc_result_t", "fromwire", FROMWIREDECL);
|
||||
dodecl("isc_result_t", "towire", TOWIREDECL);
|
||||
dodecl("int", "compare", COMPAREDECL);
|
||||
dodecl("isc_result_t", "fromstruct", FROMSTRUCTDECL);
|
||||
dodecl("isc_result_t", "tostruct", TOSTRUCTDECL);
|
||||
dodecl("void", "freestruct", FREESTRUCTDECL);
|
||||
dodecl("isc_result_t", "additionaldata", ADDITIONALDATADECL);
|
||||
dodecl("isc_result_t", "digest", DIGESTDECL);
|
||||
#endif
|
||||
|
||||
fputs("\n\n", stdout);
|
||||
for (tt = types; tt != NULL ; tt = tt->next)
|
||||
fprintf(stdout, "#include \"%s/%s_%d.c\"\n",
|
||||
@@ -559,16 +562,10 @@ main(int argc, char **argv) {
|
||||
DIGESTARGS, DIGESTTYPE,
|
||||
DIGESTCLASS, DIGESTDEF);
|
||||
|
||||
fprintf(stdout, "\n#define TYPENAMES%s\n",
|
||||
types != NULL ? " \\" : "");
|
||||
|
||||
lasttype = 0;
|
||||
for (tt = types; tt != NULL ; tt = tt->next)
|
||||
if (tt->type != lasttype)
|
||||
fprintf(stdout, "\t{ %d, \"%s\", 0 },%s\n",
|
||||
lasttype = tt->type,
|
||||
upper(tt->typename),
|
||||
tt->next != NULL ? " \\" : "");
|
||||
/*
|
||||
* From here down, we are processing the rdata names and
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
#define PRINT_COMMA(x) (x == 255 ? "" : ",")
|
||||
|
||||
@@ -613,6 +610,65 @@ main(int argc, char **argv) {
|
||||
}
|
||||
printf("};\n");
|
||||
|
||||
/*
|
||||
* Run through the list of types and pre-mark the unused
|
||||
* ones as "sorted" so we simply ignore them below.
|
||||
*/
|
||||
for (i = 0 ; i <= 255 ; i++) {
|
||||
ttn = &typenames[i];
|
||||
if (ttn->typename[0] == 0)
|
||||
ttn->sorted = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Spit out a quick and dirty hash function. Here,
|
||||
* we walk through the list of type names, and calculate
|
||||
* a hash. This isn't perfect, but it will generate "pretty
|
||||
* good" estimates. Lowercase the characters before
|
||||
* computing in all cases.
|
||||
*
|
||||
* Here, walk the list from top to bottom, calculating
|
||||
* the hash (mod 256) for each name.
|
||||
*/
|
||||
printf("#define RDATATYPE_FROMTEXT_SW(_hash,_typename,_typep) \\\n");
|
||||
printf("\tswitch (_hash) { \\\n");
|
||||
for (i = 0 ; i <= 255 ; i++) {
|
||||
ttn = &typenames[i];
|
||||
|
||||
/*
|
||||
* Skip entries we already processed.
|
||||
*/
|
||||
if (ttn->sorted != 0)
|
||||
continue;
|
||||
|
||||
hash = HASH(ttn->typename);
|
||||
printf("\t\tcase %u: \\\n", hash);
|
||||
|
||||
/*
|
||||
* Find all other entries that happen to match
|
||||
* this hash.
|
||||
*/
|
||||
for (j = i ; j <= 255 ; j++) {
|
||||
ttn2 = &typenames[j];
|
||||
if (hash == HASH(ttn2->typename)) {
|
||||
printf("\t\t\tif (strcasecmp(\"%s\", (_typename)) == 0) { \\\n"
|
||||
"\t\t\t\tif ((typeattr[%u].flags & DNS_RDATATYPEATTR_RESERVED) != 0) \\\n"
|
||||
"\t\t\t\t\treturn (ISC_R_NOTIMPLEMENTED); \\\n"
|
||||
"\t\t\t\t*(_typep) = %u; \\\n"
|
||||
"\t\t\t\treturn (ISC_R_SUCCESS); \\\n"
|
||||
"\t\t\t} \\\n",
|
||||
ttn2->typename, j, j);
|
||||
ttn2->sorted = 1;
|
||||
}
|
||||
}
|
||||
printf("\t\t\tbreak; \\\n");
|
||||
}
|
||||
printf("\t}\n");
|
||||
|
||||
|
||||
/*
|
||||
* Dump the class names.
|
||||
*/
|
||||
|
||||
fputs("\n", stdout);
|
||||
fprintf(stdout, "\n#define CLASSNAMES%s\n",
|
||||
|
@@ -15,10 +15,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdata.c,v 1.77 2000/04/14 20:13:45 explorer Exp $ */
|
||||
/* $Id: rdata.c,v 1.78 2000/04/25 19:09:07 explorer Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -119,22 +120,6 @@ static const char octdigits[] = "01234567";
|
||||
#define META 0x0001
|
||||
#define RESERVED 0x0002
|
||||
|
||||
#define METATYPES \
|
||||
{ 0, "RESERVED0", META }, \
|
||||
{ 31, "EID", RESERVED }, \
|
||||
{ 32, "NIMLOC", RESERVED }, \
|
||||
{ 34, "ATMA", RESERVED }, \
|
||||
{ 100, "UINFO", RESERVED }, \
|
||||
{ 101, "UID", RESERVED }, \
|
||||
{ 102, "GID", RESERVED }, \
|
||||
{ 249, "TKEY", META }, \
|
||||
{ 250, "TSIG", META }, \
|
||||
{ 251, "IXFR", META }, \
|
||||
{ 252, "AXFR", META }, \
|
||||
{ 253, "MAILB", META }, \
|
||||
{ 254, "MAILA", META }, \
|
||||
{ 255, "ANY", META },
|
||||
|
||||
/*
|
||||
* Empty classes are those without any types of their own.
|
||||
*/
|
||||
@@ -194,16 +179,19 @@ static const char octdigits[] = "01234567";
|
||||
{ 255, "ALL", 0 }, \
|
||||
{ 0, NULL, 0}
|
||||
|
||||
static struct tbl {
|
||||
struct tbl {
|
||||
unsigned int value;
|
||||
char *name;
|
||||
int flags;
|
||||
} types[] = { TYPENAMES METATYPES {0, NULL, 0} },
|
||||
classes[] = { METACLASSES CLASSNAMES EMPTYCLASSES { 0, NULL, 0} },
|
||||
rcodes[] = { RCODENAMES },
|
||||
certs[] = { CERTNAMES },
|
||||
secalgs[] = { SECALGNAMES },
|
||||
secprotos[] = { SECPROTONAMES };
|
||||
};
|
||||
|
||||
static struct tbl classes[] = {
|
||||
METACLASSES CLASSNAMES EMPTYCLASSES { 0, NULL, 0}
|
||||
};
|
||||
static struct tbl rcodes[] = { RCODENAMES };
|
||||
static struct tbl certs[] = { CERTNAMES };
|
||||
static struct tbl secalgs[] = { SECALGNAMES };
|
||||
static struct tbl secprotos[] = { SECPROTONAMES };
|
||||
|
||||
static struct keyflag {
|
||||
char *name;
|
||||
@@ -738,21 +726,29 @@ dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target) {
|
||||
/* XXXRTH Should we use a hash table here? */
|
||||
|
||||
isc_result_t
|
||||
dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
|
||||
int i = 0;
|
||||
dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source)
|
||||
{
|
||||
unsigned int hash;
|
||||
unsigned int n;
|
||||
unsigned char a, b;
|
||||
|
||||
n = source->length;
|
||||
|
||||
if (n == 0)
|
||||
return (DNS_R_UNKNOWN);
|
||||
|
||||
a = tolower(source->base[0]);
|
||||
b = tolower(source->base[n - 1]);
|
||||
|
||||
hash = ((a + n) * b) % 256;
|
||||
|
||||
/*
|
||||
* This switch block is inlined via #define, and will use "return"
|
||||
* to return a result to the caller if it is a valid (known)
|
||||
* rdatatype name.
|
||||
*/
|
||||
RDATATYPE_FROMTEXT_SW(hash, source->base, typep);
|
||||
|
||||
while (types[i].name != NULL) {
|
||||
n = strlen(types[i].name);
|
||||
if (n == source->length &&
|
||||
strncasecmp(source->base, types[i].name, n) == 0) {
|
||||
*typep = types[i].value;
|
||||
if ((types[i].flags & RESERVED) != 0)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (DNS_R_UNKNOWN);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user