1.1 --- a/librazor/razor.c Fri Jul 03 18:02:33 2009 +0100
1.2 +++ b/librazor/razor.c Sat Jul 04 11:11:59 2009 +0100
1.3 @@ -59,25 +59,27 @@
1.4 struct razor_set_section_index {
1.5 const char *name;
1.6 uint32_t offset;
1.7 + uint32_t flags;
1.8 };
1.9
1.10 +#define MAIN(type, field) \
1.11 + { type, offsetof(struct razor_set, field), RAZOR_SECTION_MAIN }
1.12 +#define FILES(type, field) \
1.13 + { type, offsetof(struct razor_set, field), RAZOR_SECTION_FILES }
1.14 +#define DETAILS(type, field) \
1.15 + { type, offsetof(struct razor_set, field), RAZOR_SECTION_DETAILS }
1.16 +
1.17 struct razor_set_section_index razor_sections[] = {
1.18 - { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
1.19 - { RAZOR_PACKAGES, offsetof(struct razor_set, packages) },
1.20 - { RAZOR_PROPERTIES, offsetof(struct razor_set, properties) },
1.21 - { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
1.22 - { RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) },
1.23 - { RAZOR_PREFIX_POOL, offsetof(struct razor_set, prefix_pool) },
1.24 -};
1.25 -
1.26 -struct razor_set_section_index razor_files_sections[] = {
1.27 - { RAZOR_FILES, offsetof(struct razor_set, files) },
1.28 - { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) },
1.29 - { RAZOR_FILE_STRING_POOL, offsetof(struct razor_set, file_string_pool) },
1.30 -};
1.31 -
1.32 -struct razor_set_section_index razor_details_sections[] = {
1.33 - { RAZOR_DETAILS_STRING_POOL, offsetof(struct razor_set, details_string_pool) },
1.34 + MAIN(RAZOR_STRING_POOL, string_pool),
1.35 + MAIN(RAZOR_PACKAGES, packages),
1.36 + MAIN(RAZOR_PROPERTIES, properties),
1.37 + MAIN(RAZOR_PACKAGE_POOL, package_pool),
1.38 + MAIN(RAZOR_PROPERTY_POOL, property_pool),
1.39 + MAIN(RAZOR_PREFIX_POOL, prefix_pool),
1.40 + FILES(RAZOR_FILES, files),
1.41 + FILES(RAZOR_FILE_POOL, file_pool),
1.42 + FILES(RAZOR_FILE_STRING_POOL, file_string_pool),
1.43 + DETAILS(RAZOR_DETAILS_STRING_POOL, details_string_pool)
1.44 };
1.45
1.46 RAZOR_EXPORT struct razor_set *
1.47 @@ -111,37 +113,47 @@
1.48 return set;
1.49 }
1.50
1.51 -static int
1.52 -razor_set_bind_sections(struct razor_set *set,
1.53 - struct razor_set_header **header,
1.54 - size_t *header_size,
1.55 - struct razor_set_section_index section_index[],
1.56 - int section_index_size,
1.57 - const char *filename)
1.58 +struct razor_mapped_file {
1.59 + struct razor_set_header *header;
1.60 + size_t size;
1.61 + struct razor_mapped_file *next;
1.62 +};
1.63 +
1.64 +RAZOR_EXPORT int
1.65 +razor_set_bind_sections(struct razor_set *set, const char *filename)
1.66 {
1.67 struct razor_set_section *s, *sections;
1.68 + struct razor_mapped_file *file;
1.69 + const char *pool;
1.70 struct array *array;
1.71 - const char *pool;
1.72 - int i;
1.73 + int i, j;
1.74
1.75 - *header = razor_file_get_contents(filename, header_size);
1.76 - if (!*header)
1.77 + file = zalloc(sizeof *file);
1.78 + if (file == NULL)
1.79 return -1;
1.80
1.81 - sections = (void *) *header + sizeof **header;
1.82 - pool = (void *) sections + (*header)->num_sections * sizeof *sections;
1.83 + file->header = razor_file_get_contents(filename, &file->size);
1.84 + if (!file->header) {
1.85 + free(file);
1.86 + return -1;
1.87 + }
1.88
1.89 - for (i = 0; i < (*header)->num_sections; i++) {
1.90 - int j;
1.91 + file->next = set->mapped_files;
1.92 + set->mapped_files = file;
1.93 +
1.94 + sections = (void *) file->header + sizeof *file->header;
1.95 + pool = (void *) sections +
1.96 + file->header->num_sections * sizeof *sections;
1.97 +
1.98 + for (i = 0; i < file->header->num_sections; i++) {
1.99 s = sections + i;
1.100 - for (j = 0; j < section_index_size; j++)
1.101 - if (!strcmp(section_index[j].name,
1.102 - &pool[s->name]))
1.103 + for (j = 0; j < ARRAY_SIZE(razor_sections); j++)
1.104 + if (!strcmp(razor_sections[j].name, &pool[s->name]))
1.105 break;
1.106 - if (j == section_index_size)
1.107 + if (j == ARRAY_SIZE(razor_sections))
1.108 continue;
1.109 - array = (void *) set + section_index[j].offset;
1.110 - array->data = (void *) *header + s->offset;
1.111 + array = (void *) set + razor_sections[j].offset;
1.112 + array->data = (void *) file->header + s->offset;
1.113 array->size = s->size;
1.114 array->alloc = s->size;
1.115 }
1.116 @@ -155,149 +167,93 @@
1.117 struct razor_set *set;
1.118
1.119 set = zalloc(sizeof *set);
1.120 - if (razor_set_bind_sections(set, &set->header, &set->header_size,
1.121 - razor_sections, ARRAY_SIZE(razor_sections),
1.122 - filename)){
1.123 + if (razor_set_bind_sections(set, filename)){
1.124 free(set);
1.125 return NULL;
1.126 }
1.127 return set;
1.128 }
1.129
1.130 -RAZOR_EXPORT int
1.131 -razor_set_open_details(struct razor_set *set, const char *filename)
1.132 -{
1.133 - return razor_set_bind_sections(set, &set->details_header,
1.134 - &set->details_header_size,
1.135 - razor_details_sections,
1.136 - ARRAY_SIZE(razor_details_sections),
1.137 - filename);
1.138 -}
1.139 -
1.140 -RAZOR_EXPORT int
1.141 -razor_set_open_files(struct razor_set *set, const char *filename)
1.142 -{
1.143 - return razor_set_bind_sections(set, &set->files_header,
1.144 - &set->files_header_size,
1.145 - razor_files_sections,
1.146 - ARRAY_SIZE(razor_files_sections),
1.147 - filename);
1.148 -}
1.149 -
1.150 RAZOR_EXPORT void
1.151 razor_set_destroy(struct razor_set *set)
1.152 {
1.153 - struct array *a;
1.154 + struct razor_mapped_file *file, *next;
1.155 + struct array *array;
1.156 int i;
1.157
1.158 assert (set != NULL);
1.159
1.160 - if (set->header) {
1.161 - razor_file_free_contents(set->header, set->header_size);
1.162 + if (set->mapped_files == NULL) {
1.163 + for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
1.164 + array = (void *) set + razor_sections[i].offset;
1.165 + array_release(array);
1.166 + }
1.167 } else {
1.168 - for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
1.169 - a = (void *) set + razor_sections[i].offset;
1.170 - free(a->data);
1.171 - }
1.172 - }
1.173 -
1.174 - if (set->details_header) {
1.175 - razor_file_free_contents(set->details_header,
1.176 - set->details_header_size);
1.177 - } else {
1.178 - for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) {
1.179 - a = (void *) set + razor_details_sections[i].offset;
1.180 - free(a->data);
1.181 - }
1.182 - }
1.183 -
1.184 - if (set->files_header) {
1.185 - razor_file_free_contents(set->files_header,
1.186 - set->files_header_size);
1.187 - } else {
1.188 - for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) {
1.189 - a = (void *) set + razor_files_sections[i].offset;
1.190 - free(a->data);
1.191 + for (file = set->mapped_files; file != NULL; file = next) {
1.192 + next = file->next;
1.193 + razor_file_free_contents(file->header, file->size);
1.194 + free(file);
1.195 }
1.196 }
1.197
1.198 free(set);
1.199 }
1.200
1.201 -static int
1.202 -razor_set_write_sections_to_fd(struct razor_set *set, int fd,
1.203 - struct razor_set_section_index *sections,
1.204 - size_t array_size)
1.205 +RAZOR_EXPORT int
1.206 +razor_set_write_to_fd(struct razor_set *set, int fd, uint32_t section_mask)
1.207 {
1.208 struct razor_set_header header;
1.209 - struct razor_set_section *out_sections =
1.210 - malloc(array_size * sizeof *out_sections);
1.211 + struct razor_set_section sections[ARRAY_SIZE(razor_sections)];
1.212 struct hashtable table;
1.213 - struct array *a, pool;
1.214 + struct array pool, *arrays[ARRAY_SIZE(razor_sections)];
1.215 uint32_t offset;
1.216 - int i;
1.217 -
1.218 - header.magic = RAZOR_MAGIC;
1.219 - header.version = RAZOR_VERSION;
1.220 - header.num_sections = array_size;
1.221 - offset = sizeof header + array_size * sizeof *out_sections;
1.222 + int count, i, j;
1.223 + static const char padding[4];
1.224
1.225 array_init(&pool);
1.226 hashtable_init(&table, &pool);
1.227
1.228 - for (i = 0; i < array_size; i++)
1.229 - out_sections[i].name =
1.230 - hashtable_tokenize(&table, sections[i].name);
1.231 + j = 0;
1.232 + for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
1.233 + if ((razor_sections[i].flags & section_mask) == 0)
1.234 + continue;
1.235
1.236 - offset += pool.size;
1.237 + arrays[j] = (void *) set + razor_sections[i].offset;
1.238 + sections[j].name =
1.239 + hashtable_tokenize(&table, razor_sections[i].name);
1.240 + j++;
1.241 + }
1.242
1.243 - for (i = 0; i < array_size; i++) {
1.244 - a = (void *) set + sections[i].offset;
1.245 - out_sections[i].offset = offset;
1.246 - out_sections[i].size = a->size;
1.247 - offset += a->size;
1.248 + count = j;
1.249 + header.magic = RAZOR_MAGIC;
1.250 + header.version = RAZOR_VERSION;
1.251 + header.num_sections = count;
1.252 + offset = sizeof header + count * sizeof *sections + ALIGN(pool.size, 4);
1.253 +
1.254 + for (i = 0; i < count; i++) {
1.255 + sections[i].offset = offset;
1.256 + sections[i].size = arrays[i]->size;
1.257 + offset += ALIGN(arrays[i]->size, 4);
1.258 }
1.259
1.260 razor_write(fd, &header, sizeof header);
1.261 - razor_write(fd, out_sections, array_size * sizeof *out_sections);
1.262 + razor_write(fd, sections, count * sizeof *sections);
1.263 razor_write(fd, pool.data, pool.size);
1.264 + razor_write(fd, padding, PADDING(pool.size, 4));
1.265
1.266 - for (i = 0; i < array_size; i++) {
1.267 - a = (void *) set + sections[i].offset;
1.268 - razor_write(fd, a->data, a->size);
1.269 + for (i = 0; i < count; i++) {
1.270 + razor_write(fd, arrays[i]->data, arrays[i]->size);
1.271 + razor_write(fd, padding, PADDING(arrays[i]->size, 4));
1.272 }
1.273
1.274 - free(out_sections);
1.275 + array_release(&pool);
1.276 + hashtable_release(&table);
1.277
1.278 return 0;
1.279 }
1.280
1.281 RAZOR_EXPORT int
1.282 -razor_set_write_to_fd(struct razor_set *set, int fd,
1.283 - enum razor_repo_file_type type)
1.284 -{
1.285 - switch (type) {
1.286 - case RAZOR_REPO_FILE_MAIN:
1.287 - return razor_set_write_sections_to_fd(set, fd,
1.288 - razor_sections,
1.289 - ARRAY_SIZE(razor_sections));
1.290 -
1.291 - case RAZOR_REPO_FILE_DETAILS:
1.292 - return razor_set_write_sections_to_fd(set, fd,
1.293 - razor_details_sections,
1.294 - ARRAY_SIZE(razor_details_sections));
1.295 - case RAZOR_REPO_FILE_FILES:
1.296 - return razor_set_write_sections_to_fd(set, fd,
1.297 - razor_files_sections,
1.298 - ARRAY_SIZE(razor_files_sections));
1.299 - default:
1.300 - return -1;
1.301 - }
1.302 -}
1.303 -
1.304 -RAZOR_EXPORT int
1.305 -razor_set_write(struct razor_set *set, const char *filename,
1.306 - enum razor_repo_file_type type)
1.307 +razor_set_write(struct razor_set *set, const char *filename, uint32_t sections)
1.308 {
1.309 int fd, status;
1.310
1.311 @@ -305,7 +261,7 @@
1.312 if (fd < 0)
1.313 return -1;
1.314
1.315 - status = razor_set_write_to_fd(set, fd, type);
1.316 + status = razor_set_write_to_fd(set, fd, sections);
1.317 if (status) {
1.318 close(fd);
1.319 return status;