Skip to content

Commit 6ef7fd2

Browse files
committed
[DRAFT] Add bam_aux_remove_if()
1 parent 78ee824 commit 6ef7fd2

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

htslib/sam.h

+14
Original file line numberDiff line numberDiff line change
@@ -1804,6 +1804,20 @@ BAM record's aux data is corrupt.
18041804
HTSLIB_EXPORT
18051805
uint8_t *bam_aux_remove(bam1_t *b, uint8_t *s);
18061806

1807+
typedef int bam_aux_filter_func(bam1_t *b, uint8_t *s, void *data);
1808+
1809+
/// Delete several aux fields from a BAM record
1810+
/** @param b The BAM record to update
1811+
@param filter Pointer to decision function (non-zero means remove)
1812+
@param data Pointer to any user data needed by the decision function
1813+
@return Number of aux fields removed, or negative on error
1814+
1815+
Calls @p filter() for each aux field in turn, and removes each aux field
1816+
for which the decision function returns non-zero.
1817+
*/
1818+
HTSLIB_EXPORT
1819+
int bam_aux_remove_if(bam1_t *b, bam_aux_filter_func *filter, void *data);
1820+
18071821
/// Update or add a string-type tag
18081822
/* @param b The bam record to update
18091823
@param tag Tag identifier

sam.c

+33
Original file line numberDiff line numberDiff line change
@@ -4682,6 +4682,39 @@ uint8_t *bam_aux_remove(bam1_t *b, uint8_t *s)
46824682
return NULL;
46834683
}
46844684

4685+
int bam_aux_remove_if(bam1_t *b, bam_aux_filter_func *remove, void *data)
4686+
{
4687+
uint8_t *end = b->data + b->l_data;
4688+
uint8_t *p_from, *p_to;
4689+
int removed = 0;
4690+
4691+
p_from = p_to = bam_get_aux(b);
4692+
4693+
while (p_from < end) {
4694+
uint8_t *next = skip_aux(p_from+2, end);
4695+
if (next == NULL) goto bad_aux;
4696+
4697+
if (remove(b, p_from+2, data)) {
4698+
removed++;
4699+
}
4700+
else {
4701+
size_t len = next - p_from;
4702+
if (p_to != p_from) memmove(p_to, p_from, len);
4703+
p_to += len;
4704+
}
4705+
4706+
p_from = next;
4707+
}
4708+
4709+
b->l_data = p_to - b->data;
4710+
return removed;
4711+
4712+
bad_aux:
4713+
hts_log_error("Corrupted aux data for read %s", bam_get_qname(b));
4714+
memset(p_to, '\0', p_from - p_to);
4715+
return -1;
4716+
}
4717+
46854718
int bam_aux_update_str(bam1_t *b, const char tag[2], int len, const char *data)
46864719
{
46874720
// FIXME: This is not at all efficient!

0 commit comments

Comments
 (0)