+ solv_free(buf);
+
+ if (data.error)
+ {
+ /* free solvables */
+ repo_free_solvable_block(repo, data.start, data.end - data.start, 1);
+ /* free id array */
+ repo->idarraysize -= size_idarray;
+ /* free incore data */
+ data.incoredata = solv_free(data.incoredata);
+ data.incoredatalen = data.incoredatafree = 0;
+ }
+
+ if (data.incoredatafree)
+ {
+ /* shrink excess size */
+ data.incoredata = solv_realloc(data.incoredata, data.incoredatalen);
+ data.incoredatafree = 0;
+ }
+ solv_free(idmap);
+
+ /* fixup the special idarray type */
+ for (i = 1; i < numkeys; i++)
+ if (keys[i].type == REPOKEY_TYPE_REL_IDARRAY)
+ keys[i].type = REPOKEY_TYPE_IDARRAY;
+
+ for (i = 1; i < numkeys; i++)
+ if (keys[i].storage == KEY_STORAGE_VERTICAL_OFFSET)
+ break;
+ if (i < numkeys && !data.error)
+ {
+ Id fileoffset = 0;
+ unsigned int pagesize;
+
+ /* we have vertical data, make it available */
+ data.verticaloffset = solv_calloc(numkeys, sizeof(Id));
+ for (i = 1; i < numkeys; i++)
+ if (keys[i].storage == KEY_STORAGE_VERTICAL_OFFSET)
+ {
+ data.verticaloffset[i] = fileoffset;
+ fileoffset += keys[i].size;
+ }
+ data.lastverticaloffset = fileoffset;
+ pagesize = read_u32(&data);
+ if (!data.error)
+ {
+ data.error = repopagestore_read_or_setup_pages(&data.store, data.fp, pagesize, fileoffset);
+ if (data.error == SOLV_ERROR_EOF)
+ pool_error(pool, data.error, "repopagestore setup: unexpected EOF");
+ else if (data.error)
+ pool_error(pool, data.error, "repopagestore setup failed");
+ }
+ }
+ data.fp = 0; /* no longer needed */
+
+ if (data.error)
+ {
+ i = data.error;
+ repodata_freedata(&data);
+ return i;
+ }
+
+ if (parent)
+ {
+ /* overwrite stub repodata */
+ repodata_freedata(parent);
+ data.repodataid = parent->repodataid;
+ *parent = data;
+ }
+ else
+ {
+ /* make it available as new repodata */
+ if (!repo->nrepodata)
+ {
+ repo->nrepodata = 1;
+ repo->repodata = solv_calloc(2, sizeof(data));
+ }
+ else
+ repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata + 1, sizeof(data));
+ data.repodataid = repo->nrepodata;
+ repo->repodata[repo->nrepodata++] = data;
+ }
+
+ /* create stub repodata entries for all external */
+ if (!(flags & SOLV_ADD_NO_STUBS) && !parent)
+ {
+ for (key = 1 ; key < data.nkeys; key++)
+ if (data.keys[key].name == REPOSITORY_EXTERNAL && data.keys[key].type == REPOKEY_TYPE_FLEXARRAY)
+ break;
+ if (key < data.nkeys)
+ repodata_create_stubs(repo->repodata + (repo->nrepodata - 1));
+ }
+
+ POOL_DEBUG(SOLV_DEBUG_STATS, "repo_add_solv took %d ms\n", solv_timems(now));
+ POOL_DEBUG(SOLV_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data.incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
+ return 0;