<commit_before>//! A flash simulator
//!
//! This module is capable of simulating the type of NOR flash commonly used in microcontrollers.
//! These generally can be written as individual bytes, but must be erased in larger units.

use std::iter::Enumerate;
use std::slice;
use pdump::HexDump;

error_chain! {
    errors {
        OutOfBounds(t: String) {
            description("Offset is out of bounds")
            display("Offset out of bounds: {}", t)
        }
        Write(t: String) {
            description("Invalid write")
            display("Invalid write: {}", t)
        }
    }
}

fn ebounds<T: AsRef<str>>(message: T) -> ErrorKind {
    ErrorKind::OutOfBounds(message.as_ref().to_owned())
}

fn ewrite<T: AsRef<str>>(message: T) -> ErrorKind {
    ErrorKind::Write(message.as_ref().to_owned())
}

/// An emulated flash device.  It is represented as a block of bytes, and a list of the sector
/// mapings.
#[derive(Clone)]
pub struct Flash {
    data: Vec<u8>,
    sectors: Vec<usize>,
    // Alignment required for writes.
    align: usize,
}

impl Flash {
    /// Given a sector size map, construct a flash device for that.
    pub fn new(sectors: Vec<usize>, align: usize) -> Flash {
        // Verify that the alignment is a positive power of two.
        assert!(align > 0);
        assert!(align & (align - 1) == 0);

        let total = sectors.iter().sum();
        Flash {
            data: vec![0xffu8; total],
            sectors: sectors,
            align: align,
        }
    }

    /// The flash drivers tend to erase beyond the bounds of the given range.  Instead, we'll be
    /// strict, and make sure that the passed arguments are exactly at a sector boundary, otherwise
    /// return an error.
    pub fn erase(&mut self, offset: usize, len: usize) -> Result<()> {
        let (_start, slen) = self.get_sector(offset).ok_or_else(|| ebounds("start"))?;
        let (end, elen) = self.get_sector(offset + len - 1).ok_or_else(|| ebounds("end"))?;

        if slen != 0 {
            bail!(ebounds("offset not at start of sector"));
        }
        if elen != self.sectors[end] - 1 {
            bail!(ebounds("end not at start of sector"));
        }

        for x in &mut self.data[offset .. offset + len] {
            *x = 0xff;
        }

        Ok(())
    }

    /// Writes are fairly unconstrained, but we restrict to only allowing writes of values that
    /// are entirely written as 0xFF.
    pub fn write(&mut self, offset: usize, payload: &[u8]) -> Result<()> {
        if offset + payload.len() > self.data.len() {
            bail!(ebounds("Write outside of device"));
        }

        // Verify the alignment (which must be a power of two).
        if offset & (self.align - 1) != 0 {
            bail!(ewrite("Misaligned write address"));
        }

        if payload.len() & (self.align - 1) != 0 {
            bail!(ewrite("Write length not multiple of alignment"));
        }

        let mut sub = &mut self.data[offset .. offset + payload.len()];
        if sub.iter().any(|x| *x != 0xFF) {
            bail!(ewrite("Write to non-FF location"));
        }

        sub.copy_from_slice(payload);
        Ok(())
    }

    /// Read is simple.
    pub fn read(&self, offset: usize, data: &mut [u8]) -> Result<()> {
        if offset + data.len() > self.data.len() {
            bail!(ebounds("Read outside of device"));
        }

        let sub = &self.data[offset .. offset + data.len()];
        data.copy_from_slice(sub);
        Ok(())
    }

    // Scan the sector map, and return the base and offset within a sector for this given byte.
    // Returns None if the value is outside of the device.
    fn get_sector(&self, offset: usize) -> Option<(usize, usize)> {
        let mut offset = offset;
        for (sector, &size) in self.sectors.iter().enumerate() {
            if offset < size {
                return Some((sector, offset));
            }
            offset -= size;
        }
        return None;
    }

    /// An iterator over each sector in the device.
    pub fn sector_iter(&self) -> SectorIter {
        SectorIter {
            iter: self.sectors.iter().enumerate(),
            base: 0,
        }
    }

    pub fn device_size(&self) -> usize {
        self.data.len()
    }

    pub fn dump(&self) {
        self.data.dump();
    }
}

/// It is possible to iterate over the sectors in the device, each element returning this.
#[derive(Debug)]
pub struct Sector {
    /// Which sector is this, starting from 0.
    pub num: usize,
    /// The offset, in bytes, of the start of this sector.
    pub base: usize,
    /// The length, in bytes, of this sector.
    pub size: usize,
}

pub struct SectorIter<'a> {
    iter: Enumerate<slice::Iter<'a, usize>>,
    base: usize,
}

impl<'a> Iterator for SectorIter<'a> {
    type Item = Sector;

    fn next(&mut self) -> Option<Sector> {
        match self.iter.next() {
            None => None,
            Some((num, &size)) => {
                let base = self.base;
                self.base += size;
                Some(Sector {
                    num: num,
                    base: base,
                    size: size,
                })
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::{Flash, Error, ErrorKind, Result, Sector};

    #[test]
    fn test_flash() {
        // NXP-style, uniform sectors.
        let mut f1 = Flash::new(vec![4096usize; 256]);
        test_device(&mut f1);

        // STM style, non-uniform sectors
        let mut f2 = Flash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 64 * 1024,
                                128 * 1024, 128 * 1024, 128 * 1024]);
        test_device(&mut f2);
    }

    fn test_device(flash: &mut Flash) {
        let sectors: Vec<Sector> = flash.sector_iter().collect();

        flash.erase(0, sectors[0].size).unwrap();
        let flash_size = flash.device_size();
        flash.erase(0, flash_size).unwrap();
        assert!(flash.erase(0, sectors[0].size - 1).is_bounds());

        // Verify that write and erase do something.
        flash.write(0, &[0]).unwrap();
        let mut buf = [0; 4];
        flash.read(0, &mut buf).unwrap();
        assert_eq!(buf, [0, 0xff, 0xff, 0xff]);

        flash.erase(0, sectors[0].size).unwrap();
        flash.read(0, &mut buf).unwrap();
        assert_eq!(buf, [0xff; 4]);

        // Program the first and last byte of each sector, verify that has been done, and then
        // erase to verify the erase boundaries.
        for sector in &sectors {
            let byte = [(sector.num & 127) as u8];
            flash.write(sector.base, &byte).unwrap();
            flash.write(sector.base + sector.size - 1, &byte).unwrap();
        }

        // Verify the above
        let mut buf = Vec::new();
        for sector in &sectors {
            let byte = (sector.num & 127) as u8;
            buf.resize(sector.size, 0);
            flash.read(sector.base, &mut buf).unwrap();
            assert_eq!(buf.first(), Some(&byte));
            assert_eq!(buf.last(), Some(&byte));
            assert!(buf[1..buf.len()-1].iter().all(|&x| x == 0xff));
        }
    }

    // Helper checks for the result type.
    trait EChecker {
        fn is_bounds(&self) -> bool;
    }

    impl<T> EChecker for Result<T> {

        fn is_bounds(&self) -> bool {
            match *self {
                Err(Error(ErrorKind::OutOfBounds(_), _)) => true,
                _ => false,
            }
        }
    }
}
<commit_msg>sim: Make misaligned writes panic<commit_after>//! A flash simulator
//!
//! This module is capable of simulating the type of NOR flash commonly used in microcontrollers.
//! These generally can be written as individual bytes, but must be erased in larger units.

use std::iter::Enumerate;
use std::slice;
use pdump::HexDump;

error_chain! {
    errors {
        OutOfBounds(t: String) {
            description("Offset is out of bounds")
            display("Offset out of bounds: {}", t)
        }
        Write(t: String) {
            description("Invalid write")
            display("Invalid write: {}", t)
        }
    }
}

fn ebounds<T: AsRef<str>>(message: T) -> ErrorKind {
    ErrorKind::OutOfBounds(message.as_ref().to_owned())
}

fn ewrite<T: AsRef<str>>(message: T) -> ErrorKind {
    ErrorKind::Write(message.as_ref().to_owned())
}

/// An emulated flash device.  It is represented as a block of bytes, and a list of the sector
/// mapings.
#[derive(Clone)]
pub struct Flash {
    data: Vec<u8>,
    sectors: Vec<usize>,
    // Alignment required for writes.
    align: usize,
}

impl Flash {
    /// Given a sector size map, construct a flash device for that.
    pub fn new(sectors: Vec<usize>, align: usize) -> Flash {
        // Verify that the alignment is a positive power of two.
        assert!(align > 0);
        assert!(align & (align - 1) == 0);

        let total = sectors.iter().sum();
        Flash {
            data: vec![0xffu8; total],
            sectors: sectors,
            align: align,
        }
    }

    /// The flash drivers tend to erase beyond the bounds of the given range.  Instead, we'll be
    /// strict, and make sure that the passed arguments are exactly at a sector boundary, otherwise
    /// return an error.
    pub fn erase(&mut self, offset: usize, len: usize) -> Result<()> {
        let (_start, slen) = self.get_sector(offset).ok_or_else(|| ebounds("start"))?;
        let (end, elen) = self.get_sector(offset + len - 1).ok_or_else(|| ebounds("end"))?;

        if slen != 0 {
            bail!(ebounds("offset not at start of sector"));
        }
        if elen != self.sectors[end] - 1 {
            bail!(ebounds("end not at start of sector"));
        }

        for x in &mut self.data[offset .. offset + len] {
            *x = 0xff;
        }

        Ok(())
    }

    /// Writes are fairly unconstrained, but we restrict to only allowing writes of values that
    /// are entirely written as 0xFF.
    pub fn write(&mut self, offset: usize, payload: &[u8]) -> Result<()> {
        if offset + payload.len() > self.data.len() {
            panic!("Write outside of device");
        }

        // Verify the alignment (which must be a power of two).
        if offset & (self.align - 1) != 0 {
            panic!("Misaligned write address");
        }

        if payload.len() & (self.align - 1) != 0 {
            panic!("Write length not multiple of alignment");
        }

        let mut sub = &mut self.data[offset .. offset + payload.len()];
        if sub.iter().any(|x| *x != 0xFF) {
            bail!(ewrite("Write to non-FF location"));
        }

        sub.copy_from_slice(payload);
        Ok(())
    }

