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
krh@248
     1
/*
krh@248
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
krh@248
     3
 * Copyright (C) 2008  Red Hat, Inc
krh@248
     4
 *
krh@248
     5
 * This program is free software; you can redistribute it and/or modify
krh@248
     6
 * it under the terms of the GNU General Public License as published by
krh@248
     7
 * the Free Software Foundation; either version 2 of the License, or
krh@248
     8
 * (at your option) any later version.
krh@248
     9
 *
krh@248
    10
 * This program is distributed in the hope that it will be useful,
krh@248
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
krh@248
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
krh@248
    13
 * GNU General Public License for more details.
krh@248
    14
 *
krh@248
    15
 * You should have received a copy of the GNU General Public License along
krh@248
    16
 * with this program; if not, write to the Free Software Foundation, Inc.,
krh@248
    17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
krh@248
    18
 */
krh@248
    19
krh@248
    20
#define _GNU_SOURCE
krh@248
    21
krh@248
    22
#include <string.h>
richard@301
    23
#include <assert.h>
richard@301
    24
krh@248
    25
#include "razor-internal.h"
krh@248
    26
#include "razor.h"
krh@248
    27
krh@248
    28
static struct razor_package_iterator *
krh@248
    29
razor_package_iterator_create_with_index(struct razor_set *set,
krh@248
    30
					 struct list *index)
krh@248
    31
{
krh@248
    32
	struct razor_package_iterator *pi;
krh@248
    33
krh@248
    34
	pi = zalloc(sizeof *pi);
krh@248
    35
	pi->set = set;
krh@248
    36
	pi->index = index;
krh@248
    37
krh@248
    38
	return pi;
krh@248
    39
}
krh@248
    40
jbowes@278
    41
static struct razor_package_iterator *
jbowes@278
    42
razor_package_iterator_create_empty(struct razor_set *set)
jbowes@278
    43
{
jbowes@278
    44
	struct razor_package_iterator *pi;
jbowes@278
    45
	return zalloc(sizeof *pi);
jbowes@278
    46
}
jbowes@278
    47
krh@269
    48
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    49
razor_package_iterator_create(struct razor_set *set)
krh@248
    50
{
krh@248
    51
	struct razor_package_iterator *pi;
krh@248
    52
richard@301
    53
	assert (set != NULL);
richard@301
    54
krh@248
    55
	pi = zalloc(sizeof *pi);
krh@248
    56
	pi->set = set;
krh@248
    57
	pi->end = set->packages.data + set->packages.size;
krh@248
    58
	pi->package = set->packages.data;
krh@248
    59
krh@248
    60
	return pi;
krh@248
    61
}
krh@248
    62
krh@269
    63
RAZOR_EXPORT void
krh@248
    64
razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
krh@248
    65
					 struct razor_set *set,
krh@248
    66
					 struct razor_property *property)
krh@248
    67
{
richard@301
    68
	assert (pi != NULL);
richard@301
    69
	assert (set != NULL);
richard@301
    70
	assert (property != NULL);
richard@301
    71
krh@248
    72
	memset(pi, 0, sizeof *pi);
krh@248
    73
	pi->set = set;
krh@248
    74
	pi->index = list_first(&property->packages, &set->package_pool);
krh@248
    75
}
krh@248
    76
krh@269
    77
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    78
razor_package_iterator_create_for_property(struct razor_set *set,
krh@248
    79
					   struct razor_property *property)
krh@248
    80
{
krh@248
    81
	struct list *index;
krh@248
    82
richard@301
    83
	assert (set != NULL);
richard@301
    84
	assert (property != NULL);
richard@301
    85
krh@248
    86
	index = list_first(&property->packages, &set->package_pool);
krh@248
    87
	return razor_package_iterator_create_with_index(set, index);
krh@248
    88
}
krh@248
    89
krh@269
    90
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    91
razor_package_iterator_create_for_file(struct razor_set *set,
krh@248
    92
				       const char *filename)
krh@248
    93
{
krh@248
    94
	struct razor_entry *entry;
krh@248
    95
	struct list *index;
krh@248
    96
richard@301
    97
	assert (set != NULL);
richard@301
    98
	assert (filename != NULL);
richard@301
    99
krh@248
   100
	entry = razor_set_find_entry(set, set->files.data, filename);
krh@248
   101
	if (entry == NULL)
jbowes@278
   102
		return razor_package_iterator_create_empty(set);
krh@248
   103
krh@248
   104
	index = list_first(&entry->packages, &set->package_pool);
krh@248
   105
	return razor_package_iterator_create_with_index(set, index);
krh@248
   106
}
krh@248
   107
