librazor/iterator.c
author J. Ali Harlow <ali@juiblex.co.uk>
Mon Sep 08 10:26:39 2014 +0100 (2014-09-08)
changeset 445 aada48958b92
parent 438 fab0b8a61dcb
child 458 3f841a46eab5
permissions -rw-r--r--
Add control over database location
krh@248
     1
/*
krh@248
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
krh@248
     3
 * Copyright (C) 2008  Red Hat, Inc
ali@351
     4
 * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
krh@248
     5
 *
krh@248
     6
 * This program is free software; you can redistribute it and/or modify
krh@248
     7
 * it under the terms of the GNU General Public License as published by
krh@248
     8
 * the Free Software Foundation; either version 2 of the License, or
krh@248
     9
 * (at your option) any later version.
krh@248
    10
 *
krh@248
    11
 * This program is distributed in the hope that it will be useful,
krh@248
    12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
krh@248
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
krh@248
    14
 * GNU General Public License for more details.
krh@248
    15
 *
krh@248
    16
 * You should have received a copy of the GNU General Public License along
krh@248
    17
 * with this program; if not, write to the Free Software Foundation, Inc.,
krh@248
    18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
krh@248
    19
 */
krh@248
    20
krh@248
    21
#define _GNU_SOURCE
krh@248
    22
ali@438
    23
#include "config.h"
richard@302
    24
#include <stdarg.h>
krh@248
    25
#include <string.h>
richard@301
    26
#include <assert.h>
ali@442
    27
#include <stdio.h>
richard@301
    28
krh@248
    29
#include "razor-internal.h"
krh@248
    30
#include "razor.h"
krh@248
    31
krh@248
    32
static struct razor_package_iterator *
krh@248
    33
razor_package_iterator_create_with_index(struct razor_set *set,
krh@248
    34
					 struct list *index)
krh@248
    35
{
krh@248
    36
	struct razor_package_iterator *pi;
krh@248
    37
krh@248
    38
	pi = zalloc(sizeof *pi);
krh@248
    39
	pi->set = set;
krh@248
    40
	pi->index = index;
krh@248
    41
krh@248
    42
	return pi;
krh@248
    43
}
krh@248
    44
jbowes@278
    45
static struct razor_package_iterator *
jbowes@278
    46
razor_package_iterator_create_empty(struct razor_set *set)
jbowes@278
    47
{
jbowes@278
    48
	struct razor_package_iterator *pi;
jbowes@278
    49
	return zalloc(sizeof *pi);
jbowes@278
    50
}
jbowes@278
    51
krh@269
    52
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    53
razor_package_iterator_create(struct razor_set *set)
krh@248
    54
{
krh@248
    55
	struct razor_package_iterator *pi;
krh@248
    56
richard@301
    57
	assert (set != NULL);
richard@301
    58
krh@248
    59
	pi = zalloc(sizeof *pi);
krh@248
    60
	pi->set = set;
krh@248
    61
	pi->end = set->packages.data + set->packages.size;
krh@248
    62
	pi->package = set->packages.data;
krh@248
    63
krh@248
    64
	return pi;
krh@248
    65
}
krh@248
    66
krh@269
    67
RAZOR_EXPORT void
krh@248
    68
razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
krh@248
    69
					 struct razor_set *set,
krh@248
    70
					 struct razor_property *property)
krh@248
    71
{
richard@301
    72
	assert (pi != NULL);
richard@301
    73
	assert (set != NULL);
richard@301
    74
	assert (property != NULL);
richard@301
    75
krh@248
    76
	memset(pi, 0, sizeof *pi);
krh@248
    77
	pi->set = set;
krh@248
    78
	pi->index = list_first(&property->packages, &set->package_pool);
krh@248
    79
}
krh@248
    80
krh@269
    81
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    82
razor_package_iterator_create_for_property(struct razor_set *set,
krh@248
    83
					   struct razor_property *property)
krh@248
    84
{
krh@248
    85
	struct list *index;
krh@248
    86
richard@301
    87
	assert (set != NULL);
richard@301
    88
	assert (property != NULL);
richard@301
    89
krh@248
    90
	index = list_first(&property->packages, &set->package_pool);
krh@248
    91
	return razor_package_iterator_create_with_index(set, index);
krh@248
    92
}
krh@248
    93
krh@269
    94
RAZOR_EXPORT struct razor_package_iterator *
krh@248
    95
razor_package_iterator_create_for_file(struct razor_set *set,
krh@248
    96
				       const char *filename)