    /// Read is simple.
    pub fn read(&self, offset: usize, data: &mut [u8]) -> Result<()> {
        if offset + data.len() > self.data.len() {
            bail!(ebounds("Read outside of device"));
        }

        let sub = &self.data[offset .. offset + data.len()];
        data.copy_from_slice(sub);
        Ok(())
    }

    // Scan the sector map, and return the base and offset within a sector for this given byte.
    // Returns None if the value is outside of the device.
    fn get_sector(&self, offset: usize) -> Option<(usize, usize)> {
        let mut offset = offset;
        for (sector, &size) in self.sectors.iter().enumerate() {
            if offset < size {
                return Some((sector, offset));
            }
            offset -= size;
        }
        return None;
    }

    /// An iterator over each sector in the device.
    pub fn sector_iter(&self) -> SectorIter {
        SectorIter {
            iter: self.sectors.iter().enumerate(),
            base: 0,
        }
    }

    pub fn device_size(&self) -> usize {
        self.data.len()
    }

    pub fn dump(&self) {
        self.data.dump();
    }
}

/// It is possible to iterate over the sectors in the device, each element returning this.
#[derive(Debug)]
pub struct Sector {
    /// Which sector is this, starting from 0.
    pub num: usize,
    /// The offset, in bytes, of the start of this sector.
    pub base: usize,
    /// The length, in bytes, of this sector.
    pub size: usize,
}

pub struct SectorIter<'a> {
    iter: Enumerate<slice::Iter<'a, usize>>,
    base: usize,
}

impl<'a> Iterator for SectorIter<'a> {
    type Item = Sector;

    fn next(&mut self) -> Option<Sector> {
        match self.iter.next() {
            None => None,
            Some((num, &size)) => {
                let base = self.base;
                self.base += size;
                Some(Sector {
                    num: num,
                    base: base,
                    size: size,
                })
            }
        }
    }
}

#[cfg(test)]
mod test {
    use super::{Flash, Error, ErrorKind, Result, Sector};

    #[test]
    fn test_flash() {
        // NXP-style, uniform sectors.
        let mut f1 = Flash::new(vec![4096usize; 256]);
        test_device(&mut f1);

        // STM style, non-uniform sectors
        let mut f2 = Flash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 64 * 1024,
                                128 * 1024, 128 * 1024, 128 * 1024]);
        test_device(&mut f2);
    }

    fn test_device(flash: &mut Flash) {
        let sectors: Vec<Sector> = flash.sector_iter().collect();

        flash.erase(0, sectors[0].size).unwrap();
        let flash_size = flash.device_size();
        flash.erase(0, flash_size).unwrap();
        assert!(flash.erase(0, sectors[0].size - 1).is_bounds());

        // Verify that write and erase do something.
        flash.write(0, &[0]).unwrap();
        let mut buf = [0; 4];
        flash.read(0, &mut buf).unwrap();
        assert_eq!(buf, [0, 0xff, 0xff, 0xff]);

        flash.erase(0, sectors[0].size).unwrap();
        flash.read(0, &mut buf).unwrap();
        assert_eq!(buf, [0xff; 4]);

        // Program the first and last byte of each sector, verify that has been done, and then
        // erase to verify the erase boundaries.
        for sector in &sectors {
            let byte = [(sector.num & 127) as u8];
            flash.write(sector.base, &byte).unwrap();
            flash.write(sector.base + sector.size - 1, &byte).unwrap();
        }

        // Verify the above
        let mut buf = Vec::new();
        for sector in &sectors {
            let byte = (sector.num & 127) as u8;
            buf.resize(sector.size, 0);
            flash.read(sector.base, &mut buf).unwrap();
            assert_eq!(buf.first(), Some(&byte));
            assert_eq!(buf.last(), Some(&byte));
            assert!(buf[1..buf.len()-1].iter().all(|&x| x == 0xff));
        }
    }

    // Helper checks for the result type.
    trait EChecker {
        fn is_bounds(&self) -> bool;
    }

    impl<T> EChecker for Result<T> {

        fn is_bounds(&self) -> bool {
            match *self {
                Err(Error(ErrorKind::OutOfBounds(_), _)) => true,
                _ => false,
            }
        }
    }
}
<|endoftext|>


<commit_before>pub fn score(word: &str) -> u32 {
    let mut score = 0;

    for c in word.chars() {
        score += match c.to_lowercase().to_string().as_ref() {
            "a" | "e" | "i" | "o" | "u" | "l" | "n" | "r" | "s" | "t" => 1,
            "d" | "g" => 2,
            "b" | "c" | "m" | "p" => 3,
            "f" | "h" | "v" | "w" | "y" => 4,
            "k" => 5,
            "j" | "x" => 8,
            "q" | "z" => 10,
            _ => 0
        }
    }

    score
}
<commit_msg>Improve solution for Scrabble Score<commit_after>pub fn score(word: &str) -> u32 {
    word.to_lowercase().chars().map(|c| {
        match c {
            'a' | 'e' | 'i' | 'o' | 'u' | 'l' | 'n' | 'r' | 's' | 't' => 1,
            'd' | 'g' => 2,
            'b' | 'c' | 'm' | 'p' => 3,
            'f' | 'h' | 'v' | 'w' | 'y' => 4,
            'k' => 5,
            'j' | 'x' => 8,
            'q' | 'z' => 10,
            _ => 0
        }
    }).sum()
}
<|endoftext|>


<commit_before><commit_msg>Avoid bound-checking on cholesky decomposition.<commit_after><|endoftext|>


<commit_before>#[link(name = "timer",
       vers = "0.1",
       author = "Damien Schoof")];
#[crate_type = "lib"];

extern mod std;

static SEC_MULTIPLIER:u64 = 1000 * 1000 * 1000;
static MIN_MULTIPLIER:u64 = 60 * SEC_MULTIPLIER;
static HR_MULTIPLIER:u64 = 60 * MIN_MULTIPLIER;

pub struct Timer {
    mut start_time: u64,
    mut end_time: u64
}

pub impl Timer {
    pub fn new() -> Timer {
        Timer { start_time: 0, end_time: 0}
    }
    pub fn start(&mut self) -> () {
        self.start_time = std::time::precise_time_ns();
    }
    pub fn end(&mut self) -> () {
        self.end_time = std::time::precise_time_ns();
    }
    fn get_time_string(&mut self) -> ~str {
        return format_as_time(self.get_total_time());
    }
    fn get_total_time(&mut self) -> u64 {
        return self.end_time - self.start_time;
    }
    pub fn show_time(&mut self) -> () {
        core::io::println(fmt!("Total time: %s", self.get_time_string()));
    }
}

pub fn format_as_time(total_time: u64) -> ~str {
    let hours = total_time / HR_MULTIPLIER;
    let minutes = (total_time
                   - hours * HR_MULTIPLIER)
        / MIN_MULTIPLIER;
    let seconds = (total_time
                   - hours * HR_MULTIPLIER
                   - minutes * MIN_MULTIPLIER)
        / SEC_MULTIPLIER;
    let nanoseconds = (total_time
                       - hours * HR_MULTIPLIER
                       - minutes * MIN_MULTIPLIER
                       - seconds * SEC_MULTIPLIER);

    let mut time_string = ~"";
    if hours > 0 {
        time_string += fmt!("%?:", hours);
    }
    if hours > 0 || minutes > 0 {
        if minutes < 10 && hours > 0 {
            time_string += "0";
        }
        time_string += fmt!("%?:", minutes);
    }
    if hours > 0 || minutes > 0 || seconds > 0 {
        if seconds < 10 && (minutes > 0 || hours > 0) {
            // HACK: fmt!("%02?.", seconds) doesn't zero pad
            time_string += "0";
        }
        time_string += fmt!("%?.", seconds);
        // nanoseconds don't need to be quite as accurate if we measure seconds
        time_string += fmt!("%.3?", nanoseconds);
    } else {
        time_string += fmt!("%s", format_number(nanoseconds));
    }

    if hours > 0 {
        time_string += " hr";
    } else if minutes > 0 {
        time_string += " min";
    } else if seconds > 0 {
        time_string += " sec";
    } else {
        time_string += " ns";
    }

    //time_string += fmt!(" (%?)", total_time);

    return time_string;
}

fn format_number(num: u64) -> ~str {
    let repr = num.to_str();
    let mut ret_val = ~"";
    let mut index = 0;
    let length = str::len(repr);

    while index < length {
        ret_val += str::slice(repr, index, index + 1);

        if (length - index - 1) % 3 == 0 && length > index + 1{
            ret_val += ",";
        }
        index += 1;
    }

    return ret_val
}

#[test]
fn format_number_test() {
    let num1 = 123456789;
    let num2 = 12345678;
    let num3 = 1234;

    assert!(format_number(num1) == ~"123,456,789");
    assert!(format_number(num2) == ~"12,345,678");
    assert!(format_number(num3) == ~"1,234");
}

#[test]
fn format_as_time_test() {
    let num1 = 2000;    // ns
    let num2 = 3 * SEC_MULTIPLIER + 141591234;
    let num3 = 1 * MIN_MULTIPLIER + 5 * SEC_MULTIPLIER + 98765432;
    let num4 = 3 * HR_MULTIPLIER + num3;

    assert!(format_as_time(num1) == ~"2,000 ns");
    assert!(format_as_time(num2) == ~"3.142 sec");
    assert!(format_as_time(num3) == ~"1:05.099 min");
    assert!(format_as_time(num4) == ~"3:01:05.099 hr");
}
<commit_msg>Fix failing timer.rs tests<commit_after>#[link(name = "timer",
       vers = "0.1",
       author = "Damien Schoof")];
#[crate_type = "lib"];

extern mod std;

static SEC_MULTIPLIER:u64 = 1000 * 1000 * 1000;
static MIN_MULTIPLIER:u64 = 60 * SEC_MULTIPLIER;
static HR_MULTIPLIER:u64 = 60 * MIN_MULTIPLIER;

pub struct Timer {
    mut start_time: u64,
    mut end_time: u64
}

pub impl Timer {
    pub fn new() -> Timer {
        Timer { start_time: 0, end_time: 0}
    }
    pub fn start(&mut self) -> () {
        self.start_time = std::time::precise_time_ns();
    }
    pub fn end(&mut self) -> () {
        self.end_time = std::time::precise_time_ns();
    }
    fn get_time_string(&mut self) -> ~str {
        return format_as_time(self.get_total_time());
    }
    fn get_total_time(&mut self) -> u64 {
        return self.end_time - self.start_time;
    }
    pub fn show_time(&mut self) -> () {
        core::io::println(fmt!("Total time: %s", self.get_time_string()));
    }
}