krh@269
   108
RAZOR_EXPORT int
krh@248
   109
razor_package_iterator_next(struct razor_package_iterator *pi,
krh@248
   110
			    struct razor_package **package,
krh@248
   111
			    const char **name,
krh@248
   112
			    const char **version,
krh@248
   113
			    const char **arch)
krh@248
   114
{
krh@248
   115
	char *pool;
krh@248
   116
	int valid;
krh@248
   117
	struct razor_package *p, *packages;
krh@248
   118
richard@301
   119
	assert (pi != NULL);
richard@301
   120
krh@248
   121
	if (pi->package) {
krh@248
   122
		p = pi->package++;
krh@248
   123
		valid = p < pi->end;
krh@248
   124
	} else if (pi->index) {
krh@248
   125
		packages = pi->set->packages.data;
krh@248
   126
		p = &packages[pi->index->data];
krh@248
   127
		pi->index = list_next(pi->index);
krh@248
   128
		valid = 1;
krh@248
   129
	} else
krh@248
   130
		valid = 0;
krh@248
   131
krh@248
   132
	if (valid) {
krh@248
   133
		pool = pi->set->string_pool.data;
krh@248
   134
		*package = p;
krh@248
   135
		*name = &pool[p->name];
krh@248
   136
		*version = &pool[p->version];
krh@248
   137
		*arch = &pool[p->arch];
krh@248
   138
	} else {
krh@248
   139
		*package = NULL;
krh@248
   140
	}
krh@248
   141
krh@248
   142
	return valid;
krh@248
   143
}
krh@248
   144
krh@269
   145
RAZOR_EXPORT void
krh@248
   146
razor_package_iterator_destroy(struct razor_package_iterator *pi)
krh@248
   147
{
richard@301
   148
	assert (pi != NULL);
richard@301
   149
krh@248
   150
	if (pi->free_index)
krh@248
   151
		free(pi->index);
krh@248
   152
krh@248
   153
	free(pi);
krh@248
   154
}
krh@248
   155
krh@269
   156
RAZOR_EXPORT struct razor_property_iterator *
krh@248
   157
razor_property_iterator_create(struct razor_set *set,
krh@248
   158
			       struct razor_package *package)
krh@248
   159
{
krh@248
   160
	struct razor_property_iterator *pi;
krh@248
   161
richard@301
   162
	assert (set != NULL);
richard@301
   163
	assert (package != NULL);
richard@301
   164
krh@248
   165
	pi = zalloc(sizeof *pi);
krh@248
   166
	pi->set = set;
krh@248
   167
krh@248
   168
	if (package) {
krh@248
   169
		pi->index = list_first(&package->properties,
krh@248
   170
				       &set->property_pool);
krh@248
   171
	} else {
krh@248
   172
		pi->property = set->properties.data;
krh@248
   173
		pi->end = set->properties.data + set->properties.size;
krh@248
   174
	}
krh@248
   175
krh@248
   176
	return pi;
krh@248
   177
}
krh@248
   178
krh@269
   179
RAZOR_EXPORT int
krh@248
   180
razor_property_iterator_next(struct razor_property_iterator *pi,
krh@248
   181
			     struct razor_property **property,
krh@248
   182
			     const char **name,
krh@248
   183
			     uint32_t *flags,
krh@248
   184
			     const char **version)
krh@248
   185
{
krh@248
   186
	char *pool;
krh@248
   187
	int valid;
krh@248
   188
	struct razor_property *p, *properties;
krh@248
   189
richard@301
   190
	assert (pi != NULL);
richard@301
   191
krh@248
   192
	if (pi->property) {
krh@248
   193
		p = pi->property++;
krh@248
   194
		valid = p < pi->end;
krh@248
   195
	} else if (pi->index) {
krh@248
   196
		properties = pi->set->properties.data;
krh@248
   197
		p = &properties[pi->index->data];
krh@248
   198
		pi->index = list_next(pi->index);
krh@248
   199
		valid = 1;
krh@248
   200
	} else
krh@248
   201
		valid = 0;
krh@248
   202
krh@248
   203
	if (valid) {
krh@248
   204
		pool = pi->set->string_pool.data;
krh@248
   205
		*property = p;
krh@248
   206
		*name = &pool[p->name];
krh@248
   207
		*flags = p->flags;
krh@248
   208
		*version = &pool[p->version];
krh@248
   209
	} else {
krh@248
   210
		*property = NULL;
krh@248
   211
	}
krh@248
   212
krh@248
   213
	return valid;
krh@248
   214
}
krh@248
   215