krh@248
    97
{
krh@248
    98
	struct razor_entry *entry;
krh@248
    99
	struct list *index;
krh@248
   100
richard@301
   101
	assert (set != NULL);
richard@301
   102
	assert (filename != NULL);
richard@301
   103
krh@248
   104
	entry = razor_set_find_entry(set, set->files.data, filename);
krh@248
   105
	if (entry == NULL)
jbowes@278
   106
		return razor_package_iterator_create_empty(set);
krh@248
   107
krh@248
   108
	index = list_first(&entry->packages, &set->package_pool);
krh@248
   109
	return razor_package_iterator_create_with_index(set, index);
krh@248
   110
}
krh@248
   111
richard@302
   112
/**
richard@302
   113
 * razor_package_iterator_next:
richard@302
   114
 * @pi: a %razor_package_iterator
richard@302
   115
 * @package: a %razor_package
richard@302
   116
 *
richard@302
   117
 * Gets the next iteratr along with any vararg data.
krh@308
   118
 * The vararg must be terminated with %RAZOR_DETAIL_LAST.
richard@302
   119
 *
richard@307
   120
 * Example: razor_package_iterator_next (pi, package,
richard@307
   121
 *					 RAZOR_DETAIL_NAME, &name,
richard@307
   122
 *					 RAZOR_DETAIL_LAST);
richard@302
   123
 **/
krh@269
   124
RAZOR_EXPORT int
krh@248
   125
razor_package_iterator_next(struct razor_package_iterator *pi,
richard@302
   126
			    struct razor_package **package, ...)
krh@248
   127
{
richard@302
   128
	va_list args;
krh@248
   129
	int valid;
krh@248
   130
	struct razor_package *p, *packages;
krh@248
   131
richard@301
   132
	assert (pi != NULL);
richard@301
   133
krh@248
   134
	if (pi->package) {
krh@248
   135
		p = pi->package++;
krh@248
   136
		valid = p < pi->end;
krh@248
   137
	} else if (pi->index) {
krh@248
   138
		packages = pi->set->packages.data;
krh@248
   139
		p = &packages[pi->index->data];
krh@248
   140
		pi->index = list_next(pi->index);
krh@248
   141
		valid = 1;
krh@248
   142
	} else
krh@248
   143
		valid = 0;
krh@248
   144
richard@302
   145
	if (valid == 0) {
krh@248
   146
		*package = NULL;
richard@302
   147
		goto out;
krh@248
   148
	}
krh@248
   149
richard@302
   150
	*package = p;
richard@302
   151
richard@302
   152
	va_start(args, NULL);
richard@302
   153
	razor_package_get_details_varg (pi->set, p, args);
richard@302
   154
	va_end (args);
richard@302
   155
out:
krh@248
   156
	return valid;
krh@248
   157
}
krh@248
   158
krh@269
   159
RAZOR_EXPORT void
krh@248
   160
razor_package_iterator_destroy(struct razor_package_iterator *pi)
krh@248
   161
{
richard@301
   162
	assert (pi != NULL);
richard@301
   163
krh@248
   164
	if (pi->free_index)
krh@248
   165
		free(pi->index);
krh@248
   166
krh@248
   167
	free(pi);
krh@248
   168
}
krh@248
   169
krh@269
   170
RAZOR_EXPORT struct razor_property_iterator *
krh@248
   171
razor_property_iterator_create(struct razor_set *set,
krh@248
   172
			       struct razor_package *package)
krh@248
   173
{
krh@248
   174
	struct razor_property_iterator *pi;
krh@248
   175
richard@301
   176
	assert (set != NULL);
richard@301
   177
krh@248
   178
	pi = zalloc(sizeof *pi);
krh@248
   179
	pi->set = set;
krh@248
   180
krh@248
   181
	if (package) {
krh@248
   182
		pi->index = list_first(&package->properties,
krh@248
   183
				       &set->property_pool);
krh@248
   184
	} else {
krh@248
   185
		pi->property = set->properties.data;
krh@248
   186
		pi->end = set->properties.data + set->properties.size;
krh@248
   187
	}
krh@248
   188
krh@248
   189
	return pi;
krh@248
   190
}
krh@248
   191
krh@269
   192
RAZOR_EXPORT int
krh@248
   193
razor_property_iterator_next(struct razor_property_iterator *pi,
krh@248
   194
			     struct razor_property **property,
krh@248
   195
			     const char **name,
krh@248
   196
			     uint32_t *flags,
krh@248
   197
			     const char **version)