pub fn format_as_time(total_time: u64) -> ~str {
    let hours = total_time / HR_MULTIPLIER;
    let minutes = (total_time
                   - hours * HR_MULTIPLIER)
        / MIN_MULTIPLIER;
    let seconds = (total_time
                   - hours * HR_MULTIPLIER
                   - minutes * MIN_MULTIPLIER)
        / SEC_MULTIPLIER;
    let nanoseconds = (total_time
                       - hours * HR_MULTIPLIER
                       - minutes * MIN_MULTIPLIER
                       - seconds * SEC_MULTIPLIER);

    let mut time_string = ~"";
    if hours > 0 {
        time_string += fmt!("%?:", hours);
    }
    if hours > 0 || minutes > 0 {
        if minutes < 10 && hours > 0 {
            time_string += "0";
        }
        time_string += fmt!("%?:", minutes);
    }
    if hours > 0 || minutes > 0 || seconds > 0 {
        if seconds < 10 && (minutes > 0 || hours > 0) {
            // HACK: fmt!("%02?.", seconds) doesn't zero pad
            time_string += "0";
        }
        time_string += fmt!("%?.", seconds);
        // nanoseconds don't need to be quite as accurate if we measure seconds
        let ns_as_string = fmt!("%.5?", (nanoseconds as f64) / (SEC_MULTIPLIER as f64));
        time_string += fmt!("%s", str::slice(ns_as_string, 2, 5));
    } else {
        time_string += fmt!("%s", format_number(nanoseconds));
    }

    if hours > 0 {
        time_string += " hr";
    } else if minutes > 0 {
        time_string += " min";
    } else if seconds > 0 {
        time_string += " sec";
    } else {
        time_string += " ns";
    }

    //time_string += fmt!(" (%?)", total_time);

    return time_string;
}

fn format_number(num: u64) -> ~str {
    let repr = num.to_str();
    let mut ret_val = ~"";
    let mut index = 0;
    let length = str::len(repr);

    while index < length {
        ret_val += str::slice(repr, index, index + 1);

        if (length - index - 1) % 3 == 0 && length > index + 1{
            ret_val += ",";
        }
        index += 1;
    }

    return ret_val
}

#[test]
fn format_number_test() {
    let num1 = 123456789;
    let num2 = 12345678;
    let num3 = 1234;

    assert!(format_number(num1) == ~"123,456,789");
    assert!(format_number(num2) == ~"12,345,678");
    assert!(format_number(num3) == ~"1,234");
}

#[test]
fn format_as_time_test() {
    let num1 = 2000;    // ns
    let num2 = 3 * SEC_MULTIPLIER + 141591234;
    let num3 = 1 * MIN_MULTIPLIER + 5 * SEC_MULTIPLIER + 98765432;
    let num4 = 3 * HR_MULTIPLIER + num3;

    assert!(format_as_time(num1) == ~"2,000 ns");
    assert!(format_as_time(num2) == ~"3.141 sec");
    assert!(format_as_time(num3) == ~"1:05.098 min");
    assert!(format_as_time(num4) == ~"3:01:05.098 hr");
}
<|endoftext|>


<commit_before>
//! Experimental: custom audio stuff

// NB (Morten, 04.10.17)
// Regarding terminology
// A "sample" is a single i16 (Or whatever `SampleData` is): i16
// A "frame" is one i16 per channel:  (left, right): (i16, i16)

// TODO fix error handling, custom error types!

// TODO Change sample rate back to 44100, implement resampling for sound buffers
// We don't neccesarily have to output at 44.1kHz in the end, but this would be
// an easy way to implement and test resampling

use std::thread;
use std::sync::mpsc;

use window::Window;
use time::{Time, Timer};

// Different platforms
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use self::windows::*;

pub mod wav;

const OUTPUT_CHANNELS: u32 = 2;
const OUTPUT_SAMPLE_RATE: u32 = 48000;
const OUTPUT_BUFFER_SIZE_IN_FRAMES: usize = 2*(OUTPUT_SAMPLE_RATE as usize);
type SampleData = i16;

type BufferHandle = usize;

pub struct AudioSystem {
    next_buffer_handle: BufferHandle,
    broken:   bool,
    receiver: mpsc::Receiver<MessageFromAudioThread>,
    sender:   mpsc::Sender<MessageToAudioThread>,
}

enum MessageToAudioThread {
    NewEvent { event: Event },
    AddBuffer { buffer: AudioBuffer },
}

enum MessageFromAudioThread {
    CriticalError,
}

impl AudioSystem {
    pub fn initialize(window: &Window) -> AudioSystem {
        // TODO Remove the stupid hack!
        #[cfg(target_os = "windows")]
        let window_handle = window.window_handle() as usize; // Stupid hack

        let (thread_sender, receiver) = mpsc::channel();
        let (sender, thread_receiver) = mpsc::channel();

        thread::spawn(move || {
            // Initialize backend
            #[cfg(target_os = "windows")]
            let backend = AudioBackend::initialize(window_handle);
            #[cfg(not(target_os = "windows"))]
            let backend = AudioBackend::initialize();

            let mut backend = match backend {
                Ok(b) => b,
                Err(()) => {
                    let _ = thread_sender.send(MessageFromAudioThread::CriticalError);
                    return;
                },
            };

            let mut frame_counter = 0;
            let mut timer = Timer::new();

            let mut buffers = Vec::with_capacity(100);
            let mut events  = Vec::with_capacity(100);

            let mut last_write = Time::ZERO;

            loop {
                // Actually update audio output
                let write_result = backend.write(&mut frame_counter, &buffers, &mut events);
                match write_result {
                    Ok(wrote) => {
                        if wrote {
                            last_write = timer.tick().0;
                        }
                    },
                    Err(()) => {
                        // TODO proper error handling, should we stop the loop?
                        println!("backend.write failed!");
                    },
                }

                // Remove events when they are done playing
                let mut i = 0;
                while i < events.len() {
                    if events[i].done {
                        events.swap_remove(i);
                    } else {
                        i += 1;
                    }
                }

                // Add new buffers/events
                for message in thread_receiver.try_recv() {
                    use self::MessageToAudioThread::*;
                    match message {
                        NewEvent { event } => {
                            events.push(event);
                        },
                        AddBuffer { buffer } => {
                            buffers.push(buffer);
                        },
                    }
                }

                // Sleep for a bit, so this loop does not run constantly
                let write_interval = backend.estimated_write_interval();
                let before_sleep = timer.tick().0;
                let next_write = last_write + write_interval;
                let sleep_margin = Time::from_ms(1);

                if next_write > before_sleep {
                    // TODO this should also trigger a hard error!
                    // NB (Morten, 07.10.17)
                    // In the case of this, and the next todo we probably want to stop playing
                    // audio for a couple of seconds, and then try again. Maybe there was just a
                    // temporary issue which prevented us from playing audio at a reasonable rate.
                    // If we have a couple of consecutive fails, we can just back out entirely of
                    // playing audio.
                    // We should probably find some completly fucked sound-card to test error cases
                    // first though
                    println!("We took more time than allocated to write audio");
                } else {
                    let sleep_time = next_write - before_sleep;

                    if sleep_time > sleep_margin {
                        thread::sleep((sleep_time - sleep_margin).into());
                        let after_sleep = timer.tick().0;

                        if next_write > after_sleep {
                            // TODO properly handle this case
                            println!(
                                "thread::sleep took to long! Should sleep to {} s, but slept until {} s",
                                next_write.as_secs_float(), after_sleep.as_secs_float(),
                            );
                        }
                    }
                }
            }
        });

        AudioSystem {
            broken: false,
            next_buffer_handle: 0,
            sender,
            receiver,
        }
    }

    pub fn tick(&mut self) {
        use self::MessageFromAudioThread::*;
        for message in self.receiver.try_recv() {
            match message {
                CriticalError => {
                    self.broken = true;
                },
            }
        }
    }

    pub fn play(&mut self, buffer: BufferHandle) {
        if self.broken {
            return;
        }

        let event = Event {
            start_frame: 0,
            done: false,
            buffer,
        };

        let message = MessageToAudioThread::NewEvent { event };
        let broken = self.sender.send(message).is_err();
        if broken {
            self.broken = true;
        }
    }

    pub fn add_buffer(&mut self, buffer: AudioBuffer) -> BufferHandle {
        if self.broken {
            return 0;
        }

        let message = MessageToAudioThread::AddBuffer { buffer };
        let broken = self.sender.send(message).is_err();
        if broken {
            self.broken = true;
        }

        let handle = self.next_buffer_handle;
        self.next_buffer_handle += 1;
        return handle;
    }
}

#[derive(Clone)]
pub struct AudioBuffer {
    pub channels: u32,
    pub sample_rate: u32,
    pub data: Vec<SampleData>,
}

impl AudioBuffer {
    pub fn duration(&self) -> Time {
        let frames = self.frames();
        let frequency = self.sample_rate as u64;

        Time((frames*Time::NANOSECONDS_PER_SECOND) / frequency)
    }

    #[inline(always)]
    pub fn frames(&self) -> u64 {
        self.data.len() as u64 / self.channels as u64
    }
}

pub struct Event {
    pub start_frame: u64, // Set internally when the event is actually started
    pub done: bool,
    pub buffer: BufferHandle,
}
<commit_msg>Fixed multithreading time allocation<commit_after>
//! Experimental: custom audio stuff

// NB (Morten, 04.10.17)
// Regarding terminology
// A "sample" is a single i16 (Or whatever `SampleData` is): i16
// A "frame" is one i16 per channel:  (left, right): (i16, i16)

// TODO fix error handling, custom error types!

// TODO Change sample rate back to 44100, implement resampling for sound buffers
// We don't neccesarily have to output at 44.1kHz in the end, but this would be
// an easy way to implement and test resampling

use std::thread;
use std::sync::mpsc;

use window::Window;
use time::{Time, Timer};

// Different platforms
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use self::windows::*;

pub mod wav;

const OUTPUT_CHANNELS: u32 = 2;
const OUTPUT_SAMPLE_RATE: u32 = 48000;
const OUTPUT_BUFFER_SIZE_IN_FRAMES: usize = 2*(OUTPUT_SAMPLE_RATE as usize);
type SampleData = i16;

type BufferHandle = usize;

