librazor/iterator.c
author Kristian H?gsberg <krh@redhat.com>
Mon Jun 30 13:28:59 2008 -0400 (2008-06-30)
changeset 306 cd3954499086
parent 303 2d450078e46e
child 307 95b6bcadd6c4
permissions -rw-r--r--
Get rid of razor_set_get_package().

This was always a silly little helper function, not general enough for
real world applications. Use an iterator to search through the set to
find the package of interest.
     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 NULL.
   116  *
   117  * Example: razor_package_iterator_next (pi, package, RAZOR_DETAIL_NAME, &name, 0);
   118  **/
   119 RAZOR_EXPORT int
   120 razor_package_iterator_next(struct razor_package_iterator *pi,
   121 			    struct razor_package **package, ...)
   122 {
   123 	va_list args;
   124 	int valid;
   125 	struct razor_package *p, *packages;
   126 
   127 	assert (pi != NULL);
   128 
   129 	if (pi->package) {
   130 		p = pi->package++;
   131 		valid = p < pi->end;
   132 	} else if (pi->index) {
   133 		packages = pi->set->packages.data;
   134 		p = &packages[pi->index->data];
   135 		pi->index = list_next(pi->index);
   136 		valid = 1;
   137 	} else
   138 		valid = 0;
   139 
   140 	if (valid == 0) {
   141 		*package = NULL;
   142 		goto out;
   143 	}
   144 
   145 	*package = p;
   146 
   147 	va_start(args, NULL);
   148 	razor_package_get_details_varg (pi->set, p, args);
   149 	va_end (args);
   150 out:
   151 	return valid;
   152 }
   153 
   154 RAZOR_EXPORT void
   155 razor_package_iterator_destroy(struct razor_package_iterator *pi)
   156 {
   157 	assert (pi != NULL);
   158 
   159 	if (pi->free_index)
   160 		free(pi->index);
   161 
   162 	free(pi);
   163 }
   164 
   165 RAZOR_EXPORT struct razor_property_iterator *
   166 razor_property_iterator_create(struct razor_set *set,
   167 			       struct razor_package *package)
   168 {
   169 	struct razor_property_iterator *pi;
   170 
   171 	assert (set != NULL);
   172 
   173 	pi = zalloc(sizeof *pi);
   174 	pi->set = set;
   175 
   176 	if (package) {
   177 		pi->index = list_first(&package->properties,
   178 				       &set->property_pool);
   179 	} else {
   180 		pi->property = set->properties.data;
   181 		pi->end = set->properties.data + set->properties.size;
   182 	}
   183 
   184 	return pi;
   185 }
   186 
   187 RAZOR_EXPORT int
   188 razor_property_iterator_next(struct razor_property_iterator *pi,
   189 			     struct razor_property **property,
   190 			     const char **name,
   191 			     uint32_t *flags,
   192 			     const char **version)
   193 {
   194 	char *pool;
   195 	int valid;
   196 	struct razor_property *p, *properties;
   197 
   198 	assert (pi != NULL);
   199 
   200 	if (pi->property) {
   201 		p = pi->property++;
   202 		valid = p < pi->end;
   203 	} else if (pi->index) {
   204 		properties = pi->set->properties.data;
   205 		p = &properties[pi->index->data];
   206 		pi->index = list_next(pi->index);
   207 		valid = 1;
   208 	} else
   209 		valid = 0;
   210 
   211 	if (valid) {
   212 		pool = pi->set->string_pool.data;
   213 		*property = p;
   214 		*name = &pool[p->name];
   215 		*flags = p->flags;
   216 		*version = &pool[p->version];
   217 	} else {
   218 		*property = NULL;
   219 	}
   220 
   221 	return valid;
   222 }
   223 
   224 RAZOR_EXPORT void
   225 razor_property_iterator_destroy(struct razor_property_iterator *pi)
   226 {
   227 	free(pi);
   228 }
   229 
   230 struct razor_package_query {
   231 	struct razor_set *set;
   232 	char *vector;
   233 	int count;
   234 };
   235 
   236 RAZOR_EXPORT struct razor_package_query *
   237 razor_package_query_create(struct razor_set *set)
   238 {
   239 	struct razor_package_query *pq;
   240 	int count;
   241 
   242 	assert (set != NULL);
   243 
   244 	pq = zalloc(sizeof *pq);
   245 	pq->set = set;
   246 	count = set->packages.size / sizeof(struct razor_package);
   247 	pq->vector = zalloc(count * sizeof(char));
   248 
   249 	return pq;
   250 }
   251 
   252 RAZOR_EXPORT void
   253 razor_package_query_add_package(struct razor_package_query *pq,
   254 				struct razor_package *p)
   255 {
   256 	struct razor_package *packages;
   257 
   258 	assert (pq != NULL);
   259 	assert (p != NULL);
   260 
   261 	packages = pq->set->packages.data;
   262 	pq->count += pq->vector[p - packages] ^ 1;
   263 	pq->vector[p - packages] = 1;
   264 }
   265 
   266 RAZOR_EXPORT void
   267 razor_package_query_add_iterator(struct razor_package_query *pq,
   268 				 struct razor_package_iterator *pi)
   269 {
   270 	struct razor_package *packages, *p;
   271 
   272 	assert (pq != NULL);
   273 	assert (pi != NULL);
   274 
   275 	packages = pq->set->packages.data;
   276 	while (razor_package_iterator_next(pi, &p, NULL)) {
   277 		pq->count += pq->vector[p - packages] ^ 1;
   278 		pq->vector[p - packages] = 1;
   279 	}
   280 }
   281 
   282 RAZOR_EXPORT struct razor_package_iterator *
   283 razor_package_query_finish(struct razor_package_query *pq)
   284 {
   285 	struct razor_package_iterator *pi;
   286 	struct razor_set *set;
   287 	struct list *index;
   288 	int i, j;
   289 
   290 	assert (pq != NULL);
   291 
   292 	set = pq->set;
   293 	if (pq->count > 0)
   294 		index = zalloc(pq->count * sizeof *index);
   295 	else
   296 		index = NULL;
   297 
   298 	for (i = 0, j = 0; j < pq->count; i++) {
   299 		if (!pq->vector[i])
   300 			continue;
   301 
   302 		index[j].data = i;
   303 		if (j == pq->count - 1)
   304 			index[j].flags = 0x80;
   305 		j++;
   306 	}
   307 
   308 	free(pq->vector);
   309 	free(pq);
   310 
   311 	pi = razor_package_iterator_create_with_index(set, index);
   312 	pi->free_index = 1;
   313 
   314 	return pi;
   315 }