<commit_before>extern mod std;

use libc::c_char;
use libc::c_int;
use libc::size_t;
use libc::c_ulong;
use libc::c_void;
use ptr::null;
use ptr::addr_of;
use ptr::mut_addr_of;
use str::as_c_str;

struct mpz_struct {
  _mp_alloc: c_int,
  _mp_size: c_int,
  _mp_d: *c_void
}

type mpz_srcptr = *const mpz_struct;
type mpz_ptr = *mut mpz_struct;

extern mod gmp {
  fn __gmpz_init(x: mpz_ptr);
  fn __gmpz_init_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_clear(x: mpz_ptr);
  fn __gmpz_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_get_str(str: *c_char, base: c_int, op: mpz_srcptr) -> *c_char;
  pure fn __gmpz_sizeinbase(op: mpz_srcptr, base: c_int) -> size_t;
  pure fn __gmpz_cmp(op: mpz_srcptr, op2: mpz_srcptr) -> c_int;
  pure fn __gmpz_cmp_ui(op1: mpz_srcptr, op2: c_ulong) -> c_int;
  fn __gmpz_add(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_sub(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_mul(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_neg(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_tdiv_q(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
  fn __gmpz_mod(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
}

use gmp::*;

pub struct Mpz {
  priv mpz: mpz_struct,

  drop {
    __gmpz_clear(mut_addr_of(&self.mpz));
  }
}

impl Mpz {
  fn set_str(&self, s: &str, base: int) -> bool {
    let mpz = mut_addr_of(&self.mpz);
    let r = as_c_str(s, { |s| __gmpz_set_str(mpz, s, base as c_int) });
    r == 0
  }

  pure fn size_in_base(&self, base: int) -> uint {
    __gmpz_sizeinbase(addr_of(&self.mpz), base as c_int) as uint
  }
}

impl Mpz: cmp::Eq {
  pure fn eq(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) == 0
  }
  pure fn ne(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) != 0
  }
}

impl Mpz: cmp::Ord {
  pure fn lt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) < 0
  }
  pure fn le(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) <= 0
  }
  pure fn gt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) > 0
  }
  pure fn ge(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) >= 0
  }
}