pub struct AudioSystem {
    next_buffer_handle: BufferHandle,
    broken:   bool,
    receiver: mpsc::Receiver<MessageFromAudioThread>,
    sender:   mpsc::Sender<MessageToAudioThread>,
}

enum MessageToAudioThread {
    NewEvent { event: Event },
    AddBuffer { buffer: AudioBuffer },
}

enum MessageFromAudioThread {
    CriticalError,
}

impl AudioSystem {
    pub fn initialize(window: &Window) -> AudioSystem {
        // TODO Remove the stupid hack!
        #[cfg(target_os = "windows")]
        let window_handle = window.window_handle() as usize; // Stupid hack

        let (thread_sender, receiver) = mpsc::channel();
        let (sender, thread_receiver) = mpsc::channel();

        thread::spawn(move || {
            // Initialize backend
            #[cfg(target_os = "windows")]
            let backend = AudioBackend::initialize(window_handle);
            #[cfg(not(target_os = "windows"))]
            let backend = AudioBackend::initialize();

            let mut backend = match backend {
                Ok(b) => b,
                Err(()) => {
                    let _ = thread_sender.send(MessageFromAudioThread::CriticalError);
                    return;
                },
            };

            let mut frame_counter = 0;
            let mut timer = Timer::new();

            let mut buffers = Vec::with_capacity(100);
            let mut events  = Vec::with_capacity(100);

            let mut last_write = Time::ZERO;
            let mut average_write_time = Time::ZERO;
            let mut total_write_time = Time::ZERO;
            let mut write_count = 0;

            loop {
                let mut did_write = false;

                let start = timer.tick().0;

                // Actually update audio output
                let write_result = backend.write(&mut frame_counter, &buffers, &mut events);
                match write_result {
                    Ok(wrote) => {
                        if wrote {
                            did_write = true;
                            last_write = timer.tick().0;
                        }
                    },
                    Err(()) => {
                        // TODO proper error handling, should we stop the loop?
                        println!("backend.write failed!");
                    },
                }

                // Remove events when they are done playing
                let mut i = 0;
                while i < events.len() {
                    if events[i].done {
                        events.swap_remove(i);
                    } else {
                        i += 1;
                    }
                }

                // Add new buffers/events
                for message in thread_receiver.try_recv() {
                    use self::MessageToAudioThread::*;
                    match message {
                        NewEvent { event } => {
                            events.push(event);
                        },
                        AddBuffer { buffer } => {
                            buffers.push(buffer);
                        },
                    }
                }

                let end = timer.tick().0;
                if did_write {
                    total_write_time += end - start;
                    write_count += 1;
                    average_write_time = Time(total_write_time.0 / write_count);
                }

                // Sleep for a bit, so this loop does not run constantly
                let write_interval = backend.estimated_write_interval();
                let before_sleep = timer.tick().0;
                let next_write = last_write + write_interval;
                let sleep_margin = Time::from_ms(2);

                if average_write_time > write_interval {
                    // TODO This means the computer we are running on is to slow to mix audio!
                    println!("Average write time is {} ns, but write interval is {} ns", average_write_time.0, write_interval.0);
                    return;
                }

                if next_write > before_sleep + sleep_margin {
                    let sleep_time = next_write - (before_sleep + sleep_margin);
                    thread::sleep(sleep_time.into());
                    let after_sleep = timer.tick().0;

                    if next_write + (write_interval - average_write_time) < after_sleep {
                        // TODO properly handle this case
                        println!(
                            "thread::sleep took to long! Should sleep to {} s, but slept until {} s",
                            next_write.as_secs_float(), after_sleep.as_secs_float(),
                        );
                    }
                }
            }
        });

        AudioSystem {
            broken: false,
            next_buffer_handle: 0,
            sender,
            receiver,
        }
    }

    pub fn tick(&mut self) {
        use self::MessageFromAudioThread::*;
        for message in self.receiver.try_recv() {
            match message {
                CriticalError => {
                    self.broken = true;
                },
            }
        }
    }

    pub fn play(&mut self, buffer: BufferHandle) {
        if self.broken {
            return;
        }

        let event = Event {
            start_frame: 0,
            done: false,
            buffer,
        };

        let message = MessageToAudioThread::NewEvent { event };
        let broken = self.sender.send(message).is_err();
        if broken {
            self.broken = true;
        }
    }

    pub fn add_buffer(&mut self, buffer: AudioBuffer) -> BufferHandle {
        if self.broken {
            return 0;
        }

        let message = MessageToAudioThread::AddBuffer { buffer };
        let broken = self.sender.send(message).is_err();
        if broken {
            self.broken = true;
        }

        let handle = self.next_buffer_handle;
        self.next_buffer_handle += 1;
        return handle;
    }
}

#[derive(Clone)]
pub struct AudioBuffer {
    pub channels: u32,
    pub sample_rate: u32,
    pub data: Vec<SampleData>,
}

impl AudioBuffer {
    pub fn duration(&self) -> Time {
        let frames = self.frames();
        let frequency = self.sample_rate as u64;

        Time((frames*Time::NANOSECONDS_PER_SECOND) / frequency)
    }

    #[inline(always)]
    pub fn frames(&self) -> u64 {
        self.data.len() as u64 / self.channels as u64
    }
}

pub struct Event {
    pub start_frame: u64, // Set internally when the event is actually started
    pub done: bool,
    pub buffer: BufferHandle,
}
<|endoftext|>


<commit_before>#[derive(Eq,PartialEq,Hash,Debug)]
pub struct BS {
    length: i64,
    value: i64,
}

pub trait BitString {
    fn pow(i64, i64) -> i64;
    fn flip(i64, i64) -> i64;
    fn is_set(i64, i64) -> bool;
    fn prepend(i64, BS) -> BS;
    fn length(BS) -> i64;
}

impl BitString for BS {
    fn pow(b: i64, n: i64) -> i64 {
        match n {
            0 => 1,
            1 => b,
            n => {
                let x = Self::pow(b, n / 2);
                x * x * (if n % 2 == 0 { 1 } else { b })
            }
        }
    }
    fn flip(i: i64, b: i64) -> i64 {
        let n = Self::pow(2, i);
        if n & b == n {
            return b - Self::pow(2, i);
        } else {
            return b + Self::pow(2, i);
        }
    }
    fn is_set(i: i64, b: i64) -> bool {
        let n = Self::flip(i, 0);
        (n & b) == n
    }
    fn prepend(b: i64, bs: BS) -> BS {
        match b {
            0 => {
                if !(Self::is_set(bs.length, bs.value)) {
                    BS {
                        length: bs.length + 1,
                        value: bs.value,
                    }
                } else {
                    BS {
                        length: bs.length + 1,
                        value: Self::flip(bs.length, bs.value),
                    }
                }
            }
            1 => {
                if Self::is_set(bs.length, bs.value) {
                    BS {
                        length: bs.length + 1,
                        value: bs.value,
                    }
                } else {
                    BS {
                        length: bs.length + 1,
                        value: Self::flip(bs.length, bs.value),
                    }
                }
            }
            _ => panic!("b has to be a bit (0 or 1)"),
        }
    }
    fn length(bs: BS) -> i64 {
        bs.length
    }
}

#[test]
fn test_pow() {
    assert_eq!(BS::pow(0, 0), 1);
    assert_eq!(BS::pow(42, 0), 1);
    assert_eq!(BS::pow(-2, 0), 1);
    assert_eq!(BS::pow(2, 4), 16);
    assert_eq!(BS::pow(-2, 3), -8);
}

#[test]
fn test_flip() {
    assert_eq!(BS::flip(0, 0), 1);
    assert_eq!(BS::flip(2, 0), 4);
    assert_eq!(BS::flip(1, 7), 5);
    assert_eq!(BS::flip(3, 7), 15);
}

#[test]
fn test_is_set() {
    assert_eq!(BS::is_set(4, 0), false);
    assert_eq!(BS::is_set(0, 0), false);
    assert_eq!(BS::is_set(0, 1), true);
    assert_eq!(BS::is_set(1, 2), true);
    assert_eq!(BS::is_set(0, 2), false);
}

#[test]
fn test_prepend() {
    assert_eq!(BS::prepend(0, BS { length: 0, value: 0}), BS { length: 1, value: 0 });
    assert_eq!(BS::prepend(1, BS { length: 0, value: 0}), BS { length: 1, value: 1});
    assert_eq!(BS::prepend(1, BS { length: 1, value: 1}), BS { length: 2, value: 3});
    assert_eq!(BS::prepend(0, BS { length: 1, value: 1}), BS { length: 2, value: 1});
    assert_eq!(BS::prepend(1, BS { length: 2, value: 1}), BS { length: 3, value: 5});
}
<commit_msg>Make bitstring fields public<commit_after>#[derive(Eq,PartialEq,Hash,Debug,Clone,Copy)]
pub struct BS {
    pub length: i64,
    pub value: i64,
}

pub trait BitString {
    fn pow(i64, i64) -> i64;
    fn flip(i64, i64) -> i64;
    fn is_set(i64, i64) -> bool;
    fn prepend(i64, BS) -> BS;
    fn length(BS) -> i64;
}

impl BitString for BS {
    fn pow(b: i64, n: i64) -> i64 {
        match n {
            0 => 1,
            1 => b,
            n => {
                let x = Self::pow(b, n / 2);
                x * x * (if n % 2 == 0 { 1 } else { b })
            }
        }
    }
    fn flip(i: i64, b: i64) -> i64 {
        let n = Self::pow(2, i);
        if n & b == n {
            return b - Self::pow(2, i);
        } else {
            return b + Self::pow(2, i);
        }
    }
    fn is_set(i: i64, b: i64) -> bool {
        let n = Self::flip(i, 0);
        (n & b) == n
    }
    fn prepend(b: i64, bs: BS) -> BS {
        match b {
            0 => {
                if !(Self::is_set(bs.length, bs.value)) {
                    BS {
                        length: bs.length + 1,
                        value: bs.value,
                    }
                } else {
                    BS {
                        length: bs.length + 1,
                        value: Self::flip(bs.length, bs.value),
                    }
                }
            }
            1 => {
                if Self::is_set(bs.length, bs.value) {
                    BS {
                        length: bs.length + 1,
                        value: bs.value,
                    }
                } else {
                    BS {
                        length: bs.length + 1,
                        value: Self::flip(bs.length, bs.value),
                    }
                }
            }
            _ => panic!("b has to be a bit (0 or 1)"),
        }
    }
    fn length(bs: BS) -> i64 {
        bs.length
    }
}

