+ if ((ret = ti_readline(fp, &iter->str)) >= 0) {
+ ti_intv_t intv;
+ iter->curr_off = bgzf_tell(fp);
+ if (iter->str.s[0] == iter->idx->conf.meta_char) continue;
+ get_intv((ti_index_t*)iter->idx, &iter->str, &intv);
+ if (intv.tid != iter->tid || intv.beg >= iter->end) break; // no need to proceed
+ else if (intv.end > iter->beg && iter->end > intv.beg) {
+ if (len) *len = iter->str.l;
+ return iter->str.s;
+ }
+ } else break; // end of file
+ }
+ iter->finished = 1;
+ return 0;
+}
+
+void ti_iter_destroy(ti_iter_t iter)
+{
+ if (iter) {
+ free(iter->str.s); free(iter->off);
+ free(iter);
+ }
+}
+
+int ti_fetch(BGZF *fp, const ti_index_t *idx, int tid, int beg, int end, void *data, ti_fetch_f func)
+{
+ ti_iter_t iter;
+ const char *s;
+ int len;
+ iter = ti_iter_query(idx, tid, beg, end);
+ while ((s = ti_iter_read(fp, iter, &len)) != 0)
+ func(len, s, data);
+ ti_iter_destroy(iter);
+ return 0;
+}
+
+const ti_conf_t *ti_get_conf(ti_index_t *idx) { return idx? &idx->conf : 0; }
+
+/*******************
+ * High-level APIs *
+ *******************/
+
+tabix_t *ti_open(const char *fn, const char *fnidx)
+{
+ tabix_t *t;
+ BGZF *fp;
+ if ((fp = bgzf_open(fn, "r")) == 0) return 0;
+ t = calloc(1, sizeof(tabix_t));
+ t->fn = strdup(fn);
+ if (fnidx) t->fnidx = strdup(fnidx);
+ t->fp = fp;
+ return t;
+}
+
+void ti_close(tabix_t *t)
+{
+ if (t) {
+ bgzf_close(t->fp);
+ if (t->idx) ti_index_destroy(t->idx);
+ free(t->fn); free(t->fnidx);
+ free(t);
+ }
+}
+
+int ti_lazy_index_load(tabix_t *t)
+{
+ if (t->idx == 0) { // load index
+ if (t->fnidx) t->idx = ti_index_load_local(t->fnidx);
+ else t->idx = ti_index_load(t->fn);
+ if (t->idx == 0) return -1; // fail to load index