impl Mpz: num::Num {
  pure fn add(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_add(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn sub(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_sub(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn mul(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_mul(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn div(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_tdiv_q(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn modulo(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_mod(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn neg() -> Mpz unsafe {
    let res = init();
    __gmpz_neg(mut_addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
  pure fn to_int() -> int {
    fail ~"not implemented";
  }
  static pure fn from_int(other: int) -> Mpz unsafe {
    let res = init();
    // the gmp functions dealing with longs aren't usable here - long is only
    // guaranteed to be at least 32-bit
    assert(res.set_str(other.to_str(), 10));
    res
  }
}

pub pure fn from_str(s: &str) -> Option<Mpz> {
  init_set_str(s, 10)
}

impl Mpz : from_str::FromStr {
  static fn from_str(s: &str) -> Option<Mpz> {
    from_str(s)
  }
}

impl Mpz : to_str::ToStr {
  pure fn to_str() -> ~str unsafe {
    let length = self.size_in_base(10) + 2;
    let dst = vec::to_mut(vec::from_elem(length, '0'));
    let pdst = vec::raw::to_ptr(dst);

    str::raw::from_c_str(__gmpz_get_str(pdst as *c_char, 10, addr_of(&self.mpz)))
  }
}

pub pure fn init() -> Mpz unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  __gmpz_init(mut_addr_of(&mpz));
  Mpz { mpz: mpz }
}

pub pure fn init_set_str(s: &str, base: int) -> Option<Mpz> unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  let mpz_ptr = mut_addr_of(&mpz);
  let r = as_c_str(s, { |s| __gmpz_init_set_str(mpz_ptr, s, base as c_int) });
  if r == 0 {
    Some(Mpz { mpz: mpz })
  } else {
    __gmpz_clear(mpz_ptr);
    None
  }
}

#[cfg(test)]
mod tests {
  #[test]
  fn size_in_base() {
    let x = option::unwrap(from_str("150000"));
    assert(x.size_in_base(10) == 6);
  }

  #[test]
  fn eq() {
    let x = option::unwrap(from_str("4242142195"));
    let y = option::unwrap(from_str("4242142195"));
    let z = option::unwrap(from_str("4242142196"));

    assert(x == y);
    assert(x != z);
    assert(y != z);
  }

  #[test]
  fn ord() {
    let x = option::unwrap(from_str("40000000000000000000000"));
    let y = option::unwrap(from_str("45000000000000000000000"));
    let z = option::unwrap(from_str("50000000000000000000000"));

    assert(x < y && x < z && y < z);
    assert(x <= x && x <= y && x <= z && y <= z);
    assert(z > y && z > x && y > x);
    assert(z >= z && z >= y && z >= x && y >= x);
  }

  #[test]
  #[should_fail]
  fn div_zero() {
    let x = init();
    x / x;
  }

  #[test]
  #[should_fail]
  fn modulo_zero() {
    let x = init();
    x % x;
  }

  #[test]
  fn test_div_round() {
    let x = init();
    let y = init();
    let mut z: Mpz;

    x.set_str("2", 10);
    y.set_str("3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / 3) == 0);

    x.set_str("2", 10);
    y.set_str("-3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / -3) == 0);
  }

  #[test]
  fn to_str() {
    let x = option::unwrap(from_str("1234567890"));
    assert(x.to_str() == ~"1234567890");
  }

  #[test]
  fn invalid_str() {
    assert(from_str("foobar").is_none());
  }
}
<commit_msg>fix set_str's mutability issues<commit_after>extern mod std;

use libc::c_char;
use libc::c_int;
use libc::size_t;
use libc::c_ulong;
use libc::c_void;
use ptr::null;
use ptr::addr_of;
use ptr::mut_addr_of;
use ptr::to_mut_unsafe_ptr;
use str::as_c_str;

struct mpz_struct {
  _mp_alloc: c_int,
  _mp_size: c_int,
  _mp_d: *c_void
}

type mpz_srcptr = *const mpz_struct;
type mpz_ptr = *mut mpz_struct;

extern mod gmp {
  fn __gmpz_init(x: mpz_ptr);
  fn __gmpz_init_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_clear(x: mpz_ptr);
  fn __gmpz_set_str(rop: mpz_ptr, str: *c_char, base: c_int) -> c_int;
  fn __gmpz_get_str(str: *c_char, base: c_int, op: mpz_srcptr) -> *c_char;
  pure fn __gmpz_sizeinbase(op: mpz_srcptr, base: c_int) -> size_t;
  pure fn __gmpz_cmp(op: mpz_srcptr, op2: mpz_srcptr) -> c_int;
  pure fn __gmpz_cmp_ui(op1: mpz_srcptr, op2: c_ulong) -> c_int;
  fn __gmpz_add(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_sub(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_mul(rop: mpz_ptr, op1: mpz_srcptr, op2: mpz_srcptr);
  fn __gmpz_neg(rop: mpz_ptr, op: mpz_srcptr);
  fn __gmpz_tdiv_q(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
  fn __gmpz_mod(r: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
}

use gmp::*;

pub struct Mpz {
  priv mpz: mpz_struct,

  drop {
    __gmpz_clear(mut_addr_of(&self.mpz));
  }
}

impl Mpz {
  fn set_str(&mut self, s: &str, base: int) -> bool {
    let mpz = to_mut_unsafe_ptr(&mut self.mpz);
    let r = as_c_str(s, { |s| __gmpz_set_str(mpz, s, base as c_int) });
    r == 0
  }

  pure fn size_in_base(&self, base: int) -> uint {
    __gmpz_sizeinbase(addr_of(&self.mpz), base as c_int) as uint
  }
}

impl Mpz: cmp::Eq {
  pure fn eq(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) == 0
  }
  pure fn ne(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) != 0
  }
}

impl Mpz: cmp::Ord {
  pure fn lt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) < 0
  }
  pure fn le(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) <= 0
  }
  pure fn gt(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) > 0
  }
  pure fn ge(other: &Mpz) -> bool {
    __gmpz_cmp(addr_of(&self.mpz), addr_of(&other.mpz)) >= 0
  }
}

impl Mpz: num::Num {
  pure fn add(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_add(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn sub(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_sub(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn mul(other: &Mpz) -> Mpz unsafe {
    let res = init();
    __gmpz_mul(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn div(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_tdiv_q(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn modulo(other: &Mpz) -> Mpz unsafe {
    if __gmpz_cmp_ui(addr_of(&self.mpz), 0) == 0 {
      fail ~"divide by zero";
    }

    let res = init();
    __gmpz_mod(mut_addr_of(&res.mpz), addr_of(&self.mpz), addr_of(&other.mpz));
    res
  }
  pure fn neg() -> Mpz unsafe {
    let res = init();
    __gmpz_neg(mut_addr_of(&res.mpz), addr_of(&self.mpz));
    res
  }
  pure fn to_int() -> int {
    fail ~"not implemented";
  }
  static pure fn from_int(other: int) -> Mpz unsafe {
    let mut res = init();
    // the gmp functions dealing with longs aren't usable here - long is only
    // guaranteed to be at least 32-bit
    assert(res.set_str(other.to_str(), 10));
    res
  }
}

pub pure fn from_str(s: &str) -> Option<Mpz> {
  init_set_str(s, 10)
}

impl Mpz : from_str::FromStr {
  static fn from_str(s: &str) -> Option<Mpz> {
    from_str(s)
  }
}

impl Mpz : to_str::ToStr {
  pure fn to_str() -> ~str unsafe {
    let length = self.size_in_base(10) + 2;
    let dst = vec::to_mut(vec::from_elem(length, '0'));
    let pdst = vec::raw::to_ptr(dst);

    str::raw::from_c_str(__gmpz_get_str(pdst as *c_char, 10, addr_of(&self.mpz)))
  }
}

pub pure fn init() -> Mpz unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  __gmpz_init(mut_addr_of(&mpz));
  Mpz { mpz: mpz }
}

pub pure fn init_set_str(s: &str, base: int) -> Option<Mpz> unsafe {
  let mpz = mpz_struct { _mp_alloc: 0, _mp_size: 0, _mp_d: null() };
  let mpz_ptr = mut_addr_of(&mpz);
  let r = as_c_str(s, { |s| __gmpz_init_set_str(mpz_ptr, s, base as c_int) });
  if r == 0 {
    Some(Mpz { mpz: mpz })
  } else {
    __gmpz_clear(mpz_ptr);
    None
  }
}

#[cfg(test)]
mod tests {
  #[test]
  fn size_in_base() {
    let x = option::unwrap(from_str("150000"));
    assert(x.size_in_base(10) == 6);
  }

  #[test]
  fn eq() {
    let x = option::unwrap(from_str("4242142195"));
    let y = option::unwrap(from_str("4242142195"));
    let z = option::unwrap(from_str("4242142196"));

    assert(x == y);
    assert(x != z);
    assert(y != z);
  }

  #[test]
  fn ord() {
    let x = option::unwrap(from_str("40000000000000000000000"));
    let y = option::unwrap(from_str("45000000000000000000000"));
    let z = option::unwrap(from_str("50000000000000000000000"));

    assert(x < y && x < z && y < z);
    assert(x <= x && x <= y && x <= z && y <= z);
    assert(z > y && z > x && y > x);
    assert(z >= z && z >= y && z >= x && y >= x);
  }

  #[test]
  #[should_fail]
  fn div_zero() {
    let x = init();
    x / x;
  }

  #[test]
  #[should_fail]
  fn modulo_zero() {
    let x = init();
    x % x;
  }

  #[test]
  fn test_div_round() {
    let mut x = init();
    let mut y = init();
    let mut z: Mpz;

    x.set_str("2", 10);
    y.set_str("3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / 3) == 0);

    x.set_str("2", 10);
    y.set_str("-3", 10);
    z = x / y;
    assert(__gmpz_cmp_ui(addr_of(&z.mpz), 2 / -3) == 0);
  }

  #[test]
  fn to_str() {
    let x = option::unwrap(from_str("1234567890"));
    assert(x.to_str() == ~"1234567890");
  }

  #[test]
  fn invalid_str() {
    assert(from_str("foobar").is_none());
  }
}
<|endoftext|>


<commit_before><commit_msg>Give the original SSL object to the FtpStream<commit_after><|endoftext|>


<commit_before><commit_msg>Add username to ion<commit_after><|endoftext|>


<commit_before><commit_msg>Node launch funcitonality missed Added<commit_after><|endoftext|>


<commit_before>extern crate zip;
extern crate quick_xml;
extern crate encoding;
extern crate byteorder;
#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate log;

mod errors;
mod vba;

use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use std::collections::HashMap;
use std::slice::Chunks;

use errors::*;
use vba::VbaProject;

use zip::read::{ZipFile, ZipArchive};
use zip::result::ZipError;
use quick_xml::{XmlReader, Event, AsStr};

macro_rules! unexp {
    ($pat: expr) => {
        {
            return Err($pat.into());
        }
    };
    ($pat: expr, $($args: expr)* ) => {
        {
            return Err(format!($pat, $($args)*).into());
        }
    };
}

#[derive(Debug, Clone)]
pub enum DataType {
    Int(i64),
    Float(f64),
    String(String),
    Empty,
}

pub struct Excel {
    zip: ZipArchive<File>,
    strings: Vec<String>,
    /// Map of sheet names/sheet path within zip archive
    sheets: HashMap<String, String>,
}

#[derive(Debug, Default)]
pub struct Range {
    position: (u32, u32),
    size: (usize, usize),
    inner: Vec<DataType>,
}

/// An iterator to read `Range` struct row by row
pub struct Rows<'a> {
    inner: Chunks<'a, DataType>,
}

impl Excel {

    /// Opens a new workbook
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Excel> {
        let f = try!(File::open(path));
        let zip = try!(ZipArchive::new(f));
        Ok(Excel { zip: zip, strings: vec![], sheets: HashMap::new() })
    }

    /// Does the workbook contain a vba project
    pub fn has_vba(&mut self) -> bool {
        self.zip.by_name("xl/vbaProject.bin").is_ok()
    }

    /// Gets vba project
    pub fn vba_project(&mut self) -> Result<VbaProject> {
        let f = try!(self.zip.by_name("xl/vbaProject.bin"));
        VbaProject::new(f)
    }

    /// Get all data from `Worksheet`
    pub fn worksheet_range(&mut self, name: &str) -> Result<Range> {
        try!(self.read_shared_strings());
        try!(self.read_sheets_names());
        let strings = &self.strings;
        let ws = match self.sheets.get(name) {
            Some(p) => try!(self.zip.by_name(p)),
            None => unexp!("Sheet '{}' does not exist", name),
        };
        Range::from_worksheet(ws, strings)
    }

    /// Loop through all archive files and opens 'xl/worksheets' files
    /// Store sheet name and path into self.sheets
    fn read_sheets_names(&mut self) -> Result<()> {
        if self.sheets.is_empty() {
            let sheets = {
                let mut sheets = HashMap::new();
                for i in 0..self.zip.len() {
                    let f = try!(self.zip.by_index(i));
                    let name = f.name().to_string();
                    if name.starts_with("xl/worksheets/") {
                        let xml = XmlReader::from_reader(BufReader::new(f))
                            .with_check(false)
                            .trim_text(false);
                        'xml_loop: for res_event in xml {
                            if let Ok(Event::Start(ref e)) = res_event {
                                if e.name() == b"sheetPr" {
                                    for a in e.attributes() {
                                        if let Ok((b"codeName", v)) = a {
                                            sheets.insert(try!(v.as_str()).to_string(), name);
                                            break 'xml_loop;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                sheets
            };
            self.sheets = sheets;
        }
        Ok(())
    }

    /// Read shared string list
    fn read_shared_strings(&mut self) -> Result<()> {
        if self.strings.is_empty() {
            match self.zip.by_name("xl/sharedStrings.xml") {
                Ok(f) => {
                    let mut xml = XmlReader::from_reader(BufReader::new(f))
                        .with_check(false)
                        .trim_text(false);

                    let mut strings = Vec::new();
                    while let Some(res_event) = xml.next() {
                        match res_event {
                            Ok(Event::Start(ref e)) if e.name() == b"t" => {
                                strings.push(try!(xml.read_text(b"t")));
                            }
                            Err(e) => return Err(e.into()),
                            _ => (),
                        }
                    }
                    self.strings = strings;
                },
                Err(ZipError::FileNotFound) => (),
                Err(e) => return Err(e.into()),
            }
        }

        Ok(())
    }

}

impl Range {

    /// open a xml `ZipFile` reader and read content of *sheetData* and *dimension* node
    fn from_worksheet(xml: ZipFile, strings: &[String]) -> Result<Range> {
        let mut xml = XmlReader::from_reader(BufReader::new(xml))
            .with_check(false)
            .trim_text(false);
        let mut data = Range::default();
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref e)) => {
                    match e.name() {
                        b"dimension" => match e.attributes().filter_map(|a| a.ok())
                                .find(|&(key, _)| key == b"ref") {
                            Some((_, dim)) => {
                                let (position, size) = try!(get_dimension(try!(dim.as_str())));
                                data.position = position;
                                data.size = (size.0 as usize, size.1 as usize);
                                data.inner.reserve_exact(data.size.0 * data.size.1);
                            },
                            None => unexp!("Expecting dimension, got {:?}", e),
                        },
                        b"sheetData" => {
                            let _ = try!(data.read_sheet_data(&mut xml, strings));
                        }
                        _ => (),
                    }
                },
                _ => (),
            }
        }
        data.inner.shrink_to_fit();
        Ok(data)
    }

    /// get worksheet position (row, column)
    pub fn get_position(&self) -> (u32, u32) {
        self.position
    }

    /// get size
    pub fn get_size(&self) -> (usize, usize) {
        self.size
    }

    /// get cell value
    pub fn get_value(&self, i: usize, j: usize) -> &DataType {
        let idx = i * self.size.0 + j;
        &self.inner[idx]
    }

    /// get an iterator over inner rows
    pub fn rows(&self) -> Rows {
        let width = self.size.0;
        Rows { inner: self.inner.chunks(width) }
    }

    /// read sheetData node
    fn read_sheet_data(&mut self, xml: &mut XmlReader<BufReader<ZipFile>>, strings: &[String])
        -> Result<()>
    {
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref c_element)) => {
                    if c_element.name() == b"c" {
                        loop {
                            match xml.next() {
                                Some(Err(e)) => return Err(e.into()),
                                Some(Ok(Event::Start(ref e))) => {
                                    if e.name() == b"v" {
                                        let v = try!(xml.read_text(b"v"));
                                        let value = match c_element.attributes()
                                            .filter_map(|a| a.ok())
                                            .find(|&(k, _)| k == b"t") {
                                                Some((_, b"s")) => {
                                                    let idx: usize = try!(v.parse());
                                                    DataType::String(strings[idx].clone())
                                                },
                                                // TODO: check in styles to know which type is
                                                // supposed to be used
                                                _ => match v.parse() {
                                                    Ok(i) => DataType::Int(i),
                                                    Err(_) => try!(v.parse()
                                                                   .map(DataType::Float)),
                                                },
                                            };
                                        self.inner.push(value);
                                        break;
                                    } else {
                                        unexp!("not v node");
                                    }
                                },
                                Some(Ok(Event::End(ref e))) => {
                                    if e.name() == b"c" {
                                        self.inner.push(DataType::Empty);
                                        break;
                                    }
                                }
                                None => unexp!("End of xml"),
                                _ => (),
                            }
                        }
                    }
                },
                Ok(Event::End(ref e)) if e.name() == b"sheetData" => return Ok(()),
                _ => (),
            }
        }
        unexp!("Could not find </sheetData>")
    }

}

impl<'a> Iterator for Rows<'a> {
    type Item = &'a [DataType];
    fn next(&mut self) -> Option<&'a [DataType]> {
        self.inner.next()
    }
}

/// converts a text representation (e.g. "A6:G67") of a dimension into integers
/// - top left (row, column),
/// - size (width, height)
fn get_dimension(dimension: &str) -> Result<((u32, u32), (u32, u32))> {
    match dimension.chars().position(|c| c == ':') {
        None => {
            get_row_column(dimension).map(|position| (position, (1, 1)))
        },
        Some(p) => {
            let top_left = try!(get_row_column(&dimension[..p]));
            let bottom_right = try!(get_row_column(&dimension[p + 1..]));
            Ok((top_left, (bottom_right.0 - top_left.0 + 1, bottom_right.1 - top_left.1 + 1)))
        }
    }
}

/// converts a text range name into its position (row, column)
fn get_row_column(range: &str) -> Result<(u32, u32)> {
    let mut col = 0;
    let mut pow = 1;
    let mut rowpos = range.len();
    let mut readrow = true;
    for c in range.chars().rev() {
        match c {
            '0'...'9' => {
                if readrow {
                    rowpos -= 1;
                } else {
                    unexp!("Numeric character are only allowed at the end of the range: {}", c);
                }
            }
            c @ 'A'...'Z' => {
                readrow = false;
                col += ((c as u8 - b'A') as u32 + 1) * pow;
                pow *= 26;
            },
            c @ 'a'...'z' => {
                readrow = false;
                col += ((c as u8 - b'a') as u32 + 1) * pow;
                pow *= 26;
            },
            _ => unexp!("Expecting alphanumeric character, got {:?}", c),
        }
    }
    let row = try!(range[rowpos..].parse());
    Ok((row, col))
}

#[cfg(test)]
mod tests {

    extern crate env_logger;

    use super::Excel;

    #[test]
    fn test_range_sample() {
        let mut xl = Excel::open("/home/jtuffe/download/DailyValo_FX_Rates_Credit_05 25 16.xlsm")
            .expect("cannot open excel file");
        println!("{:?}", xl.sheets);
        let data = xl.worksheet_range("Sheet1");
        assert!(data.is_ok());
        for (i, r) in data.unwrap().rows().enumerate() {
            println!("Row {}: {:?}", i, r);
        }
    }

    #[test]
    fn test_vba() {

        env_logger::init().unwrap();

//         let path = "/home/jtuffe/download/test_vba.xlsm";
        let path = "/home/jtuffe/download/Extractions Simples.xlsb";
        let path = "/home/jtuffe/download/test_xl/ReportRDM_CVA VF_v3.xlsm";
        let mut xl = Excel::open(path).expect("cannot open excel file");
        let vba_project = xl.vba_project().unwrap();
        let vba = vba_project.read_vba();
        let (references, modules) = vba.unwrap();
        println!("references: {:#?}", references);
        for module in &modules {
            let data = vba_project.read_module(module).unwrap();
            println!("module {}:\r\n{}", module.name, data);
        }

    }
}
<commit_msg>pub use errors::*<commit_after>extern crate zip;
extern crate quick_xml;
extern crate encoding;
extern crate byteorder;
#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate log;

mod errors;
mod vba;

use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use std::collections::HashMap;
use std::slice::Chunks;

pub use errors::*;
use vba::VbaProject;

use zip::read::{ZipFile, ZipArchive};
use zip::result::ZipError;
use quick_xml::{XmlReader, Event, AsStr};

macro_rules! unexp {
    ($pat: expr) => {
        {
            return Err($pat.into());
        }
    };
    ($pat: expr, $($args: expr)* ) => {
        {
            return Err(format!($pat, $($args)*).into());
        }
    };
}

#[derive(Debug, Clone)]
pub enum DataType {
    Int(i64),
    Float(f64),
    String(String),
    Empty,
}

pub struct Excel {
    zip: ZipArchive<File>,
    strings: Vec<String>,
    /// Map of sheet names/sheet path within zip archive
    sheets: HashMap<String, String>,
}

#[derive(Debug, Default)]
pub struct Range {
    position: (u32, u32),
    size: (usize, usize),
    inner: Vec<DataType>,
}

/// An iterator to read `Range` struct row by row
pub struct Rows<'a> {
    inner: Chunks<'a, DataType>,
}

impl Excel {

    /// Opens a new workbook
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Excel> {
        let f = try!(File::open(path));
        let zip = try!(ZipArchive::new(f));
        Ok(Excel { zip: zip, strings: vec![], sheets: HashMap::new() })
    }

    /// Does the workbook contain a vba project
    pub fn has_vba(&mut self) -> bool {
        self.zip.by_name("xl/vbaProject.bin").is_ok()
    }

    /// Gets vba project
    pub fn vba_project(&mut self) -> Result<VbaProject> {
        let f = try!(self.zip.by_name("xl/vbaProject.bin"));
        VbaProject::new(f)
    }

    /// Get all data from `Worksheet`
    pub fn worksheet_range(&mut self, name: &str) -> Result<Range> {
        try!(self.read_shared_strings());
        try!(self.read_sheets_names());
        let strings = &self.strings;
        let ws = match self.sheets.get(name) {
            Some(p) => try!(self.zip.by_name(p)),
            None => unexp!("Sheet '{}' does not exist", name),
        };
        Range::from_worksheet(ws, strings)
    }

    /// Loop through all archive files and opens 'xl/worksheets' files
    /// Store sheet name and path into self.sheets
    fn read_sheets_names(&mut self) -> Result<()> {
        if self.sheets.is_empty() {
            let sheets = {
                let mut sheets = HashMap::new();
                for i in 0..self.zip.len() {
                    let f = try!(self.zip.by_index(i));
                    let name = f.name().to_string();
                    if name.starts_with("xl/worksheets/") {
                        let xml = XmlReader::from_reader(BufReader::new(f))
                            .with_check(false)
                            .trim_text(false);
                        'xml_loop: for res_event in xml {
                            if let Ok(Event::Start(ref e)) = res_event {
                                if e.name() == b"sheetPr" {
                                    for a in e.attributes() {
                                        if let Ok((b"codeName", v)) = a {
                                            sheets.insert(try!(v.as_str()).to_string(), name);
                                            break 'xml_loop;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                sheets
            };
            self.sheets = sheets;
        }
        Ok(())
    }

    /// Read shared string list
    fn read_shared_strings(&mut self) -> Result<()> {
        if self.strings.is_empty() {
            match self.zip.by_name("xl/sharedStrings.xml") {
                Ok(f) => {
                    let mut xml = XmlReader::from_reader(BufReader::new(f))
                        .with_check(false)
                        .trim_text(false);

                    let mut strings = Vec::new();
                    while let Some(res_event) = xml.next() {
                        match res_event {
                            Ok(Event::Start(ref e)) if e.name() == b"t" => {
                                strings.push(try!(xml.read_text(b"t")));
                            }
                            Err(e) => return Err(e.into()),
                            _ => (),
                        }
                    }
                    self.strings = strings;
                },
                Err(ZipError::FileNotFound) => (),
                Err(e) => return Err(e.into()),
            }
        }

        Ok(())
    }

}

impl Range {

    /// open a xml `ZipFile` reader and read content of *sheetData* and *dimension* node
    fn from_worksheet(xml: ZipFile, strings: &[String]) -> Result<Range> {
        let mut xml = XmlReader::from_reader(BufReader::new(xml))
            .with_check(false)
            .trim_text(false);
        let mut data = Range::default();
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref e)) => {
                    match e.name() {
                        b"dimension" => match e.attributes().filter_map(|a| a.ok())
                                .find(|&(key, _)| key == b"ref") {
                            Some((_, dim)) => {
                                let (position, size) = try!(get_dimension(try!(dim.as_str())));
                                data.position = position;
                                data.size = (size.0 as usize, size.1 as usize);
                                data.inner.reserve_exact(data.size.0 * data.size.1);
                            },
                            None => unexp!("Expecting dimension, got {:?}", e),
                        },
                        b"sheetData" => {
                            let _ = try!(data.read_sheet_data(&mut xml, strings));
                        }
                        _ => (),
                    }
                },
                _ => (),
            }
        }
        data.inner.shrink_to_fit();
        Ok(data)
    }

    /// get worksheet position (row, column)
    pub fn get_position(&self) -> (u32, u32) {
        self.position
    }

    /// get size
    pub fn get_size(&self) -> (usize, usize) {
        self.size
    }

    /// get cell value
    pub fn get_value(&self, i: usize, j: usize) -> &DataType {
        let idx = i * self.size.0 + j;
        &self.inner[idx]
    }

    /// get an iterator over inner rows
    pub fn rows(&self) -> Rows {
        let width = self.size.0;
        Rows { inner: self.inner.chunks(width) }
    }

    /// read sheetData node
    fn read_sheet_data(&mut self, xml: &mut XmlReader<BufReader<ZipFile>>, strings: &[String])
        -> Result<()>
    {
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref c_element)) => {
                    if c_element.name() == b"c" {
                        loop {
                            match xml.next() {
                                Some(Err(e)) => return Err(e.into()),
                                Some(Ok(Event::Start(ref e))) => {
                                    if e.name() == b"v" {
                                        let v = try!(xml.read_text(b"v"));
                                        let value = match c_element.attributes()
                                            .filter_map(|a| a.ok())
                                            .find(|&(k, _)| k == b"t") {
                                                Some((_, b"s")) => {
                                                    let idx: usize = try!(v.parse());
                                                    DataType::String(strings[idx].clone())
                                                },
                                                // TODO: check in styles to know which type is
                                                // supposed to be used
                                                _ => match v.parse() {
                                                    Ok(i) => DataType::Int(i),
                                                    Err(_) => try!(v.parse()
                                                                   .map(DataType::Float)),
                                                },
                                            };
                                        self.inner.push(value);
                                        break;
                                    } else {
                                        unexp!("not v node");
                                    }
                                },
                                Some(Ok(Event::End(ref e))) => {
                                    if e.name() == b"c" {
                                        self.inner.push(DataType::Empty);
                                        break;
                                    }
                                }
                                None => unexp!("End of xml"),
                                _ => (),
                            }
                        }
                    }
                },
                Ok(Event::End(ref e)) if e.name() == b"sheetData" => return Ok(()),
                _ => (),
            }
        }
        unexp!("Could not find </sheetData>")
    }

}

impl<'a> Iterator for Rows<'a> {
    type Item = &'a [DataType];
    fn next(&mut self) -> Option<&'a [DataType]> {
        self.inner.next()
    }
}

/// converts a text representation (e.g. "A6:G67") of a dimension into integers
/// - top left (row, column),
/// - size (width, height)
fn get_dimension(dimension: &str) -> Result<((u32, u32), (u32, u32))> {
    match dimension.chars().position(|c| c == ':') {
        None => {
            get_row_column(dimension).map(|position| (position, (1, 1)))
        },
        Some(p) => {
            let top_left = try!(get_row_column(&dimension[..p]));
            let bottom_right = try!(get_row_column(&dimension[p + 1..]));
            Ok((top_left, (bottom_right.0 - top_left.0 + 1, bottom_right.1 - top_left.1 + 1)))
        }
    }
}

/// converts a text range name into its position (row, column)
fn get_row_column(range: &str) -> Result<(u32, u32)> {
    let mut col = 0;
    let mut pow = 1;
    let mut rowpos = range.len();
    let mut readrow = true;
    for c in range.chars().rev() {
        match c {
            '0'...'9' => {
                if readrow {
                    rowpos -= 1;
                } else {
                    unexp!("Numeric character are only allowed at the end of the range: {}", c);
                }
            }
            c @ 'A'...'Z' => {
                readrow = false;
                col += ((c as u8 - b'A') as u32 + 1) * pow;
                pow *= 26;
            },
            c @ 'a'...'z' => {
                readrow = false;
                col += ((c as u8 - b'a') as u32 + 1) * pow;
                pow *= 26;
            },
            _ => unexp!("Expecting alphanumeric character, got {:?}", c),
        }
    }
    let row = try!(range[rowpos..].parse());
    Ok((row, col))
}

#[cfg(test)]
mod tests {

    extern crate env_logger;

    use super::Excel;

    #[test]
    fn test_range_sample() {
        let mut xl = Excel::open("/home/jtuffe/download/DailyValo_FX_Rates_Credit_05 25 16.xlsm")
            .expect("cannot open excel file");
        println!("{:?}", xl.sheets);
        let data = xl.worksheet_range("Sheet1");
        assert!(data.is_ok());
        for (i, r) in data.unwrap().rows().enumerate() {
            println!("Row {}: {:?}", i, r);
        }
    }

    #[test]
    fn test_vba() {

        env_logger::init().unwrap();

//         let path = "/home/jtuffe/download/test_vba.xlsm";
        let path = "/home/jtuffe/download/Extractions Simples.xlsb";
        let path = "/home/jtuffe/download/test_xl/ReportRDM_CVA VF_v3.xlsm";
        let mut xl = Excel::open(path).expect("cannot open excel file");
        let vba_project = xl.vba_project().unwrap();
        let vba = vba_project.read_vba();
        let (references, modules) = vba.unwrap();
        println!("references: {:#?}", references);
        for module in &modules {
            let data = vba_project.read_module(module).unwrap();
            println!("module {}:\r\n{}", module.name, data);
        }

    }
}
<|endoftext|>


<commit_before><commit_msg>Formatting changes<commit_after><|endoftext|>


<commit_before><commit_msg>refactor(lib): errors if there is no docs<commit_after><|endoftext|>


<commit_before><commit_msg>Formatting and comments<commit_after><|endoftext|>


<commit_before>extern crate cobalt;

use cobalt::Runner;
use std::os;

// TODO: implement cli with getopts
// http://doc.rust-lang.org/getopts/
fn main() {
    let args        = os::args();
    let use_default = args.len() == 1u;

    if use_default {
        Runner::run(".");
    } else {
        Runner::run(args[1].as_slice());
    }
}
<commit_msg>use getopts crate for cli<commit_after>extern crate cobalt;
extern crate getopts;

use cobalt::Runner;
use getopts::{optflag, getopts, OptGroup};
use std::os;

fn print_usage(program: &str, _opts: &[OptGroup]) {
    println!("Usage: {} [path] [options]", program);
    println!("-h --help\tUsage");
    println!("-v --version\tDisplay version");
}

fn print_version() {
    let version = vec!["0", "0", "1"];

    println!("{}", version.connect("."));
}

fn main() {
    let args: Vec<String> = os::args();
    let program = args[0].clone();

    let opts = [
        optflag("h", "help", "print this help menu"),
        optflag("v", "version", "Display version")
    ];

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(program.as_slice(), opts);
        return;
    }

    if matches.opt_present("v") {
        print_version();
        return;
    }

    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(program.as_slice(), opts);
        return;
    };

    Runner::run(input.as_slice());
}
<|endoftext|>


<commit_before><commit_msg>Position fn _move implemented<commit_after><|endoftext|>


<commit_before><commit_msg>Remove Trampoline<commit_after><|endoftext|>


<commit_before><commit_msg>immutable variables added<commit_after><|endoftext|>


<commit_before><commit_msg>adding small testing main.rs<commit_after>extern crate sqlib;

use sqlib::Connection;

fn main() {
    let mut conn = Connection::new("127.0.0.1:10011".to_string()).unwrap();
    let str = conn.send_command("help login").unwrap();
    println!("{}", str);
    let _ = conn.quit();
}
<|endoftext|>


<commit_before><commit_msg>cmd/init: fix template<commit_after><|endoftext|>


<commit_before><commit_msg>added p003 outline<commit_after>struct Prime {
    current: u64,
}

// implement iterator

fn main() {
    // The prime factors of 13195 are 5, 7, 13 and 29.
    // What is the largest prime factor of the number 600851475143 ?

    println!("The largest prime factor of the number 600851475143 is: {}", 0);
}
<|endoftext|>


<commit_before><commit_msg>Checking to make sure we know what 'self' is in nested objects.<commit_after>fn main() {

  obj foo() {
      fn m1() -> str {
          ret "foo.m1";
      }
      fn m2() -> str {
          ret self.m1();
      }
      fn m3() -> str {
          let str s1 = self.m2();
          assert s1 == "foo.m1";

          obj bar() {
              fn m1() -> str {
                  ret "bar.m1";
              }

              fn m2() -> str {
                  ret self.m1();
              }
          }

          auto b = bar();
          let str s3 = b.m2();

          let str s4 = self.m2();
          assert s4 == "foo.m1";

          ret s3;
      }
  }

  auto a = foo();

  let str s1 = a.m1();
  assert s1 == "foo.m1";

  let str s2 = a.m2();
  assert s2 == "foo.m1";

  let str s3 = a.m3();
  assert s3 == "bar.m1";
}

<|endoftext|>


<commit_before><commit_msg>Comment coerce method<commit_after><|endoftext|>


<commit_before><commit_msg>Rewrite imag header version output test<commit_after><|endoftext|>


<commit_before>use common::debug::*;
use common::pio::*;

use drivers::keyboard::KeyEvent;

use programs::session::*;

pub struct Serial {
    pub port: u16,
    pub irq: u8,
    pub escape: bool,
    pub cursor_control: bool
}

impl Serial {
    pub fn new(port: u16, irq: u8) -> Serial{
        return Serial {
            port: port,
            irq: irq,
            escape: false,
            cursor_control: false
        };
    }
}

impl SessionDevice for Serial {
    #[allow(unused_variables)]
    fn on_irq(&mut self, session: &Session, updates: &mut SessionUpdates, irq: u8){
        if irq == self.irq {
            unsafe{
                while inb(self.port + 5) & 1 == 0 {}
                let mut c = inb(self.port) as char;
                let mut sc = 0;

                if self.escape {
                    self.escape = false;

                    if c == '['{
                        self.cursor_control = true;
                    }

                    c = '\0';
                }else if self.cursor_control {
                    self.cursor_control = false;

                    if c == 'A'{
                        sc = 0x48;
                    }else if c == 'B'{
                        sc = 0x50;
                    }else if c == 'C'{
                        sc = 0x4D;
                    }else if c == 'D'{
                        sc = 0x4B;
                    }

                    c = '\0';
                }else if c == '\x1B' {
                    self.escape = true;
                    c = '\0';
                }else if c == '\r' {
                    c = '\n';
                    dc(c);
                }else if c == '\x7F' {
                    c = '\x08';
                    dc(c);
                }else{
                    dc(c);
                }

                if c != '\0' || sc != 0 {
                    updates.key_events.push(KeyEvent {
                        character: c,
                        scancode: sc,
                        pressed: true
                    });
                }
            }
        }
    }
}
<commit_msg>WIP Serial terminal<commit_after>use common::debug::*;
use common::pio::*;

use drivers::keyboard::KeyEvent;

use programs::session::*;

pub struct Serial {
    pub port: u16,
    pub irq: u8,
    pub escape: bool,
    pub cursor_control: bool
}

impl Serial {
    pub fn new(port: u16, irq: u8) -> Serial{
        return Serial {
            port: port,
            irq: irq,
            escape: false,
            cursor_control: false
        };
    }
}

impl SessionDevice for Serial {
    #[allow(unused_variables)]
    fn on_irq(&mut self, session: &Session, updates: &mut SessionUpdates, irq: u8){
        if irq == self.irq {
            unsafe{
                while inb(self.port + 5) & 1 == 0 {}
                let mut c = inb(self.port) as char;
                let mut sc = 0;

                if self.escape {
                    self.escape = false;

                    if c == '['{
                        self.cursor_control = true;
                    }

                    c = '\0';
                }else if self.cursor_control {
                    self.cursor_control = false;

                    if c == 'A'{
                        sc = 0x48;
                    }else if c == 'B'{
                        sc = 0x50;
                    }else if c == 'C'{
                        sc = 0x4D;
                    }else if c == 'D'{
                        sc = 0x4B;
                    }

                    c = '\0';
                }else if c == '\x1B' {
                    self.escape = true;
                    c = '\0';
                }else if c == '\r' {
                    c = '\n';
                    dl();
                }else if c == '\x7F' {
                    c = '\x08';
                }else{
                    dc(c);
                }

                if c != '\0' || sc != 0 {
                    updates.key_events.push(KeyEvent {
                        character: c,
                        scancode: sc,
                        pressed: true
                    });
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Update comment<commit_after><|endoftext|>


<commit_before><commit_msg>Stabilize `std::process::id()`<commit_after><|endoftext|>


<commit_before><commit_msg>Add code for assembly-line<commit_after>pub fn production_rate_per_hour(speed: u8) -> f64 {
    let percentage = match speed {
        1..=4 => 1.0,
        5..=8 => 0.9,
        9..=10 => 0.77,
        _ => 0.0,
    };

    percentage * (221 * speed as u32) as f64
}

pub fn working_items_per_minute(speed: u8) -> u32 {
    (production_rate_per_hour(speed) / 60.0) as u32
}
<|endoftext|>


<commit_before><commit_msg>slice<commit_after><|endoftext|>


<commit_before>//! Shared Vectors

use ptr::addr_of;

export init_op;
export capacity;
export build_sized, build, build_sized_opt;
export map;
export from_fn, from_elem;
export unsafe;

/// Code for dealing with @-vectors. This is pretty incomplete, and
/// contains a bunch of duplication from the code for ~-vectors.

#[abi = "cdecl"]
extern mod rustrt {
    fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
                                 ++v: **vec::raw::VecRepr,
                                 ++n: libc::size_t);
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn move_val_init<T>(&dst: T, -src: T);
}

/// Returns the number of elements the vector can hold without reallocating
#[inline(always)]
pure fn capacity<T>(&&v: @[const T]) -> uint {
    unsafe {
        let repr: **raw::VecRepr =
            ::cast::reinterpret_cast(&addr_of(v));
        (**repr).unboxed.alloc / sys::size_of::<T>()
    }
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 * This version takes an initial size for the vector.
 *
 * # Arguments
 *
 * * size - An initial size of the vector to reserve
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pure fn build_sized<A>(size: uint, builder: fn(push: pure fn(+A))) -> @[A] {
    let mut vec = @[];
    unsafe { raw::reserve(vec, size); }
    builder(|+x| unsafe { raw::push(vec, move x) });
    return vec;
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 *
 * # Arguments
 *
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pure fn build<A>(builder: fn(push: pure fn(+A))) -> @[A] {
    build_sized(4, builder)
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 * This version takes an initial size for the vector.
 *
 * # Arguments
 *
 * * size - An option, maybe containing initial size of the vector to reserve
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pure fn build_sized_opt<A>(size: Option<uint>,
                           builder: fn(push: pure fn(+A))) -> @[A] {
    build_sized(size.get_default(4), builder)
}

// Appending
#[inline(always)]
pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
    do build_sized(lhs.len() + rhs.len()) |push| {
        for vec::each(lhs) |x| { push(*x); }
        for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
    }
}

/// Apply a function to each element of a vector and return the results
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> @[U] {
    do build_sized(v.len()) |push| {
        for vec::each(v) |elem| {
            push(f(*elem));
        }
    }
}

/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value returned by the function `op`.
 */
pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> @[T] {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(op(i)); i += 1u; }
    }
}

/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value `t`.
 */
pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(t); i += 1u; }
    }
}

#[cfg(notest)]
impl<T: Copy> @[T]: Add<&[const T],@[T]> {
    #[inline(always)]
    pure fn add(rhs: &[const T]) -> @[T] {
        append(self, rhs)
    }
}

mod raw {
    type VecRepr = vec::raw::VecRepr;
    type SliceRepr = vec::raw::SliceRepr;

    /**
     * Sets the length of a vector
     *
     * This will explicitly set the size of the vector, without actually
     * modifing its buffers, so it is up to the caller to ensure that
     * the vector is actually the specified size.
     */
    #[inline(always)]
    unsafe fn set_len<T>(&&v: @[const T], new_len: uint) {
        let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
        (**repr).unboxed.fill = new_len * sys::size_of::<T>();
    }

    #[inline(always)]
    unsafe fn push<T>(&v: @[const T], +initval: T) {
        let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
        let fill = (**repr).unboxed.fill;
        if (**repr).unboxed.alloc > fill {
            push_fast(v, move initval);
        }
        else {
            push_slow(v, move initval);
        }
    }
    // This doesn't bother to make sure we have space.
    #[inline(always)] // really pretty please
    unsafe fn push_fast<T>(&v: @[const T], +initval: T) {
        let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
        let fill = (**repr).unboxed.fill;
        (**repr).unboxed.fill += sys::size_of::<T>();
        let p = ptr::addr_of((**repr).unboxed.data);
        let p = ptr::offset(p, fill) as *mut T;
        rusti::move_val_init(*p, move initval);
    }

    unsafe fn push_slow<T>(&v: @[const T], +initval: T) {
        reserve_at_least(v, v.len() + 1u);
        push_fast(v, move initval);
    }

    /**
     * Reserves capacity for exactly `n` elements in the given vector.
     *
     * If the capacity for `v` is already equal to or greater than the
     * requested capacity, then no action is taken.
     *
     * # Arguments
     *
     * * v - A vector
     * * n - The number of elements to reserve space for
     */
    unsafe fn reserve<T>(&v: @[const T], n: uint) {
        // Only make the (slow) call into the runtime if we have to
        if capacity(v) < n {
            let ptr = addr_of(v) as **VecRepr;
            rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
                                              ptr, n as libc::size_t);
        }
    }

    /**
     * Reserves capacity for at least `n` elements in the given vector.
     *
     * This function will over-allocate in order to amortize the
     * allocation costs in scenarios where the caller may need to
     * repeatedly reserve additional space.
     *
     * If the capacity for `v` is already equal to or greater than the
     * requested capacity, then no action is taken.
     *
     * # Arguments
     *
     * * v - A vector
     * * n - The number of elements to reserve space for
     */
    unsafe fn reserve_at_least<T>(&v: @[const T], n: uint) {
        reserve(v, uint::next_power_of_two(n));
    }

}

#[test]
fn test() {
    // Some code that could use that, then:
    fn seq_range(lo: uint, hi: uint) -> @[uint] {
        do build |push| {
            for uint::range(lo, hi) |i| {
                push(i);
            }
        }
    }

    assert seq_range(10, 15) == @[10, 11, 12, 13, 14];
    assert from_fn(5, |x| x+1) == @[1, 2, 3, 4, 5];
    assert from_elem(5, 3.14) == @[3.14, 3.14, 3.14, 3.14, 3.14];
}

#[test]
fn append_test() {
    assert @[1,2,3] + @[4,5,6] == @[1,2,3,4,5,6];
}

<commit_msg>Export the correct raw module from core::at_vec<commit_after>//! Shared Vectors

use ptr::addr_of;

export init_op;
export capacity;
export build_sized, build, build_sized_opt;
export map;
export from_fn, from_elem;
export raw;

/// Code for dealing with @-vectors. This is pretty incomplete, and
/// contains a bunch of duplication from the code for ~-vectors.

#[abi = "cdecl"]
extern mod rustrt {
    fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
                                 ++v: **vec::raw::VecRepr,
                                 ++n: libc::size_t);
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn move_val_init<T>(&dst: T, -src: T);
}

/// Returns the number of elements the vector can hold without reallocating
#[inline(always)]
pure fn capacity<T>(&&v: @[const T]) -> uint {
    unsafe {
        let repr: **raw::VecRepr =
            ::cast::reinterpret_cast(&addr_of(v));
        (**repr).unboxed.alloc / sys::size_of::<T>()
    }
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 * This version takes an initial size for the vector.
 *
 * # Arguments
 *
 * * size - An initial size of the vector to reserve
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pure fn build_sized<A>(size: uint, builder: fn(push: pure fn(+A))) -> @[A] {
    let mut vec = @[];
    unsafe { raw::reserve(vec, size); }
    builder(|+x| unsafe { raw::push(vec, move x) });
    return vec;
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 *
 * # Arguments
 *
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pure fn build<A>(builder: fn(push: pure fn(+A))) -> @[A] {
    build_sized(4, builder)
}

/**
 * Builds a vector by calling a provided function with an argument
 * function that pushes an element to the back of a vector.
 * This version takes an initial size for the vector.
 *
 * # Arguments
 *
 * * size - An option, maybe containing initial size of the vector to reserve
 * * builder - A function that will construct the vector. It recieves
 *             as an argument a function that will push an element
 *             onto the vector being constructed.
 */
#[inline(always)]
pure fn build_sized_opt<A>(size: Option<uint>,
                           builder: fn(push: pure fn(+A))) -> @[A] {
    build_sized(size.get_default(4), builder)
}

// Appending
#[inline(always)]
pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
    do build_sized(lhs.len() + rhs.len()) |push| {
        for vec::each(lhs) |x| { push(*x); }
        for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
    }
}

/// Apply a function to each element of a vector and return the results
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> @[U] {
    do build_sized(v.len()) |push| {
        for vec::each(v) |elem| {
            push(f(*elem));
        }
    }
}

/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value returned by the function `op`.
 */
pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> @[T] {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(op(i)); i += 1u; }
    }
}

/**
 * Creates and initializes an immutable vector.
 *
 * Creates an immutable vector of size `n_elts` and initializes the elements
 * to the value `t`.
 */
pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
    do build_sized(n_elts) |push| {
        let mut i: uint = 0u;
        while i < n_elts { push(t); i += 1u; }
    }
}

#[cfg(notest)]
impl<T: Copy> @[T]: Add<&[const T],@[T]> {
    #[inline(always)]
    pure fn add(rhs: &[const T]) -> @[T] {
        append(self, rhs)
    }
}

mod raw {
    type VecRepr = vec::raw::VecRepr;
    type SliceRepr = vec::raw::SliceRepr;

    /**
     * Sets the length of a vector
     *
     * This will explicitly set the size of the vector, without actually
     * modifing its buffers, so it is up to the caller to ensure that
     * the vector is actually the specified size.
     */
    #[inline(always)]
    unsafe fn set_len<T>(&&v: @[const T], new_len: uint) {
        let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
        (**repr).unboxed.fill = new_len * sys::size_of::<T>();
    }

    #[inline(always)]
    unsafe fn push<T>(&v: @[const T], +initval: T) {
        let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
        let fill = (**repr).unboxed.fill;
        if (**repr).unboxed.alloc > fill {
            push_fast(v, move initval);
        }
        else {
            push_slow(v, move initval);
        }
    }
    // This doesn't bother to make sure we have space.
    #[inline(always)] // really pretty please
    unsafe fn push_fast<T>(&v: @[const T], +initval: T) {
        let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
        let fill = (**repr).unboxed.fill;
        (**repr).unboxed.fill += sys::size_of::<T>();
        let p = ptr::addr_of((**repr).unboxed.data);
        let p = ptr::offset(p, fill) as *mut T;
        rusti::move_val_init(*p, move initval);
    }

    unsafe fn push_slow<T>(&v: @[const T], +initval: T) {
        reserve_at_least(v, v.len() + 1u);
        push_fast(v, move initval);
    }

    /**
     * Reserves capacity for exactly `n` elements in the given vector.
     *
     * If the capacity for `v` is already equal to or greater than the
     * requested capacity, then no action is taken.
     *
     * # Arguments
     *
     * * v - A vector
     * * n - The number of elements to reserve space for
     */
    unsafe fn reserve<T>(&v: @[const T], n: uint) {
        // Only make the (slow) call into the runtime if we have to
        if capacity(v) < n {
            let ptr = addr_of(v) as **VecRepr;
            rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
                                              ptr, n as libc::size_t);
        }
    }

    /**
     * Reserves capacity for at least `n` elements in the given vector.
     *
     * This function will over-allocate in order to amortize the
     * allocation costs in scenarios where the caller may need to
     * repeatedly reserve additional space.
     *
     * If the capacity for `v` is already equal to or greater than the
     * requested capacity, then no action is taken.
     *
     * # Arguments
     *
     * * v - A vector
     * * n - The number of elements to reserve space for
     */
    unsafe fn reserve_at_least<T>(&v: @[const T], n: uint) {
        reserve(v, uint::next_power_of_two(n));
    }

}

#[test]
fn test() {
    // Some code that could use that, then:
    fn seq_range(lo: uint, hi: uint) -> @[uint] {
        do build |push| {
            for uint::range(lo, hi) |i| {
                push(i);
            }
        }
    }

    assert seq_range(10, 15) == @[10, 11, 12, 13, 14];
    assert from_fn(5, |x| x+1) == @[1, 2, 3, 4, 5];
    assert from_elem(5, 3.14) == @[3.14, 3.14, 3.14, 3.14, 3.14];
}

#[test]
fn append_test() {
    assert @[1,2,3] + @[4,5,6] == @[1,2,3,4,5,6];
}

<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Simple compression

*/

#[allow(missing_doc)];

use std::libc::{c_void, size_t, c_int};
use std::libc;
use std::vec;

pub mod rustrt {
    use std::libc::{c_int, c_void, size_t};

    #[link(name = "rustrt")]
    extern {
        pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
                                          src_buf_len: size_t,
                                          pout_len: *mut size_t,
                                          flags: c_int)
                                          -> *c_void;

        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
                                            src_buf_len: size_t,
                                            pout_len: *mut size_t,
                                            flags: c_int)
                                            -> *c_void;
    }
}

static LZ_NONE : c_int = 0x0;   // Huffman-coding only.
static LZ_FAST : c_int = 0x1;   // LZ with only one probe
static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best"
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
    bytes.as_imm_buf(|b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tdefl_compress_mem_to_heap(b as *c_void,
                                                   len as size_t,
                                                   &mut outsz,
                                                   flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                             outsz as uint);
            libc::free(res);
            out
        }
    })
}

pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
    deflate_bytes_internal(bytes, LZ_NORM)
}

pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
    bytes.as_imm_buf(|b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
                                                     len as size_t,
                                                     &mut outsz,
                                                     flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                            outsz as uint);
            libc::free(res);
            out
        }
    })
}

pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_internal(bytes, 0)
}

pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::rand;
    use std::rand::Rng;

    #[test]
    fn test_flate_round_trip() {
        let mut r = rand::rng();
        let mut words = ~[];
        20.times(|| {
            let range = r.gen_range(1u, 10);
            words.push(r.gen_vec::<u8>(range));
        });
        20.times(|| {
            let mut input = ~[];
            2000.times(|| {
                input.push_all(r.choose(words));
            });
            debug!("de/inflate of {} bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(input);
            let out = inflate_bytes(cmp);
            debug!("{} bytes deflated to {} ({:.1f}% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
            assert_eq!(input, out);
        });
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = ~[1, 2, 3, 4, 5];
        let deflated = deflate_bytes(bytes);
        let inflated = inflate_bytes(deflated);
        assert_eq!(inflated, bytes);
    }
}
<commit_msg>auto merge of #10770 : alexcrichton/rust/static-librustrt, r=alexcrichton<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

Simple compression

*/

#[allow(missing_doc)];

use std::libc::{c_void, size_t, c_int};
use std::libc;
use std::vec;

pub mod rustrt {
    use std::libc::{c_int, c_void, size_t};

    #[link(name = "rustrt", kind = "static")]
    extern {
        pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
                                          src_buf_len: size_t,
                                          pout_len: *mut size_t,
                                          flags: c_int)
                                          -> *c_void;

        pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
                                            src_buf_len: size_t,
                                            pout_len: *mut size_t,
                                            flags: c_int)
                                            -> *c_void;
    }
}