#[test]
fn test_pow() {
    assert_eq!(BS::pow(0, 0), 1);
    assert_eq!(BS::pow(42, 0), 1);
    assert_eq!(BS::pow(-2, 0), 1);
    assert_eq!(BS::pow(2, 4), 16);
    assert_eq!(BS::pow(-2, 3), -8);
}

#[test]
fn test_flip() {
    assert_eq!(BS::flip(0, 0), 1);
    assert_eq!(BS::flip(2, 0), 4);
    assert_eq!(BS::flip(1, 7), 5);
    assert_eq!(BS::flip(3, 7), 15);
}

#[test]
fn test_is_set() {
    assert_eq!(BS::is_set(4, 0), false);
    assert_eq!(BS::is_set(0, 0), false);
    assert_eq!(BS::is_set(0, 1), true);
    assert_eq!(BS::is_set(1, 2), true);
    assert_eq!(BS::is_set(0, 2), false);
}

#[test]
fn test_prepend() {
    assert_eq!(BS::prepend(0, BS { length: 0, value: 0}), BS { length: 1, value: 0 });
    assert_eq!(BS::prepend(1, BS { length: 0, value: 0}), BS { length: 1, value: 1});
    assert_eq!(BS::prepend(1, BS { length: 1, value: 1}), BS { length: 2, value: 3});
    assert_eq!(BS::prepend(0, BS { length: 1, value: 1}), BS { length: 2, value: 1});
    assert_eq!(BS::prepend(1, BS { length: 2, value: 1}), BS { length: 3, value: 5});
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::rc::{Rc, Weak};
use entity::{Vec3f64, Entity};

struct Address {
    x: u64,
    y: u64,
    z: u64,
}

struct Element {
    name: String,
}

pub enum ChunkOption {
    Local(Rc<LocalChunk>),
    Remote(Rc<RemoteChunk>)
}

pub enum ChildOption {
    Local(Rc<LocalChunk>),
    Remote(Rc<RemoteChunk>),
    None
}

pub enum ParentOption {
    Local(Weak<LocalChunk>),
    Remote(Rc<RemoteChunk>),
    None
}

pub struct LocalChunk {
    address: Address,
    center: Vec3f64,
    children: [ChildOption; 8],
    child_number: Option<u8>,
    entities: Vec<Rc<Entity>>,
    mass: f64,
    parent: ParentOption,
    scale: u8,
    structure: u64,
    summary: Rc<Element>,
}

pub struct RemoteChunk {
    connection: i32,
}

impl Address {
    fn from_string(address: String) -> Option<Address> {
        let mut xyz: (u64, u64, u64) = (1, 1, 1);
        let mut xyz_add: (u64, u64, u64);

        for (i, c) in address.chars().enumerate() {
            if i > 63 {
                break;
            }
            xyz_add =  match c.to_digit(8) {
                Some(0) => (0, 0, 0),
                Some(1) => (0, 0, 1),
                Some(2) => (0, 1, 0),
                Some(3) => (0, 1, 1),
                Some(4) => (1, 0, 0),
                Some(5) => (1, 0, 1),
                Some(6) => (1, 1, 0),
                Some(7) => (1, 1, 1),
                _ => return None,
            };
            xyz = (xyz.0 << 1, xyz.1 << 1, xyz.2 << 1);
            xyz = (xyz.0 + xyz_add.0, xyz.1 + xyz_add.1, xyz.2 + xyz_add.2);
        }
        Some(Address {x: xyz.0, y: xyz.1, z: xyz.2})
    }
}

impl ToString for Address {
    fn to_string(&self) -> String {
        String::from_str("")
    }
}

impl PartialEq for Address {
    fn eq(&self, other: &Self) -> bool {
        (((self.x == other.x) && (self.y == other.y)) && (self.z == other.z))
    }
}

pub trait Chunk {
    fn get_child(&self, x: u8, y: u8, z: u8) -> ChildOption;
    fn tick(&self, time_delta: f64);
}

impl Chunk for LocalChunk {
    fn get_child(&self, x: u8, y: u8, z: u8) -> ChildOption {

        let index = match (x, y, z) {
            (0, 0, 0) => Some(0),
            (0, 0, 1) => Some(1),
            (0, 1, 0) => Some(2),
            (0, 1, 1) => Some(3),
            (1, 0, 0) => Some(4),
            (1, 0, 1) => Some(5),
            (1, 1, 0) => Some(6),
            (1, 1, 1) => Some(7),
            _ => None,
        };

        match index {
            Some(i) => match self.children[i] {
                ChildOption::Local(ref chunk) => ChildOption::Local(chunk.clone()),
                ChildOption::Remote(ref chunk) => ChildOption::Remote(chunk.clone()),
                ChildOption::None => ChildOption::None
            },
            None => ChildOption::None
        }
    }

    fn tick(&self, time_delta: f64) {
    }
}

impl Chunk for RemoteChunk {
    fn get_child(&self, x: u8, y: u8, z: u8) -> ChildOption {
        ChildOption::None
    }
    fn tick (&self, time_delta: f64) {
    }
}

<commit_msg>Update mod.rs<commit_after>#![allow(dead_code)]

use std::rc::{Rc, Weak};
use entity::{Vec3f64, Entity};

struct Address {
    x: u64,
    y: u64,
    z: u64,
    depth: u8,
}

struct Element {
    name: String,
}

pub enum ChunkOption {
    Local(Rc<LocalChunk>),
    Remote(Rc<RemoteChunk>)
}

pub enum ChildOption {
    Local(Rc<LocalChunk>),
    Remote(Rc<RemoteChunk>),
    None
}

pub enum ParentOption {
    Local(Weak<LocalChunk>),
    Remote(Rc<RemoteChunk>),
    None
}

pub struct LocalChunk {
    address: Address,
    center: Vec3f64,
    children: [ChildOption; 8],
    child_number: Option<u8>,
    entities: Vec<Rc<Entity>>,
    mass: f64,
    parent: ParentOption,
    scale: u8,
    structure: u64,
    summary: Rc<Element>,
}

pub struct RemoteChunk {
    connection: i32,
}

impl Address {
    fn from_string(address: String) -> Option<Address> {
        let mut xyz: (u64, u64, u64) = (1, 1, 1);
        let mut xyz_add: (u64, u64, u64);

        for (i, c) in address.chars().enumerate() {
            if i > 63 {
                break;
            }
            xyz_add =  match c.to_digit(8) {
                Some(0) => (0, 0, 0),
                Some(1) => (0, 0, 1),
                Some(2) => (0, 1, 0),
                Some(3) => (0, 1, 1),
                Some(4) => (1, 0, 0),
                Some(5) => (1, 0, 1),
                Some(6) => (1, 1, 0),
                Some(7) => (1, 1, 1),
                _ => return None,
            };
            xyz = (xyz.0 << 1, xyz.1 << 1, xyz.2 << 1);
            xyz = (xyz.0 + xyz_add.0, xyz.1 + xyz_add.1, xyz.2 + xyz_add.2);
        }
        Some(Address {x: xyz.0, y: xyz.1, z: xyz.2})
    }
}

impl ToString for Address {
    fn to_string(&self) -> String {
        String::from_str("")
    }
}

impl PartialEq for Address {
    fn eq(&self, other: &Self) -> bool {
        (((self.x == other.x) && (self.y == other.y)) && (self.z == other.z))
    }
}

pub trait Chunk {
    fn get_child(&self, x: u8, y: u8, z: u8) -> ChildOption;
    fn tick(&self, time_delta: f64);
}

impl Chunk for LocalChunk {
    fn get_child(&self, x: u8, y: u8, z: u8) -> ChildOption {

        let index = match (x, y, z) {
            (0, 0, 0) => Some(0),
            (0, 0, 1) => Some(1),
            (0, 1, 0) => Some(2),
            (0, 1, 1) => Some(3),
            (1, 0, 0) => Some(4),
            (1, 0, 1) => Some(5),
            (1, 1, 0) => Some(6),
            (1, 1, 1) => Some(7),
            _ => None,
        };

        match index {
            Some(i) => match self.children[i] {
                ChildOption::Local(ref chunk) => ChildOption::Local(chunk.clone()),
                ChildOption::Remote(ref chunk) => ChildOption::Remote(chunk.clone()),
                ChildOption::None => ChildOption::None
            },
            None => ChildOption::None
        }
    }

    fn tick(&self, time_delta: f64) {
    }
}

impl Chunk for RemoteChunk {
    fn get_child(&self, x: u8, y: u8, z: u8) -> ChildOption {
        ChildOption::None
    }
    fn tick (&self, time_delta: f64) {
    }
}

<|endoftext|>


<commit_before>// Macros for changing function names.
// This is created and edited manually, but should be kept roughly in sync with `build.rs`.

/// This library was build with version renaming, so rewrite every function name
/// with its name with version number appended.
///
/// The macro below will rename a symbol `foo::bar` to `foo::bar_64` (where "64")
/// may be some other number depending on the ICU library in use.
#[cfg(all(feature="renaming", not(feature="icu_version_in_env")))]
#[macro_export]
macro_rules! versioned_function {
    ($i:ident) => {
      $crate::__private_do_not_use::paste::expr! {
        $crate::[< $i _64 >]
      }
    }
}

/// This library was build with version renaming, so rewrite every function name
/// with its name with version number appended.
///
/// The macro below will rename a symbol `foo::bar` to `foo::bar_XX` (where "XX")
/// is a string coming from the environment variable RUST_ICU_MAJOR_VERSION_NUMBER,
/// which is expected to be defined at compile time.
#[cfg(all(feature="renaming",feature="icu_version_in_env"))]
#[macro_export]
macro_rules! versioned_function {
    ($i:ident) => {
      $crate::__private_do_not_use::paste::expr! {
        $crate::[< $i _ env!("RUST_ICU_MAJOR_VERSION_NUMBER") >]
      }
    }
}

// This macro will be used when no function renaming is needed
#[cfg(not(feature="renaming"))]
#[macro_export]
macro_rules! versioned_function {
    ($func_name:ident) => {
        $crate::$func_name
    }
}
<commit_msg>Reduce unnecessary changes in `bindgen/macros.rs`<commit_after>// Macros for changing function names.
// This is created and edited manually, but should be kept roughly in sync with `build.rs`.

/// This library was build with version renaming, so rewrite every function name
/// with its name with version number appended.

/// The macro will rename a symbol `foo::bar` to `foo::bar_64` (where "64")
/// may be some other number depending on the ICU library in use.
#[cfg(all(feature="renaming",not(feature="icu_version_in_env")))]
#[macro_export]
macro_rules! versioned_function {
    ($i:ident) => {
      $crate::__private_do_not_use::paste::expr! {
        $crate::[< $i _ 64 >]
      }
    }
}

/// This library was build with version renaming, so rewrite every function name
/// with its name with version number appended.
///
/// The macro will rename a symbol `foo::bar` to `foo::bar_XX` (where "XX")
/// is a string coming from the environment variable RUST_ICU_MAJOR_VERSION_NUMBER,
/// which is expected to be defined at compile time.
#[cfg(all(feature="renaming",feature="icu_version_in_env"))]
#[macro_export]
macro_rules! versioned_function {
    ($i:ident) => {
      $crate::__private_do_not_use::paste::expr! {
        $crate::[< $i _ env!("RUST_ICU_MAJOR_VERSION_NUMBER") >]
      }
    }
}

/// This macro will be used when no function renaming is needed.
#[cfg(not(feature="renaming"))]
#[macro_export]
macro_rules! versioned_function {
    ($func_name:ident) => {
        $crate::$func_name
    }
}
<|endoftext|>


<commit_before><commit_msg>Update to match serialize::json<commit_after><|endoftext|>


<commit_before><commit_msg>Improve error handling slightly<commit_after><|endoftext|>


<commit_before><commit_msg>Factored out the find predicate<commit_after><|endoftext|>


<commit_before><commit_msg>Zmiany.<commit_after><|endoftext|>


<commit_before><commit_msg>Use boxed iterators to iterate files and words.<commit_after><|endoftext|>


<commit_before><commit_msg>Added message about functions<commit_after><|endoftext|>


<commit_before><commit_msg>Writing received messages to stream<commit_after><|endoftext|>


<commit_before><commit_msg>Made rendering code less redundant<commit_after><|endoftext|>


<commit_before><commit_msg>Rewrote pattern depacking<commit_after><|endoftext|>


<commit_before><commit_msg>add clean_path and made canon_path use it<commit_after><|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("InheritedTable", inherited=True, gecko_name="TableBorder") %>

${helpers.single_keyword(
    "border-collapse",
    "separate collapse",
    engines="gecko servo-2013",
    gecko_enum_prefix="StyleBorderCollapse",
    animation_value_type="discrete",
    spec="https://drafts.csswg.org/css-tables/#propdef-border-collapse",
    servo_restyle_damage = "reflow",
)}

${helpers.single_keyword(
    "empty-cells",
    "show hide",
    engines="gecko servo-2013",
    gecko_constant_prefix="NS_STYLE_TABLE_EMPTY_CELLS",
    animation_value_type="discrete",
    spec="https://drafts.csswg.org/css-tables/#propdef-empty-cells",
    servo_restyle_damage="rebuild_and_reflow",
)}

${helpers.single_keyword(
    "caption-side",
    "top bottom",
    engines="gecko servo-2013",
    extra_gecko_values="right left top-outside bottom-outside",
    needs_conversion="True",
    animation_value_type="discrete",
    spec="https://drafts.csswg.org/css-tables/#propdef-caption-side",
    servo_restyle_damage="rebuild_and_reflow",
)}

${helpers.predefined_type(
    "border-spacing",
    "BorderSpacing",
    "computed::BorderSpacing::zero()",
    engines="gecko servo-2013 servo-2020",
    servo_2020_pref="layout.2020.unimplemented",
    animation_value_type="BorderSpacing",
    boxed=True,
    spec="https://drafts.csswg.org/css-tables/#propdef-border-spacing",
    servo_restyle_damage = "reflow",
)}
<commit_msg>style: Converting empty-cells defines into enum class.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("InheritedTable", inherited=True, gecko_name="TableBorder") %>

${helpers.single_keyword(
    "border-collapse",
    "separate collapse",
    engines="gecko servo-2013",
    gecko_enum_prefix="StyleBorderCollapse",
    animation_value_type="discrete",
    spec="https://drafts.csswg.org/css-tables/#propdef-border-collapse",
    servo_restyle_damage = "reflow",
)}

${helpers.single_keyword(
    "empty-cells",
    "show hide",
    engines="gecko servo-2013",
    gecko_enum_prefix="StyleEmptyCells",
    animation_value_type="discrete",
    spec="https://drafts.csswg.org/css-tables/#propdef-empty-cells",
    servo_restyle_damage="rebuild_and_reflow",
)}

${helpers.single_keyword(
    "caption-side",
    "top bottom",
    engines="gecko servo-2013",
    extra_gecko_values="right left top-outside bottom-outside",
    needs_conversion="True",
    animation_value_type="discrete",
    spec="https://drafts.csswg.org/css-tables/#propdef-caption-side",
    servo_restyle_damage="rebuild_and_reflow",
)}

${helpers.predefined_type(
    "border-spacing",
    "BorderSpacing",
    "computed::BorderSpacing::zero()",
    engines="gecko servo-2013 servo-2020",
    servo_2020_pref="layout.2020.unimplemented",
    animation_value_type="BorderSpacing",
    boxed=True,
    spec="https://drafts.csswg.org/css-tables/#propdef-border-spacing",
    servo_restyle_damage = "reflow",
)}
<|endoftext|>


<commit_before>//! Types for compile-time endianity.

use byteorder;
use std::borrow::Cow;
use std::cmp;
use std::fmt::Debug;
use std::io;
use std::io::Read;
use std::marker::PhantomData;
use std::ops::{Deref, Index, Range, RangeFrom, RangeTo};

/// A trait describing the endianity of some buffer.
///
/// All interesting methods are from the `byteorder` crate's `ByteOrder`
/// trait. All methods are static. You shouldn't instantiate concrete objects
/// that implement this trait, it is just used as compile-time phantom data.
pub trait Endianity
    : byteorder::ByteOrder + Debug + Default + Clone + Copy + PartialEq + Eq {
    /// Return true for big endian byte order.
    fn is_big_endian() -> bool;

    /// Return true for little endian byte order.
    fn is_little_endian() -> bool {
        !Self::is_big_endian()
    }
}

/// Little endian byte order.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LittleEndian {}

impl Default for LittleEndian {
    fn default() -> LittleEndian {
        unreachable!()
    }
}

impl byteorder::ByteOrder for LittleEndian {
    fn read_u16(buf: &[u8]) -> u16 {
        byteorder::LittleEndian::read_u16(buf)
    }
    fn read_u32(buf: &[u8]) -> u32 {
        byteorder::LittleEndian::read_u32(buf)
    }
    fn read_u64(buf: &[u8]) -> u64 {
        byteorder::LittleEndian::read_u64(buf)
    }
    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
        byteorder::LittleEndian::read_uint(buf, nbytes)
    }
    fn write_u16(buf: &mut [u8], n: u16) {
        byteorder::LittleEndian::write_u16(buf, n)
    }
    fn write_u32(buf: &mut [u8], n: u32) {
        byteorder::LittleEndian::write_u32(buf, n)
    }
    fn write_u64(buf: &mut [u8], n: u64) {
        byteorder::LittleEndian::write_u64(buf, n)
    }
    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
        byteorder::LittleEndian::write_uint(buf, n, nbytes)
    }
}

