- some pieces of code for the unified lookup/search interface
[platform/upstream/libsolv.git] / src / repo.c
index 9f00727..0a18895 100644 (file)
@@ -20,6 +20,7 @@
 #include "pool.h"
 #include "poolid_private.h"
 #include "util.h"
+#include "attr_store_p.h"
 
 #define IDARRAY_BLOCK     4095
 
@@ -286,7 +287,7 @@ repo_free(Repo *repo, int reuseids)
 }
 
 void
-pool_freeallrepos(Pool *pool, int reuseids)
+repo_freeallrepos(Pool *pool, int reuseids)
 {
   int i;
 
@@ -444,4 +445,215 @@ repo_fix_legacy(Repo *repo, Offset provides, Offset supplements)
   return supplements;
 }
 
+void
+repodata_search(Repodata *data, Id key)
+{
+}
+
+unsigned char *
+data_read_id(unsigned char *dp, Id *idp)
+{
+  Id x = 0;
+  unsigned char c;
+  for (;;)
+    {
+      c = *dp++;
+      if (!(c & 0x80))
+       {
+         *idp = (x << 7) ^ c;
+          return dp;
+       }
+      x = (x << 7) ^ c ^ 128;
+    }
+}
+
+unsigned char *
+data_skip(unsigned char *dp, int type)
+{
+  switch (type)
+    {
+    case TYPE_VOID:
+      return dp;
+    case TYPE_ID:
+      while ((*dp & 0x80) != 0)
+       dp++;
+      return dp;
+    case TYPE_IDARRAY:
+    case TYPE_REL_IDARRAY:
+    case TYPE_IDVALUEARRAY:
+    case TYPE_IDVALUEVALUEARRAY:
+      while ((*dp & 0xc0) != 0)
+       dp++;
+      return dp;
+    default:
+      fprintf(stderr, "unknown type in data_skip\n");
+      exit(1);
+    }
+}
+
+const char *
+repodata_lookup_str(Repodata *data, Id entry, Id key)
+{
+  Id schema;
+  Id id, k, *kp, *keyp;
+  unsigned char *dp;
+
+  if (data->entryschemau8)
+    schema = data->entryschemau8[entry];
+  else
+    schema = data->entryschema[entry];
+  keyp = data->schemadata + schema;
+  /* make sure the schema of this solvable contains the key */
+  for (kp = keyp; (k = *kp++) != 0; )
+    if (k == key)
+      break;
+  if (k == 0)
+    return 0;
+  switch (data->keys[key].storage)
+    {
+    case KEY_STORAGE_VERTICAL_OFFSET:
+    case KEY_STORAGE_INCORE:
+      dp = data->incoredata + data->incoreoffset[entry];
+      while ((k = *keyp++) != 0)
+       {
+         if (k == key)
+           break;
+         if (data->keys[k].storage == KEY_STORAGE_VERTICAL_OFFSET)
+           {
+             /* skip that offset */
+             dp = data_skip(dp, TYPE_ID);
+             continue;
+           }
+         if (data->keys[k].storage != KEY_STORAGE_INCORE)
+           continue;
+         dp = data_skip(dp, data->keys[k].type);
+       }
+      if (data->keys[key].storage == KEY_STORAGE_VERTICAL_OFFSET)
+       {
+         int i, oi, max;
+         if (!data->fp)
+           return 0;
+         dp = data_read_id(dp, &id);
+         max = data->keys[key].size - id;
+         if (max <= 0)
+           return 0;
+          /* we now have the offset, go into vertical */
+         for (i = 1; i < key; i++)
+           if (data->keys[i].storage == KEY_STORAGE_VERTICAL_OFFSET)
+             id += data->keys[i].size;
+         if (fseek(data->fp, data->verticaloffset + id, SEEK_SET))
+           return 0;
+         i = max > 256 ? 256 : max;
+         for (oi = 0;; oi = i, i += 256)
+           {
+             if (i > max)
+               i = max;
+             if (i == oi)
+               return 0;
+             if (i > data->strbuflen)
+               {
+                 data->strbuf = xrealloc(data->strbuf, i);
+                 data->strbuflen = i;
+               }
+             if (fread(data->strbuf + oi, i - oi, 1, data->fp) != 1)
+               return 0;
+             if (memchr(data->strbuf + oi, 0, i - oi))
+               return data->strbuf;
+           }
+       }
+      if (data->keys[key].type == TYPE_STR)
+       return (const char *)dp;
+      /* id type, must either use global or local string strore*/
+      dp = data_read_id(dp, &id);
+#if 0
+      /* not yet working */
+      return data->ss.stringspace + data->ss.strings[id];
+#else
+      return id2str(data->repo->pool, id);
+#endif
+    }
+  return 0;
+}
+
+const char *
+repo_lookup_str(Solvable *s, Id key)
+{
+  Repo *repo = s->repo;
+  Pool *pool = repo->pool;
+  Repodata *data;
+  int i, j, n;
+
+  switch(key)
+    {
+    case SOLVABLE_NAME:
+      return id2str(pool, s->name);
+    case SOLVABLE_ARCH:
+      return id2str(pool, s->arch);
+    case SOLVABLE_EVR:
+      return id2str(pool, s->evr);
+    case SOLVABLE_VENDOR:
+      return id2str(pool, s->vendor);
+    }
+  n = s - pool->solvables;
+  for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+    {
+      if (n < data->start || n >= data->end)
+       continue;
+      for (j = 1; j < data->nkeys; j++)
+       {
+         if (data->keys[j].name == key && (data->keys[j].type == TYPE_ID || data->keys[j].type == TYPE_STR))
+           return repodata_lookup_str(data, n - data->start, j);
+       }
+    }
+  return 0;
+}
+
+
+static int
+key_cmp (const void *pa, const void *pb)
+{
+  Repokey *a = (Repokey *)pa;
+  Repokey *b = (Repokey *)pb;
+  return a->name - b->name;
+}
+
+void
+repo_add_attrstore (Repo *repo, Attrstore *s, const char *location)
+{
+  unsigned i;
+  Repodata *data;
+  /* If this is meant to be the embedded attributes, make sure we don't
+     have them already.  */
+  if (!location)
+    {
+      for (i = 0; i < repo->nrepodata; i++)
+        if (repo->repodata[i].location == 0)
+         break;
+      if (i != repo->nrepodata)
+        {
+         pool_debug (repo->pool, SAT_FATAL, "embedded attribs added twice\n");
+         exit (1);
+       }
+    }
+  repo->nrepodata++;
+  repo->repodata = xrealloc (repo->repodata, repo->nrepodata * sizeof (*data));
+  data = repo->repodata + repo->nrepodata - 1;
+  memset (data, 0, sizeof (*data));
+  data->s = s;
+  data->nkeys = s->nkeys;
+  if (data->nkeys)
+    {
+      data->keys = xmalloc(data->nkeys * sizeof(data->keys[0]));
+      for (i = 1; i < data->nkeys; i++)
+        {
+          data->keys[i].name = s->keys[i].name;
+         data->keys[i].type = s->keys[i].type;
+       }
+      if (data->nkeys > 2)
+        qsort(data->keys + 1, data->nkeys - 1, sizeof(data->keys[0]), key_cmp);
+    }
+  if (location)
+    data->location = strdup(location);
+}
+
 // EOF