Ignore:
Timestamp:
Apr 16, 2015, 2:22:24 AM (8 years ago)
Author:
Peter
Message:

Implement functions to get/set free text in BamHeader?. As setting the
header text modifies underlying data, copy and assignment are now
implemented as hard copy (rather than the implicit pointer copy as
before). It also means that the bam_hdr_t* is no longer owned by
InBamFile?, but is now owned by BamHeader? and destroyed in its
destructor.

refs #817

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/yat/omic/BamHeader.cc

    r3360 r3408  
    2727
    2828#include <cassert>
     29#include <cstdlib>
     30#include <cstring>
    2931#include <string>
    3032#include <sstream>
     33#include <utility>
    3134
    3235namespace theplu {
     
    3740    : header_(NULL)
    3841  {
     42  }
     43
     44
     45  BamHeader::~BamHeader(void)
     46  {
     47#if YAT_HAVE_HTSLIB
     48    bam_hdr_destroy(header_);
     49#else
     50    bam_header_destroy(header_);
     51#endif
     52  }
     53
     54
     55  BamHeader::BamHeader(const BamHeader& other)
     56  {
     57#ifndef YAT_HAVE_HTSLIB
     58    using namespace detail; // for bam_hdr_dup in YAT_HAVE_LIBBAM mode
     59#endif
     60    header_ = bam_hdr_dup(other.header_);
    3961  }
    4062
     
    7092
    7193
     94  void BamHeader::swap(BamHeader& other)
     95  {
     96    std::swap(header_, other.header_);
     97  }
     98
     99
    72100  uint32_t BamHeader::target_length(size_t tid) const
    73101  {
     
    81109    assert(tid < static_cast<size_t>(n_targets()));
    82110    return header_->target_name[tid];
     111  }
     112
     113
     114  std::string BamHeader::text(void) const
     115  {
     116    assert(header_);
     117    return std::string(header_->text, header_->l_text);
     118  }
     119
     120  void BamHeader::text(const std::string& txt)
     121  {
     122#ifdef YAT_HAVE_HTSLIB
     123    // destroy the old
     124    bam_hdr_destroy(header_);
     125    // and create header pointer
     126    header_ = sam_hdr_parse(txt.size(), txt.c_str());
     127#endif
     128    header_->l_text = txt.size();
     129    header_->text = (char*)realloc(header_->text, txt.size()+1);
     130    memcpy(header_->text, txt.c_str(), txt.size()+1);
     131#ifndef YAT_HAVE_HTSLIB
     132    sam_header_parse(header_);
     133#endif
    83134  }
    84135
     
    118169  }
    119170
     171
     172  void swap(BamHeader& lhs, BamHeader& rhs)
     173  {
     174    lhs.swap(rhs);
     175  }
     176
     177
     178  BamHeader& BamHeader::operator=(const BamHeader& rhs)
     179  {
     180    BamHeader tmp(rhs);
     181    swap(tmp);
     182    return *this;
     183  }
     184
     185#ifndef YAT_HAVE_HTSLIB
     186  namespace detail {
     187    bam_header_t * bam_hdr_dup(const bam_header_t* other)
     188    {
     189      // taken from htslib 1.2.1 and adjusted to fit old struct bam_header_t
     190      if (!other)
     191        return NULL;
     192      bam_header_t* h = bam_header_init();
     193      if (!h)
     194        return NULL;
     195      // copy stuff
     196      h->n_targets = other->n_targets;
     197      h->l_text = other->l_text;
     198      h->n_text = other->n_text;
     199      h->dict = NULL;
     200      h->hash = NULL;
     201      h->rg2lib = NULL;
     202
     203      h->text = (char*)calloc(h->l_text + 1, 1);
     204      memcpy(h->text, other->text, h->l_text);
     205      h->target_len = (uint32_t*)calloc(h->n_targets, sizeof(uint32_t));
     206      h->target_name = (char**)calloc(h->n_targets, sizeof(char*));
     207      for (int i = 0; i < h->n_targets; ++i) {
     208        h->target_len[i] = other->target_len[i];
     209        h->target_name[i] = strdup(other->target_name[i]);
     210      }
     211      return h;
     212    }
     213  }
     214#endif
     215
    120216}}}
Note: See TracChangeset for help on using the changeset viewer.