static LZ_NONE : c_int = 0x0;   // Huffman-coding only.
static LZ_FAST : c_int = 0x1;   // LZ with only one probe
static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best"
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
    bytes.as_imm_buf(|b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tdefl_compress_mem_to_heap(b as *c_void,
                                                   len as size_t,
                                                   &mut outsz,
                                                   flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                             outsz as uint);
            libc::free(res);
            out
        }
    })
}

pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
    deflate_bytes_internal(bytes, LZ_NORM)
}

pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
    bytes.as_imm_buf(|b, len| {
        unsafe {
            let mut outsz : size_t = 0;
            let res =
                rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
                                                     len as size_t,
                                                     &mut outsz,
                                                     flags);
            assert!(res as int != 0);
            let out = vec::raw::from_buf_raw(res as *u8,
                                            outsz as uint);
            libc::free(res);
            out
        }
    })
}

pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_internal(bytes, 0)
}

pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::rand;
    use std::rand::Rng;

    #[test]
    fn test_flate_round_trip() {
        let mut r = rand::rng();
        let mut words = ~[];
        20.times(|| {
            let range = r.gen_range(1u, 10);
            words.push(r.gen_vec::<u8>(range));
        });
        20.times(|| {
            let mut input = ~[];
            2000.times(|| {
                input.push_all(r.choose(words));
            });
            debug!("de/inflate of {} bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(input);
            let out = inflate_bytes(cmp);
            debug!("{} bytes deflated to {} ({:.1f}% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
            assert_eq!(input, out);
        });
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = ~[1, 2, 3, 4, 5];
        let deflated = deflate_bytes(bytes);
        let inflated = inflate_bytes(deflated);
        assert_eq!(inflated, bytes);
    }
}
<|endoftext|>


<commit_before><commit_msg>added more integer generators<commit_after><|endoftext|>


<commit_before>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;

pub struct PriorityQueue <T: Copy Ord>{
    priv data: ~[T],
}

impl <T: Copy Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> T { self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let last = self.data.pop();
        if self.is_not_empty() {
            let ret = self.data[0];
            self.data[0] = last;
            self.siftup(0);
            ret
        } else { last }
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftdown(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftup(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let ret = self.data[0];
        self.data[0] = item;
        self.siftup(0);
        ret
    }

    priv fn siftdown(&mut self, startpos: uint, pos: uint) {
        let mut pos = pos;
        let newitem = self.data[pos];

        while pos > startpos {
            let parentpos = (pos - 1) >> 1;
            let parent = self.data[parentpos];
            if newitem > parent {
                self.data[pos] = parent;
                pos = parentpos;
                loop
            }
            break
        }
        self.data[pos] = newitem;
    }

    priv fn siftup_range(&mut self, pos: uint, endpos: uint) {
        let mut pos = pos;
        let startpos = pos;
        let newitem = self.data[pos];

        let mut childpos = 2 * pos + 1;
        while childpos < endpos {
            let rightpos = childpos + 1;
            if rightpos < endpos &&
                   !(self.data[childpos] > self.data[rightpos]) {
                childpos = rightpos;
            }
            self.data[pos] = self.data[childpos];
            pos = childpos;
            childpos = 2 * pos + 1;
        }
        self.data[pos] = newitem;
        self.siftdown(startpos, pos);
    }

    priv fn siftup(&mut self, pos: uint) {
        self.siftup_range(pos, self.len());
    }
}

/// Consume the PriorityQueue and return the underlying vector
pub pure fn to_vec<T: Copy Ord>(q: PriorityQueue<T>) -> ~[T] {
    let PriorityQueue{data: v} = q;
    v
}

/// Consume the PriorityQueue and return a vector in sorted (ascending) order
pub pure fn to_sorted_vec<T: Copy Ord>(q: PriorityQueue<T>) -> ~[T] {
    let mut q = q;
    let mut end = q.len() - 1;
    while end > 0 {
        q.data[end] <-> q.data[0];
        end -= 1;
        unsafe { q.siftup_range(0, end) } // purity-checking workaround
    }
    to_vec(q)
}

pub pure fn from_vec<T: Copy Ord>(xs: ~[T]) -> PriorityQueue<T> {
    let mut q = PriorityQueue{data: xs,};
    let mut n = q.len() / 2;
    while n > 0 {
        n -= 1;
        unsafe { q.siftup(n) }; // purity-checking workaround
    }
    q
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert heap.top() == 103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_to_sorted_vec() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        assert to_sorted_vec(from_vec(data)) == merge_sort(data, le);
    }

    #[test]
    #[should_fail]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_top() { from_vec::<int>(~[]).top(); }

    #[test]
    fn test_empty_maybe_top() {
        assert from_vec::<int>(~[]).maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }

    #[test]
    fn test_to_vec() {
        let data = ~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0];
        let heap = from_vec(copy data);
        assert merge_sort(to_vec(heap), le) == merge_sort(data, le);
    }
}
<commit_msg>priority_queue: make to_vec/to_sorted_vec methods<commit_after>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;

