librazor/iterator.c
author Richard Hughes <richard@hughsie.com>
Sun Jun 29 17:32:19 2008 +0100 (2008-06-29)
changeset 301 4124c37fd953
parent 278 97c12ddedfb3
child 302 9b71b537d175
permissions -rw-r--r--
protect all exported functions by checking the input parameters for NULL input
     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 <string.h>
    23 #include <assert.h>
    24 
    25 #include "razor-internal.h"
    26 #include "razor.h"
    27 
    28 static struct razor_package_iterator *
    29 razor_package_iterator_create_with_index(struct razor_set *set,
    30 					 struct list *index)
    31 {
    32 	struct razor_package_iterator *pi;
    33 
    34 	pi = zalloc(sizeof *pi);
    35 	pi->set = set;
    36 	pi->index = index;
    37 
    38 	return pi;
    39 }
    40 
    41 static struct razor_package_iterator *
    42 razor_package_iterator_create_empty(struct razor_set *set)
    43 {
    44 	struct razor_package_iterator *pi;
    45 	return zalloc(sizeof *pi);
    46 }
    47 
    48 RAZOR_EXPORT struct razor_package_iterator *
    49 razor_package_iterator_create(struct razor_set *set)
    50 {
    51 	struct razor_package_iterator *pi;
    52 
    53 	assert (set != NULL);
    54 
    55 	pi = zalloc(sizeof *pi);
    56 	pi->set = set;
    57 	pi->end = set->packages.data + set->packages.size;
    58 	pi->package = set->packages.data;
    59 
    60 	return pi;
    61 }
    62 
    63 RAZOR_EXPORT void
    64 razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
    65 					 struct razor_set *set,
    66 					 struct razor_property *property)
    67 {
    68 	assert (pi != NULL);
    69 	assert (set != NULL);
    70 	assert (property != NULL);
    71 
    72 	memset(pi, 0, sizeof *pi);
    73 	pi->set = set;
    74 	pi->index = list_first(&property->packages, &set->package_pool);
    75 }
    76 
    77 RAZOR_EXPORT struct razor_package_iterator *
    78 razor_package_iterator_create_for_property(struct razor_set *set,
    79 					   struct razor_property *property)
    80 {
    81 	struct list *index;
    82 
    83 	assert (set != NULL);
    84 	assert (property != NULL);
    85 
    86 	index = list_first(&property->packages, &set->package_pool);
    87 	return razor_package_iterator_create_with_index(set, index);
    88 }
    89 
    90 RAZOR_EXPORT struct razor_package_iterator *
    91 razor_package_iterator_create_for_file(struct razor_set *set,
    92 				       const char *filename)
    93 {
    94 	struct razor_entry *entry;
    95 	struct list *index;
    96 
    97 	assert (set != NULL);
    98 	assert (filename != NULL);
    99 
   100 	entry = razor_set_find_entry(set, set->files.data, filename);
   101 	if (entry == NULL)
   102 		return razor_package_iterator_create_empty(set);
   103 
   104 	index = list_first(&entry->packages, &set->package_pool);
   105 	return razor_package_iterator_create_with_index(set, index);
   106 }
   107 
   108 RAZOR_EXPORT int
   109 razor_package_iterator_next(struct razor_package_iterator *pi,
   110 			    struct razor_package **package,
   111 			    const char **name,
   112 			    const char **version,
   113 			    const char **arch)
   114 {
   115 	char *pool;
   116 	int valid;
   117 	struct razor_package *p, *packages;
   118 
   119 	assert (pi != NULL);
   120 
   121 	if (pi->package) {
   122 		p = pi->package++;
   123 		valid = p < pi->end;
   124 	} else if (pi->index) {
   125 		packages = pi->set->packages.data;
   126 		p = &packages[pi->index->data];
   127 		pi->index = list_next(pi->index);
   128 		valid = 1;
   129 	} else
   130 		valid = 0;
   131 
   132 	if (valid) {
   133 		pool = pi->set->string_pool.data;
   134 		*package = p;
   135 		*name = &pool[p->name];
   136 		*version = &pool[p->version];
   137 		*arch = &pool[p->arch];
   138 	} else {
   139 		*package = NULL;
   140 	}
   141 
   142 	return valid;
   143 }
   144 
   145 RAZOR_EXPORT void
   146 razor_package_iterator_destroy(struct razor_package_iterator *pi)
   147 {
   148 	assert (pi != NULL);
   149 
   150 	if (pi->free_index)
   151 		free(pi->index);
   152 
   153 	free(pi);
   154 }
   155 
   156 RAZOR_EXPORT struct razor_property_iterator *
   157 razor_property_iterator_create(struct razor_set *set,
   158 			       struct razor_package *package)
   159 {
   160 	struct razor_property_iterator *pi;
   161 
   162 	assert (set != NULL);
   163 	assert (package != NULL);
   164 
   165 	pi = zalloc(sizeof *pi);
   166 	pi->set = set;
   167 
   168 	if (package) {
   169 		pi->index = list_first(&package->properties,
   170 				       &set->property_pool);
   171 	} else {
   172 		pi->property = set->properties.data;
   173 		pi->end = set->properties.data + set->properties.size;
   174 	}
   175 
   176 	return pi;
   177 }
   178 
   179 RAZOR_EXPORT int
   180 razor_property_iterator_next(struct razor_property_iterator *pi,
   181 			     struct razor_property **property,
   182 			     const char **name,
   183 			     uint32_t *flags,
   184 			     const char **version)
   185 {
   186 	char *pool;
   187 	int valid;
   188 	struct razor_property *p, *properties;
   189 
   190 	assert (pi != NULL);
   191 
   192 	if (pi->property) {
   193 		p = pi->property++;
   194 		valid = p < pi->end;
   195 	} else if (pi->index) {
   196 		properties = pi->set->properties.data;
   197 		p = &properties[pi->index->data];
   198 		pi->index = list_next(pi->index);
   199 		valid = 1;
   200 	} else
   201 		valid = 0;
   202 
   203 	if (valid) {
   204 		pool = pi->set->string_pool.data;
   205 		*property = p;
   206 		*name = &pool[p->name];
   207 		*flags = p->flags;
   208 		*version = &pool[p->version];
   209 	} else {
   210 		*property = NULL;
   211 	}
   212 
   213 	return valid;
   214 }
   215 
   216 RAZOR_EXPORT void
   217 razor_property_iterator_destroy(struct razor_property_iterator *pi)
   218 {
   219 	free(pi);
   220 }
   221 
   222 struct razor_package_query {
   223 	struct razor_set *set;
   224 	char *vector;
   225 	int count;
   226 };
   227 
   228 RAZOR_EXPORT struct razor_package_query *
   229 razor_package_query_create(struct razor_set *set)
   230 {
   231 	struct razor_package_query *pq;
   232 	int count;
   233 
   234 	assert (set != NULL);
   235 
   236 	pq = zalloc(sizeof *pq);
   237 	pq->set = set;
   238 	count = set->packages.size / sizeof(struct razor_package);
   239 	pq->vector = zalloc(count * sizeof(char));
   240 
   241 	return pq;
   242 }
   243 
   244 RAZOR_EXPORT void
   245 razor_package_query_add_package(struct razor_package_query *pq,
   246 				struct razor_package *p)
   247 {
   248 	struct razor_package *packages;
   249 
   250 	assert (pq != NULL);
   251 	assert (p != NULL);
   252 
   253 	packages = pq->set->packages.data;
   254 	pq->count += pq->vector[p - packages] ^ 1;
   255 	pq->vector[p - packages] = 1;
   256 }
   257 
   258 RAZOR_EXPORT void
   259 razor_package_query_add_iterator(struct razor_package_query *pq,
   260 				 struct razor_package_iterator *pi)
   261 {
   262 	struct razor_package *packages, *p;
   263 	const char *name, *version, *arch;
   264 
   265 	assert (pq != NULL);
   266 	assert (pi != NULL);
   267 
   268 	packages = pq->set->packages.data;
   269 	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
   270 		pq->count += pq->vector[p - packages] ^ 1;
   271 		pq->vector[p - packages] = 1;
   272 	}
   273 }
   274 
   275 RAZOR_EXPORT struct razor_package_iterator *
   276 razor_package_query_finish(struct razor_package_query *pq)
   277 {
   278 	struct razor_package_iterator *pi;
   279 	struct razor_set *set;
   280 	struct list *index;
   281 	int i, j;
   282 
   283 	assert (pq != NULL);
   284 
   285 	set = pq->set;
   286 	if (pq->count > 0)
   287 		index = zalloc(pq->count * sizeof *index);
   288 	else
   289 		index = NULL;
   290 
   291 	for (i = 0, j = 0; j < pq->count; i++) {
   292 		if (!pq->vector[i])
   293 			continue;
   294 
   295 		index[j].data = i;
   296 		if (j == pq->count - 1)
   297 			index[j].flags = 0x80;
   298 		j++;
   299 	}
   300 
   301 	free(pq->vector);
   302 	free(pq);
   303 
   304 	pi = razor_package_iterator_create_with_index(set, index);
   305 	pi->free_index = 1;
   306 
   307 	return pi;
   308 }