Changeset 3408


Ignore:
Timestamp:
Apr 16, 2015, 2:22:24 AM (4 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

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/bam_header.cc

    r3210 r3408  
    7979  suite.out() << hdr.target_length(0) << "\n";
    8080  suite.add(hdr.target_length(0)==249250621);
     81
     82  std::string str = hdr.text();
     83  std::string str1(str);
     84  str1 += "@PG\tID:prog\tVN:1.0\n";
     85  omic::BamHeader hdr2(hdr);
     86  hdr.text(str1);
     87  std::string str2 = hdr.text();
     88  if (str2.substr(0, str.size()) != str) {
     89    suite.add(false);
     90    suite.err() << "incorrect text:\n" << str2 << "\nexpected:\n"
     91                << str1 << "\n";
     92  }
     93  else if (str2 != str1) {
     94    suite.add(false);
     95    suite.err() << "error: line was not added to header\n";
     96  }
     97  if (hdr2.text() != str) {
     98    suite.add(false);
     99    suite.err() << "function text(1) affects copies\n";
     100  }
     101
    81102#endif
    82103}
  • trunk/yat/omic/BamFile.cc

    r3359 r3408  
    9292#else
    9393    open_base(fn, "rb", NULL);
    94     header_.header_ = sf_->header;
     94    header_.header_ = detail::bam_hdr_dup(sf_->header);
    9595#endif
    9696    if (header_.header_ == NULL) {
  • 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}}}
  • trunk/yat/omic/BamHeader.h

    r3363 r3408  
    2525#include "config_bam.h"
    2626
     27#include "yat/utility/config_public.h"
     28
    2729#include YAT_SAM_HEADER
    2830
     
    3234namespace yat {
    3335namespace omic {
     36
     37#ifndef YAT_HAVE_HTSLIB
     38  namespace detail {
     39    bam_header_t * bam_hdr_dup(const bam_header_t* other);
     40  }
     41#endif
    3442
    3543  /**
     
    5462
    5563    /**
     64       \brief Destructor
     65     */
     66    ~BamHeader(void);
     67
     68    /**
     69       \brief Copy constructor
     70     */
     71    BamHeader(const BamHeader&);
     72
     73    /**
    5674       Parse a region in the format: 'chr2:100,000-200,000 and return
    5775       values in variables \a tid, \a begin and \a end. \a reg is
     
    7088
    7189    /**
     90       \brief Exchanges the content in \c *this and \a other
     91
     92       \since New in yat 0.13
     93     */
     94    void swap(BamHeader& other);
     95
     96    /**
    7297       Name of chromosome with ID \a tid
    7398     */
     
    78103     */
    79104    uint32_t target_length(size_t tid) const;
     105
     106    /**
     107       \return text in header
     108
     109       \since New in yat 0.13
     110     */
     111    std::string text(void) const;
     112
     113    /**
     114       \brief set text in header
     115
     116       This function parses \a txt and updates fields.
     117
     118       \since New in yat 0.13
     119     */
     120    void text(const std::string& txt);
    80121
    81122    /**
     
    94135     */
    95136    int32_t n_targets(void) const;
     137
     138    /**
     139       \brief assignment operator
     140     */
     141    BamHeader& operator=(const BamHeader& rhs);
     142
    96143  private:
    97144#ifndef YAT_HAVE_HTSLIB
     
    104151
    105152    // using compiler generated copy and assignment
    106     //BamHeader(const BamHeader&);
    107     //BamHeader& operator=(const BamHeader& rhs);
    108153  };
     154
     155  /**
     156     Exchanges the content in the headers.
     157
     158     \since New in yat 0.13
     159
     160     \relates BamHeader
     161   */
     162  void swap(BamHeader& lhs, BamHeader& rhs);
    109163
    110164}}}
Note: See TracChangeset for help on using the changeset viewer.