impl Endianity for LittleEndian {
    fn is_big_endian() -> bool {
        false
    }
}

/// Big endian byte order.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BigEndian {}

impl Default for BigEndian {
    fn default() -> BigEndian {
        unreachable!()
    }
}

impl byteorder::ByteOrder for BigEndian {
    fn read_u16(buf: &[u8]) -> u16 {
        byteorder::BigEndian::read_u16(buf)
    }
    fn read_u32(buf: &[u8]) -> u32 {
        byteorder::BigEndian::read_u32(buf)
    }
    fn read_u64(buf: &[u8]) -> u64 {
        byteorder::BigEndian::read_u64(buf)
    }
    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
        byteorder::BigEndian::read_uint(buf, nbytes)
    }
    fn write_u16(buf: &mut [u8], n: u16) {
        byteorder::BigEndian::write_u16(buf, n)
    }
    fn write_u32(buf: &mut [u8], n: u32) {
        byteorder::BigEndian::write_u32(buf, n)
    }
    fn write_u64(buf: &mut [u8], n: u64) {
        byteorder::BigEndian::write_u64(buf, n)
    }
    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
        byteorder::BigEndian::write_uint(buf, n, nbytes)
    }
}

impl Endianity for BigEndian {
    fn is_big_endian() -> bool {
        true
    }
}

/// The native endianity for the target platform.
#[cfg(target_endian = "little")]
pub type NativeEndian = LittleEndian;
#[cfg(target_endian = "big")]
pub type NativeEndian = BigEndian;

/// A `&[u8]` slice with compile-time endianity metadata.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EndianBuf<'input, Endian>
    where Endian: Endianity
{
    buf: &'input [u8],
    endian: PhantomData<Endian>,
}

impl<'input, Endian> EndianBuf<'input, Endian>
    where Endian: Endianity
{
    /// Construct a new `EndianBuf` with the given buffer.
    pub fn new(buf: &'input [u8]) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf,
            endian: PhantomData,
        }
    }

    /// Return a reference to the raw buffer.
    pub fn buf(&self) -> &'input [u8] {
        self.buf
    }

    /// Split the buffer in two at the given index, resulting in the tuple where
    /// the first item has range [0, idx), and the second has range
    /// [idx, len). Panics if the index is out of bounds.
    #[inline]
    pub fn split_at(&self, idx: usize) -> (EndianBuf<'input, Endian>, EndianBuf<'input, Endian>) {
        (self.range_to(..idx), self.range_from(idx..))
    }

    /// Find the first occurence of a byte in the buffer, and return its index.
    #[inline]
    pub fn find(&self, byte: u8) -> Option<usize> {
        self.buf.iter().position(|ch| *ch == byte)
    }

    /// Return the offset of the start of the buffer relative to the start
    /// of the given buffer.
    pub fn offset_from(&self, base: EndianBuf<'input, Endian>) -> usize {
        let base_ptr = base.buf.as_ptr() as *const u8 as usize;
        let ptr = self.buf.as_ptr() as *const u8 as usize;
        debug_assert!(base_ptr <= ptr);
        debug_assert!(ptr + self.buf.len() <= base_ptr + base.buf.len());
        ptr - base_ptr
    }

    /// Converts the buffer to a string, including invalid characters,
    /// using `String::from_utf8_lossy`.
    pub fn to_string_lossy(&self) -> Cow<'input, str> {
        String::from_utf8_lossy(self.buf)
    }
}

/// # Range Methods
///
/// Unfortunately, `std::ops::Index` *must* return a reference, so we can't
/// implement `Index<Range<usize>>` to return a new `EndianBuf` the way we would
/// like to. Instead, we abandon fancy indexing operators and have these plain
/// old methods.
impl<'input, Endian> EndianBuf<'input, Endian>
    where Endian: Endianity
{
    /// Take the given `start..end` range of the underlying buffer and return a
    /// new `EndianBuf`.
    ///
    /// ```
    /// use gimli::{EndianBuf, LittleEndian};
    ///
    /// let buf = [0x01, 0x02, 0x03, 0x04];
    /// let endian_buf = EndianBuf::<LittleEndian>::new(&buf);
    /// assert_eq!(endian_buf.range(1..3),
    ///            EndianBuf::new(&buf[1..3]));
    /// ```
    pub fn range(&self, idx: Range<usize>) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf: &self.buf[idx],
            endian: self.endian,
        }
    }

    /// Take the given `start..` range of the underlying buffer and return a new
    /// `EndianBuf`.
    ///
    /// ```
    /// use gimli::{EndianBuf, LittleEndian};
    ///
    /// let buf = [0x01, 0x02, 0x03, 0x04];
    /// let endian_buf = EndianBuf::<LittleEndian>::new(&buf);
    /// assert_eq!(endian_buf.range_from(2..),
    ///            EndianBuf::new(&buf[2..]));
    /// ```
    pub fn range_from(&self, idx: RangeFrom<usize>) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf: &self.buf[idx],
            endian: self.endian,
        }
    }

    /// Take the given `..end` range of the underlying buffer and return a new
    /// `EndianBuf`.
    ///
    /// ```
    /// use gimli::{EndianBuf, LittleEndian};
    ///
    /// let buf = [0x01, 0x02, 0x03, 0x04];
    /// let endian_buf = EndianBuf::<LittleEndian>::new(&buf);
    /// assert_eq!(endian_buf.range_to(..3),
    ///            EndianBuf::new(&buf[..3]));
    /// ```
    pub fn range_to(&self, idx: RangeTo<usize>) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf: &self.buf[idx],
            endian: self.endian,
        }
    }
}

impl<'input, Endian> Index<usize> for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Output = u8;
    fn index(&self, idx: usize) -> &Self::Output {
        &self.buf[idx]
    }
}

impl<'input, Endian> Index<RangeFrom<usize>> for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Output = [u8];
    fn index(&self, idx: RangeFrom<usize>) -> &Self::Output {
        &self.buf[idx]
    }
}

impl<'input, Endian> Deref for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Target = [u8];
    fn deref(&self) -> &Self::Target {
        self.buf
    }
}

impl<'input, Endian> Into<&'input [u8]> for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    fn into(self) -> &'input [u8] {
        self.buf
    }
}

impl<'input, Endian> Read for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let len = cmp::min(buf.len(), self.buf.len());
        buf[..len].copy_from_slice(&self.buf[..len]);
        self.buf = &self.buf[len..];
        Ok(len)
    }
}

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

    #[test]
    fn test_endian_buf_split_at() {
        let buf = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
        let eb = EndianBuf::<NativeEndian>::new(&buf);
        assert_eq!(eb.split_at(3),
                   (EndianBuf::new(&buf[..3]), EndianBuf::new(&buf[3..])));
    }

    #[test]
    #[should_panic]
    fn test_endian_buf_split_at_out_of_bounds() {
        let buf = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
        let eb = EndianBuf::<NativeEndian>::new(&buf);
        eb.split_at(30);
    }
}
<commit_msg>Implement Reader for EndianBuf<commit_after>//! Types for compile-time endianity.

use byteorder;
use std::borrow::Cow;
use std::cmp;
use std::fmt::Debug;
use std::io;
use std::io::Read;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, Index, Range, RangeFrom, RangeTo};
use parser::{Error, Result};
use reader::Reader;

/// A trait describing the endianity of some buffer.
///
/// All interesting methods are from the `byteorder` crate's `ByteOrder`
/// trait. All methods are static. You shouldn't instantiate concrete objects
/// that implement this trait, it is just used as compile-time phantom data.
pub trait Endianity
    : byteorder::ByteOrder + Debug + Default + Clone + Copy + PartialEq + Eq {
    /// Return true for big endian byte order.
    fn is_big_endian() -> bool;

    /// Return true for little endian byte order.
    fn is_little_endian() -> bool {
        !Self::is_big_endian()
    }
}

/// Little endian byte order.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LittleEndian {}

impl Default for LittleEndian {
    fn default() -> LittleEndian {
        unreachable!()
    }
}

impl byteorder::ByteOrder for LittleEndian {
    fn read_u16(buf: &[u8]) -> u16 {
        byteorder::LittleEndian::read_u16(buf)
    }
    fn read_u32(buf: &[u8]) -> u32 {
        byteorder::LittleEndian::read_u32(buf)
    }
    fn read_u64(buf: &[u8]) -> u64 {
        byteorder::LittleEndian::read_u64(buf)
    }
    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
        byteorder::LittleEndian::read_uint(buf, nbytes)
    }
    fn write_u16(buf: &mut [u8], n: u16) {
        byteorder::LittleEndian::write_u16(buf, n)
    }
    fn write_u32(buf: &mut [u8], n: u32) {
        byteorder::LittleEndian::write_u32(buf, n)
    }
    fn write_u64(buf: &mut [u8], n: u64) {
        byteorder::LittleEndian::write_u64(buf, n)
    }
    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
        byteorder::LittleEndian::write_uint(buf, n, nbytes)
    }
}

impl Endianity for LittleEndian {
    fn is_big_endian() -> bool {
        false
    }
}

/// Big endian byte order.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BigEndian {}

impl Default for BigEndian {
    fn default() -> BigEndian {
        unreachable!()
    }
}

impl byteorder::ByteOrder for BigEndian {
    fn read_u16(buf: &[u8]) -> u16 {
        byteorder::BigEndian::read_u16(buf)
    }
    fn read_u32(buf: &[u8]) -> u32 {
        byteorder::BigEndian::read_u32(buf)
    }
    fn read_u64(buf: &[u8]) -> u64 {
        byteorder::BigEndian::read_u64(buf)
    }
    fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
        byteorder::BigEndian::read_uint(buf, nbytes)
    }
    fn write_u16(buf: &mut [u8], n: u16) {
        byteorder::BigEndian::write_u16(buf, n)
    }
    fn write_u32(buf: &mut [u8], n: u32) {
        byteorder::BigEndian::write_u32(buf, n)
    }
    fn write_u64(buf: &mut [u8], n: u64) {
        byteorder::BigEndian::write_u64(buf, n)
    }
    fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
        byteorder::BigEndian::write_uint(buf, n, nbytes)
    }
}

impl Endianity for BigEndian {
    fn is_big_endian() -> bool {
        true
    }
}

/// The native endianity for the target platform.
#[cfg(target_endian = "little")]
pub type NativeEndian = LittleEndian;
#[cfg(target_endian = "big")]
pub type NativeEndian = BigEndian;

/// A `&[u8]` slice with compile-time endianity metadata.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct EndianBuf<'input, Endian>
    where Endian: Endianity
{
    buf: &'input [u8],
    endian: PhantomData<Endian>,
}

impl<'input, Endian> EndianBuf<'input, Endian>
    where Endian: Endianity
{
    /// Construct a new `EndianBuf` with the given buffer.
    pub fn new(buf: &'input [u8]) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf,
            endian: PhantomData,
        }
    }

    /// Return a reference to the raw buffer.
    pub fn buf(&self) -> &'input [u8] {
        self.buf
    }

    /// Split the buffer in two at the given index, resulting in the tuple where
    /// the first item has range [0, idx), and the second has range
    /// [idx, len). Panics if the index is out of bounds.
    #[inline]
    pub fn split_at(&self, idx: usize) -> (EndianBuf<'input, Endian>, EndianBuf<'input, Endian>) {
        (self.range_to(..idx), self.range_from(idx..))
    }

    /// Find the first occurence of a byte in the buffer, and return its index.
    #[inline]
    pub fn find(&self, byte: u8) -> Option<usize> {
        self.buf.iter().position(|ch| *ch == byte)
    }

    /// Return the offset of the start of the buffer relative to the start
    /// of the given buffer.
    pub fn offset_from(&self, base: EndianBuf<'input, Endian>) -> usize {
        let base_ptr = base.buf.as_ptr() as *const u8 as usize;
        let ptr = self.buf.as_ptr() as *const u8 as usize;
        debug_assert!(base_ptr <= ptr);
        debug_assert!(ptr + self.buf.len() <= base_ptr + base.buf.len());
        ptr - base_ptr
    }

    /// Converts the buffer to a string, including invalid characters,
    /// using `String::from_utf8_lossy`.
    pub fn to_string_lossy(&self) -> Cow<'input, str> {
        String::from_utf8_lossy(self.buf)
    }

    #[inline]
    fn read_slice(&mut self, len: usize) -> Result<&'input [u8]> {
        if self.buf.len() < len {
            Err(Error::UnexpectedEof)
        } else {
            let val = &self.buf[..len];
            self.buf = &self.buf[len..];
            Ok(val)
        }
    }
}

