Use an array of tags instead of a big switch for parsing the RPM headers.
1.1 --- a/rpm.c Fri Nov 16 17:14:51 2007 -0500
1.2 +++ b/rpm.c Thu Dec 27 15:46:52 2007 -0500
1.3 @@ -1,4 +1,5 @@
1.4 #include <stdio.h>
1.5 +#include <stddef.h>
1.6 #include <string.h>
1.7 #include <sys/stat.h>
1.8 #include <sys/mman.h>
1.9 @@ -60,6 +61,11 @@
1.10 struct rpm_header_index *filestates;
1.11 const char **dirs;
1.12
1.13 + struct rpm_header_index *prein;
1.14 + struct rpm_header_index *postin;
1.15 + struct rpm_header_index *preun;
1.16 + struct rpm_header_index *postun;
1.17 +
1.18 struct properties provides;
1.19 struct properties requires;
1.20 struct properties obsoletes;
1.21 @@ -121,13 +127,47 @@
1.22 }
1.23 }
1.24
1.25 +#define MAP_ENTRY(field, tag) { offsetof(struct razor_rpm, field), tag }
1.26 +
1.27 +static struct index_map {
1.28 + unsigned int offset;
1.29 + unsigned int tag;
1.30 +} index_map[] = {
1.31 + MAP_ENTRY(prein, RPMTAG_PREIN),
1.32 + MAP_ENTRY(prein, RPMTAG_PREIN),
1.33 + MAP_ENTRY(postin, RPMTAG_POSTIN),
1.34 + MAP_ENTRY(preun, RPMTAG_PREUN),
1.35 + MAP_ENTRY(postun, RPMTAG_POSTUN),
1.36 + MAP_ENTRY(name, RPMTAG_NAME),
1.37 + MAP_ENTRY(version, RPMTAG_VERSION),
1.38 + MAP_ENTRY(release, RPMTAG_RELEASE),
1.39 + MAP_ENTRY(requires.name, RPMTAG_REQUIRENAME),
1.40 + MAP_ENTRY(requires.version, RPMTAG_REQUIREVERSION),
1.41 + MAP_ENTRY(requires.flags, RPMTAG_REQUIREFLAGS),
1.42 + MAP_ENTRY(provides.name, RPMTAG_PROVIDENAME),
1.43 + MAP_ENTRY(provides.version, RPMTAG_PROVIDEVERSION),
1.44 + MAP_ENTRY(provides.flags, RPMTAG_PROVIDEFLAGS),
1.45 + MAP_ENTRY(obsoletes.name, RPMTAG_OBSOLETENAME),
1.46 + MAP_ENTRY(obsoletes.version, RPMTAG_OBSOLETEVERSION),
1.47 + MAP_ENTRY(obsoletes.flags, RPMTAG_OBSOLETEFLAGS),
1.48 + MAP_ENTRY(conflicts.name, RPMTAG_CONFLICTNAME),
1.49 + MAP_ENTRY(conflicts.version, RPMTAG_CONFLICTVERSION),
1.50 + MAP_ENTRY(conflicts.flags, RPMTAG_CONFLICTFLAGS),
1.51 + MAP_ENTRY(dirindexes, RPMTAG_DIRINDEXES),
1.52 + MAP_ENTRY(basenames, RPMTAG_BASENAMES),
1.53 + MAP_ENTRY(dirnames, RPMTAG_DIRNAMES),
1.54 + MAP_ENTRY(filesizes, RPMTAG_FILESIZES),
1.55 + MAP_ENTRY(filemodes, RPMTAG_FILEMODES),
1.56 + MAP_ENTRY(filestates, RPMTAG_FILESTATES),
1.57 +};
1.58 +
1.59 struct razor_rpm *
1.60 razor_rpm_open(const char *filename)
1.61 {
1.62 struct razor_rpm *rpm;
1.63 struct rpm_header_index *base, *index;
1.64 struct stat buf;
1.65 - int fd, nindex, hsize, i, count;
1.66 + int fd, nindex, hsize, i, j, count;
1.67 const char *name;
1.68
1.69 rpm = malloc(sizeof *rpm);
1.70 @@ -165,76 +205,13 @@
1.71
1.72 for (i = 0; i < nindex; i++) {
1.73 index = base + i;
1.74 - switch (ntohl(index->tag)) {
1.75 - case RPMTAG_NAME:
1.76 - rpm->name = index;
1.77 - break;
1.78 - case RPMTAG_VERSION:
1.79 - rpm->version = index;
1.80 - break;
1.81 - case RPMTAG_RELEASE:
1.82 - rpm->release = index;
1.83 - break;
1.84 -
1.85 - case RPMTAG_REQUIRENAME:
1.86 - rpm->requires.name = index;
1.87 - break;
1.88 - case RPMTAG_REQUIREVERSION:
1.89 - rpm->requires.version = index;
1.90 - break;
1.91 - case RPMTAG_REQUIREFLAGS:
1.92 - rpm->requires.flags = index;
1.93 - break;
1.94 -
1.95 - case RPMTAG_PROVIDENAME:
1.96 - rpm->provides.name = index;
1.97 - break;
1.98 - case RPMTAG_PROVIDEVERSION:
1.99 - rpm->provides.version = index;
1.100 - break;
1.101 - case RPMTAG_PROVIDEFLAGS:
1.102 - rpm->provides.flags = index;
1.103 - break;
1.104 -
1.105 - case RPMTAG_OBSOLETENAME:
1.106 - rpm->obsoletes.name = index;
1.107 - break;
1.108 - case RPMTAG_OBSOLETEVERSION:
1.109 - rpm->obsoletes.version = index;
1.110 - break;
1.111 - case RPMTAG_OBSOLETEFLAGS:
1.112 - rpm->obsoletes.flags = index;
1.113 - break;
1.114 -
1.115 - case RPMTAG_CONFLICTNAME:
1.116 - rpm->conflicts.name = index;
1.117 - break;
1.118 - case RPMTAG_CONFLICTVERSION:
1.119 - rpm->conflicts.version = index;
1.120 - break;
1.121 - case RPMTAG_CONFLICTFLAGS:
1.122 - rpm->conflicts.flags = index;
1.123 - break;
1.124 -
1.125 - case RPMTAG_DIRINDEXES:
1.126 - rpm->dirindexes = index;
1.127 - break;
1.128 - case RPMTAG_BASENAMES:
1.129 - rpm->basenames = index;
1.130 - break;
1.131 - case RPMTAG_DIRNAMES:
1.132 - rpm->dirnames = index;
1.133 - break;
1.134 - case RPMTAG_FILESIZES:
1.135 - rpm->filesizes = index;
1.136 - break;
1.137 - case RPMTAG_FILEMODES:
1.138 - rpm->filemodes = index;
1.139 - break;
1.140 - case RPMTAG_FILESTATES:
1.141 - rpm->filestates = index;
1.142 - break;
1.143 - }
1.144 + for (j = 0; j < ARRAY_SIZE(index_map); j++) {
1.145 + struct rpm_header_index **p;
1.146 + if (index_map[j].tag == ntohl(index->tag)) {
1.147 + p = (void *) rpm + index_map[j].offset;
1.148 + *p = index;
1.149 + }
1.150 + }
1.151 }
1.152
1.153 /* Look up dir names now so we can index them directly. */