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