Skip to content

Commit 53ab02f

Browse files
Merge pull request #18 from rust-bio/bam_record_pointer
Use raw pointers in BAM record and refactor access to pointers in BCF record.
2 parents 1f90c8c + 7bfe4c3 commit 53ab02f

File tree

7 files changed

+85
-66
lines changed

7 files changed

+85
-66
lines changed

src/bam/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl Reader {
7474

7575
impl Read for Reader {
7676
fn read(&self, record: &mut record::Record) -> Result<(), ReadError> {
77-
match unsafe { htslib::bam_read1(self.bgzf, &mut record.inner) } {
77+
match unsafe { htslib::bam_read1(self.bgzf, record.inner) } {
7878
-1 => Err(ReadError::NoMoreRecord),
7979
-2 => Err(ReadError::Truncated),
8080
-4 => Err(ReadError::Invalid),
@@ -188,7 +188,7 @@ impl IndexedReader {
188188
impl Read for IndexedReader {
189189
fn read(&self, record: &mut record::Record) -> Result<(), ReadError> {
190190
match self.itr {
191-
Some(itr) => match itr_next(self.bgzf, itr, &mut record.inner) {
191+
Some(itr) => match itr_next(self.bgzf, itr, record.inner) {
192192
-1 => Err(ReadError::NoMoreRecord),
193193
-2 => Err(ReadError::Truncated),
194194
-4 => Err(ReadError::Invalid),
@@ -294,7 +294,7 @@ impl Writer {
294294
///
295295
/// * `record` - the record to write
296296
pub fn write(&mut self, record: &record::Record) -> Result<(), ()> {
297-
if unsafe { htslib::bam_write1(self.f, &record.inner) } == -1 {
297+
if unsafe { htslib::bam_write1(self.f, record.inner) } == -1 {
298298
Err(())
299299
}
300300
else {

src/bam/record.rs

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ use utils;
1818
macro_rules! flag {
1919
($get:ident, $set:ident, $bit:expr) => (
2020
pub fn $get(&self) -> bool {
21-
self.inner.core.flag & $bit != 0
21+
self.inner().core.flag & $bit != 0
2222
}
2323

2424
pub fn $set(&mut self) {
25-
self.inner.core.flag |= $bit;
25+
self.inner_mut().core.flag |= $bit;
2626
}
2727
)
2828
}
2929

3030

3131
/// A BAM record.
3232
pub struct Record {
33-
pub inner: htslib::bam1_t,
33+
pub inner: *mut htslib::bam1_t,
3434
own: bool,
3535
}
3636

@@ -41,109 +41,115 @@ unsafe impl Send for Record {}
4141
impl Record {
4242
/// Create an empty BAM record.
4343
pub fn new() -> Self {
44-
let mut inner;
45-
unsafe {
46-
let aux = htslib::bam_init1();
47-
inner = *aux;
48-
::libc::free(aux as *mut ::libc::c_void);
49-
}
50-
inner.m_data = 0;
51-
Record { inner: inner, own: true }
44+
let inner = unsafe { htslib::bam_init1() };
45+
let mut record = Record { inner: inner, own: true };
46+
record.inner_mut().m_data = 0;
47+
record
5248
}
5349

5450
pub fn from_inner(inner: *mut htslib::bam1_t) -> Self {
55-
Record { inner: unsafe { *inner }, own: false }
51+
Record { inner: inner, own: false }
5652
}
5753

5854
fn data(&self) -> &[u8] {
59-
unsafe { slice::from_raw_parts(self.inner.data, self.inner.l_data as usize) }
55+
unsafe { slice::from_raw_parts(self.inner().data, self.inner().l_data as usize) }
56+
}
57+
58+
#[inline]
59+
pub fn inner_mut(&mut self) -> &mut htslib::bam1_t {
60+
unsafe { &mut *self.inner }
61+
}
62+
63+
#[inline]
64+
pub fn inner(&self) -> &htslib::bam1_t {
65+
unsafe { &*self.inner }
6066
}
6167

6268
/// Get target id.
6369
pub fn tid(&self) -> i32 {
64-
self.inner.core.tid
70+
self.inner().core.tid
6571
}
6672

6773
/// Set target id.
6874
pub fn set_tid(&mut self, tid: i32) {
69-
self.inner.core.tid = tid;
75+
self.inner_mut().core.tid = tid;
7076
}
7177

7278
/// Get position.
7379
pub fn pos(&self) -> i32 {
74-
self.inner.core.pos
80+
self.inner().core.pos
7581
}
7682

7783
/// Set position.
7884
pub fn set_pos(&mut self, pos: i32) {
79-
self.inner.core.pos = pos;
85+
self.inner_mut().core.pos = pos;
8086
}
8187

8288
pub fn bin(&self) -> u16 {
83-
self.inner.core.bin
89+
self.inner().core.bin
8490
}
8591

8692
pub fn set_bin(&mut self, bin: u16) {
87-
self.inner.core.bin = bin;
93+
self.inner_mut().core.bin = bin;
8894
}
8995

9096
/// Get MAPQ.
9197
pub fn mapq(&self) -> u8 {
92-
self.inner.core.qual
98+
self.inner().core.qual
9399
}
94100

95101
/// Set MAPQ.
96102
pub fn set_mapq(&mut self, mapq: u8) {
97-
self.inner.core.qual = mapq;
103+
self.inner_mut().core.qual = mapq;
98104
}
99105

100106
/// Get raw flags.
101107
pub fn flags(&self) -> u16 {
102-
self.inner.core.flag
108+
self.inner().core.flag
103109
}
104110

105111
/// Set raw flags.
106112
pub fn set_flags(&mut self, flags: u16) {
107-
self.inner.core.flag = flags;
113+
self.inner_mut().core.flag = flags;
108114
}
109115

110116
/// Unset all flags.
111117
pub fn unset_flags(&mut self) {
112-
self.inner.core.flag = 0;
118+
self.inner_mut().core.flag = 0;
113119
}
114120

115121
/// Get target id of mate.
116122
pub fn mtid(&self) -> i32 {
117-
self.inner.core.mtid
123+
self.inner().core.mtid
118124
}
119125

120126
/// Set target id of mate.
121127
pub fn set_mtid(&mut self, mtid: i32) {
122-
self.inner.core.mtid = mtid;
128+
self.inner_mut().core.mtid = mtid;
123129
}
124130

125131
/// Get mate position.
126132
pub fn mpos(&self) -> i32 {
127-
self.inner.core.mpos
133+
self.inner().core.mpos
128134
}
129135

130136
/// Set mate position.
131137
pub fn set_mpos(&mut self, mpos: i32) {
132-
self.inner.core.mpos = mpos;
138+
self.inner_mut().core.mpos = mpos;
133139
}
134140

135141
/// Get insert size.
136142
pub fn insert_size(&self) -> i32 {
137-
self.inner.core.isize
143+
self.inner().core.isize
138144
}
139145

140146
/// Set insert size.
141147
pub fn set_insert_size(&mut self, insert_size: i32) {
142-
self.inner.core.isize = insert_size;
148+
self.inner_mut().core.isize = insert_size;
143149
}
144150

145151
fn qname_len(&self) -> usize {
146-
self.inner.core.l_qname as usize
152+
self.inner().core.l_qname as usize
147153
}
148154

149155
/// Get qname (read name).
@@ -153,25 +159,25 @@ impl Record {
153159

154160
/// Set variable length data (qname, cigar, seq, qual).
155161
pub fn set(&mut self, qname: &[u8], cigar: &[Cigar], seq: &[u8], qual: &[u8]) {
156-
self.inner.l_data = (qname.len() + 1 + cigar.len() * 4 + seq.len() / 2 + qual.len()) as i32;
162+
self.inner_mut().l_data = (qname.len() + 1 + cigar.len() * 4 + seq.len() / 2 + qual.len()) as i32;
157163

158-
if self.inner.m_data < self.inner.l_data {
164+
if self.inner().m_data < self.inner().l_data {
159165

160-
self.inner.m_data = self.inner.l_data;
161-
self.inner.m_data += 32 - self.inner.m_data % 32;
166+
self.inner_mut().m_data = self.inner().l_data;
167+
self.inner_mut().m_data += 32 - self.inner().m_data % 32;
162168
unsafe {
163-
self.inner.data = ::libc::realloc(
164-
self.inner.data as *mut ::libc::c_void, self.inner.m_data as usize
169+
self.inner_mut().data = ::libc::realloc(
170+
self.inner().data as *mut ::libc::c_void, self.inner().m_data as usize
165171
) as *mut u8;
166172
}
167173
}
168174

169-
let mut data = unsafe { slice::from_raw_parts_mut(self.inner.data, self.inner.l_data as usize) };
175+
let mut data = unsafe { slice::from_raw_parts_mut((*self.inner).data, self.inner().l_data as usize) };
170176
// qname
171177
utils::copy_memory(qname, data);
172178
data[qname.len()] = b'\0';
173179
let mut i = qname.len() + 1;
174-
self.inner.core.l_qname = i as u8;
180+
self.inner_mut().core.l_qname = i as u8;
175181

176182
// cigar
177183
{
@@ -181,7 +187,7 @@ impl Record {
181187
for (i, c) in cigar.iter().enumerate() {
182188
cigar_data[i] = c.encode();
183189
}
184-
self.inner.core.n_cigar = cigar.len() as u16;
190+
self.inner_mut().core.n_cigar = cigar.len() as u16;
185191
i += cigar.len() * 4;
186192
}
187193

@@ -190,7 +196,7 @@ impl Record {
190196
for j in (0..seq.len()).step(2) {
191197
data[i + j / 2] = ENCODE_BASE[seq[j] as usize] << 4 | ENCODE_BASE[seq[j + 1] as usize];
192198
}
193-
self.inner.core.l_qseq = seq.len() as i32;
199+
self.inner_mut().core.l_qseq = seq.len() as i32;
194200
i += (seq.len() + 1) / 2;
195201
}
196202

@@ -199,7 +205,7 @@ impl Record {
199205
}
200206

201207
fn cigar_len(&self) -> usize {
202-
self.inner.core.n_cigar as usize
208+
self.inner().core.n_cigar as usize
203209
}
204210

205211
/// Get cigar sequence.
@@ -224,7 +230,7 @@ impl Record {
224230
}
225231

226232
fn seq_len(&self) -> usize {
227-
self.inner.core.l_qseq as usize
233+
self.inner().core.l_qseq as usize
228234
}
229235

230236
/// Get read sequence.
@@ -244,7 +250,7 @@ impl Record {
244250

245251
/// Get auxiliary data (tags).
246252
pub fn aux(&self, tag: &[u8]) -> Option<Aux> {
247-
let aux = unsafe { htslib::bam_aux_get(&self.inner, ffi::CString::new(tag).unwrap().as_ptr() as *mut i8 ) };
253+
let aux = unsafe { htslib::bam_aux_get(self.inner, ffi::CString::new(tag).unwrap().as_ptr() as *mut i8 ) };
248254

249255
unsafe {
250256
if aux.is_null() {
@@ -269,11 +275,11 @@ impl Record {
269275
let ctag = tag.as_ptr() as *mut i8;
270276
unsafe {
271277
match *value {
272-
Aux::Integer(v) => htslib::bam_aux_append(&mut self.inner, ctag, b'i' as i8, 4, [v].as_mut_ptr() as *mut u8),
273-
Aux::Float(v) => htslib::bam_aux_append(&mut self.inner, ctag, b'f' as i8, 4, [v].as_mut_ptr() as *mut u8),
274-
Aux::Char(v) => htslib::bam_aux_append(&mut self.inner, ctag, b'A' as i8, 1, [v].as_mut_ptr() as *mut u8),
278+
Aux::Integer(v) => htslib::bam_aux_append(self.inner, ctag, b'i' as i8, 4, [v].as_mut_ptr() as *mut u8),
279+
Aux::Float(v) => htslib::bam_aux_append(self.inner, ctag, b'f' as i8, 4, [v].as_mut_ptr() as *mut u8),
280+
Aux::Char(v) => htslib::bam_aux_append(self.inner, ctag, b'A' as i8, 1, [v].as_mut_ptr() as *mut u8),
275281
Aux::String(v) => htslib::bam_aux_append(
276-
&mut self.inner,
282+
self.inner,
277283
ctag,
278284
b'Z' as i8,
279285
(v.len() + 1) as i32,
@@ -301,7 +307,7 @@ impl Record {
301307
impl Drop for Record {
302308
fn drop(&mut self) {
303309
if self.own {
304-
unsafe { ::libc::free(self.inner.data as *mut ::libc::c_void) };
310+
unsafe { htslib::bam_destroy1(self.inner) };
305311
}
306312
}
307313
}

src/bcf/record.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,37 +29,45 @@ impl Record {
2929
Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
3030
}
3131

32+
pub fn inner(&self) -> &htslib::vcf::bcf1_t {
33+
unsafe { &*self.inner }
34+
}
35+
36+
pub fn inner_mut(&mut self) -> &mut htslib::vcf::bcf1_t {
37+
unsafe { &mut *self.inner }
38+
}
39+
3240
pub fn rid(&self) -> Option<u32> {
33-
match unsafe { *self.inner }.rid {
41+
match self.inner().rid {
3442
-1 => None,
3543
rid => Some(rid as u32)
3644
}
3745
}
3846

3947
// 0-based position.
4048
pub fn pos(&self) -> u32 {
41-
unsafe { *self.inner }.pos as u32
49+
self.inner().pos as u32
4250
}
4351

4452

4553
pub fn set_pos(&mut self, pos: i32) {
46-
unsafe { (*self.inner).pos = pos; }
54+
self.inner_mut().pos = pos;
4755
}
4856

4957
pub fn alleles(&self) -> Vec<&[u8]> {
5058
unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
51-
let n = unsafe { *self.inner }.n_allele as usize;
52-
let dec = unsafe { *self.inner }.d;
59+
let n = self.inner().n_allele as usize;
60+
let dec = self.inner().d;
5361
let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
5462
(0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
5563
}
5664

5765
pub fn qual(&self) -> f32 {
58-
unsafe { *self.inner }.qual
66+
self.inner().qual
5967
}
6068

6169
pub fn set_qual(&mut self, qual: f32) {
62-
unsafe { (*self.inner).qual = qual; }
70+
self.inner_mut().qual = qual;
6371
}
6472

6573
/// Get the value of the given info tag.
@@ -68,11 +76,11 @@ impl Record {
6876
}
6977

7078
pub fn sample_count(&self) -> u32 {
71-
unsafe { *self.inner }.n_fmt_n_sample >> 8
79+
self.inner().n_fmt_n_sample >> 8
7280
}
7381

7482
pub fn allele_count(&self) -> u16 {
75-
unsafe { *self.inner }.n_allele
83+
self.inner().n_allele
7684
}
7785

7886
/// Get the value of the given format tag for each sample.
@@ -264,8 +272,16 @@ impl<'a> Format<'a> {
264272
Format { record: record, tag: tag, inner: inner }
265273
}
266274

275+
pub fn inner(&self) -> &htslib::vcf::bcf_fmt_t {
276+
unsafe { &*self.inner }
277+
}
278+
279+
pub fn inner_mut(&mut self) -> &mut htslib::vcf::bcf_fmt_t {
280+
unsafe { &mut *self.inner }
281+
}
282+
267283
fn values_per_sample(&self) -> usize {
268-
unsafe { (*self.inner).n as usize }
284+
self.inner().n as usize
269285
}
270286

271287
fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {

src/htslib/sam.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![allow(non_camel_case_types)]
22
#![allow(non_upper_case_globals)]
3-
#![allow(raw_pointer_derive)]
43

54
/* manually added */
65
// bgzf.h

src/htslib/vcf.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![allow(non_camel_case_types)]
22
#![allow(non_upper_case_globals)]
33
#![allow(non_snake_case)]
4-
#![allow(raw_pointer_derive)]
54

65

76
pub const BCF_HL_FLT: ::libc::c_int = 0;

0 commit comments

Comments
 (0)