use std::ptr::null;
use std::mem::transmute;
use libc::c_int;
use onig_sys;
use super::CaptureTreeNode;
#[derive(Debug)]
pub struct Region {
raw: onig_sys::OnigRegion,
}
impl Region {
pub fn new() -> Region {
Region {
raw: onig_sys::OnigRegion {
allocated: 0,
num_regs: 0,
beg: null(),
end: null(),
history_root: null(),
},
}
}
pub fn with_capacity(capacity: usize) -> Region {
let mut region = Self::new();
region.reserve(capacity);
region
}
pub fn clear(&mut self) {
unsafe {
onig_sys::onig_region_clear(&self.raw);
}
}
pub fn capacity(&self) -> usize {
self.raw.allocated as usize
}
pub fn reserve(&mut self, new_capacity: usize) {
let r = unsafe { onig_sys::onig_region_resize(&self.raw, new_capacity as c_int) };
if r != 0 {
panic!("Onig: fail to memory allocation during region resize")
}
}
pub fn len(&self) -> usize {
self.raw.num_regs as usize
}
pub fn pos(&self, pos: usize) -> Option<(usize, usize)> {
if pos >= self.len() {
return None;
}
let (beg, end) = unsafe {
(*self.raw.beg.offset(pos as isize),
*self.raw.end.offset(pos as isize))
};
if beg >= 0 {
Some((beg as usize, end as usize))
} else {
None
}
}
pub fn tree(&self) -> Option<&CaptureTreeNode> {
let tree = unsafe { onig_sys::onig_get_capture_tree(&self.raw) };
if tree.is_null() {
None
} else {
Some(unsafe { transmute(tree) })
}
}
}
impl Drop for Region {
fn drop(&mut self) {
unsafe {
onig_sys::onig_region_free(&mut self.raw, 0);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_region_create() {
Region::new();
}
#[test]
fn test_region_clear() {
let mut region = Region::new();
region.clear();
}
#[test]
fn test_region_resize() {
{
let mut region = Region::new();
assert!(region.capacity() == 0);
region.reserve(100);
{
let region_borrowed = ®ion;
assert!(region_borrowed.capacity() == 100);
}
}
{
let region = Region::with_capacity(10);
assert!(region.capacity() == 10);
}
}
}