- if (mask < 0) buf->flag_mask = BAM_DEF_MASK;
- else buf->flag_mask = BAM_FUNMAP | mask;
-}
-
-bam_plbuf_t *bam_plbuf_init(bam_pileup_f func, void *data)
-{
- bam_plbuf_t *buf;
- buf = (bam_plbuf_t*)calloc(1, sizeof(bam_plbuf_t));
- buf->func = func; buf->func_data = data;
- buf->mp = mp_init();
- buf->head = buf->tail = mp_alloc(buf->mp);
- buf->dummy = mp_alloc(buf->mp);
- buf->max_tid = buf->max_pos = -1;
- buf->flag_mask = BAM_DEF_MASK;
- return buf;
-}
-
-void bam_plbuf_destroy(bam_plbuf_t *buf)
-{
- mp_free(buf->mp, buf->dummy);
- mp_free(buf->mp, buf->head);
- if (buf->mp->cnt != 0)
- fprintf(stderr, "[bam_plbuf_destroy] memory leak: %d. Continue anyway.\n", buf->mp->cnt);
- mp_destroy(buf->mp);
- free(buf->pu);
- free(buf);
+ *_n_plp = 0;
+ if (iter->is_eof && iter->head->next == 0) return 0;
+ while (iter->is_eof || iter->max_tid > iter->tid || (iter->max_tid == iter->tid && iter->max_pos > iter->pos)) {
+ int n_plp = 0;
+ lbnode_t *p, *q;
+ // write iter->plp at iter->pos
+ iter->dummy->next = iter->head;
+ for (p = iter->head, q = iter->dummy; p->next; q = p, p = p->next) {
+ if (p->b.core.tid < iter->tid || (p->b.core.tid == iter->tid && p->end <= iter->pos)) { // then remove
+ q->next = p->next; mp_free(iter->mp, p); p = q;
+ } else if (p->b.core.tid == iter->tid && p->beg <= iter->pos) { // here: p->end > pos; then add to pileup
+ if (n_plp == iter->max_plp) { // then double the capacity
+ iter->max_plp = iter->max_plp? iter->max_plp<<1 : 256;
+ iter->plp = (bam_pileup1_t*)realloc(iter->plp, sizeof(bam_pileup1_t) * iter->max_plp);
+ }
+ iter->plp[n_plp].b = &p->b;
+ if (resolve_cigar(iter->plp + n_plp, iter->pos)) ++n_plp; // skip the read if we are looking at ref-skip
+ }
+ }
+ iter->head = iter->dummy->next; // dummy->next may be changed
+ *_n_plp = n_plp; *_tid = iter->tid; *_pos = iter->pos;
+ // update iter->tid and iter->pos
+ if (iter->head->next) {
+ if (iter->tid > iter->head->b.core.tid) {
+ fprintf(stderr, "[%s] unsorted input. Pileup aborts.\n", __func__);
+ *_n_plp = -1;
+ return 0;
+ }
+ }
+ if (iter->tid < iter->head->b.core.tid) { // come to a new reference sequence
+ iter->tid = iter->head->b.core.tid; iter->pos = iter->head->beg; // jump to the next reference
+ } else if (iter->pos < iter->head->beg) { // here: tid == head->b.core.tid
+ iter->pos = iter->head->beg; // jump to the next position
+ } else ++iter->pos; // scan contiguously
+ // return
+ if (n_plp) return iter->plp;
+ if (iter->is_eof && iter->head->next == 0) break;
+ }
+ return 0;