Skip to content

Commit

Permalink
Allow sam_write1 to take a NULL header parameter.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
valeriuo committed Apr 21, 2020
1 parent 2e36fa6 commit 445de25
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 7 deletions.
6 changes: 6 additions & 0 deletions hts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@ int hts_close(htsFile *fp)
hts_idx_destroy(fp->idx);
free(fp->fn);
free(fp->fn_aux);
free((void *)fp->fnidx);
free(fp->line.s);
free(fp);
errno = save;
Expand All @@ -1242,6 +1243,11 @@ const htsFormat *hts_get_format(htsFile *fp)
return fp? &fp->format : NULL;
}

const char *hts_get_fn(htsFile *fp)
{
return fp? fp->fn : NULL;
}

const char *hts_format_file_extension(const htsFormat *format) {
if (!format)
return "?";
Expand Down
8 changes: 8 additions & 0 deletions htslib/hts.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,14 @@ int hts_close(htsFile *fp);
HTSLIB_EXPORT
const htsFormat *hts_get_format(htsFile *fp);

/*!
@abstract Returns the file's name
@param fp The file handle
@return Read-only pointer to the file's fn field.
*/
HTSLIB_EXPORT
const char *hts_get_fn(htsFile *fp);

/*!
@ abstract Returns a string containing the file format extension.
@ param format Format structure containing the file type.
Expand Down
20 changes: 17 additions & 3 deletions htslib/sam.h
Original file line number Diff line number Diff line change
Expand Up @@ -1089,8 +1089,7 @@ int bam_set_qname(bam1_t *b, const char *qname);
/** @param fp File handle for the data file being written.
@param h Bam header structured (needed for BAI and CSI).
@param min_shift 0 for BAI, or larger for CSI (CSI defaults to 14).
@param fnidx Filename to write index to. This pointer must remain valid
until after sam_idx_save is called.
@param fnidx Filename to write index to.
@return 0 on success, <0 on failure.
@note This must be called after the header has been written, but before
Expand Down Expand Up @@ -1325,6 +1324,20 @@ const char *sam_parse_region(sam_hdr_t *h, const char *s, int *tid,
const char *mode,
const char *format);

/// sam_open_write - Open a file for writing only
/** The method opens a new alignment file for writing, writes header hdr to it
* and attaches the header struct to the returned htsFile struct.
* If successful, ownership of hdr is given to the htsFile struct and hdr
* should not be freed separately.
* @param fn Name of the file
* @param h Pointer to the header previously read or created
* @param mode Pointer to the mode string (must contain "w")
* @param fmt Pointer to the format
* @return Pointer to the htsFile (with hdr) on success, NULL on failure
*/
HTSLIB_EXPORT
htsFile *sam_open_write(const char *fn, sam_hdr_t *hdr, const char *mode, const htsFormat *fmt);

HTSLIB_EXPORT
int sam_hdr_change_HD(sam_hdr_t *h, const char *key, const char *val);

Expand All @@ -1343,7 +1356,8 @@ const char *sam_parse_region(sam_hdr_t *h, const char *s, int *tid,
int sam_read1(samFile *fp, sam_hdr_t *h, bam1_t *b) HTS_RESULT_USED;
/// sam_write1 - Write a record to a file
/** @param fp Pointer to the destination file
* @param h Pointer to the header structure previously read
* @param h Pointer to the header structure previously read. Can be NULL,
* if fp has a non-NULL pointer to a valid header struct.
* @param b Pointer to the record to be written
* @return >= 0 on successfully writing the record, -1 on error
*/
Expand Down
32 changes: 30 additions & 2 deletions sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,9 @@ int bam_index_build(const char *fn, int min_shift)
// Initialise fp->idx for the current format type.
// This must be called after the header has been written but no other data.
int sam_idx_init(htsFile *fp, sam_hdr_t *h, int min_shift, const char *fnidx) {
fp->fnidx = fnidx;
fp->fnidx = strdup(fnidx);
if (!fp->fnidx) return -1;

if (fp->format.format == bam || fp->format.format == bcf ||
(fp->format.format == sam && fp->format.compression == bgzf)) {
int n_lvls, fmt = HTS_FMT_CSI;
Expand Down Expand Up @@ -1671,6 +1673,30 @@ int sam_hdr_write(htsFile *fp, const sam_hdr_t *h)
return 0;
}

htsFile *sam_open_write(const char *fn, sam_hdr_t *hdr, const char *mode, const htsFormat *fmt) {
htsFile *sf = NULL;
if (fn && mode) {
if (strchr(mode, 'w')) {
sf = hts_open_format(fn, mode, fmt);
if (sf) {
if (sam_hdr_write(sf, hdr) < 0) {
hts_log_error("Writing header to file \"%s\" failed", fn);
sam_close(sf);
sf = NULL;
} else {
if (sf->bam_header)
sam_hdr_destroy(sf->bam_header);
sf->bam_header = hdr;
}
}
} else {
hts_log_error("Only write mode allowed");
}
}

return sf;
}

static int old_sam_hdr_change_HD(sam_hdr_t *h, const char *key, const char *val)
{
char *p, *q, *beg = NULL, *end = NULL, *newtext;
Expand Down Expand Up @@ -3192,8 +3218,10 @@ int sam_format1(const bam_hdr_t *h, const bam1_t *b, kstring_t *str)

// Sadly we need to be able to modify the bam_hdr here so we can
// reference count the structure.
int sam_write1(htsFile *fp, const sam_hdr_t *h, const bam1_t *b)
int sam_write1(htsFile *fp, const sam_hdr_t *hdr, const bam1_t *b)
{
const sam_hdr_t *h = hdr;
if (!h) h = fp->bam_header;
switch (fp->format.format) {
case binary_format:
fp->format.category = sequence_data;
Expand Down
6 changes: 4 additions & 2 deletions vcf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3295,7 +3295,8 @@ static int vcf_idx_init(htsFile *fp, bcf_hdr_t *h, int min_shift, const char *fn
fp->idx = NULL;
return -1;
}
fp->fnidx = fnidx;
fp->fnidx = strdup(fnidx);
if (!fp->fnidx) return -1;

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

fp->idx = hts_idx_init(nids, HTS_FMT_CSI, bgzf_tell(fp->fp.bgzf), min_shift, n_lvls);
if (!fp->idx) return -1;
fp->fnidx = fnidx;
fp->fnidx = strdup(fnidx);
if (!fp->fnidx) return -1;

return 0;
}
Expand Down

0 comments on commit 445de25

Please sign in to comment.