krh@248
   198
{
krh@248
   199
	char *pool;
krh@248
   200
	int valid;
krh@248
   201
	struct razor_property *p, *properties;
krh@248
   202
richard@301
   203
	assert (pi != NULL);
richard@301
   204
krh@248
   205
	if (pi->property) {
krh@248
   206
		p = pi->property++;
krh@248
   207
		valid = p < pi->end;
krh@248
   208
	} else if (pi->index) {
krh@248
   209
		properties = pi->set->properties.data;
krh@248
   210
		p = &properties[pi->index->data];
krh@248
   211
		pi->index = list_next(pi->index);
krh@248
   212
		valid = 1;
krh@248
   213
	} else
krh@248
   214
		valid = 0;
krh@248
   215
krh@248
   216
	if (valid) {
krh@248
   217
		pool = pi->set->string_pool.data;
krh@248
   218
		*property = p;
krh@248
   219
		*name = &pool[p->name];
krh@248
   220
		*flags = p->flags;
krh@248
   221
		*version = &pool[p->version];
krh@248
   222
	} else {
krh@248
   223
		*property = NULL;
krh@248
   224
	}
krh@248
   225
krh@248
   226
	return valid;
krh@248
   227
}
krh@248
   228
krh@269
   229
RAZOR_EXPORT void
krh@248
   230
razor_property_iterator_destroy(struct razor_property_iterator *pi)
krh@248
   231
{
krh@248
   232
	free(pi);
krh@248
   233
}
krh@248
   234
ali@351
   235
RAZOR_EXPORT struct razor_file_iterator *
ali@377
   236
razor_file_iterator_create(struct razor_set *set, struct razor_package *package,
ali@377
   237
			   int post_order)
ali@351
   238
{
ali@351
   239
	struct razor_file_iterator *fi;
ali@351
   240
ali@351
   241
	assert (set != NULL);
ali@351
   242
	assert (package != NULL);
ali@351
   243
ali@351
   244
	fi = zalloc(sizeof *fi);
ali@351
   245
	fi->set = set;
ali@377
   246
	fi->post_order = post_order;
ali@377
   247
	if (post_order)
ali@377
   248
		fi->index = list_last(&package->files, &set->file_pool);
ali@377
   249
	else
ali@377
   250
		fi->index = list_first(&package->files, &set->file_pool);
ali@351
   251
	array_init(&fi->path);
ali@351
   252
ali@351
   253
	return fi;
ali@351
   254
}
ali@351
   255
ali@351
   256
RAZOR_EXPORT int
ali@351
   257
razor_file_iterator_next(struct razor_file_iterator *fi,
ali@351
   258
			 const char **name)
ali@351
   259
{
ali@351
   260
	struct razor_entry *e, *dir, *entries;
ali@351
   261
	char *pool, *s, *f;
ali@351
   262
ali@351
   263
	assert (fi != NULL);
ali@351
   264
ali@351
   265
	if (!fi->index) {
ali@351
   266
		*name = NULL;
ali@351
   267
		return 0;
ali@351
   268
	}
ali@351
   269
ali@351
   270
	entries = (struct razor_entry *) fi->set->files.data;
ali@351
   271
	pool = fi->set->file_string_pool.data;
ali@351
   272
ali@351
   273
	dir = entries;
ali@351
   274
	fi->path.size = 0;
ali@351
   275
	for(;;) {
ali@351
   276
		e = dir;
ali@351
   277
		do {
ali@351
   278
			if (entries + fi->index->data == e) {
ali@351
   279
				f = pool + e->name;
ali@351
   280
				s = array_add(&fi->path, strlen(f) + 1);
ali@351
   281
				strcpy(s, f);
ali@351
   282
				if (fi->path.size == 1) {
ali@351
   283
					array_add(&fi->path, 1);
ali@351
   284
					strcpy(fi->path.data, "/");
ali@351
   285
				}
ali@351
   286
				*name = fi->path.data;
ali@377
   287
				if (fi->post_order)
ali@377
   288
					fi->index = list_prev(fi->index);
ali@377
   289
				else
ali@377
   290
					fi->index = list_next(fi->index);
ali@351
   291
				return 1;
ali@351
   292
			}
ali@351
   293
		} while (!((e++)->flags & RAZOR_ENTRY_LAST));
ali@351
   294
		for(e--; e >= dir; e--)
ali@351
   295
			if (e->start && fi->index->data >= e->start)
ali@351
   296
				break;
ali@351
   297
		if (e < dir)
ali@351
   298
			break;
ali@351
   299
		f = pool + e->name;
ali@351
   300
		s = array_add(&fi->path, strlen(f) + 1);
ali@351
   301
		strcpy(s, f);
ali@351
   302
		s += strlen(f);
ali@351
   303
		*s = '/';
ali@351
   304
		dir = entries + e->start;
ali@351
   305
	}
ali@351
   306
ali@351
   307
	printf("file_iterator_next: Failed to find file %d\n",fi->index->data);
ali@351
   308
	*name = NULL;
ali@351
   309
	return 0;
ali@351
   310
}
ali@351
   311