pub struct PriorityQueue <T: Copy Ord>{
    priv data: ~[T],
}

impl <T: Copy Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> T { self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let last = self.data.pop();
        if self.is_not_empty() {
            let ret = self.data[0];
            self.data[0] = last;
            self.siftup(0);
            ret
        } else { last }
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftdown(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftup(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let ret = self.data[0];
        self.data[0] = item;
        self.siftup(0);
        ret
    }

    /// Consume the PriorityQueue and return the underlying vector
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len() - 1;
        while end > 0 {
            q.data[end] <-> q.data[0];
            end -= 1;
            unsafe { q.siftup_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    priv fn siftdown(&mut self, startpos: uint, pos: uint) {
        let mut pos = pos;
        let newitem = self.data[pos];

        while pos > startpos {
            let parentpos = (pos - 1) >> 1;
            let parent = self.data[parentpos];
            if newitem > parent {
                self.data[pos] = parent;
                pos = parentpos;
                loop
            }
            break
        }
        self.data[pos] = newitem;
    }

    priv fn siftup_range(&mut self, pos: uint, endpos: uint) {
        let mut pos = pos;
        let startpos = pos;
        let newitem = self.data[pos];

        let mut childpos = 2 * pos + 1;
        while childpos < endpos {
            let rightpos = childpos + 1;
            if rightpos < endpos &&
                   !(self.data[childpos] > self.data[rightpos]) {
                childpos = rightpos;
            }
            self.data[pos] = self.data[childpos];
            pos = childpos;
            childpos = 2 * pos + 1;
        }
        self.data[pos] = newitem;
        self.siftdown(startpos, pos);
    }

    priv fn siftup(&mut self, pos: uint) {
        self.siftup_range(pos, self.len());
    }
}

pub pure fn from_vec<T: Copy Ord>(xs: ~[T]) -> PriorityQueue<T> {
    let mut q = PriorityQueue{data: xs,};
    let mut n = q.len() / 2;
    while n > 0 {
        n -= 1;
        unsafe { q.siftup(n) }; // purity-checking workaround
    }
    q
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert heap.top() == 103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_to_sorted_vec() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        assert from_vec(data).to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    #[should_fail]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_top() { from_vec::<int>(~[]).top(); }

    #[test]
    fn test_empty_maybe_top() {
        assert from_vec::<int>(~[]).maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }

    #[test]
    fn test_to_vec() {
        let data = ~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0];
        let heap = from_vec(copy data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
    }
}
<|endoftext|>


<commit_before><commit_msg>Added tests for FramedParts<commit_after>extern crate tokio_io;
extern crate bytes;
extern crate futures;

use futures::{Stream, Future};
use std::io::{self, Read};
use tokio_io::codec::{Framed, FramedParts, Decoder, Encoder};
use tokio_io::AsyncRead;
use bytes::{BytesMut, Buf, BufMut, IntoBuf, BigEndian};

const INITIAL_CAPACITY: usize = 8 * 1024;

struct U32Codec;

impl Decoder for U32Codec {
    type Item = u32;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<u32>> {
        if buf.len() < 4 {
            return Ok(None);
        }

        let n = buf.split_to(4).into_buf().get_u32::<BigEndian>();
        Ok(Some(n))
    }
}

impl Encoder for U32Codec {
    type Item = u32;
    type Error = io::Error;

    fn encode(&mut self, item: u32, dst: &mut BytesMut) -> io::Result<()> {
        // Reserve space
        dst.reserve(4);
        dst.put_u32::<BigEndian>(item);
        Ok(())
    }
}

struct DontReadIntoThis;

impl Read for DontReadIntoThis {
    fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
        Err(io::Error::new(io::ErrorKind::Other,
                           "Read into something you weren't supposed to."))
    }
}

impl AsyncRead for DontReadIntoThis {}

#[test]
fn can_read_from_existing_buf() {
    let parts = FramedParts {
        inner: DontReadIntoThis,
        readbuf: vec![0, 0, 0, 42].into(),
        writebuf: BytesMut::with_capacity(0),
    };
    let framed = Framed::from_parts(parts, U32Codec);

    let num = framed
        .into_future()
        .map(|(first_num, _)| {
            first_num.unwrap()
        })
        .wait()
        .map_err(|e| e.0)
        .unwrap();
    assert_eq!(num, 42);
}

#[test]
fn external_buf_grows_to_init() {
    let parts = FramedParts {
        inner: DontReadIntoThis,
        readbuf: vec![0, 0, 0, 42].into(),
        writebuf: BytesMut::with_capacity(0),
    };
    let framed = Framed::from_parts(parts, U32Codec);
    let FramedParts { readbuf, .. } = framed.into_parts();

    assert_eq!(readbuf.capacity(), INITIAL_CAPACITY);
}

#[test]
fn external_buf_does_not_shrink() {
    let parts = FramedParts {
        inner: DontReadIntoThis,
        readbuf: vec![0; INITIAL_CAPACITY * 2].into(),
        writebuf: BytesMut::with_capacity(0),
    };
    let framed = Framed::from_parts(parts, U32Codec);
    let FramedParts { readbuf, .. } = framed.into_parts();

    assert_eq!(readbuf.capacity(), INITIAL_CAPACITY * 2);
}

<|endoftext|>


<commit_before><commit_msg>Add tests<commit_after>extern crate rlisp;

use rlisp::parser::parse;
use rlisp::Node;

#[test]
fn test_read_nil() {
    assert_eq!(parse("()").unwrap(), Node::Nil);
}

#[test]
fn test_read_int() {
    assert_eq!(parse("1").unwrap(), Node::Int(1));
    assert_eq!(parse("100").unwrap(), Node::Int(100));
    assert_eq!(parse("1000").unwrap(), Node::Int(1000));
}
<|endoftext|>


<commit_before><commit_msg>added multithreaded pi calc<commit_after>use std::sync::{Arc, Mutex};
use std::thread;

// calculate pi multithreaded
// based on riemann integration

// This code is editable and runnable!
fn main() {
    const NUM_THREADS: u64 = 6;
    const NUM_STEPS: u64 = 100_000;
    const THREAD_STEPS: u64 = NUM_STEPS / NUM_THREADS;
    const STEP: f64 = 1.0 / NUM_STEPS as f64;

    let pi: Arc<Mutex<f64>> = Arc::new(Mutex::new(0.0f64));

    let guards: Vec<_> = (0..NUM_THREADS).map(|i| {
        let lower: u64 = THREAD_STEPS *i;
        let upper: u64 = THREAD_STEPS * (i+1);
        let pi_ref = pi.clone();

        thread::spawn(move || {
            for j in lower..upper {
                let x: f64 = (j as f64 + 0.5) * STEP;
                let mut lock = pi_ref.lock().unwrap();
                *lock += 4.0/(1.0 + x*x) * STEP;
            }
        })
    }).collect();

    for g in guards { g.join().unwrap(); }

    println!("Pi = {:.10}", *pi.lock().unwrap());
}<|endoftext|>