librazor/razor.c
changeset 320 53e1185e2366
parent 316 5ebed314390c
child 322 66c281524c98
     1.1 --- a/librazor/razor.c	Tue Jul 08 22:02:58 2008 -0400
     1.2 +++ b/librazor/razor.c	Tue Jan 06 14:06:00 2009 +0000
     1.3 @@ -49,7 +49,12 @@
     1.4  	return p;
     1.5  }
     1.6  
     1.7 -struct razor_set_section razor_sections[] = {
     1.8 +struct razor_set_section_index {
     1.9 +	const char *name;
    1.10 +	uint32_t offset;
    1.11 +};
    1.12 +
    1.13 +struct razor_set_section_index razor_sections[] = {
    1.14  	{ RAZOR_STRING_POOL,	offsetof(struct razor_set, string_pool) },
    1.15  	{ RAZOR_PACKAGES,	offsetof(struct razor_set, packages) },
    1.16  	{ RAZOR_PROPERTIES,	offsetof(struct razor_set, properties) },
    1.17 @@ -57,13 +62,13 @@
    1.18  	{ RAZOR_PROPERTY_POOL,	offsetof(struct razor_set, property_pool) },
    1.19  };
    1.20  
    1.21 -struct razor_set_section razor_files_sections[] = {
    1.22 +struct razor_set_section_index razor_files_sections[] = {
    1.23  	{ RAZOR_FILES,			offsetof(struct razor_set, files) },
    1.24  	{ RAZOR_FILE_POOL,		offsetof(struct razor_set, file_pool) },
    1.25  	{ RAZOR_FILE_STRING_POOL,	offsetof(struct razor_set, file_string_pool) },
    1.26  };
    1.27  
    1.28 -struct razor_set_section razor_details_sections[] = {
    1.29 +struct razor_set_section_index razor_details_sections[] = {
    1.30  	{ RAZOR_DETAILS_STRING_POOL,	offsetof(struct razor_set, details_string_pool) },
    1.31  };
    1.32  
    1.33 @@ -87,65 +92,42 @@
    1.34  	return set;
    1.35  }
    1.36  
    1.37 -RAZOR_EXPORT struct razor_set *
    1.38 -razor_set_open(const char *filename)
    1.39 +static int
    1.40 +razor_set_bind_sections(struct razor_set *set,
    1.41 +			struct razor_set_header **header,
    1.42 +			size_t *header_size,
    1.43 +			struct razor_set_section_index section_index[],
    1.44 +			int section_index_size,
    1.45 +			const char *filename)
    1.46  {
    1.47 -	struct razor_set *set;
    1.48 -	struct razor_set_section *s;
    1.49 +	struct razor_set_section *s, *sections;
    1.50  	struct stat stat;
    1.51  	struct array *array;
    1.52 -	int fd;
    1.53 -
    1.54 -	set = zalloc(sizeof *set);
    1.55 -	fd = open(filename, O_RDONLY);
    1.56 -	if (fstat(fd, &stat) < 0)
    1.57 -		return NULL;
    1.58 -	set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    1.59 -	if (set->header == MAP_FAILED) {
    1.60 -		free(set);
    1.61 -		return NULL;
    1.62 -	}
    1.63 -
    1.64 -	for (s = set->header->sections; ~s->type; s++) {
    1.65 -		if (s->type >= ARRAY_SIZE(razor_sections))
    1.66 -			continue;
    1.67 -		if (s->type != razor_sections[s->type].type)
    1.68 -			continue;
    1.69 -		array = (void *) set + razor_sections[s->type].offset;
    1.70 -		array->data = (void *) set->header + s->offset;
    1.71 -		array->size = s->size;
    1.72 -		array->alloc = s->size;
    1.73 -	}
    1.74 -	close(fd);
    1.75 -
    1.76 -	return set;
    1.77 -}
    1.78 -
    1.79 -RAZOR_EXPORT int
    1.80 -razor_set_open_details(struct razor_set *set, const char *filename)
    1.81 -{
    1.82 -	struct razor_set_section *s;
    1.83 -	struct stat stat;
    1.84 -	struct array *array;
    1.85 -	int fd;
    1.86 -
    1.87 -	assert (set != NULL);
    1.88 -	assert (filename != NULL);
    1.89 +	const char *pool;
    1.90 +	int fd, i;
    1.91  
    1.92  	fd = open(filename, O_RDONLY);
    1.93  	if (fstat(fd, &stat) < 0)
    1.94  		return -1;
    1.95 -	set->details_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    1.96 -	if (set->details_header == MAP_FAILED)
    1.97 +	*header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    1.98 +	if (*header == MAP_FAILED)
    1.99  		return -1;
   1.100 +	*header_size = stat.st_size;
   1.101  
   1.102 -	for (s = set->details_header->sections; ~s->type; s++) {
   1.103 -		if (s->type >= ARRAY_SIZE(razor_details_sections))
   1.104 +	sections = (void *) *header + sizeof **header;
   1.105 +	pool = (void *) sections + (*header)->num_sections * sizeof *sections;
   1.106 +
   1.107 +	for (i = 0; i < (*header)->num_sections; i++) {
   1.108 +		int j;
   1.109 +		s = sections + i;
   1.110 +		for (j = 0; j < section_index_size; j++)
   1.111 +			if (!strcmp(section_index[j].name,
   1.112 +				    &pool[s->name]))
   1.113 +				break;
   1.114 +		if (j == section_index_size)
   1.115  			continue;
   1.116 -		if (s->type != razor_details_sections[s->type].type)
   1.117 -			continue;
   1.118 -		array = (void *) set + razor_details_sections[s->type].offset;
   1.119 -		array->data = (void *) set->details_header + s->offset;
   1.120 +		array = (void *) set + section_index[j].offset;
   1.121 +		array->data = (void *) *header + s->offset;
   1.122  		array->size = s->size;
   1.123  		array->alloc = s->size;
   1.124  	}
   1.125 @@ -154,53 +136,51 @@
   1.126  	return 0;
   1.127  }
   1.128  
   1.129 +RAZOR_EXPORT struct razor_set *
   1.130 +razor_set_open(const char *filename)
   1.131 +{
   1.132 +	struct razor_set *set;
   1.133 +
   1.134 +	set = zalloc(sizeof *set);
   1.135 +	if (razor_set_bind_sections(set, &set->header, &set->header_size,
   1.136 +				    razor_sections, ARRAY_SIZE(razor_sections),
   1.137 +				    filename)){
   1.138 +		free(set);
   1.139 +		return NULL;
   1.140 +	}
   1.141 +	return set;
   1.142 +}
   1.143 +
   1.144 +RAZOR_EXPORT int
   1.145 +razor_set_open_details(struct razor_set *set, const char *filename)
   1.146 +{
   1.147 +	return razor_set_bind_sections(set, &set->details_header,
   1.148 +				       &set->details_header_size,
   1.149 +				       razor_details_sections,
   1.150 +				       ARRAY_SIZE(razor_details_sections),
   1.151 +				       filename);
   1.152 +}
   1.153 +
   1.154  RAZOR_EXPORT int
   1.155  razor_set_open_files(struct razor_set *set, const char *filename)
   1.156  {
   1.157 -	struct razor_set_section *s;
   1.158 -	struct stat stat;
   1.159 -	struct array *array;
   1.160 -	int fd;
   1.161 -
   1.162 -	assert (set != NULL);
   1.163 -	assert (filename != NULL);
   1.164 -
   1.165 -	fd = open(filename, O_RDONLY);
   1.166 -	if (fstat(fd, &stat) < 0)
   1.167 -		return -1;
   1.168 -	set->files_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   1.169 -	if (set->files_header == MAP_FAILED)
   1.170 -		return -1;
   1.171 -
   1.172 -	for (s = set->files_header->sections; ~s->type; s++) {
   1.173 -		if (s->type >= ARRAY_SIZE(razor_files_sections))
   1.174 -			continue;
   1.175 -		if (s->type != razor_files_sections[s->type].type)
   1.176 -			continue;
   1.177 -		array = (void *) set + razor_files_sections[s->type].offset;
   1.178 -		array->data = (void *) set->files_header + s->offset;
   1.179 -		array->size = s->size;
   1.180 -		array->alloc = s->size;
   1.181 -	}
   1.182 -	close(fd);
   1.183 -
   1.184 -	return 0;
   1.185 +	return razor_set_bind_sections(set, &set->files_header,
   1.186 +				       &set->files_header_size,
   1.187 +				       razor_files_sections,
   1.188 +				       ARRAY_SIZE(razor_files_sections),
   1.189 +				       filename);
   1.190  }
   1.191  
   1.192  RAZOR_EXPORT void
   1.193  razor_set_destroy(struct razor_set *set)
   1.194  {
   1.195 -	unsigned int size;
   1.196  	struct array *a;
   1.197  	int i;
   1.198  
   1.199  	assert (set != NULL);
   1.200  
   1.201  	if (set->header) {
   1.202 -		for (i = 0; set->header->sections[i].type; i++)
   1.203 -			;
   1.204 -		size = set->header->sections[i].type;
   1.205 -		munmap(set->header, size);
   1.206 +		munmap(set->header, set->header_size);
   1.207  	} else {
   1.208  		for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
   1.209  			a = (void *) set + razor_sections[i].offset;
   1.210 @@ -209,10 +189,7 @@
   1.211  	}
   1.212  
   1.213  	if (set->details_header) {
   1.214 -		for (i = 0; set->details_header->sections[i].type; i++)
   1.215 -			;
   1.216 -		size = set->details_header->sections[i].type;
   1.217 -		munmap(set->details_header, size);
   1.218 +		munmap(set->details_header, set->details_header_size);
   1.219  	} else {
   1.220  		for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) {
   1.221  			a = (void *) set + razor_details_sections[i].offset;
   1.222 @@ -221,10 +198,7 @@
   1.223  	}
   1.224  
   1.225  	if (set->files_header) {
   1.226 -		for (i = 0; set->files_header->sections[i].type; i++)
   1.227 -			;
   1.228 -		size = set->files_header->sections[i].type;
   1.229 -		munmap(set->files_header, size);
   1.230 +		munmap(set->files_header, set->files_header_size);
   1.231  	} else {
   1.232  		for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) {
   1.233  			a = (void *) set + razor_files_sections[i].offset;
   1.234 @@ -236,45 +210,50 @@
   1.235  }
   1.236  
   1.237  static int
   1.238 -razor_set_write_sections_to_fd(struct razor_set *set, int fd, int magic,
   1.239 -			       struct razor_set_section *sections,
   1.240 +razor_set_write_sections_to_fd(struct razor_set *set, int fd,
   1.241 +			       struct razor_set_section_index *sections,
   1.242  			       size_t array_size)
   1.243  {
   1.244 -	char data[4096];
   1.245 -	struct razor_set_header *header = (struct razor_set_header *) data;
   1.246 -	struct array *a;
   1.247 +	struct razor_set_header header;
   1.248 +	struct razor_set_section *out_sections =
   1.249 +		malloc(array_size * sizeof *out_sections);
   1.250 +	struct hashtable table;
   1.251 +	struct array *a, pool;
   1.252  	uint32_t offset;
   1.253  	int i;
   1.254  
   1.255 -	memset(data, 0, sizeof data);
   1.256 -	header->magic = magic;
   1.257 -	header->version = RAZOR_VERSION;
   1.258 -	offset = sizeof data;
   1.259 +	header.magic = RAZOR_MAGIC;
   1.260 +	header.version = RAZOR_VERSION;
   1.261 +	header.num_sections = array_size;
   1.262 +	offset = sizeof header + array_size * sizeof *out_sections;
   1.263 +
   1.264 +	array_init(&pool);
   1.265 +	hashtable_init(&table, &pool);
   1.266 +
   1.267 +	for (i = 0; i < array_size; i++)
   1.268 +		out_sections[i].name =
   1.269 +			hashtable_tokenize(&table, sections[i].name);
   1.270 +
   1.271 +	offset += pool.size;
   1.272  
   1.273  	for (i = 0; i < array_size; i++) {
   1.274 -		if (sections[i].type != i)
   1.275 -			continue;
   1.276  		a = (void *) set + sections[i].offset;
   1.277 -		header->sections[i].type = i;
   1.278 -		header->sections[i].offset = offset;
   1.279 -		header->sections[i].size = a->size;
   1.280 -		offset += ALIGN(a->size, 4096);
   1.281 +		out_sections[i].offset = offset;
   1.282 +		out_sections[i].size = a->size;
   1.283 +		offset += a->size;
   1.284  	}
   1.285  
   1.286 -	header->sections[i].type = ~0;
   1.287 -	header->sections[i].offset = 0;
   1.288 -	header->sections[i].size = 0;
   1.289 +	razor_write(fd, &header, sizeof header);
   1.290 +	razor_write(fd, out_sections, array_size * sizeof *out_sections);
   1.291 +	razor_write(fd, pool.data, pool.size);
   1.292  
   1.293 -	razor_write(fd, data, sizeof data);
   1.294 -	memset(data, 0, sizeof data);
   1.295  	for (i = 0; i < array_size; i++) {
   1.296 -		if (sections[i].type != i)
   1.297 -			continue;
   1.298  		a = (void *) set + sections[i].offset;
   1.299  		razor_write(fd, a->data, a->size);
   1.300 -		razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
   1.301  	}
   1.302  
   1.303 +	free(out_sections);
   1.304 +
   1.305  	return 0;
   1.306  }
   1.307  
   1.308 @@ -284,16 +263,16 @@
   1.309  {
   1.310  	switch (type) {
   1.311  	case RAZOR_REPO_FILE_MAIN:
   1.312 -		return razor_set_write_sections_to_fd(set, fd, RAZOR_MAGIC,
   1.313 +		return razor_set_write_sections_to_fd(set, fd,
   1.314  						      razor_sections,
   1.315  						      ARRAY_SIZE(razor_sections));
   1.316  
   1.317  	case RAZOR_REPO_FILE_DETAILS:
   1.318 -		return razor_set_write_sections_to_fd(set, fd, RAZOR_DETAILS_MAGIC,
   1.319 +		return razor_set_write_sections_to_fd(set, fd,
   1.320  						      razor_details_sections,
   1.321  						      ARRAY_SIZE(razor_details_sections));
   1.322  	case RAZOR_REPO_FILE_FILES:
   1.323 -		return razor_set_write_sections_to_fd(set, fd, RAZOR_FILES_MAGIC,
   1.324 +		return razor_set_write_sections_to_fd(set, fd,
   1.325  						      razor_files_sections,
   1.326  						      ARRAY_SIZE(razor_files_sections));
   1.327  	default: