Skip to content

Commit 445de25

Browse files
committed
Allow sam_write1 to take a NULL header parameter.
Decouple htsFile::fnidx from its source and let HTSlib manage its memory. Add method sam_open_write for opening a htsFile file for writing only and setting a header to it. Add getter method hts_get_fn.
1 parent 2e36fa6 commit 445de25

File tree

5 files changed

+65
-7
lines changed

5 files changed

+65
-7
lines changed

hts.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,7 @@ int hts_close(htsFile *fp)
12311231
hts_idx_destroy(fp->idx);
12321232
free(fp->fn);
12331233
free(fp->fn_aux);
1234+
free((void *)fp->fnidx);
12341235
free(fp->line.s);
12351236
free(fp);
12361237
errno = save;
@@ -1242,6 +1243,11 @@ const htsFormat *hts_get_format(htsFile *fp)
12421243
return fp? &fp->format : NULL;
12431244
}
12441245

1246+
const char *hts_get_fn(htsFile *fp)
1247+
{
1248+
return fp? fp->fn : NULL;
1249+
}
1250+
12451251
const char *hts_format_file_extension(const htsFormat *format) {
12461252
if (!format)
12471253
return "?";

htslib/hts.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,14 @@ int hts_close(htsFile *fp);
508508
HTSLIB_EXPORT
509509
const htsFormat *hts_get_format(htsFile *fp);
510510

511+
/*!
512+
@abstract Returns the file's name
513+
@param fp The file handle
514+
@return Read-only pointer to the file's fn field.
515+
*/
516+
HTSLIB_EXPORT
517+
const char *hts_get_fn(htsFile *fp);
518+
511519
/*!
512520
@ abstract Returns a string containing the file format extension.
513521
@ param format Format structure containing the file type.

htslib/sam.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,8 +1089,7 @@ int bam_set_qname(bam1_t *b, const char *qname);
10891089
/** @param fp File handle for the data file being written.
10901090
@param h Bam header structured (needed for BAI and CSI).
10911091
@param min_shift 0 for BAI, or larger for CSI (CSI defaults to 14).
1092-
@param fnidx Filename to write index to. This pointer must remain valid
1093-
until after sam_idx_save is called.
1092+
@param fnidx Filename to write index to.
10941093
@return 0 on success, <0 on failure.
10951094
10961095
@note This must be called after the header has been written, but before
@@ -1325,6 +1324,20 @@ const char *sam_parse_region(sam_hdr_t *h, const char *s, int *tid,
13251324
const char *mode,
13261325
const char *format);
13271326

1327+
/// sam_open_write - Open a file for writing only
1328+
/** The method opens a new alignment file for writing, writes header hdr to it
1329+
* and attaches the header struct to the returned htsFile struct.
1330+
* If successful, ownership of hdr is given to the htsFile struct and hdr
1331+
* should not be freed separately.
1332+
* @param fn Name of the file
1333+
* @param h Pointer to the header previously read or created
1334+
* @param mode Pointer to the mode string (must contain "w")
1335+
* @param fmt Pointer to the format
1336+
* @return Pointer to the htsFile (with hdr) on success, NULL on failure
1337+
*/
1338+
HTSLIB_EXPORT
1339+
htsFile *sam_open_write(const char *fn, sam_hdr_t *hdr, const char *mode, const htsFormat *fmt);
1340+
13281341
HTSLIB_EXPORT
13291342
int sam_hdr_change_HD(sam_hdr_t *h, const char *key, const char *val);
13301343

@@ -1343,7 +1356,8 @@ const char *sam_parse_region(sam_hdr_t *h, const char *s, int *tid,
13431356
int sam_read1(samFile *fp, sam_hdr_t *h, bam1_t *b) HTS_RESULT_USED;
13441357
/// sam_write1 - Write a record to a file
13451358
/** @param fp Pointer to the destination file
1346-
* @param h Pointer to the header structure previously read
1359+
* @param h Pointer to the header structure previously read. Can be NULL,
1360+
* if fp has a non-NULL pointer to a valid header struct.
13471361
* @param b Pointer to the record to be written
13481362
* @return >= 0 on successfully writing the record, -1 on error
13491363
*/

sam.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,9 @@ int bam_index_build(const char *fn, int min_shift)
894894
// Initialise fp->idx for the current format type.
895895
// This must be called after the header has been written but no other data.
896896
int sam_idx_init(htsFile *fp, sam_hdr_t *h, int min_shift, const char *fnidx) {
897-
fp->fnidx = fnidx;
897+
fp->fnidx = strdup(fnidx);
898+
if (!fp->fnidx) return -1;
899+
898900
if (fp->format.format == bam || fp->format.format == bcf ||
899901
(fp->format.format == sam && fp->format.compression == bgzf)) {
900902
int n_lvls, fmt = HTS_FMT_CSI;
@@ -1671,6 +1673,30 @@ int sam_hdr_write(htsFile *fp, const sam_hdr_t *h)
16711673
return 0;
16721674
}
16731675

1676+
htsFile *sam_open_write(const char *fn, sam_hdr_t *hdr, const char *mode, const htsFormat *fmt) {
1677+
htsFile *sf = NULL;
1678+
if (fn && mode) {
1679+
if (strchr(mode, 'w')) {
1680+
sf = hts_open_format(fn, mode, fmt);
1681+
if (sf) {
1682+
if (sam_hdr_write(sf, hdr) < 0) {
1683+
hts_log_error("Writing header to file \"%s\" failed", fn);
1684+
sam_close(sf);
1685+
sf = NULL;
1686+
} else {
1687+
if (sf->bam_header)
1688+
sam_hdr_destroy(sf->bam_header);
1689+
sf->bam_header = hdr;
1690+
}
1691+
}
1692+
} else {
1693+
hts_log_error("Only write mode allowed");
1694+
}
1695+
}
1696+
1697+
return sf;
1698+
}
1699+
16741700
static int old_sam_hdr_change_HD(sam_hdr_t *h, const char *key, const char *val)
16751701
{
16761702
char *p, *q, *beg = NULL, *end = NULL, *newtext;
@@ -3192,8 +3218,10 @@ int sam_format1(const bam_hdr_t *h, const bam1_t *b, kstring_t *str)
31923218

31933219
// Sadly we need to be able to modify the bam_hdr here so we can
31943220
// reference count the structure.
3195-
int sam_write1(htsFile *fp, const sam_hdr_t *h, const bam1_t *b)
3221+
int sam_write1(htsFile *fp, const sam_hdr_t *hdr, const bam1_t *b)
31963222
{
3223+
const sam_hdr_t *h = hdr;
3224+
if (!h) h = fp->bam_header;
31973225
switch (fp->format.format) {
31983226
case binary_format:
31993227
fp->format.category = sequence_data;

vcf.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3295,7 +3295,8 @@ static int vcf_idx_init(htsFile *fp, bcf_hdr_t *h, int min_shift, const char *fn
32953295
fp->idx = NULL;
32963296
return -1;
32973297
}
3298-
fp->fnidx = fnidx;
3298+
fp->fnidx = strdup(fnidx);
3299+
if (!fp->fnidx) return -1;
32993300

33003301
return 0;
33013302
}
@@ -3315,7 +3316,8 @@ int bcf_idx_init(htsFile *fp, bcf_hdr_t *h, int min_shift, const char *fnidx) {
33153316

33163317
fp->idx = hts_idx_init(nids, HTS_FMT_CSI, bgzf_tell(fp->fp.bgzf), min_shift, n_lvls);
33173318
if (!fp->idx) return -1;
3318-
fp->fnidx = fnidx;
3319+
fp->fnidx = strdup(fnidx);
3320+
if (!fp->fnidx) return -1;
33193321

33203322
return 0;
33213323
}

0 commit comments

Comments
 (0)