librazor/iterator.c
author James Bowes <jbowes@redhat.com>
Wed Jul 09 10:11:13 2008 -0400 (2008-07-09)
changeset 318 829d6711b316
parent 307 95b6bcadd6c4
child 351 48b0adfe3059
permissions -rw-r--r--
Use strings to identify section types in the on-disk repo format.

Previously, a given razor file type had a fixed number of sections in a
fixed order, identified by an integer type. Now, sections are identified
by a named string (stored in a string pool after the section lists).

This will allow for razor files to contain arbitrary sections.

For bonus points, also drop the 4k section alignment and change the
magic byte string to "RZDB".

committer: Kristian H?gsberg <krh@redhat.com>
     1 /*
     2  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     3  * Copyright (C) 2008  Red Hat, Inc
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; either version 2 of the License, or
     8  * (at your option) any later version.
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along
    16  * with this program; if not, write to the Free Software Foundation, Inc.,
    17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    18  */
    19 
    20 #define _GNU_SOURCE
    21 
    22 #include <stdarg.h>
    23 #include <string.h>
    24 #include <assert.h>
    25 
    26 #include "razor-internal.h"
    27 #include "razor.h"
    28 
    29 static struct razor_package_iterator *
    30 razor_package_iterator_create_with_index(struct razor_set *set,
    31 					 struct list *index)
    32 {
    33 	struct razor_package_iterator *pi;
    34 
    35 	pi = zalloc(sizeof *pi);
    36 	pi->set = set;
    37 	pi->index = index;
    38 
    39 	return pi;
    40 }
    41 
    42 static struct razor_package_iterator *
    43 razor_package_iterator_create_empty(struct razor_set *set)
    44 {
    45 	struct razor_package_iterator *pi;
    46 	return zalloc(sizeof *pi);
    47 }
    48 
    49 RAZOR_EXPORT struct razor_package_iterator *
    50 razor_package_iterator_create(struct razor_set *set)
    51 {
    52 	struct razor_package_iterator *pi;
    53 
    54 	assert (set != NULL);
    55 
    56 	pi = zalloc(sizeof *pi);
    57 	pi->set = set;
    58 	pi->end = set->packages.data + set->packages.size;
    59 	pi->package = set->packages.data;
    60 
    61 	return pi;
    62 }
    63 
    64 RAZOR_EXPORT void
    65 razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
    66 					 struct razor_set *set,
    67 					 struct razor_property *property)
    68 {
    69 	assert (pi != NULL);
    70 	assert (set != NULL);
    71 	assert (property != NULL);
    72 
    73 	memset(pi, 0, sizeof *pi);
    74 	pi->set = set;
    75 	pi->index = list_first(&property->packages, &set->package_pool);
    76 }
    77 
    78 RAZOR_EXPORT struct razor_package_iterator *
    79 razor_package_iterator_create_for_property(struct razor_set *set,
    80 					   struct razor_property *property)
    81 {
    82 	struct list *index;
    83 
    84 	assert (set != NULL);
    85 	assert (property != NULL);
    86 
    87 	index = list_first(&property->packages, &set->package_pool);
    88 	return razor_package_iterator_create_with_index(set, index);
    89 }
    90 
    91 RAZOR_EXPORT struct razor_package_iterator *
    92 razor_package_iterator_create_for_file(struct razor_set *set,
    93 				       const char *filename)
    94 {
    95 	struct razor_entry *entry;
    96 	struct list *index;
    97 
    98 	assert (set != NULL);
    99 	assert (filename != NULL);
   100 
   101 	entry = razor_set_find_entry(set, set->files.data, filename);
   102 	if (entry == NULL)
   103 		return razor_package_iterator_create_empty(set);
   104 
   105 	index = list_first(&entry->packages, &set->package_pool);
   106 	return razor_package_iterator_create_with_index(set, index);
   107 }
   108 
   109 /**
   110  * razor_package_iterator_next:
   111  * @pi: a %razor_package_iterator
   112  * @package: a %razor_package
   113  *
   114  * Gets the next iteratr along with any vararg data.
   115  * The vararg must be terminated with %RAZOR_DETAIL_LAST.
   116  *
   117  * Example: razor_package_iterator_next (pi, package,
   118  *					 RAZOR_DETAIL_NAME, &name,
   119  *					 RAZOR_DETAIL_LAST);
   120  **/
   121 RAZOR_EXPORT int
   122 razor_package_iterator_next(struct razor_package_iterator *pi,
   123 			    struct razor_package **package, ...)
   124 {
   125 	va_list args;
   126 	int valid;
   127 	struct razor_package *p, *packages;
   128 
   129 	assert (pi != NULL);
   130 
   131 	if (pi->package) {
   132 		p = pi->package++;
   133 		valid = p < pi->end;
   134 	} else if (pi->index) {
   135 		packages = pi->set->packages.data;
   136 		p = &packages[pi->index->data];
   137 		pi->index = list_next(pi->index);
   138 		valid = 1;
   139 	} else
   140 		valid = 0;
   141 
   142 	if (valid == 0) {
   143 		*package = NULL;
   144 		goto out;
   145 	}
   146 
   147 	*package = p;
   148 
   149 	va_start(args, NULL);
   150 	razor_package_get_details_varg (pi->set, p, args);
   151 	va_end (args);
   152 out:
   153 	return valid;
   154 }
   155 
   156 RAZOR_EXPORT void
   157 razor_package_iterator_destroy(struct razor_package_iterator *pi)
   158 {
   159 	assert (pi != NULL);
   160 
   161 	if (pi->free_index)
   162 		free(pi->index);
   163 
   164 	free(pi);
   165 }
   166 
   167 RAZOR_EXPORT struct razor_property_iterator *
   168 razor_property_iterator_create(struct razor_set *set,
   169 			       struct razor_package *package)
   170 {
   171 	struct razor_property_iterator *pi;
   172 
   173 	assert (set != NULL);
   174 
   175 	pi = zalloc(sizeof *pi);
   176 	pi->set = set;
   177 
   178 	if (package) {
   179 		pi->index = list_first(&package->properties,
   180 				       &set->property_pool);
   181 	} else {
   182 		pi->property = set->properties.data;
   183 		pi->end = set->properties.data + set->properties.size;
   184 	}
   185 
   186 	return pi;
   187 }
   188 
   189 RAZOR_EXPORT int
   190 razor_property_iterator_next(struct razor_property_iterator *pi,
   191 			     struct razor_property **property,
   192 			     const char **name,
   193 			     uint32_t *flags,
   194 			     const char **version)
   195 {
   196 	char *pool;
   197 	int valid;
   198 	struct razor_property *p, *properties;
   199 
   200 	assert (pi != NULL);
   201 
   202 	if (pi->property) {
   203 		p = pi->property++;
   204 		valid = p < pi->end;
   205 	} else if (pi->index) {
   206 		properties = pi->set->properties.data;
   207 		p = &properties[pi->index->data];
   208 		pi->index = list_next(pi->index);
   209 		valid = 1;
   210 	} else
   211 		valid = 0;
   212 
   213 	if (valid) {
   214 		pool = pi->set->string_pool.data;
   215 		*property = p;
   216 		*name = &pool[p->name];
   217 		*flags = p->flags;
   218 		*version = &pool[p->version];
   219 	} else {
   220 		*property = NULL;
   221 	}
   222 
   223 	return valid;
   224 }
   225 
   226 RAZOR_EXPORT void
   227 razor_property_iterator_destroy(struct razor_property_iterator *pi)
   228 {
   229 	free(pi);
   230 }
   231 
   232 struct razor_package_query {
   233 	struct razor_set *set;
   234 	char *vector;
   235 	int count;
   236 };
   237 
   238 RAZOR_EXPORT struct razor_package_query *
   239 razor_package_query_create(struct razor_set *set)
   240 {
   241 	struct razor_package_query *pq;
   242 	int count;
   243 
   244 	assert (set != NULL);
   245 
   246 	pq = zalloc(sizeof *pq);
   247 	pq->set = set;
   248 	count = set->packages.size / sizeof(struct razor_package);
   249 	pq->vector = zalloc(count * sizeof(char));
   250 
   251 	return pq;
   252 }
   253 
   254 RAZOR_EXPORT void
   255 razor_package_query_add_package(struct razor_package_query *pq,
   256 				struct razor_package *p)
   257 {
   258 	struct razor_package *packages;
   259 
   260 	assert (pq != NULL);
   261 	assert (p != NULL);
   262 
   263 	packages = pq->set->packages.data;
   264 	pq->count += pq->vector[p - packages] ^ 1;
   265 	pq->vector[p - packages] = 1;
   266 }
   267 
   268 RAZOR_EXPORT void
   269 razor_package_query_add_iterator(struct razor_package_query *pq,
   270 				 struct razor_package_iterator *pi)
   271 {
   272 	struct razor_package *packages, *p;
   273 
   274 	assert (pq != NULL);
   275 	assert (pi != NULL);
   276 
   277 	packages = pq->set->packages.data;
   278 	while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) {
   279 		pq->count += pq->vector[p - packages] ^ 1;
   280 		pq->vector[p - packages] = 1;
   281 	}
   282 }
   283 
   284 RAZOR_EXPORT struct razor_package_iterator *
   285 razor_package_query_finish(struct razor_package_query *pq)
   286 {
   287 	struct razor_package_iterator *pi;
   288 	struct razor_set *set;
   289 	struct list *index;
   290 	int i, j;
   291 
   292 	assert (pq != NULL);
   293 
   294 	set = pq->set;
   295 	if (pq->count > 0)
   296 		index = zalloc(pq->count * sizeof *index);
   297 	else
   298 		index = NULL;
   299 
   300 	for (i = 0, j = 0; j < pq->count; i++) {
   301 		if (!pq->vector[i])
   302 			continue;
   303 
   304 		index[j].data = i;
   305 		if (j == pq->count - 1)
   306 			index[j].flags = 0x80;
   307 		j++;
   308 	}
   309 
   310 	free(pq->vector);
   311 	free(pq);
   312 
   313 	pi = razor_package_iterator_create_with_index(set, index);
   314 	pi->free_index = 1;
   315 
   316 	return pi;
   317 }