/// # Range Methods
///
/// Unfortunately, `std::ops::Index` *must* return a reference, so we can't
/// implement `Index<Range<usize>>` to return a new `EndianBuf` the way we would
/// like to. Instead, we abandon fancy indexing operators and have these plain
/// old methods.
impl<'input, Endian> EndianBuf<'input, Endian>
    where Endian: Endianity
{
    /// Take the given `start..end` range of the underlying buffer and return a
    /// new `EndianBuf`.
    ///
    /// ```
    /// use gimli::{EndianBuf, LittleEndian};
    ///
    /// let buf = [0x01, 0x02, 0x03, 0x04];
    /// let endian_buf = EndianBuf::<LittleEndian>::new(&buf);
    /// assert_eq!(endian_buf.range(1..3),
    ///            EndianBuf::new(&buf[1..3]));
    /// ```
    pub fn range(&self, idx: Range<usize>) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf: &self.buf[idx],
            endian: self.endian,
        }
    }

    /// Take the given `start..` range of the underlying buffer and return a new
    /// `EndianBuf`.
    ///
    /// ```
    /// use gimli::{EndianBuf, LittleEndian};
    ///
    /// let buf = [0x01, 0x02, 0x03, 0x04];
    /// let endian_buf = EndianBuf::<LittleEndian>::new(&buf);
    /// assert_eq!(endian_buf.range_from(2..),
    ///            EndianBuf::new(&buf[2..]));
    /// ```
    pub fn range_from(&self, idx: RangeFrom<usize>) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf: &self.buf[idx],
            endian: self.endian,
        }
    }

    /// Take the given `..end` range of the underlying buffer and return a new
    /// `EndianBuf`.
    ///
    /// ```
    /// use gimli::{EndianBuf, LittleEndian};
    ///
    /// let buf = [0x01, 0x02, 0x03, 0x04];
    /// let endian_buf = EndianBuf::<LittleEndian>::new(&buf);
    /// assert_eq!(endian_buf.range_to(..3),
    ///            EndianBuf::new(&buf[..3]));
    /// ```
    pub fn range_to(&self, idx: RangeTo<usize>) -> EndianBuf<'input, Endian> {
        EndianBuf {
            buf: &self.buf[idx],
            endian: self.endian,
        }
    }
}

impl<'input, Endian> Index<usize> for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Output = u8;
    fn index(&self, idx: usize) -> &Self::Output {
        &self.buf[idx]
    }
}

impl<'input, Endian> Index<RangeFrom<usize>> for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Output = [u8];
    fn index(&self, idx: RangeFrom<usize>) -> &Self::Output {
        &self.buf[idx]
    }
}

impl<'input, Endian> Deref for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Target = [u8];
    fn deref(&self) -> &Self::Target {
        self.buf
    }
}

impl<'input, Endian> Into<&'input [u8]> for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    fn into(self) -> &'input [u8] {
        self.buf
    }
}

impl<'input, Endian> Read for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let len = cmp::min(buf.len(), self.buf.len());
        buf[..len].copy_from_slice(&self.buf[..len]);
        self.buf = &self.buf[len..];
        Ok(len)
    }
}

impl<'input, Endian> Reader for EndianBuf<'input, Endian>
    where Endian: Endianity
{
    type Endian = Endian;

    #[inline]
    fn len(&self) -> usize {
        self.buf.len()
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.buf.is_empty()
    }

    #[inline]
    fn empty(&mut self) {
        self.buf = &[];
    }

    #[inline]
    fn truncate(&mut self, len: usize) -> Result<()> {
        if self.buf.len() < len {
            Err(Error::UnexpectedEof)
        } else {
            self.buf = &self.buf[..len];
            Ok(())
        }
    }

    #[inline]
    fn offset_from(&self, base: &Self) -> usize {
        self.offset_from(*base)
    }

    #[inline]
    fn find(&self, byte: u8) -> Option<usize> {
        self.find(byte)
    }

    #[inline]
    fn skip(&mut self, len: usize) -> Result<()> {
        if self.buf.len() < len {
            Err(Error::UnexpectedEof)
        } else {
            self.buf = &self.buf[len..];
            Ok(())
        }
    }

    #[inline]
    fn split(&mut self, len: usize) -> Result<Self> {
        let slice = self.read_slice(len)?;
        Ok(EndianBuf::new(slice))
    }

    #[inline]
    fn read_u8_array<A>(&mut self) -> Result<A>
        where A: Sized + Default + AsMut<[u8]>
    {
        let len = mem::size_of::<A>();
        let slice = self.read_slice(len)?;
        let mut val = Default::default();
        <A as AsMut<[u8]>>::as_mut(&mut val).clone_from_slice(slice);
        Ok(val)
    }

    #[inline]
    fn read_u8(&mut self) -> Result<u8> {
        let slice = self.read_slice(1)?;
        Ok(slice[0])
    }

    #[inline]
    fn read_i8(&mut self) -> Result<i8> {
        let slice = self.read_slice(1)?;
        Ok(slice[0] as i8)
    }

    #[inline]
    fn read_u16(&mut self) -> Result<u16> {
        let slice = self.read_slice(2)?;
        Ok(Endian::read_u16(&slice))
    }

    #[inline]
    fn read_i16(&mut self) -> Result<i16> {
        let slice = self.read_slice(2)?;
        Ok(Endian::read_i16(&slice))
    }

    #[inline]
    fn read_u32(&mut self) -> Result<u32> {
        let slice = self.read_slice(4)?;
        Ok(Endian::read_u32(&slice))
    }

    #[inline]
    fn read_i32(&mut self) -> Result<i32> {
        let slice = self.read_slice(4)?;
        Ok(Endian::read_i32(&slice))
    }

    #[inline]
    fn read_u64(&mut self) -> Result<u64> {
        let slice = self.read_slice(8)?;
        Ok(Endian::read_u64(&slice))
    }

    #[inline]
    fn read_i64(&mut self) -> Result<i64> {
        let slice = self.read_slice(8)?;
        Ok(Endian::read_i64(&slice))
    }
}

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

    #[test]
    fn test_endian_buf_split_at() {
        let buf = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
        let eb = EndianBuf::<NativeEndian>::new(&buf);
        assert_eq!(eb.split_at(3),
                   (EndianBuf::new(&buf[..3]), EndianBuf::new(&buf[3..])));
    }

    #[test]
    #[should_panic]
    fn test_endian_buf_split_at_out_of_bounds() {
        let buf = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
        let eb = EndianBuf::<NativeEndian>::new(&buf);
        eb.split_at(30);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! Usage: ./key-manager node.config

#![forbid(unsafe_code)]

use libra_config::config::KeyManagerConfig;
use libra_key_manager::{
    counters,
    libra_interface::JsonRpcLibraInterface,
    logging::{LogEntry, LogEvent, LogSchema},
    Error, KeyManager,
};
use libra_logger::info;
use libra_secure_push_metrics::MetricsPusher;
use libra_secure_storage::Storage;
use libra_secure_time::RealTimeService;
use std::{convert::TryInto, env, process};

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() != 2 {
        eprintln!("Error! Incorrect number of parameters, expected a path to a config file.");
        process::exit(1);
    }

    let key_manager_config = KeyManagerConfig::load(&args[1]).unwrap_or_else(|e| {
        eprintln!(
            "Error! Unable to load provided key manager config: {}, error: {}",
            args[1], e
        );
        process::exit(1);
    });

    libra_logger::Logger::new()
        .channel_size(key_manager_config.logger.chan_size)
        .is_async(key_manager_config.logger.is_async)
        .level(key_manager_config.logger.level)
        .read_env()
        .init();

    let _mp = MetricsPusher::start();
    counters::initialize_all_metric_counters();

    create_and_execute_key_manager(key_manager_config).unwrap_or_else(|e| {
        eprintln!("Error! The Key Manager has failed during execution: {}", e);
        process::exit(1);
    });
}

fn create_and_execute_key_manager(key_manager_config: KeyManagerConfig) -> Result<(), Error> {
    let json_rpc_endpoint = key_manager_config.json_rpc_endpoint;
    let libra_interface = JsonRpcLibraInterface::new(json_rpc_endpoint.clone());
    let storage: Storage = (&key_manager_config.secure_backend)
        .try_into()
        .expect("Unable to initialize storage");
    let time_service = RealTimeService::new();

    let mut key_manager = KeyManager::new(
        libra_interface,
        storage,
        time_service,
        key_manager_config.rotation_period_secs,
        key_manager_config.sleep_period_secs,
        key_manager_config.txn_expiration_secs,
        key_manager_config.chain_id,
    );

    info!(LogSchema::new(LogEntry::Initialized)
        .event(LogEvent::Success)
        .json_rpc_endpoint(&json_rpc_endpoint));
    key_manager.execute()
}
<commit_msg>[Key Manager] Log the key manager config on startup for better debugging<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! Usage: ./key-manager node.config

#![forbid(unsafe_code)]

use libra_config::config::KeyManagerConfig;
use libra_key_manager::{
    counters,
    libra_interface::JsonRpcLibraInterface,
    logging::{LogEntry, LogEvent, LogSchema},
    Error, KeyManager,
};
use libra_logger::info;
use libra_secure_push_metrics::MetricsPusher;
use libra_secure_storage::Storage;
use libra_secure_time::RealTimeService;
use std::{convert::TryInto, env, process};

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() != 2 {
        eprintln!("Error! Incorrect number of parameters, expected a path to a config file.");
        process::exit(1);
    }

    let key_manager_config = KeyManagerConfig::load(&args[1]).unwrap_or_else(|e| {
        eprintln!(
            "Error! Unable to load provided key manager config: {}, error: {}",
            args[1], e
        );
        process::exit(1);
    });

    libra_logger::Logger::new()
        .channel_size(key_manager_config.logger.chan_size)
        .is_async(key_manager_config.logger.is_async)
        .level(key_manager_config.logger.level)
        .read_env()
        .init();

    let _mp = MetricsPusher::start();
    counters::initialize_all_metric_counters();

    create_and_execute_key_manager(key_manager_config).unwrap_or_else(|e| {
        eprintln!("Error! The Key Manager has failed during execution: {}", e);
        process::exit(1);
    });
}

fn create_and_execute_key_manager(key_manager_config: KeyManagerConfig) -> Result<(), Error> {
    info!(
        LogSchema::new(LogEntry::Initialized).event(LogEvent::Pending),
        key_manager_config = key_manager_config
    );

    let json_rpc_endpoint = key_manager_config.json_rpc_endpoint;
    let libra_interface = JsonRpcLibraInterface::new(json_rpc_endpoint.clone());
    let storage: Storage = (&key_manager_config.secure_backend)
        .try_into()
        .expect("Unable to initialize storage");
    let time_service = RealTimeService::new();

    let mut key_manager = KeyManager::new(
        libra_interface,
        storage,
        time_service,
        key_manager_config.rotation_period_secs,
        key_manager_config.sleep_period_secs,
        key_manager_config.txn_expiration_secs,
        key_manager_config.chain_id,
    );

    info!(LogSchema::new(LogEntry::Initialized)
        .event(LogEvent::Success)
        .json_rpc_endpoint(&json_rpc_endpoint));

    key_manager.execute()
}
<|endoftext|>