librazor/razor.c
changeset 374 f71695220726
parent 372 6e93e5485947
child 375 c903635ae422
     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;