librazor/iterator.c
changeset 250 ce5402017488
child 251 d8b3c713aa42
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/librazor/iterator.c	Fri Jun 20 18:26:46 2008 -0400
     1.3 @@ -0,0 +1,265 @@
     1.4 +/*
     1.5 + * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     1.6 + * Copyright (C) 2008  Red Hat, Inc
     1.7 + *
     1.8 + * This program is free software; you can redistribute it and/or modify
     1.9 + * it under the terms of the GNU General Public License as published by
    1.10 + * the Free Software Foundation; either version 2 of the License, or
    1.11 + * (at your option) any later version.
    1.12 + *
    1.13 + * This program is distributed in the hope that it will be useful,
    1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 + * GNU General Public License for more details.
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License along
    1.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
    1.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + */
    1.22 +
    1.23 +#define _GNU_SOURCE
    1.24 +
    1.25 +#include <string.h>
    1.26 +#include "razor-internal.h"
    1.27 +#include "razor.h"
    1.28 +
    1.29 +static struct razor_package_iterator *
    1.30 +razor_package_iterator_create_with_index(struct razor_set *set,
    1.31 +					 struct list *index)
    1.32 +{
    1.33 +	struct razor_package_iterator *pi;
    1.34 +
    1.35 +	pi = zalloc(sizeof *pi);
    1.36 +	pi->set = set;
    1.37 +	pi->index = index;
    1.38 +
    1.39 +	return pi;
    1.40 +}
    1.41 +
    1.42 +struct razor_package_iterator *
    1.43 +razor_package_iterator_create(struct razor_set *set)
    1.44 +{
    1.45 +	struct razor_package_iterator *pi;
    1.46 +
    1.47 +	pi = zalloc(sizeof *pi);
    1.48 +	pi->set = set;
    1.49 +	pi->end = set->packages.data + set->packages.size;
    1.50 +	pi->package = set->packages.data;
    1.51 +
    1.52 +	return pi;
    1.53 +}
    1.54 +
    1.55 +void
    1.56 +razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
    1.57 +					 struct razor_set *set,
    1.58 +					 struct razor_property *property)
    1.59 +{
    1.60 +	memset(pi, 0, sizeof *pi);
    1.61 +	pi->set = set;
    1.62 +	pi->index = list_first(&property->packages, &set->package_pool);
    1.63 +}
    1.64 +
    1.65 +struct razor_package_iterator *
    1.66 +razor_package_iterator_create_for_property(struct razor_set *set,
    1.67 +					   struct razor_property *property)
    1.68 +{
    1.69 +	struct list *index;
    1.70 +
    1.71 +	index = list_first(&property->packages, &set->package_pool);
    1.72 +	return razor_package_iterator_create_with_index(set, index);
    1.73 +}
    1.74 +
    1.75 +struct razor_package_iterator *
    1.76 +razor_package_iterator_create_for_file(struct razor_set *set,
    1.77 +				       const char *filename)
    1.78 +{
    1.79 +	struct razor_entry *entry;
    1.80 +	struct list *index;
    1.81 +
    1.82 +	entry = razor_set_find_entry(set, set->files.data, filename);
    1.83 +	if (entry == NULL)
    1.84 +		return NULL;
    1.85 +
    1.86 +	index = list_first(&entry->packages, &set->package_pool);
    1.87 +	return razor_package_iterator_create_with_index(set, index);
    1.88 +}
    1.89 +
    1.90 +int
    1.91 +razor_package_iterator_next(struct razor_package_iterator *pi,
    1.92 +			    struct razor_package **package,
    1.93 +			    const char **name,
    1.94 +			    const char **version,
    1.95 +			    const char **arch)
    1.96 +{
    1.97 +	char *pool;
    1.98 +	int valid;
    1.99 +	struct razor_package *p, *packages;
   1.100 +
   1.101 +	if (pi->package) {
   1.102 +		p = pi->package++;
   1.103 +		valid = p < pi->end;
   1.104 +	} else if (pi->index) {
   1.105 +		packages = pi->set->packages.data;
   1.106 +		p = &packages[pi->index->data];
   1.107 +		pi->index = list_next(pi->index);
   1.108 +		valid = 1;
   1.109 +	} else
   1.110 +		valid = 0;
   1.111 +
   1.112 +	if (valid) {
   1.113 +		pool = pi->set->string_pool.data;
   1.114 +		*package = p;
   1.115 +		*name = &pool[p->name];
   1.116 +		*version = &pool[p->version];
   1.117 +		*arch = &pool[p->arch];
   1.118 +	} else {
   1.119 +		*package = NULL;
   1.120 +	}
   1.121 +
   1.122 +	return valid;
   1.123 +}
   1.124 +
   1.125 +void
   1.126 +razor_package_iterator_destroy(struct razor_package_iterator *pi)
   1.127 +{
   1.128 +	if (pi->free_index)
   1.129 +		free(pi->index);
   1.130 +
   1.131 +	free(pi);
   1.132 +}
   1.133 +
   1.134 +struct razor_property_iterator *
   1.135 +razor_property_iterator_create(struct razor_set *set,
   1.136 +			       struct razor_package *package)
   1.137 +{
   1.138 +	struct razor_property_iterator *pi;
   1.139 +
   1.140 +	pi = zalloc(sizeof *pi);
   1.141 +	pi->set = set;
   1.142 +
   1.143 +	if (package) {
   1.144 +		pi->index = list_first(&package->properties,
   1.145 +				       &set->property_pool);
   1.146 +	} else {
   1.147 +		pi->property = set->properties.data;
   1.148 +		pi->end = set->properties.data + set->properties.size;
   1.149 +	}
   1.150 +
   1.151 +	return pi;
   1.152 +}
   1.153 +
   1.154 +int
   1.155 +razor_property_iterator_next(struct razor_property_iterator *pi,
   1.156 +			     struct razor_property **property,
   1.157 +			     const char **name,
   1.158 +			     uint32_t *flags,
   1.159 +			     const char **version)
   1.160 +{
   1.161 +	char *pool;
   1.162 +	int valid;
   1.163 +	struct razor_property *p, *properties;
   1.164 +
   1.165 +	if (pi->property) {
   1.166 +		p = pi->property++;
   1.167 +		valid = p < pi->end;
   1.168 +	} else if (pi->index) {
   1.169 +		properties = pi->set->properties.data;
   1.170 +		p = &properties[pi->index->data];
   1.171 +		pi->index = list_next(pi->index);
   1.172 +		valid = 1;
   1.173 +	} else
   1.174 +		valid = 0;
   1.175 +
   1.176 +	if (valid) {
   1.177 +		pool = pi->set->string_pool.data;
   1.178 +		*property = p;
   1.179 +		*name = &pool[p->name];
   1.180 +		*flags = p->flags;
   1.181 +		*version = &pool[p->version];
   1.182 +	} else {
   1.183 +		*property = NULL;
   1.184 +	}
   1.185 +
   1.186 +	return valid;
   1.187 +}
   1.188 +
   1.189 +void
   1.190 +razor_property_iterator_destroy(struct razor_property_iterator *pi)
   1.191 +{
   1.192 +	free(pi);
   1.193 +}
   1.194 +
   1.195 +struct razor_package_query {
   1.196 +	struct razor_set *set;
   1.197 +	char *vector;
   1.198 +	int count;
   1.199 +};
   1.200 +
   1.201 +struct razor_package_query *
   1.202 +razor_package_query_create(struct razor_set *set)
   1.203 +{
   1.204 +	struct razor_package_query *pq;
   1.205 +	int count;
   1.206 +
   1.207 +	pq = zalloc(sizeof *pq);
   1.208 +	pq->set = set;
   1.209 +	count = set->packages.size / sizeof(struct razor_package);
   1.210 +	pq->vector = zalloc(count * sizeof(char));
   1.211 +
   1.212 +	return pq;
   1.213 +}
   1.214 +
   1.215 +void
   1.216 +razor_package_query_add_package(struct razor_package_query *pq,
   1.217 +				struct razor_package *p)
   1.218 +{
   1.219 +	struct razor_package *packages;
   1.220 +
   1.221 +	packages = pq->set->packages.data;
   1.222 +	pq->count += pq->vector[p - packages] ^ 1;
   1.223 +	pq->vector[p - packages] = 1;
   1.224 +}
   1.225 +
   1.226 +void
   1.227 +razor_package_query_add_iterator(struct razor_package_query *pq,
   1.228 +				 struct razor_package_iterator *pi)
   1.229 +{
   1.230 +	struct razor_package *packages, *p;
   1.231 +	const char *name, *version, *arch;
   1.232 +
   1.233 +	packages = pq->set->packages.data;
   1.234 +	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
   1.235 +		pq->count += pq->vector[p - packages] ^ 1;
   1.236 +		pq->vector[p - packages] = 1;
   1.237 +	}
   1.238 +}
   1.239 +
   1.240 +struct razor_package_iterator *
   1.241 +razor_package_query_finish(struct razor_package_query *pq)
   1.242 +{
   1.243 +	struct razor_package_iterator *pi;
   1.244 +	struct razor_set *set;
   1.245 +	struct list *index;
   1.246 +	int i, j, count;
   1.247 +
   1.248 +	set = pq->set;
   1.249 +	count = set->packages.size / sizeof(struct razor_package);
   1.250 +	index = zalloc(pq->count * sizeof *index);
   1.251 +
   1.252 +	for (i = 0, j = 0; i < count; i++) {
   1.253 +		if (!pq->vector[i])
   1.254 +			continue;
   1.255 +
   1.256 +		index[j].data = i;
   1.257 +		if (j == pq->count - 1)
   1.258 +			index[j].flags = 0x80;
   1.259 +		j++;
   1.260 +	}
   1.261 +
   1.262 +	free(pq);
   1.263 +
   1.264 +	pi = razor_package_iterator_create_with_index(set, index);
   1.265 +	pi->free_index = 1;
   1.266 +
   1.267 +	return pi;
   1.268 +}