add dataiterator_clonepos and dataiterator_seek
authorMichael Schroeder <mls@suse.de>
Wed, 1 Jul 2009 16:45:32 +0000 (18:45 +0200)
committerMichael Schroeder <mls@suse.de>
Wed, 1 Jul 2009 16:45:32 +0000 (18:45 +0200)
src/repo.h
src/repodata.c

index bb6eabd..90681dd 100644 (file)
@@ -275,6 +275,14 @@ void dataiterator_skip_repo(Dataiterator *di);
 void dataiterator_jump_to_solvid(Dataiterator *di, Id solvid);
 void dataiterator_jump_to_repo(Dataiterator *di, Repo *repo);
 void dataiterator_entersub(Dataiterator *di);
+void dataiterator_clonepos(Dataiterator *di, Dataiterator *from);
+void dataiterator_seek(Dataiterator *di, int whence);
+
+#define DI_SEEK_STAY    (1 << 16)
+#define DI_SEEK_CHILD   1
+#define DI_SEEK_PARENT  2
+#define DI_SEEK_REWIND  3
+
 
 void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
 void repo_set_num(Repo *repo, Id p, Id keyname, Id num);
index fb88153..aa7151d 100644 (file)
@@ -1229,6 +1229,8 @@ dataiterator_step(Dataiterator *di)
          di->key = di->data->keys + *di->keyp;
          di->ddp = (unsigned char *)di->kv.str;
          di->keyname = di->keynames[di->nparents];
+         if (!di->ddp)
+           goto di_bye;
          goto di_nextarrayelement;
 
         /* special solvable attr handling follows */
@@ -1319,6 +1321,81 @@ dataiterator_setpos_parent(Dataiterator *di)
   di->pool->pos.dp = (unsigned char *)di->kv.parent->str - di->data->incoredata;
 }
 
+/* clones just the position, not the search keys/matcher */
+void
+dataiterator_clonepos(Dataiterator *di, Dataiterator *from)
+{
+  di->state = from->state;
+  di->flags &= ~SEARCH_THISSOLVID;
+  di->flags |= (from->flags & SEARCH_THISSOLVID);
+  di->repo = from->repo;
+  di->data = from->data;
+  di->dp = from->dp;
+  di->ddp = from->ddp;
+  di->idp = from->idp;
+  di->keyp = from->keyp;
+  di->key = from->key;
+  di->kv = from->kv;
+  di->repodataid = from->repodataid;
+  di->solvid = from->solvid;
+  di->repoid = from->repoid;
+  memcpy(di->parents, from->parents, sizeof(from->parents));
+  if (di->nparents)
+    {
+      int i;
+      for (i = 1; i < di->nparents; i++)
+       di->parents[i].kv.parent = &di->parents[i - 1].kv;
+      di->kv.parent = &di->parents[di->nparents - 1].kv;
+    }
+}
+
+void
+dataiterator_seek(Dataiterator *di, int whence)
+{
+  const char *lastparentstr = 0;
+  int i;
+
+  if ((whence & DI_SEEK_STAY) != 0)
+    {
+      for (i = 0; i < di->nparents; i++)
+       di->parents[i].kv.str = 0;
+      lastparentstr = di->nparents ? di->parents[di->nparents - 1].kv.str : 0;
+    }
+  switch (whence & ~DI_SEEK_STAY)
+    {
+    case DI_SEEK_CHILD:
+      if (di->state != di_nextarrayelement)
+       break;
+      if ((whence & DI_SEEK_STAY) != 0)
+       di->kv.str = 0;
+      di->state = di_entersub;
+      break;
+    case DI_SEEK_PARENT:
+      if (!di->nparents)
+       break;
+      if ((whence & DI_SEEK_STAY) != 0)
+       di->parents[di->nparents - 1].kv.str = lastparentstr;
+      di->nparents--;
+      di->dp = di->parents[di->nparents].dp;
+      di->kv = di->parents[di->nparents].kv;
+      di->keyp = di->parents[di->nparents].keyp;
+      di->key = di->data->keys + *di->keyp;
+      di->ddp = (unsigned char *)di->kv.str;
+      di->keyname = di->keynames[di->nparents];
+      di->state = di->ddp ? di_nextarrayelement : di_bye;
+      break;
+    case DI_SEEK_REWIND:
+      if (!di->nparents)
+       break;
+      di->dp = (unsigned char *)di->kv.parent->str;
+      di->keyp = di->data->schemadata + di->data->schemata[di->kv.parent->id];
+      di->state = di_enterschema;
+      break;
+    default:
+      break;
+    }
+}
+
 void
 dataiterator_skip_attribute(Dataiterator *di)
 {