krh@269
   216
RAZOR_EXPORT void
krh@248
   217
razor_property_iterator_destroy(struct razor_property_iterator *pi)
krh@248
   218
{
krh@248
   219
	free(pi);
krh@248
   220
}
krh@248
   221
krh@248
   222
struct razor_package_query {
krh@248
   223
	struct razor_set *set;
krh@248
   224
	char *vector;
krh@248
   225
	int count;
krh@248
   226
};
krh@248
   227
krh@269
   228
RAZOR_EXPORT struct razor_package_query *
krh@248
   229
razor_package_query_create(struct razor_set *set)
krh@248
   230
{
krh@248
   231
	struct razor_package_query *pq;
krh@248
   232
	int count;
krh@248
   233
richard@301
   234
	assert (set != NULL);
richard@301
   235
krh@248
   236
	pq = zalloc(sizeof *pq);
krh@248
   237
	pq->set = set;
krh@248
   238
	count = set->packages.size / sizeof(struct razor_package);
krh@248
   239
	pq->vector = zalloc(count * sizeof(char));
krh@248
   240
krh@248
   241
	return pq;
krh@248
   242
}
krh@248
   243
krh@269
   244
RAZOR_EXPORT void
krh@248
   245
razor_package_query_add_package(struct razor_package_query *pq,
krh@248
   246
				struct razor_package *p)
krh@248
   247
{
krh@248
   248
	struct razor_package *packages;
krh@248
   249
richard@301
   250
	assert (pq != NULL);
richard@301
   251
	assert (p != NULL);
richard@301
   252
krh@248
   253
	packages = pq->set->packages.data;
krh@248
   254
	pq->count += pq->vector[p - packages] ^ 1;
krh@248
   255
	pq->vector[p - packages] = 1;
krh@248
   256
}
krh@248
   257
krh@269
   258
RAZOR_EXPORT void
krh@248
   259
razor_package_query_add_iterator(struct razor_package_query *pq,
krh@248
   260
				 struct razor_package_iterator *pi)
krh@248
   261
{
krh@248
   262
	struct razor_package *packages, *p;
krh@248
   263
	const char *name, *version, *arch;
krh@248
   264
richard@301
   265
	assert (pq != NULL);
richard@301
   266
	assert (pi != NULL);
richard@301
   267
krh@248
   268
	packages = pq->set->packages.data;
krh@248
   269
	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
krh@248
   270
		pq->count += pq->vector[p - packages] ^ 1;
krh@248
   271
		pq->vector[p - packages] = 1;
krh@248
   272
	}
krh@248
   273
}
krh@248
   274
krh@269
   275
RAZOR_EXPORT struct razor_package_iterator *
krh@248
   276
razor_package_query_finish(struct razor_package_query *pq)
krh@248
   277
{
krh@248
   278
	struct razor_package_iterator *pi;
krh@248
   279
	struct razor_set *set;
krh@248
   280
	struct list *index;
krh@251
   281
	int i, j;
krh@248
   282
richard@301
   283
	assert (pq != NULL);
richard@301
   284
krh@248
   285
	set = pq->set;
krh@251
   286
	if (pq->count > 0)
krh@251
   287
		index = zalloc(pq->count * sizeof *index);
krh@251
   288
	else
krh@251
   289
		index = NULL;
krh@248
   290
krh@267
   291
	for (i = 0, j = 0; j < pq->count; i++) {
krh@248
   292
		if (!pq->vector[i])
krh@248
   293
			continue;
krh@248
   294
krh@248
   295
		index[j].data = i;
krh@248
   296
		if (j == pq->count - 1)
krh@248
   297
			index[j].flags = 0x80;
krh@248
   298
		j++;
krh@248
   299
	}
krh@248
   300
krh@251
   301
	free(pq->vector);
krh@248
   302
	free(pq);
krh@248
   303
krh@248
   304
	pi = razor_package_iterator_create_with_index(set, index);
krh@248
   305
	pi->free_index = 1;
krh@248
   306
krh@248
   307
	return pi;
krh@248
   308
}