ali@351
   312
RAZOR_EXPORT void razor_file_iterator_destroy(struct razor_file_iterator *fi)
ali@351
   313
{
ali@351
   314
	assert (fi != NULL);
ali@351
   315
ali@351
   316
	array_release(&fi->path);
ali@351
   317
	free(fi);
ali@351
   318
}
ali@351
   319
krh@248
   320
struct razor_package_query {
krh@248
   321
	struct razor_set *set;
krh@248
   322
	char *vector;
krh@248
   323
	int count;
krh@248
   324
};
krh@248
   325
krh@269
   326
RAZOR_EXPORT struct razor_package_query *
krh@248
   327
razor_package_query_create(struct razor_set *set)
krh@248
   328
{
krh@248
   329
	struct razor_package_query *pq;
krh@248
   330
	int count;
krh@248
   331
richard@301
   332
	assert (set != NULL);
richard@301
   333
krh@248
   334
	pq = zalloc(sizeof *pq);
krh@248
   335
	pq->set = set;
krh@248
   336
	count = set->packages.size / sizeof(struct razor_package);
krh@248
   337
	pq->vector = zalloc(count * sizeof(char));
krh@248
   338
krh@248
   339
	return pq;
krh@248
   340
}
krh@248
   341
krh@269
   342
RAZOR_EXPORT void
krh@248
   343
razor_package_query_add_package(struct razor_package_query *pq,
krh@248
   344
				struct razor_package *p)
krh@248
   345
{
krh@248
   346
	struct razor_package *packages;
krh@248
   347
richard@301
   348
	assert (pq != NULL);
richard@301
   349
	assert (p != NULL);
richard@301
   350
krh@248
   351
	packages = pq->set->packages.data;
krh@248
   352
	pq->count += pq->vector[p - packages] ^ 1;
krh@248
   353
	pq->vector[p - packages] = 1;
krh@248
   354
}
krh@248
   355
krh@269
   356
RAZOR_EXPORT void
krh@248
   357
razor_package_query_add_iterator(struct razor_package_query *pq,
krh@248
   358
				 struct razor_package_iterator *pi)
krh@248
   359
{
krh@248
   360
	struct razor_package *packages, *p;
krh@248
   361
richard@301
   362
	assert (pq != NULL);
richard@301
   363
	assert (pi != NULL);
richard@301
   364
krh@248
   365
	packages = pq->set->packages.data;
richard@307
   366
	while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST)) {
krh@248
   367
		pq->count += pq->vector[p - packages] ^ 1;
krh@248
   368
		pq->vector[p - packages] = 1;
krh@248
   369
	}
krh@248
   370
}
krh@248
   371
krh@269
   372
RAZOR_EXPORT struct razor_package_iterator *
krh@248
   373
razor_package_query_finish(struct razor_package_query *pq)
krh@248
   374
{
krh@248
   375
	struct razor_package_iterator *pi;
krh@248
   376
	struct razor_set *set;
krh@248
   377
	struct list *index;
krh@251
   378
	int i, j;
krh@248
   379
richard@301
   380
	assert (pq != NULL);
richard@301
   381
krh@248
   382
	set = pq->set;
krh@251
   383
	if (pq->count > 0)
krh@251
   384
		index = zalloc(pq->count * sizeof *index);
krh@251
   385
	else
krh@251
   386
		index = NULL;
krh@248
   387
krh@267
   388
	for (i = 0, j = 0; j < pq->count; i++) {
krh@248
   389
		if (!pq->vector[i])
krh@248
   390
			continue;
krh@248
   391
krh@248
   392
		index[j].data = i;
krh@248
   393
		if (j == pq->count - 1)
krh@248
   394
			index[j].flags = 0x80;
krh@248
   395
		j++;
krh@248
   396
	}
krh@248
   397
krh@251
   398
	free(pq->vector);
krh@248
   399
	free(pq);
krh@248
   400
krh@248
   401
	pi = razor_package_iterator_create_with_index(set, index);
krh@248
   402
	pi->free_index = 1;
krh@248
   403
krh@248
   404
	return pi;
krh@248
   405
}