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