+
+static void isamb_pp_leaf_pos( ISAMB_PP pp,
+ double *current, double *total,
+ void *dummybuf )
+{
+ struct ISAMB_block *p = pp->block[pp->level];
+ const char *src=p->bytes;
+ char *end=p->bytes+p->size;
+ char *cur=p->bytes+p->offset;
+ char *dst;
+ void *decodeClientData;
+ assert(p->offset <= p->size);
+ assert(cur <= end);
+ assert(p->leaf);
+ *current=0;
+ *total=0;
+
+ decodeClientData = (pp->isamb->method->codec.start)();
+
+ while(src < end) {
+ dst=dummybuf;
+ (*pp->isamb->method->codec.decode)(decodeClientData,&dst, &src);
+ assert(dst<(char*) dummybuf+100); /*FIXME */
+ (*total)++;
+ if (src<=cur)
+ (*current)++;
+ }
+#if ISAMB_DEBUG
+ logf(LOG_DEBUG, "isamb_pp_leaf_pos: cur= %0.1f tot=%0.1f "
+ " ofs=%d sz=%d lev=%d",
+ *current, *total, p->offset, p->size, pp->level);
+#endif
+ assert(src==end);
+ (pp->isamb->method->codec.stop)(decodeClientData);
+}
+
+static void isamb_pp_upper_pos( ISAMB_PP pp, double *current, double *total,
+ double size, int level )
+{ /* estimates total/current occurrences from here up, excl leaf */
+ struct ISAMB_block *p = pp->block[level];
+ const char *src=p->bytes;
+ char *end=p->bytes+p->size;
+ char *cur=p->bytes+p->offset;
+ zint item_size;
+ ISAMB_P child;
+
+ assert(level>=0);
+ assert(!p->leaf);
+
+#if 1 // ISAMB_DEBUG
+ logf(LOG_DEBUG,"isamb_pp_upper_pos at beginning l=%d "
+ "cur=%0.1f tot=%0.1f "
+ " ofs=%d sz=%d pos=" ZINT_FORMAT,
+ level, *current, *total, p->offset, p->size, p->pos);
+#endif
+ assert (p->offset <= p->size);
+ decode_ptr (&src, &child ); /* first child */
+ if (src!=cur) {
+ *total += size;
+ if (src < cur)
+ *current +=size;
+ }
+ while(src < end) {
+ decode_ptr (&src, &item_size );
+ assert(src+item_size<=end);
+ src += item_size;
+ decode_ptr (&src, &child );
+ if (src!=cur) {
+ *total += size;
+ if (src < cur)
+ *current +=size;
+ }
+ }
+#if ISAMB_DEBUG
+ logf(LOG_DEBUG,"isamb_pp_upper_pos before recursion l=%d "
+ "cur=%0.1f tot=%0.1f "
+ " ofs=%d sz=%d pos=" ZINT_FORMAT,
+ level, *current, *total, p->offset, p->size, p->pos);
+#endif
+ if (level>0)
+ isamb_pp_upper_pos(pp, current, total, *total, level-1);
+} /* upper_pos */
+
+void isamb_pp_pos( ISAMB_PP pp, double *current, double *total )
+{ /* return an estimate of the current position and of the total number of */
+ /* occureences in the isam tree, based on the current leaf */
+ /* FIXME - Isam-B ought to know how many we have, so we could return */
+ /* that directly */
+ struct ISAMB_block *p = pp->block[pp->level];
+ char dummy[100]; /* 100 bytes/entry must be enough */
+ assert(total);
+ assert(current);
+ assert(p->leaf);
+ isamb_pp_leaf_pos(pp,current, total, dummy);
+ if (pp->level>0)
+ isamb_pp_upper_pos(pp, current, total, *total, pp->level-1);
+ *current = (double) pp->returned_numbers;
+ /* use the precise number, since we have it! */
+#if ISAMB_DEBUG
+ logf(LOG_LOG, "isamb_pp_pos returning: cur= %0.1f tot=%0.1f rn="ZINT_FORMAT,
+ *current, *total, pp->returned_numbers);
+#endif
+}