return repo_add_appdata_fn(repo, fp, flags, 0, 0);
}
+struct uninternalized_filelist_data {
+ Id did;
+ Queue *res;
+};
+
+static int
+search_uninternalized_filelist_cb(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+{
+ struct uninternalized_filelist_data *uf = cbdata;
+ const char *str;
+ Id id;
+ size_t l;
+ if (key->type != REPOKEY_TYPE_DIRSTRARRAY || kv->id != uf->did)
+ return 0;
+ str = kv->str;
+ l = strlen(str);
+ if (l > 12 && strncmp(str + l - 12, ".appdata.xml", 12))
+ id = pool_str2id(data->repo->pool, str, 1);
+ else if (l > 13 && strncmp(str + l - 13, ".metainfo.xml", 13))
+ id = pool_str2id(data->repo->pool, str, 1);
+ else
+ return 0;
+ queue_push2(uf->res, s - data->repo->pool->solvables, id);
+ return 0;
+}
+
static void
search_uninternalized_filelist(Repo *repo, const char *dir, Queue *res)
{
Pool *pool = repo->pool;
- Id rdid, p;
- Id iter, did, idid;
+ Id did, rdid, p;
+ struct uninternalized_filelist_data uf;
+ uf.res = res;
for (rdid = 1; rdid < repo->nrepodata; rdid++)
{
Repodata *data = repo_id2repodata(repo, rdid);
did = repodata_str2dir(data, dir, 0);
if (!did)
continue;
+ uf.did = did;
for (p = data->start; p < data->end; p++)
{
- if (p >= pool->nsolvables)
+ if (p >= pool->nsolvables || pool->solvables[p].repo != repo)
continue;
- if (pool->solvables[p].repo != repo)
- continue;
- iter = 0;
- for (;;)
- {
- const char *str;
- int l;
- Id id;
- idid = did;
- str = repodata_lookup_dirstrarray_uninternalized(data, p, SOLVABLE_FILELIST, &idid, &iter);
- if (!iter)
- break;
- l = strlen(str);
- if (l > 12 && strncmp(str + l - 12, ".appdata.xml", 12))
- id = pool_str2id(pool, str, 1);
- else if (l > 13 && strncmp(str + l - 13, ".metainfo.xml", 13))
- id = pool_str2id(pool, str, 1);
- else
- continue;
- queue_push2(res, p, id);
- }
+ repodata_search_uninternalized(data, p, SOLVABLE_FILELIST, 0, search_uninternalized_filelist_cb, &uf);
}
}
}
fill_cshash_from_new_solvables(struct parsedata *pd)
{
Pool *pool = pd->pool;
- Id cstype = 0;
- unsigned const char *cs;
- int i;
+ int i, l;
+ KeyValue kv;
+ Repokey *key;
for (i = pd->first; i < pool->nsolvables; i++)
{
if (pool->solvables[i].repo != pd->repo)
continue;
- cs = repodata_lookup_bin_checksum_uninternalized(pd->data, i, SOLVABLE_CHECKSUM, &cstype);
- if (cs)
- put_in_cshash(pd, cs, solv_chksum_len(cstype), i);
+ if ((key = repodata_lookup_kv_uninternalized(pd->data, i, SOLVABLE_CHECKSUM, &kv)) == 0)
+ continue;
+ if ((l = solv_chksum_len(key->type)) != 0)
+ put_in_cshash(pd, (const unsigned char *)kv.str, l, i);
}
}
return r;
}
if (uninternalized)
- return repodata_lookup_id_uninternalized(data, p, keyname, voidid);
+ {
+ KeyValue kv;
+ Repokey *key = repodata_lookup_kv_uninternalized(data, p, keyname, &kv);
+ if (!key)
+ return 0;
+ if (key->type == REPOKEY_TYPE_VOID)
+ return voidid;
+ if (key->type == REPOKEY_TYPE_ID)
+ return kv.id;
+ }
return 0;
}
repodata_key2id;
repodata_localize_id;
repodata_lookup_bin_checksum;
- repodata_lookup_bin_checksum_uninternalized;
repodata_lookup_binary;
- repodata_lookup_dirstrarray_uninternalized;
repodata_lookup_id;
- repodata_lookup_id_uninternalized;
repodata_lookup_idarray;
+ repodata_lookup_kv_uninternalized;
repodata_lookup_num;
repodata_lookup_str;
repodata_lookup_type;
repodata_search;
repodata_search_arrayelement;
repodata_search_keyskip;
+ repodata_search_uninternalized;
repodata_set_binary;
repodata_set_bin_checksum;
repodata_set_checksum;
return compid;
}
-/* uninternalized lookups */
+/************************************************************************
+ * uninternalized lookup / search
+ */
-Id
-repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid)
+static void
+data_fetch_uninternalized(Repodata *data, Repokey *key, Id value, KeyValue *kv)
+{
+ Id *array;
+ kv->eof = 1;
+ switch (key->type)
+ {
+ case REPOKEY_TYPE_STR:
+ kv->str = (const char *)data->attrdata + value;
+ return;
+ case REPOKEY_TYPE_CONSTANT:
+ kv->num2 = 0;
+ kv->num = key->size;
+ return;
+ case REPOKEY_TYPE_CONSTANTID:
+ kv->id = key->size;
+ return;
+ case REPOKEY_TYPE_NUM:
+ kv->num2 = 0;
+ kv->num = value;
+ if (value & 0x80000000)
+ {
+ kv->num = (unsigned int)data->attrnum64data[value ^ 0x80000000];
+ kv->num2 = (unsigned int)(data->attrnum64data[value ^ 0x80000000] >> 32);
+ }
+ return;
+ case_CHKSUM_TYPES:
+ kv->num = 0; /* not stringified */
+ kv->str = (const char *)data->attrdata + value;
+ return;
+ case REPOKEY_TYPE_IDARRAY:
+ array = data->attriddata + (value + kv->entry);
+ kv->id = array[0];
+ kv->eof = array[1] ? 0 : 1;
+ return;
+ case REPOKEY_TYPE_DIRSTRARRAY:
+ kv->num = 0; /* not stringified */
+ array = data->attriddata + (value + kv->entry * 2);
+ kv->id = array[0];
+ kv->str = (const char *)data->attrdata + array[1];
+ kv->eof = array[2] ? 0 : 1;
+ return;
+ case REPOKEY_TYPE_DIRNUMNUMARRAY:
+ array = data->attriddata + (value + kv->entry * 3);
+ kv->id = array[0];
+ kv->num = array[1];
+ kv->num2 = array[2];
+ kv->eof = array[3] ? 0 : 1;
+ return;
+ case REPOKEY_TYPE_FIXARRAY:
+ case REPOKEY_TYPE_FLEXARRAY:
+ array = data->attriddata + (value + kv->entry);
+ kv->id = array[0]; /* the handle */
+ kv->eof = array[1] ? 0 : 1;
+ return;
+ default:
+ kv->id = value;
+ return;
+ }
+}
+
+Repokey *
+repodata_lookup_kv_uninternalized(Repodata *data, Id solvid, Id keyname, KeyValue *kv)
{
Id *ap;
- if (!data->attrs)
+ if (!data->attrs || solvid < data->start || solvid >= data->end)
return 0;
ap = data->attrs[solvid - data->start];
if (!ap)
return 0;
for (; *ap; ap += 2)
{
- if (data->keys[*ap].name != keyname)
+ Repokey *key = data->keys + *ap;
+ if (key->name != keyname)
continue;
- if (data->keys[*ap].type == REPOKEY_TYPE_VOID)
- return voidid;
- if (data->keys[*ap].type == REPOKEY_TYPE_ID)
- return ap[1];
- return 0;
+ data_fetch_uninternalized(data, key, ap[1], kv);
+ return key;
}
return 0;
}
-/* returns the basename, stores the dir id in didp */
-const char *
-repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname, Id *didp, Id *iterp)
-{
- Id *ap, did;
- Id iter = *iterp;
- if (iter == 0) /* find key data */
- {
- if (!data->attrs)
- return 0;
- ap = data->attrs[solvid - data->start];
- if (!ap)
- return 0;
- for (; *ap; ap += 2)
- if (data->keys[*ap].name == keyname && data->keys[*ap].type == REPOKEY_TYPE_DIRSTRARRAY)
- break;
- if (!*ap)
- return 0;
- iter = ap[1];
- }
- did = *didp;
- for (ap = data->attriddata + iter; *ap; ap += 2)
- {
- if (did && ap[0] != did)
- continue;
- *didp = ap[0];
- *iterp = ap - data->attriddata + 2;
- return (const char *)data->attrdata + ap[1];
- }
- *iterp = 0;
- return 0;
-}
-
-const unsigned char *
-repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep)
+void
+repodata_search_uninternalized(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
{
Id *ap;
- if (!data->attrs)
- return 0;
+ int stop;
+ Solvable *s;
+ KeyValue kv;
+
+ if (!data->attrs || solvid < data->start || solvid >= data->end)
+ return;
ap = data->attrs[solvid - data->start];
if (!ap)
- return 0;
+ return;
for (; *ap; ap += 2)
{
- if (data->keys[*ap].name != keyname)
+ Repokey *key = data->keys + *ap;
+ if (keyname && key->name != keyname)
continue;
- switch (data->keys[*ap].type)
+ s = solvid > 0 ? data->repo->pool->solvables + solvid : 0;
+ kv.entry = 0;
+ do
{
- case_CHKSUM_TYPES:
- *typep = data->keys[*ap].type;
- return (const unsigned char *)data->attrdata + ap[1];
- default:
- break;
+ data_fetch_uninternalized(data, key, ap[1], &kv);
+ stop = callback(cbdata, s, data, key, &kv);
+ kv.entry++;
}
+ while (!kv.eof && !stop);
+ if (keyname || stop > SEARCH_NEXT_KEY)
+ return;
}
- return 0;
}
/************************************************************************
void repodata_set_deltalocation(Repodata *data, Id handle, int medianr, const char *dir, const char *file);
void repodata_set_sourcepkg(Repodata *data, Id solvid, const char *sourcepkg);
-/* uninternalized data lookup */
-Id repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid);
-const char *repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname, Id *didp, Id *iterp);
-const unsigned char *repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep);
+/* uninternalized data lookup / search */
+Repokey *repodata_lookup_kv_uninternalized(Repodata *data, Id solvid, Id keyname, struct _KeyValue *kv);
+void repodata_search_uninternalized(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, struct _KeyValue *kv), void *cbdata);
/* stats */
unsigned int repodata_memused(Repodata *data);