1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/librazor/iterator.c Fri Jun 20 19:04:47 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 +}