+repodata_translate_id(Repodata *data, Repodata *fromdata, Id id, int create)
+{
+ const char *s;
+ if (!id || !data || !fromdata)
+ return id;
+ if (data == fromdata || (!data->localpool && !fromdata->localpool))
+ return id;
+ if (fromdata->localpool)
+ s = stringpool_id2str(&fromdata->spool, id);
+ else
+ s = pool_id2str(data->repo->pool, id);
+ if (data->localpool)
+ return stringpool_str2id(&data->spool, s, create);
+ else
+ return pool_str2id(data->repo->pool, s, create);
+}
+
+Id
+repodata_translate_dir_slow(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache)
+{
+ Id parent, compid;
+ if (!dir)
+ {
+ /* make sure that the dirpool has an entry */
+ if (create && !data->dirpool.ndirs)
+ dirpool_add_dir(&data->dirpool, 0, 0, create);
+ return 0;
+ }
+ parent = dirpool_parent(&fromdata->dirpool, dir);
+ if (parent)
+ {
+ if (!(parent = repodata_translate_dir(data, fromdata, parent, create, cache)))
+ return 0;
+ }
+ compid = dirpool_compid(&fromdata->dirpool, dir);
+ if (compid > 1 && (data->localpool || fromdata->localpool))
+ {
+ if (!(compid = repodata_translate_id(data, fromdata, compid, create)))
+ return 0;
+ }
+ if (!(compid = dirpool_add_dir(&data->dirpool, parent, compid, create)))
+ return 0;
+ if (cache)
+ {
+ cache[(dir & 255) * 2] = dir;
+ cache[(dir & 255) * 2 + 1] = compid;
+ }
+ return compid;
+}
+
+/************************************************************************
+ * uninternalized lookup / search
+ */
+
+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_BINARY:
+ kv->str = (const char *)data_read_id(data->attrdata + value, (Id *)&kv->num);
+ 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)