<commit_before><commit_msg>threadshare: Add test for queue<commit_after>// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
// Boston, MA 02110-1335, USA.

extern crate glib;
use glib::prelude::*;

extern crate gstreamer as gst;
use gst::prelude::*;

use std::sync::{Arc, Mutex};

fn init() {
    use std::sync::{Once, ONCE_INIT};
    static INIT: Once = ONCE_INIT;

    INIT.call_once(|| {
        gst::init().unwrap();

        #[cfg(debug_assertions)]
        {
            use std::path::Path;

            let mut path = Path::new("target/debug");
            if !path.exists() {
                path = Path::new("../target/debug");
            }

            gst::Registry::get().scan_path(path);
        }
        #[cfg(not(debug_assertions))]
        {
            use std::path::Path;

            let mut path = Path::new("target/release");
            if !path.exists() {
                path = Path::new("../target/release");
            }

            gst::Registry::get().scan_path(path);
        }
    });
}

fn test_push(n_threads: i32) {
    init();

    let pipeline = gst::Pipeline::new(None);
    let fakesrc = gst::ElementFactory::make("fakesrc", None).unwrap();
    let queue = gst::ElementFactory::make("ts-queue", None).unwrap();
    let appsink = gst::ElementFactory::make("appsink", None).unwrap();

    pipeline.add_many(&[&fakesrc, &queue, &appsink]).unwrap();
    fakesrc.link(&queue).unwrap();
    queue.link(&appsink).unwrap();

    fakesrc.set_property("num-buffers", &3i32).unwrap();
    queue.set_property("context-threads", &n_threads).unwrap();

    appsink.set_property("emit-signals", &true).unwrap();

    let samples = Arc::new(Mutex::new(Vec::new()));

    let samples_clone = samples.clone();
    appsink
        .connect("new-sample", true, move |args| {
            let appsink = args[0].get::<gst::Element>().unwrap();

            let sample = appsink
                .emit("pull-sample", &[])
                .unwrap()
                .unwrap()
                .get::<gst::Sample>()
                .unwrap();

            samples_clone.lock().unwrap().push(sample);

            Some(gst::FlowReturn::Ok.to_value())
        })
        .unwrap();

    pipeline
        .set_state(gst::State::Playing)
        .into_result()
        .unwrap();

    let mut eos = false;
    let bus = pipeline.get_bus().unwrap();
    while let Some(msg) = bus.timed_pop(5 * gst::SECOND) {
        use gst::MessageView;
        match msg.view() {
            MessageView::Eos(..) => {
                eos = true;
                break;
            }
            MessageView::Error(..) => unreachable!(),
            _ => (),
        }
    }

    assert!(eos);
    let samples = samples.lock().unwrap();
    assert_eq!(samples.len(), 3);

    for sample in samples.iter() {
        assert!(sample.get_buffer().is_some());
    }

    pipeline.set_state(gst::State::Null).into_result().unwrap();
}

#[test]
fn test_push_single_threaded() {
    test_push(-1);
}

#[test]
fn test_push_multi_threaded() {
    test_push(2);
}
<|endoftext|>


<commit_before><commit_msg>work!<commit_after><|endoftext|>


<commit_before><commit_msg>Make code more idomatic<commit_after><|endoftext|>


<commit_before><commit_msg>Added SQL Trait file<commit_after>//! A rather simplistic SQL Trait.
//! TODO: Make this a bit more sophisticated

trait SQL<K,V>
<|endoftext|>


<commit_before><commit_msg>type not required<commit_after><|endoftext|>


<commit_before>use common::memory::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct Extent {
    pub block: u64,
    pub length: u64
}

#[repr(packed)]
pub struct Header {
    pub signature: [u8; 8],
    pub version: u32,
    pub name: [u8; 244],
    pub extents: [Extent; 16]
}

#[repr(packed)]
pub struct Node {
    pub name: [u8; 256],
    pub extents: [Extent; 16]
}

impl Clone for Node {
    fn clone(&self) -> Node {
        return Node {
            name: self.name,
            extents: self.extents
        };
    }
}

pub struct FileSystem {
    pub disk: Disk,
    pub header: Header,
    pub nodes: Vec<Node>
}

impl FileSystem {
    pub fn from_disk(disk: Disk) -> FileSystem {
        unsafe {
            let header_ptr: *const Header = alloc_type();
            disk.read(1, 1, header_ptr as usize);
            let header = ptr::read(header_ptr);
            unalloc(header_ptr as usize);

            let mut nodes = Vec::new();
            let node_ptr: *const Node = alloc_type();
            for extent in &header.extents {
                if extent.block > 0 {
                    for node_address in extent.block..extent.block + (extent.length + 511)/512 {
                        disk.read(node_address, 1, node_ptr as usize);
                        nodes.push(ptr::read(node_ptr));
                    }
                }
            }
            unalloc(node_ptr as usize);

            return FileSystem {
                disk:disk,
                header: header,
                nodes: nodes
            };
        }
    }

    pub fn valid(&self) -> bool {
        return self.header.signature[0] == 'R' as u8
            && self.header.signature[1] == 'E' as u8
            && self.header.signature[2] == 'D' as u8
            && self.header.signature[3] == 'O' as u8
            && self.header.signature[4] == 'X' as u8
            && self.header.signature[5] == 'F' as u8
            && self.header.signature[6] == 'S' as u8
            && self.header.signature[7] == '\0' as u8
            && self.header.version == 0xFFFFFFFF;
    }

    pub fn node(&self, filename: &String) -> Option<Node> {
        for node in self.nodes.iter() {
            if String::from_c_slice(&node.name) == *filename {
                return Option::Some(node.clone());
            }
        }

        return Option::None;
    }

    pub fn list(&self, directory: &String) -> Vec<String> {
        let mut ret = Vec::<String>::new();

        for node in self.nodes.iter() {
            let node_name = String::from_c_slice(&node.name);
            if node_name.starts_with(directory.clone()) {
                ret.push(node_name.substr(directory.len(), node_name.len() - directory.len()));
            }
        }

        return ret;
    }
}

pub struct FileResource {
    pub disk: Disk,
    pub node: Node,
    pub vec: Vec<u8>,
    pub seek: usize
}

impl Resource for FileResource {
    fn url(&self) -> URL {
        return URL::from_string(&String::from_c_slice(&self.node.name));
    }

    fn stat(&self) -> ResourceType {
        return ResourceType::File;
    }

    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            match self.vec.get(self.seek) {
                Option::Some(b) => buf[i] = *b,
                Option::None => ()
            }
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            self.vec.set(self.seek, buf[i]);
            self.seek += 1;
            i += 1;
        }
        while i < buf.len() {
            self.vec.push(buf[i]);
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn seek(&mut self, pos: ResourceSeek) -> Option<usize> {
        match pos {
            ResourceSeek::Start(offset) => self.seek = offset,
            ResourceSeek::Current(offset) => self.seek = max(0, self.seek as isize + offset) as usize,
            ResourceSeek::End(offset) => self.seek = max(0, self.vec.len() as isize + offset) as usize
        }
        while self.vec.len() < self.seek {
            self.vec.push(0);
        }
        return Option::Some(self.seek);
    }

    // TODO: Check to make sure proper amount of bytes written. See Disk::write
    fn flush(&mut self) -> bool {
        let mut pos: u64 = 0;
        for extent in &self.node.extents {
            //Make sure it is a valid extent
            if extent.block > 0 && extent.length > 0 {
                unsafe {
                    let mem_to_write = self.vec.as_ptr().offset(pos as isize) as usize;
                    //TODO: Make sure mem_to_write is copied safely into an zeroed area of the right size!
                    let bytes_written = self.disk.write(extent.block,
                                //Warning, not obvious, but extent.length is in bytes and count is in 512 byte sectors
                                ((extent.length + 511)/512) as u16,
                                mem_to_write as usize);
                }
                pos += extent.length;
            }
        }
        return true;
    }
}

pub struct FileScheme {
    pub fs: FileSystem
}

impl SessionItem for FileScheme {
    fn scheme(&self) -> String {
        return "file".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource>{
        let path = url.path();
        if path.len() == 0 || path.ends_with("/".to_string()) {
            let mut list = String::new();
            let mut dirs: Vec<String> = Vec::new();

            for file in self.fs.list(&path).iter() {
                let line;
                match file.find("/".to_string()) {
                    Option::Some(index) => {
                        let dirname = file.substr(0, index + 1);
                        let mut found = false;
                        for dir in dirs.iter() {
                            if dirname == *dir {
                                found = true;
                                break;
                            }
                        }
                        if found {
                            line = String::new();
                        } else {
                            line = dirname.clone();
                            dirs.push(dirname);
                        }
                    },
                    Option::None => line = file.clone()
                }
                if line.len() > 0 {
                    if list.len() > 0 {
                        list = list + '\n' + line;
                    } else {
                        list = line;
                    }
                }
            }

            return box VecResource::new(url.clone(), ResourceType::Dir, list.to_utf8());
        } else {
            match self.fs.node(&path) {
                Option::Some(node) => {
                    let mut vec: Vec<u8> = Vec::new();
                    if node.extents[0].block > 0 && node.extents[0].length > 0 {
                        unsafe {
                            let data = alloc(node.extents[0].length as usize);
                            if data > 0 {
                                let reenable = start_no_ints();

                                self.fs.disk.read(node.extents[0].block, ((node.extents[0].length + 511)/512) as u16, data);

                                end_no_ints(reenable);

                                vec = Vec {
                                    data: data as *mut u8,
                                    length: node.extents[0].length as usize
                                };
                            }
                        }
                    }

                    return box FileResource {
                        disk: self.fs.disk,
                        node: node,
                        vec: vec,
                        seek: 0
                    };
                },
                Option::None => {
                    /*
                    d("Creating ");
                    path.d();
                    dl();

                    let mut name = [0; 256];
                    for i in 0..256 {
                        //TODO: UTF8
                        let b = path[i] as u8;
                        name[i] = b;
                        if b == 0 {
                            break;
                        }
                    }

                    let node = Node {
                        name: name,
                        extents: [Extent { block: 0, length: 0 }; 16]
                    };

                    //TODO: Sync to disk
                    let mut node_i = 0;
                    while node_i < self.fs.nodes.len() {
                        let mut cmp = 0;

                        if let Option::Some(other_node) = self.fs.nodes.get(node_i) {
                            for i in 0..256 {
                                if other_node.name[i] != node.name[i] {
                                    cmp = other_node.name[i] as isize - node.name[i] as isize;
                                    break;
                                }
                            }
                        }

                        if cmp >= 0 {
                            break;
                        }

                        node_i += 1;
                    }
                    d("Insert at ");
                    dd(node_i);
                    dl();
                    self.fs.nodes.insert(node_i, node.clone());

                    return box FileResource {
                        node: node,
                        vec: Vec::new(),
                        seek: 0
                    };
                    */
                    return box NoneResource;
                }
            }
        }
    }
}
<commit_msg>Add todo for reallocation<commit_after>use common::memory::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct Extent {
    pub block: u64,
    pub length: u64
}

#[repr(packed)]
pub struct Header {
    pub signature: [u8; 8],
    pub version: u32,
    pub name: [u8; 244],
    pub extents: [Extent; 16]
}

#[repr(packed)]
pub struct Node {
    pub name: [u8; 256],
    pub extents: [Extent; 16]
}

impl Clone for Node {
    fn clone(&self) -> Node {
        return Node {
            name: self.name,
            extents: self.extents
        };
    }
}

pub struct FileSystem {
    pub disk: Disk,
    pub header: Header,
    pub nodes: Vec<Node>
}

impl FileSystem {
    pub fn from_disk(disk: Disk) -> FileSystem {
        unsafe {
            let header_ptr: *const Header = alloc_type();
            disk.read(1, 1, header_ptr as usize);
            let header = ptr::read(header_ptr);
            unalloc(header_ptr as usize);

            let mut nodes = Vec::new();
            let node_ptr: *const Node = alloc_type();
            for extent in &header.extents {
                if extent.block > 0 {
                    for node_address in extent.block..extent.block + (extent.length + 511)/512 {
                        disk.read(node_address, 1, node_ptr as usize);
                        nodes.push(ptr::read(node_ptr));
                    }
                }
            }
            unalloc(node_ptr as usize);

            return FileSystem {
                disk:disk,
                header: header,
                nodes: nodes
            };
        }
    }

    pub fn valid(&self) -> bool {
        return self.header.signature[0] == 'R' as u8
            && self.header.signature[1] == 'E' as u8
            && self.header.signature[2] == 'D' as u8
            && self.header.signature[3] == 'O' as u8
            && self.header.signature[4] == 'X' as u8
            && self.header.signature[5] == 'F' as u8
            && self.header.signature[6] == 'S' as u8
            && self.header.signature[7] == '\0' as u8
            && self.header.version == 0xFFFFFFFF;
    }

    pub fn node(&self, filename: &String) -> Option<Node> {
        for node in self.nodes.iter() {
            if String::from_c_slice(&node.name) == *filename {
                return Option::Some(node.clone());
            }
        }

        return Option::None;
    }

    pub fn list(&self, directory: &String) -> Vec<String> {
        let mut ret = Vec::<String>::new();

        for node in self.nodes.iter() {
            let node_name = String::from_c_slice(&node.name);
            if node_name.starts_with(directory.clone()) {
                ret.push(node_name.substr(directory.len(), node_name.len() - directory.len()));
            }
        }

        return ret;
    }
}

pub struct FileResource {
    pub disk: Disk,
    pub node: Node,
    pub vec: Vec<u8>,
    pub seek: usize
}

impl Resource for FileResource {
    fn url(&self) -> URL {
        return URL::from_string(&String::from_c_slice(&self.node.name));
    }

    fn stat(&self) -> ResourceType {
        return ResourceType::File;
    }

    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            match self.vec.get(self.seek) {
                Option::Some(b) => buf[i] = *b,
                Option::None => ()
            }
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            self.vec.set(self.seek, buf[i]);
            self.seek += 1;
            i += 1;
        }
        while i < buf.len() {
            self.vec.push(buf[i]);
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn seek(&mut self, pos: ResourceSeek) -> Option<usize> {
        match pos {
            ResourceSeek::Start(offset) => self.seek = offset,
            ResourceSeek::Current(offset) => self.seek = max(0, self.seek as isize + offset) as usize,
            ResourceSeek::End(offset) => self.seek = max(0, self.vec.len() as isize + offset) as usize
        }
        while self.vec.len() < self.seek {
            self.vec.push(0);
        }
        return Option::Some(self.seek);
    }

    // TODO: Check to make sure proper amount of bytes written. See Disk::write
    // TODO: Allow reallocation
    fn flush(&mut self) -> bool {
        let mut pos: u64 = 0;
        for extent in &self.node.extents {
            //Make sure it is a valid extent
            if extent.block > 0 && extent.length > 0 {
                unsafe {
                    let mem_to_write = self.vec.as_ptr().offset(pos as isize) as usize;
                    //TODO: Make sure mem_to_write is copied safely into an zeroed area of the right size!
                    let bytes_written = self.disk.write(extent.block,
                                //Warning, not obvious, but extent.length is in bytes and count is in 512 byte sectors
                                ((extent.length + 511)/512) as u16,
                                mem_to_write as usize);
                }
                pos += extent.length;
            }
        }
        return true;
    }
}

pub struct FileScheme {
    pub fs: FileSystem
}

impl SessionItem for FileScheme {
    fn scheme(&self) -> String {
        return "file".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource>{
        let path = url.path();
        if path.len() == 0 || path.ends_with("/".to_string()) {
            let mut list = String::new();
            let mut dirs: Vec<String> = Vec::new();

            for file in self.fs.list(&path).iter() {
                let line;
                match file.find("/".to_string()) {
                    Option::Some(index) => {
                        let dirname = file.substr(0, index + 1);
                        let mut found = false;
                        for dir in dirs.iter() {
                            if dirname == *dir {
                                found = true;
                                break;
                            }
                        }
                        if found {
                            line = String::new();
                        } else {
                            line = dirname.clone();
                            dirs.push(dirname);
                        }
                    },
                    Option::None => line = file.clone()
                }
                if line.len() > 0 {
                    if list.len() > 0 {
                        list = list + '\n' + line;
                    } else {
                        list = line;
                    }
                }
            }

            return box VecResource::new(url.clone(), ResourceType::Dir, list.to_utf8());
        } else {
            match self.fs.node(&path) {
                Option::Some(node) => {
                    let mut vec: Vec<u8> = Vec::new();
                    if node.extents[0].block > 0 && node.extents[0].length > 0 {
                        unsafe {
                            let data = alloc(node.extents[0].length as usize);
                            if data > 0 {
                                let reenable = start_no_ints();

                                self.fs.disk.read(node.extents[0].block, ((node.extents[0].length + 511)/512) as u16, data);

                                end_no_ints(reenable);

                                vec = Vec {
                                    data: data as *mut u8,
                                    length: node.extents[0].length as usize
                                };
                            }
                        }
                    }

                    return box FileResource {
                        disk: self.fs.disk,
                        node: node,
                        vec: vec,
                        seek: 0
                    };
                },
                Option::None => {
                    /*
                    d("Creating ");
                    path.d();
                    dl();

                    let mut name = [0; 256];
                    for i in 0..256 {
                        //TODO: UTF8
                        let b = path[i] as u8;
                        name[i] = b;
                        if b == 0 {
                            break;
                        }
                    }

                    let node = Node {
                        name: name,
                        extents: [Extent { block: 0, length: 0 }; 16]
                    };

                    //TODO: Sync to disk
                    let mut node_i = 0;
                    while node_i < self.fs.nodes.len() {
                        let mut cmp = 0;

                        if let Option::Some(other_node) = self.fs.nodes.get(node_i) {
                            for i in 0..256 {
                                if other_node.name[i] != node.name[i] {
                                    cmp = other_node.name[i] as isize - node.name[i] as isize;
                                    break;
                                }
                            }
                        }

                        if cmp >= 0 {
                            break;
                        }

                        node_i += 1;
                    }
                    d("Insert at ");
                    dd(node_i);
                    dl();
                    self.fs.nodes.insert(node_i, node.clone());

                    return box FileResource {
                        node: node,
                        vec: Vec::new(),
                        seek: 0
                    };
                    */
                    return box NoneResource;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Extra docstrings<commit_after><|endoftext|>


<commit_before><commit_msg>Challenge 3 complete<commit_after>fn hex2nibble(hex : u8) -> Result<u8, ()> {
    match hex {
        0x30u8 ... 0x39u8 => Ok(hex - 0x30u8),
        0x41u8 ... 0x46u8 | 0x61u8 ... 0x66u8 => Ok((hex & !0x20u8) - 0x37),
        _ => Err(()),
    }
}

fn hex2octets(hex: &Vec<u8>) -> Vec<u8> {
    let mut octets : Vec<u8> = Vec::with_capacity(&hex.len() / 2 + &hex.len() % 2);
    if hex.len() % 2 == 1 {
        octets.push(hex2nibble(hex[0]).unwrap())
    }
    for octet in hex[&hex.len() % 2 ..].chunks(2) {
        octets.push((hex2nibble(octet[0]).unwrap() << 4) + hex2nibble(octet[1]).unwrap());
    }
    octets
}

fn nibble2hex(nibble : u8) -> Result<u8, ()> {
    match nibble {
        0u8 ... 9u8 => Ok(nibble + 0x30u8),
        10u8 ... 15u8 => Ok(nibble + 0x57u8),
        _ => Err(()),
    }
}

fn octets2hex(octets: Vec<u8>) -> Vec<u8> {
    let mut hex : Vec<u8> = Vec::with_capacity(octets.len() * 2);
    for octet in octets {
        hex.push(nibble2hex((octet & 0xF0u8) >> 4).unwrap());
        hex.push(nibble2hex(octet & 0x0Fu8).unwrap());
    }
    hex
}

fn fixed_xor(left: &Vec<u8>, right: &Vec<u8>) -> Vec<u8> {
    assert!(left.len() == right.len());
    let left_octets = hex2octets(left);
    let right_octets = hex2octets(right);
    let mut xor : Vec<u8> = Vec::with_capacity(left_octets.len());
    for i in 0 .. xor.capacity() {
        xor.push(left_octets[i] ^ right_octets[i])
    }
    xor
}

fn main() {
    let letter_frequencies = vec![0.08167f32, 0.01492f32, 0.02782f32, 0.04253f32, 0.12702f32, 0.02228f32, 0.02015f32, 0.06094f32, 0.06966f32, 0.00153f32, 0.00772f32, 0.04025f32, 0.02406f32, 0.06749f32, 0.07507f32, 0.01929f32, 0.00095f32, 0.05987f32, 0.06327f32, 0.09056f32, 0.02758f32, 0.00978f32, 0.02361f32, 0.00150f32, 0.01974f32, 0.00074f32];
    assert!(letter_frequencies.len() == 26);

    let mut xor_character = 0u8;
    let mut xor_delta = std::f32::INFINITY;

    let input = String::from("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736").into_bytes();
    for c in 0u8 .. 127u8 {
        println!("Character: {}", c);
        let mut pattern : Vec<u8> =  Vec::with_capacity(input.len());
        for _ in 0 .. input.len() / 2 {
            pattern.push(c)
        }
        let output = fixed_xor(&input, &octets2hex(pattern));

        let mut letter_count : Vec<f32> = Vec::with_capacity(letter_frequencies.len());
        for _ in 0 .. letter_frequencies.len() {
            letter_count.push(0f32);
        }
        let mut nonletter_count = 0f32;
        for octet in &output {
            match *octet {
                0x41u8 ... 0x5Au8 | 0x61u8 ... 0x7Au8 => { letter_count[((octet | 0x20u8) - 0x61u8) as usize] += 1f32; },
                _ => { nonletter_count += 1f32; },
            }
        }

        let mut cumulative_delta = 0f32;
        for i in 0 .. letter_frequencies.len() {
            cumulative_delta += (letter_frequencies[i] - (letter_count[i] / output.len() as f32)).abs();
        }
        cumulative_delta /= ((output.len() as f32 - nonletter_count) / output.len() as f32);
        if cumulative_delta < xor_delta {
            xor_character = c;
            xor_delta = cumulative_delta;
        }
        println!("Delta: {}", cumulative_delta);
        println!("String: {}", String::from_utf8(output).unwrap());
        println!("");
    }

    let mut pattern : Vec<u8> =  Vec::with_capacity(input.len());
    for _ in 0 .. input.len() / 2 {
        pattern.push(xor_character)
    }
    let output = fixed_xor(&input, &octets2hex(pattern));
    println!("Character: {}", xor_character);
    println!("Delta: {}", xor_delta);
    println!("String: {}", String::from_utf8(output).unwrap());
}

#[cfg(test)]
mod tests {

    #[test]
    fn test_octets2hex() {
        let hex = ::octets2hex(vec![10u8]);
        assert!(hex.len() == 2);
        println!("{}, {}", hex[0], hex[1]);
        assert!(::octets2hex(vec![10u8]) == vec!['0' as u8, 'a' as u8]);
    }
}<|endoftext|>


<commit_before>use alloc::boxed::Box;

use collections::slice;
use collections::string::ToString;
use collections::vec::Vec;
use collections::vec_deque::VecDeque;

use core::ptr;

use common::{debug, memory};

use drivers::pciconfig::PciConfig;
use drivers::pio::*;

use network::common::*;
use network::scheme::*;

use schemes::{Result, KScheme, Resource, Url};

use sync::Intex;

#[repr(packed)]
struct Txd {
    pub address_port: u16,
    pub status_port: u16,
    pub buffer: usize,
}

pub struct Rtl8139 {
    pci: PciConfig,
    base: usize,
    memory_mapped: bool,
    irq: u8,
    resources: Intex<Vec<*mut NetworkResource>>,
    inbound: VecDeque<Vec<u8>>,
    outbound: VecDeque<Vec<u8>>,
    txds: Vec<Txd>,
    txd_i: usize,
}

impl Rtl8139 {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let base = unsafe { pci.read(0x10) as usize };
        let irq = unsafe { pci.read(0x3C) as u8 & 0xF };

        let mut module = box Rtl8139 {
            pci: pci,
            base: base & 0xFFFFFFF0,
            memory_mapped: base & 1 == 0,
            irq: irq,
            resources: Intex::new(Vec::new()),
            inbound: VecDeque::new(),
            outbound: VecDeque::new(),
            txds: Vec::new(),
            txd_i: 0,
        };

        unsafe { module.init() };

        module
    }

    unsafe fn init(&mut self) {
        debug::d("RTL8139 on: ");
        debug::dh(self.base);
        if self.memory_mapped {
            debug::d(" memory mapped");
        } else {
            debug::d(" port mapped");
        }
        debug::d(" IRQ: ");
        debug::dbh(self.irq);

        self.pci.flag(4, 4, true); // Bus mastering

        let base = self.base as u16;

        outb(base + 0x52, 0);

        outb(base + 0x37, 0x10);
        while inb(base + 0x37) & 0x10 != 0 {}

        debug::d(" MAC: ");
        let mac_low = ind(base);
        let mac_high = ind(base + 4);
        MAC_ADDR = MacAddr {
            bytes: [mac_low as u8,
                    (mac_low >> 8) as u8,
                    (mac_low >> 16) as u8,
                    (mac_low >> 24) as u8,
                    mac_high as u8,
                    (mac_high >> 8) as u8],
        };
        debug::d(&MAC_ADDR.to_string());

        let receive_buffer = memory::alloc(10240);
        outd(base + 0x30, receive_buffer as u32);

        for i in 0..4 {
            self.txds.push(Txd {
                address_port: base + 0x20 + (i as u16) * 4,
                status_port: base + 0x10 + (i as u16) * 4,
                buffer: memory::alloc(4096),
            });
        }

        outw(base + 0x3C, 5);
        debug::d(" IMR: ");
        debug::dh(inw(base + 0x3C) as usize);

        outb(base + 0x37, 0xC);
        debug::d(" CMD: ");
        debug::dbh(inb(base + 0x37));

        outd(base + 0x44,
             (1 << 7) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1));
        debug::d(" RCR: ");
        debug::dh(ind(base + 0x44) as usize);

        outd(base + 0x40, (0b11 << 24));
        debug::d(" TCR: ");
        debug::dh(ind(base + 0x40) as usize);

        debug::dl();
    }

    unsafe fn receive_inbound(&mut self) {
        let base = self.base as u16;

        let receive_buffer = ind(base + 0x30) as usize;
        let mut capr = (inw(base + 0x38) + 16) as usize;
        let cbr = inw(base + 0x3A) as usize;

        while capr != cbr {
            let frame_addr = receive_buffer + capr + 4;
            let frame_status = ptr::read((receive_buffer + capr) as *const u16) as usize;
            let frame_len = ptr::read((receive_buffer + capr + 2) as *const u16) as usize;

            debug::d("Recv ");
            debug::dh(capr as usize);
            debug::d(" ");
            debug::dh(frame_status);
            debug::d(" ");
            debug::dh(frame_addr);
            debug::d(" ");
            debug::dh(frame_len);
            debug::dl();

            self.inbound
                .push_back(Vec::from(slice::from_raw_parts(frame_addr as *const u8,
                                                           frame_len - 4)));

            capr = capr + frame_len + 4;
            capr = (capr + 3) & (0xFFFFFFFF - 3);
            if capr >= 8192 {
                capr -= 8192
            }

            outw(base + 0x38, (capr as u16) - 16);
        }
    }

    unsafe fn send_outbound(&mut self) {
        while let Some(bytes) = self.outbound.pop_front() {
            if let Some(txd) = self.txds.get(self.txd_i) {
                if bytes.len() < 4096 {
                    let mut tx_status;
                    loop {
                        tx_status = ind(txd.status_port);
                        if tx_status & (1 << 13) == (1 << 13) {
                            break;
                        }
                    }

                    debug::d("Send ");
                    debug::dh(txd.status_port as usize);
                    debug::d(" ");
                    debug::dh(tx_status as usize);
                    debug::d(" ");
                    debug::dh(txd.buffer);
                    debug::d(" ");
                    debug::dh(bytes.len() & 0xFFF);
                    debug::dl();

                    ::memcpy(txd.buffer as *mut u8, bytes.as_ptr(), bytes.len());

                    outd(txd.address_port, txd.buffer as u32);
                    outd(txd.status_port, bytes.len() as u32 & 0xFFF);

                    self.txd_i = (self.txd_i + 1) % 4;
                } else {
                    debug::dl();
                    debug::d("RTL8139: Frame too long for transmit: ");
                    debug::dd(bytes.len());
                    debug::dl();
                }
            } else {
                debug::d("RTL8139: TXD Overflow!\n");
                self.txd_i = 0;
            }
        }
    }
}

impl KScheme for Rtl8139 {
    fn scheme(&self) -> &str {
        "network"
    }

    fn open(&mut self, _: &Url, _: usize) -> Result<Box<Resource>> {
        Ok(NetworkResource::new(self))
    }

    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            unsafe {
                let base = self.base as u16;

                let isr = inw(base + 0x3E);
                outw(base + 0x3E, isr);

                // dh(isr as usize);
                // dl();
            }

            self.sync();
        }
    }

    fn on_poll(&mut self) {
        self.sync();
    }
}

impl NetworkScheme for Rtl8139 {
    fn add(&mut self, resource: *mut NetworkResource) {
        self.resources.lock().push(resource);
    }

    fn remove(&mut self, resource: *mut NetworkResource) {
        let mut resources = self.resources.lock();

        let mut i = 0;
        while i < resources.len() {
            let mut remove = false;

            match resources.get(i) {
                Some(ptr) => if *ptr == resource {
                    remove = true;
                } else {
                    i += 1;
                },
                None => break,
            }

            if remove {
                resources.remove(i);
            }
        }
    }

    fn sync(&mut self) {
        unsafe {
            {
                let resources = self.resources.lock();

                for resource in resources.iter() {
                    while let Some(bytes) = (**resource).outbound.lock().pop_front() {
                        self.outbound.push_back(bytes);
                    }
                }
            }

            self.send_outbound();

            self.receive_inbound();

            {
                let resources = self.resources.lock();

                while let Some(bytes) = self.inbound.pop_front() {
                    for resource in resources.iter() {
                        (**resource).inbound.lock().push_back(bytes.clone());
                    }
                }
            }
        }
    }
}
<commit_msg>rtl8139: remove magic numbers<commit_after>use alloc::boxed::Box;

use collections::slice;
use collections::string::ToString;
use collections::vec::Vec;
use collections::vec_deque::VecDeque;

use core::ptr;

use common::{debug, memory};

use drivers::pciconfig::PciConfig;
use drivers::pio::*;
use drivers::mmio::Mmio;

use network::common::*;
use network::scheme::*;

use schemes::{Result, KScheme, Resource, Url};

use sync::Intex;

const RTL8139_TSR_OWN: u32 = 1 << 13;

const RTL8139_CR_RST: u8 = 1 << 4;
const RTL8139_CR_RE: u8 = 1 << 3;
const RTL8139_CR_TE: u8 = 1 << 2;
const RTL8139_CR_BUFE: u8 = 1 << 0;

const RTL8139_ISR_SERR: u16 = 1 << 15;
const RTL8139_ISR_TIMEOUT: u16 = 1 << 14;
const RTL8139_ISR_LENCHG: u16 = 1 << 13;
const RTL8139_ISR_FOVW: u16 = 1 << 6;
const RTL8139_ISR_PUN_LINKCHG: u16 = 1 << 5;
const RTL8139_ISR_RXOVW: u16 = 1 << 4;
const RTL8139_ISR_TER: u16 = 1 << 3;
const RTL8139_ISR_TOK: u16 = 1 << 2;
const RTL8139_ISR_RER: u16 = 1 << 1;
const RTL8139_ISR_ROK: u16 = 1 << 0;

const RTL8139_TCR_IFG: u32 = 0b11 << 24;

const RTL8139_RCR_WRAP: u32 = 1 << 7;
const RTL8139_RCR_AR: u32 = 1 << 4;
const RTL8139_RCR_AB: u32 = 1 << 3;
const RTL8139_RCR_AM: u32 = 1 << 2;
const RTL8139_RCR_APM: u32 = 1 << 1;

#[repr(packed)]
struct Txd {
    pub address_port: Pio32,
    pub status_port: Pio32,
    pub buffer: usize,
}

pub struct Rtl8139Port {
    pub idr: [Pio8; 6],
    pub rbstart: Pio32,
    pub cr: Pio8,
    pub capr: Pio16,
    pub cbr: Pio16,
    pub imr: Pio16,
    pub isr: Pio16,
    pub tcr: Pio32,
    pub rcr: Pio32,
    pub config1: Pio8,
}

impl Rtl8139Port {
    pub fn new(base: u16) -> Self {
        return Rtl8139Port {
            idr: [Pio8::new(base + 0x00),
                  Pio8::new(base + 0x01),
                  Pio8::new(base + 0x02),
                  Pio8::new(base + 0x03),
                  Pio8::new(base + 0x04),
                  Pio8::new(base + 0x05)],
            rbstart: Pio32::new(base + 0x30),
            cr: Pio8::new(base + 0x37),
            capr: Pio16::new(base + 0x38),
            cbr: Pio16::new(base + 0x3A),
            imr: Pio16::new(base + 0x3C),
            isr: Pio16::new(base + 0x3E),
            tcr: Pio32::new(base + 0x40),
            rcr: Pio32::new(base + 0x44),
            config1: Pio8::new(base + 0x52),
        };
    }
}

pub struct Rtl8139 {
    pci: PciConfig,
    base: usize,
    memory_mapped: bool,
    irq: u8,
    resources: Intex<Vec<*mut NetworkResource>>,
    inbound: VecDeque<Vec<u8>>,
    outbound: VecDeque<Vec<u8>>,
    txds: Vec<Txd>,
    txd_i: usize,
    port: Rtl8139Port,
}

impl Rtl8139 {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let pci_id = unsafe { pci.read(0x00) };
        let revision = (unsafe { pci.read(0x08) } & 0xFF) as u8;
        if pci_id == 0x813910EC && revision < 0x20 {
            debug::d("Not an 8139C+ compatible chip")
        }

        let base = unsafe { pci.read(0x10) as usize };
        let irq = unsafe { pci.read(0x3C) as u8 & 0xF };

        let mut module = box Rtl8139 {
            pci: pci,
            base: base & 0xFFFFFFF0,
            memory_mapped: base & 1 == 0,
            irq: irq,
            resources: Intex::new(Vec::new()),
            inbound: VecDeque::new(),
            outbound: VecDeque::new(),
            txds: Vec::new(),
            txd_i: 0,
            port: Rtl8139Port::new((base & 0xFFFFFFF0) as u16),
        };

        unsafe { module.init() };

        module
    }

    unsafe fn init(&mut self) {
        debug::d("RTL8139 on: ");
        debug::dh(self.base);
        if self.memory_mapped {
            debug::d(" memory mapped");
        } else {
            debug::d(" port mapped");
        }
        debug::d(" IRQ: ");
        debug::dbh(self.irq);

        self.pci.flag(4, 4, true); // Bus mastering

        let base = self.base as u16;

        self.port.config1.write(0);
        self.port.cr.write(RTL8139_CR_RST);
        while self.port.cr.read() & RTL8139_CR_RST != 0 {}

        debug::d(" MAC: ");
        MAC_ADDR = MacAddr {
            bytes: [self.port.idr[0].read(),
                    self.port.idr[1].read(),
                    self.port.idr[2].read(),
                    self.port.idr[3].read(),
                    self.port.idr[4].read(),
                    self.port.idr[5].read()],
        };
        debug::d(&MAC_ADDR.to_string());

        let receive_buffer = memory::alloc(10240);
        self.port.rbstart.write(receive_buffer as u32);

        for i in 0..4 {
            self.txds.push(Txd {
                address_port: Pio32::new(base + 0x20 + (i as u16) * 4),
                status_port: Pio32::new(base + 0x10 + (i as u16) * 4),
                buffer: memory::alloc(4096),
            });
        }

        self.port.imr.write(RTL8139_ISR_TOK | RTL8139_ISR_ROK);
        debug::d(" IMR: ");
        debug::dh(self.port.imr.read() as usize);

        self.port.cr.write(RTL8139_CR_RE | RTL8139_CR_TE);
        debug::d(" CMD: ");
        debug::dbh(self.port.cr.read());

        self.port.rcr.write(RTL8139_RCR_WRAP | RTL8139_RCR_AR | RTL8139_RCR_AB | RTL8139_RCR_AM |
                            RTL8139_RCR_APM);
        debug::d(" RCR: ");
        debug::dh(self.port.rcr.read() as usize);

        self.port.tcr.writef(RTL8139_TCR_IFG, true);
        debug::d(" TCR: ");
        debug::dh(self.port.tcr.read() as usize);

        debug::dl();
    }

    unsafe fn receive_inbound(&mut self) {
        let base = self.base as u16;

        let receive_buffer = self.port.rbstart.read() as usize;
        let mut capr = (self.port.capr.read() + 16) as usize;
        let cbr = self.port.cbr.read() as usize;

        while capr != cbr {
            let frame_addr = receive_buffer + capr + 4;
            let frame_status = ptr::read((receive_buffer + capr) as *const u16) as usize;
            let frame_len = ptr::read((receive_buffer + capr + 2) as *const u16) as usize;

            debug::d("Recv ");
            debug::dh(capr as usize);
            debug::d(" ");
            debug::dh(frame_status);
            debug::d(" ");
            debug::dh(frame_addr);
            debug::d(" ");
            debug::dh(frame_len);
            debug::dl();

            self.inbound
                .push_back(Vec::from(slice::from_raw_parts(frame_addr as *const u8,
                                                           frame_len - 4)));

            capr = capr + frame_len + 4;
            capr = (capr + 3) & (0xFFFFFFFF - 3);
            if capr >= 8192 {
                capr -= 8192
            }

            self.port.capr.write((capr as u16) - 16);
        }
    }

    unsafe fn send_outbound(&mut self) {
        while let Some(bytes) = self.outbound.pop_front() {
            if let Some(ref mut txd) = self.txds.get_mut(self.txd_i) {
                if bytes.len() < 4096 {
                    while !txd.status_port.readf(RTL8139_TSR_OWN) {}

                    debug::d("Send ");
                    debug::dh(self.txd_i as usize);
                    debug::d(" ");
                    debug::dh(txd.status_port.read() as usize);
                    debug::d(" ");
                    debug::dh(txd.buffer);
                    debug::d(" ");
                    debug::dh(bytes.len() & 0xFFF);
                    debug::dl();

                    ::memcpy(txd.buffer as *mut u8, bytes.as_ptr(), bytes.len());

                    txd.address_port.write(txd.buffer as u32);
                    txd.status_port.write(bytes.len() as u32 & 0xFFF);

                    self.txd_i = (self.txd_i + 1) % 4;
                } else {
                    debug::dl();
                    debug::d("RTL8139: Frame too long for transmit: ");
                    debug::dd(bytes.len());
                    debug::dl();
                }
            } else {
                debug::d("RTL8139: TXD Overflow!\n");
                self.txd_i = 0;
            }
        }
    }
}

impl KScheme for Rtl8139 {
    fn scheme(&self) -> &str {
        "network"
    }

    fn open(&mut self, _: &Url, _: usize) -> Result<Box<Resource>> {
        Ok(NetworkResource::new(self))
    }

    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            unsafe {
                let isr = self.port.isr.read();
                self.port.isr.write(isr);

                // dh(isr as usize);
                // dl();
            }

            self.sync();
        }
    }

    fn on_poll(&mut self) {
        self.sync();
    }
}

impl NetworkScheme for Rtl8139 {
    fn add(&mut self, resource: *mut NetworkResource) {
        self.resources.lock().push(resource);
    }

    fn remove(&mut self, resource: *mut NetworkResource) {
        let mut resources = self.resources.lock();

        let mut i = 0;
        while i < resources.len() {
            let mut remove = false;

            match resources.get(i) {
                Some(ptr) => if *ptr == resource {
                    remove = true;
                } else {
                    i += 1;
                },
                None => break,
            }

            if remove {
                resources.remove(i);
            }
        }
    }

    fn sync(&mut self) {
        unsafe {
            {
                let resources = self.resources.lock();

                for resource in resources.iter() {
                    while let Some(bytes) = (**resource).outbound.lock().pop_front() {
                        self.outbound.push_back(bytes);
                    }
                }
            }

            self.send_outbound();

            self.receive_inbound();

            {
                let resources = self.resources.lock();

                while let Some(bytes) = self.inbound.pop_front() {
                    for resource in resources.iter() {
                        (**resource).inbound.lock().push_back(bytes.clone());
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>rust docs<commit_after>/// A human being is represented here
pub struct Person {
    /// A person must have a name, no matter how much Juliet may hate it
    name: String,
}

impl Person {
    /// Returns a person with the name given them
    ///
    /// # Arguments
    ///
    /// * `name` - A string slice that holds the name of the person
    ///
    /// # Example
    ///
    /// ```
    /// // You can have rust code between fences inside the comments
    /// // If you pass --test to Rustdoc, it will even test it for you!
    /// let person = Person::new("name");
    /// ```
    pub fn new(name: &str) -> Person {
        Person {
            name: name.to_string(),
        }
    }

    /// Gives a friendly hello!
    ///
    /// Says "Hello, [name]" to the `Person` it is called on.
    pub fn hello(& self) {
        println!("Hello, {}!", self.name);
    }
}

fn main() {
    let john = Person::new("John");
    john.hello();
}
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary function<commit_after><|endoftext|>


<commit_before><commit_msg>Create pi.rs<commit_after>extern crate mmap;

use std::fs::OpenOptions;
use std::os::unix::fs::OpenOptionsExt;
use mmap::{MemoryMap,MapOption};
use std::os::unix::prelude::AsRawFd;

const BCM2708_PERI_BASE: u32 = 0x20000000;
pub const GPIO_BASE: u8 = (BCM2708_PERI_BASE + 0x200000) as u8;
const O_SYNC: u32 = 1052672;
const MAP_SHARED: i32 = 0x0001;
const BLOCK_SIZE: usize = (4 * 1024);

#[allow(dead_code)]
pub struct Bcm2835Peripheral {
    pub addr_p: *const u8,
    pub mem_fd: ::std::fs::File,
    pub map: ::mmap::MemoryMap,
    pub addr: *mut u8
}

impl Bcm2835Peripheral {
    pub fn map_peripheral( & mut self) {
        self.mem_fd = OpenOptions::new()
            .read(true)
            .write(true)
            .mode(O_SYNC)
            .open("/dev/mem")
            .expect("unable to open /dev/mem, Are you root?");

        let map_opts = & [
            MapOption::MapNonStandardFlags(MAP_SHARED),
            MapOption::MapReadable,
            MapOption::MapWritable,
            // MapOption::MapAddr(self.addr_p),
            MapOption::MapFd(self.mem_fd.as_raw_fd())
        ];

        let mmap = match MemoryMap::new(BLOCK_SIZE, map_opts) {
            Ok(mmap) => mmap,
            Err(e) => panic!("ERR: {}", e)
        };
        self.map = mmap;
        self.addr = self.map.data();
    }

    pub fn unmap_peripheral(self) {
        drop(self);
    }

    pub unsafe fn in_gpio( & self, y: isize) {
        let k = & self.addr.offset(y / 10); **k &= !(7 << (((y) % 10) * 3));
    }

    pub unsafe fn out_gpio( & self, y: isize) {
        let k = & self.addr.offset(y / 10); **k |= (7 << (((y) % 10) * 3));
    }

    pub unsafe fn set_gpio_alt( & self, y: isize, a: u8) {
        let k = & self.addr.offset(y / 10); **k |= match a {
            a if a <= 3 => a + 4,
            4 => 3,
            _ => 2,
        } << ((y % 10) * 3);
    }

    pub unsafe fn set_gpio( & self, val: u8) {
        *self.addr.offset(7) = val;
    }
    pub unsafe fn clear_gpio( & self, val: u8) {
        *self.addr.offset(10) = val;
    }
}

impl Drop for Bcm2835Peripheral {
    fn drop( & mut self) {
        println!("Unmapped Peripheral {:?}", self.map.data())
    }
}
<|endoftext|>


<commit_before><commit_msg>Add rust code for isbn-verifier<commit_after>#![feature(ascii_ctype)]

pub fn is_valid_isbn(isbn: &str) -> bool {
    let mut iter = isbn.chars().peekable();

    if let Some(&c) = iter.peek() {
        if !c.is_ascii_digit() {
            return false;
        }
    }

    let mut index = 0;
    let mut sum = 0;
    let mut acc = 0;
    const X_POSTION: usize = 9;
    const MAX_LENGTH: usize = 10;

    while let Some(&c) = iter.peek() {
        match c {
            '-' => {
                iter.next();
            }
            _ if c.is_ascii_digit() => {
                index += 1;
                acc += c as usize - '0' as usize;
                sum += acc;

                iter.next();
            }
            'X' if index == X_POSTION => {
                index += 1;
                acc += 10;
                sum += acc;

                iter.next();
            }
            _ => return false,
        }

        if index > MAX_LENGTH {
            return false;
        }
    }

    sum % 11 == 0
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2433<commit_after>// https://leetcode.com/problems/find-the-original-array-of-prefix-xor/
pub fn find_array(pref: Vec<i32>) -> Vec<i32> {
    todo!()
}

fn main() {
    println!("{:?}", find_array(vec![5, 2, 0, 3, 1])); // [5,7,2,3,2]
    println!("{:?}", find_array(vec![13])); // [13]
}
<|endoftext|>


<commit_before><commit_msg>transition.rs<commit_after>use ggez::graphics::{DrawMode, Drawable, MeshBuilder, Point2};
use ggez::{graphics, timer, Context, GameResult};
use ggez_goodies::scene;
use std::time::Duration;

use crate::game::Game;
use crate::input::InputEvent;
use crate::scenes::FSceneSwitch;

#[derive(Debug)]
pub enum FadeStyle {
    In,
    Out,
}

pub struct Fade {
    pub start_time: Duration,
    pub duration: Duration,
    pub time_used: Duration,
    pub style: FadeStyle,
    done: bool,
    fade_start: u32,
    update_run: bool,
    ticks: u32,
}

impl scene::Scene<Game, InputEvent> for Fade {
    fn update(&mut self, game: &mut Game) -> FSceneSwitch {
        if !self.update_run {
            self.update_run = true;
        }
        if self.done {
                println!("transition done");
            scene::SceneSwitch::Pop
        } else {
            scene::SceneSwitch::None
        }
    }

    fn draw(&mut self, game: &mut Game, ctx: &mut Context) -> GameResult<()> {
        println!("draw transition");
        let time_since_start = timer::get_time_since_start(ctx);
        if self.update_run && self.ticks < self.fade_start {
            self.ticks += 1;
            self.start_time = time_since_start;
        }
        let time_passed = time_since_start - self.start_time;
        let time_passed = timer::duration_to_f64(time_passed);
        let alpha = match self.style {
            FadeStyle::In => {
                let mut alpha = 1.0 - time_passed / timer::duration_to_f64(self.duration);
                if alpha < 0.0 {
                    alpha = 0.0;
                }
                alpha
            }
            FadeStyle::Out => {
                let mut alpha = time_passed / timer::duration_to_f64(self.duration);
                // if alpha < 1.0 {
                //     alpha = 1.0;
                // }
                alpha
            }
        };
        graphics::set_color(ctx, graphics::Color::new(0.0, 0.0, 0.0, alpha as f32))?;
        graphics::rectangle(
            ctx,
            DrawMode::Fill,
            graphics::Rect {
                x: 0.0,
                y: 0.0,
                w: 320.0 * 3.0,
                h: 200.0 * 3.0,
            },
        );
        graphics::set_color(ctx, graphics::Color::new(1.0, 1.0, 1.0, 1.0))?;
        if self.update_run && self.start_time + self.duration < timer::get_time_since_start(ctx) {
            self.done = true;
        }
        Ok(())
    }

    fn name(&self) -> &str {
        "Fade in"
    }

    fn input(&mut self, _gameworld: &mut Game, _event: InputEvent, _started: bool) {}

    fn draw_previous(&self) -> bool {
        true
    }
}

impl Fade {
    pub fn new(duration: u64, fade_start: u32, style: FadeStyle) -> Self {
        Fade {
            start_time: Duration::new(0, 0),
            duration: Duration::from_millis(duration),
            time_used: Duration::new(0, 0),
            style,
            done: false,
            fade_start: fade_start,
            update_run: false,
            ticks: 0,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add a run-pass test that used to fail<commit_after>// Copyright 2015 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.

#![feature(optin_builtin_traits)]

use std::marker::Send;

pub struct WaitToken;
impl !Send for WaitToken {}

pub struct Test<T>(T);
unsafe impl<T: 'static> Send for Test<T> {}

pub fn spawn<F>(_: F) -> () where F: FnOnce(), F: Send + 'static {}

fn main() {
    let wt = Test(WaitToken);
    spawn(move || {
        let x = wt;
        println!("Hello, World!");
    });
}
<|endoftext|>


<commit_before><commit_msg>Refactor(syncfile): remove a TODO, not worth it<commit_after><|endoftext|>


<commit_before><commit_msg>SyncFile: add decrypt_to_writer<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
use std::collections::HashMap;
use std::sync::Arc as Rc;

use error::{ProtoErrorKind, ProtoResult};

/// Encode DNS messages and resource record types.
pub struct BinEncoder<'a> {
    offset: u32,
    buffer: &'a mut Vec<u8>,
    // TODO, it would be cool to make this slices, but then the stored slice needs to live longer
    //  than the callee of store_pointer which isn't obvious right now.
    name_pointers: HashMap<Vec<Rc<String>>, u16>, // array of string, label, location in stream
    mode: EncodeMode,
    canonical_names: bool,
}

impl<'a> BinEncoder<'a> {
    /// Create a new encoder with the Vec to fill
    pub fn new(buf: &'a mut Vec<u8>) -> Self {
        Self::with_offset(buf, 0, EncodeMode::Normal)
    }

    /// Specify the mode for encoding
    ///
    /// # Arguments
    ///
    /// * `mode` - In Signing mode, it canonical forms of all data are encoded, otherwise format matches the source form
    pub fn with_mode(buf: &'a mut Vec<u8>, mode: EncodeMode) -> Self {
        Self::with_offset(buf, 0, mode)
    }

    /// Begins the encoder at the given offset
    ///
    /// This is used for pointers. If this encoder is starting at some point further in
    ///  the sequence of bytes, for the proper offset of the pointer, the offset accounts for that
    ///  by using the offset to add to the pointer location being written.
    ///
    /// # Arguments
    ///
    /// * `offset` - index at which to start writing into the buffer
    pub fn with_offset(buf: &'a mut Vec<u8>, offset: u32, mode: EncodeMode) -> Self {
        BinEncoder {
            offset: offset,
            buffer: buf,
            name_pointers: HashMap::new(),
            mode: mode,
            canonical_names: false,
        }
    }

    /// Returns a reference to the internal buffer
    pub fn into_bytes(self) -> &'a Vec<u8> {
        self.buffer
    }

    /// Returns the length of the buffer
    pub fn len(&self) -> usize {
        self.buffer.len()
    }

    /// Returns `true` if the buffer is empty
    pub fn is_empty(&self) -> bool {
        self.buffer.is_empty()
    }

    /// Returns the current offset into the buffer
    pub fn offset(&self) -> u32 {
        self.offset
    }

    /// Returns the current Encoding mode
    pub fn mode(&self) -> EncodeMode {
        self.mode
    }

    /// If set to true, then names will be written into the buffer in canonical form
    pub fn set_canonical_names(&mut self, canonical_names: bool) {
        self.canonical_names = canonical_names;
    }

    /// Returns true if then encoder is writing in canonical form
    pub fn is_canonical_names(&self) -> bool {
        self.canonical_names
    }

    /// Reserve specified length in the internal buffer
    pub fn reserve(&mut self, extra: usize) {
        self.buffer.reserve(extra);
    }

    /// Emit one byte into the buffer
    pub fn emit(&mut self, b: u8) -> ProtoResult<()> {
        self.offset += 1;
        self.buffer.push(b);
        Ok(())
    }

    /// Stores a label pointer to an already written label
    ///
    /// The location is the current position in the buffer
    ///  implicitly, it is expected that the name will be written to the stream after the current index.
    pub fn store_label_pointer(&mut self, labels: Vec<Rc<String>>) {
        if self.offset < 0x3FFFu32 {
            self.name_pointers.insert(labels, self.offset as u16); // the next char will be at the len() location
        }
    }

    /// Looks up the index of an already written label
    pub fn get_label_pointer(&self, labels: &[Rc<String>]) -> Option<u16> {
        self.name_pointers.get(labels).cloned()
    }

    /// matches description from above.
    ///
    /// ```
    /// use trust_dns_proto::serialize::binary::BinEncoder;
    ///
    /// let mut bytes: Vec<u8> = Vec::new();
    /// {
    ///   let mut encoder: BinEncoder = BinEncoder::new(&mut bytes);
    ///   encoder.emit_character_data("abc");
    /// }
    /// assert_eq!(bytes, vec![3,b'a',b'b',b'c']);
    /// ```
    pub fn emit_character_data(&mut self, char_data: &str) -> ProtoResult<()> {
        let char_bytes = char_data.as_bytes();
        if char_bytes.len() > 255 {
            return Err(ProtoErrorKind::CharacterDataTooLong(char_bytes.len()).into());
        }

        self.buffer.reserve(char_bytes.len() + 1); // reserve the full space for the string and length marker
        self.emit(char_bytes.len() as u8)?;

        // a separate writer isn't necessary for label since it's the same first byte that's being written

        // TODO use append() once it stabalizes
        for b in char_bytes {
            self.emit(*b)?;
        }

        Ok(())
    }

    /// Emit one byte into the buffer
    pub fn emit_u8(&mut self, data: u8) -> ProtoResult<()> {
        self.emit(data)
    }

    /// Writes a u16 in network byte order to the buffer
    pub fn emit_u16(&mut self, data: u16) -> ProtoResult<()> {
        self.buffer.reserve(2); // two bytes coming

        let b1: u8 = (data >> 8 & 0xFF) as u8;
        let b2: u8 = (data & 0xFF) as u8;

        self.emit(b1)?;
        self.emit(b2)?;

        Ok(())
    }

    /// Writes an i32 in network byte order to the buffer
    pub fn emit_i32(&mut self, data: i32) -> ProtoResult<()> {
        self.buffer.reserve(4); // four bytes coming...

        let b1: u8 = (data >> 24 & 0xFF) as u8;
        let b2: u8 = (data >> 16 & 0xFF) as u8;
        let b3: u8 = (data >> 8 & 0xFF) as u8;
        let b4: u8 = (data & 0xFF) as u8;

        self.emit(b1)?;
        self.emit(b2)?;
        self.emit(b3)?;
        self.emit(b4)?;

        Ok(())
    }

    /// Writes an u32 in network byte order to the buffer
    pub fn emit_u32(&mut self, data: u32) -> ProtoResult<()> {
        self.buffer.reserve(4); // four bytes coming...

        let b1: u8 = (data >> 24 & 0xFF) as u8;
        let b2: u8 = (data >> 16 & 0xFF) as u8;
        let b3: u8 = (data >> 8 & 0xFF) as u8;
        let b4: u8 = (data & 0xFF) as u8;

        self.emit(b1)?;
        self.emit(b2)?;
        self.emit(b3)?;
        self.emit(b4)?;

        Ok(())
    }

    /// Writes the byte slice to the stream
    pub fn emit_vec(&mut self, data: &[u8]) -> ProtoResult<()> {
        self.buffer.reserve(data.len());

        for i in data {
            self.emit(*i)?;
        }

        Ok(())
    }
}

/// In the Verify mode there maybe some things which are encoded differently, e.g. SIG0 records
///  should not be included in the additional count and not in the encoded data when in Verify
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum EncodeMode {
    /// In signing mode records are written in canonical form
    Signing,
    /// Write records in standard format
    Normal,
}
<commit_msg>serialization optimizations:<commit_after>/*
 * Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
use std::collections::HashMap;
use std::sync::Arc as Rc;
use byteorder::{ByteOrder, NetworkEndian};

use error::{ProtoErrorKind, ProtoResult};

/// Encode DNS messages and resource record types.
pub struct BinEncoder<'a> {
    offset: usize,
    buffer: &'a mut Vec<u8>,
    // TODO, it would be cool to make this slices, but then the stored slice needs to live longer
    //  than the callee of store_pointer which isn't obvious right now.
    name_pointers: HashMap<Vec<Rc<String>>, u16>, // array of string, label, location in stream
    mode: EncodeMode,
    canonical_names: bool,
}

impl<'a> BinEncoder<'a> {
    /// Create a new encoder with the Vec to fill
    pub fn new(buf: &'a mut Vec<u8>) -> Self {
        Self::with_offset(buf, 0, EncodeMode::Normal)
    }

    /// Specify the mode for encoding
    ///
    /// # Arguments
    ///
    /// * `mode` - In Signing mode, it canonical forms of all data are encoded, otherwise format matches the source form
    pub fn with_mode(buf: &'a mut Vec<u8>, mode: EncodeMode) -> Self {
        Self::with_offset(buf, 0, mode)
    }

    /// Begins the encoder at the given offset
    ///
    /// This is used for pointers. If this encoder is starting at some point further in
    ///  the sequence of bytes, for the proper offset of the pointer, the offset accounts for that
    ///  by using the offset to add to the pointer location being written.
    ///
    /// # Arguments
    ///
    /// * `offset` - index at which to start writing into the buffer
    pub fn with_offset(buf: &'a mut Vec<u8>, offset: u32, mode: EncodeMode) -> Self {
        BinEncoder {
            offset: offset as usize,
            buffer: buf,
            name_pointers: HashMap::new(),
            mode: mode,
            canonical_names: false,
        }
    }

    /// Returns a reference to the internal buffer
    pub fn into_bytes(self) -> &'a Vec<u8> {
        self.buffer
    }

    /// Returns the length of the buffer
    pub fn len(&self) -> usize {
        self.buffer.len()
    }

    /// Returns `true` if the buffer is empty
    pub fn is_empty(&self) -> bool {
        self.buffer.is_empty()
    }

    /// Returns the current offset into the buffer
    pub fn offset(&self) -> u32 {
        self.offset as u32
    }

    /// Returns the current Encoding mode
    pub fn mode(&self) -> EncodeMode {
        self.mode
    }

    /// If set to true, then names will be written into the buffer in canonical form
    pub fn set_canonical_names(&mut self, canonical_names: bool) {
        self.canonical_names = canonical_names;
    }

    /// Returns true if then encoder is writing in canonical form
    pub fn is_canonical_names(&self) -> bool {
        self.canonical_names
    }

    /// Reserve specified length in the internal buffer.
    pub fn reserve(&mut self, len: usize) {
        if self.buffer.capacity() - self.buffer.len() < len {
            self.buffer.reserve(512.max(len));
        }
    }

    /// Emit one byte into the buffer
    pub fn emit(&mut self, b: u8) -> ProtoResult<()> {
        self.offset += 1;
        self.buffer.push(b);
        Ok(())
    }

    /// Stores a label pointer to an already written label
    ///
    /// The location is the current position in the buffer
    ///  implicitly, it is expected that the name will be written to the stream after the current index.
    pub fn store_label_pointer(&mut self, labels: Vec<Rc<String>>) {
        if self.offset < 0x3FFFusize {
            self.name_pointers.insert(labels, self.offset as u16); // the next char will be at the len() location
        }
    }

    /// Looks up the index of an already written label
    pub fn get_label_pointer(&self, labels: &[Rc<String>]) -> Option<u16> {
        self.name_pointers.get(labels).cloned()
    }

    /// matches description from above.
    ///
    /// ```
    /// use trust_dns_proto::serialize::binary::BinEncoder;
    ///
    /// let mut bytes: Vec<u8> = Vec::new();
    /// {
    ///   let mut encoder: BinEncoder = BinEncoder::new(&mut bytes);
    ///   encoder.emit_character_data("abc");
    /// }
    /// assert_eq!(bytes, vec![3,b'a',b'b',b'c']);
    /// ```
    pub fn emit_character_data(&mut self, char_data: &str) -> ProtoResult<()> {
        let char_bytes = char_data.as_bytes();
        if char_bytes.len() > 255 {
            return Err(ProtoErrorKind::CharacterDataTooLong(char_bytes.len()).into());
        }
        self.reserve(char_bytes.len() + 1); // reserve the full space for the string and length marker
        self.emit(char_bytes.len() as u8)?;
        self.write_slice(char_bytes);
        Ok(())
    }

    /// Emit one byte into the buffer
    pub fn emit_u8(&mut self, data: u8) -> ProtoResult<()> {
        self.emit(data)
    }

    /// Writes a u16 in network byte order to the buffer
    pub fn emit_u16(&mut self, data: u16) -> ProtoResult<()> {
        let mut bytes = [0; 2];
        {
            NetworkEndian::write_u16(&mut bytes, data);
        }
        self.write_slice(&bytes);
        Ok(())
    }

    /// Writes an i32 in network byte order to the buffer
    pub fn emit_i32(&mut self, data: i32) -> ProtoResult<()> {
        let mut bytes = [0; 4];
        {
            NetworkEndian::write_i32(&mut bytes, data);
        }
        self.write_slice(&bytes);
        Ok(())
    }

    /// Writes an u32 in network byte order to the buffer
    pub fn emit_u32(&mut self, data: u32) -> ProtoResult<()> {
        let mut bytes = [0; 4];
        {
            NetworkEndian::write_u32(&mut bytes, data);
        }
        self.write_slice(&bytes);
        Ok(())
    }

    fn write_slice(&mut self, data: &[u8]) {
        // TODO: check whether this is better that letting `Vec.extend_from_slice` do the reservation.
        self.reserve(data.len());
        self.buffer.extend_from_slice(data);
        self.offset += data.len();
    }

    /// Writes the byte slice to the stream
    pub fn emit_vec(&mut self, data: &[u8]) -> ProtoResult<()> {
        self.write_slice(data);
        Ok(())
    }
}

/// In the Verify mode there maybe some things which are encoded differently, e.g. SIG0 records
///  should not be included in the additional count and not in the encoded data when in Verify
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum EncodeMode {
    /// In signing mode records are written in canonical form
    Signing,
    /// Write records in standard format
    Normal,
}
<|endoftext|>


<commit_before>// Copyright 2015-2016 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.

use super::*;

use hir::*;
use hir::intravisit::{Visitor, NestedVisitMode};
use hir::def_id::DefId;
use middle::cstore::InlinedItem;
use std::iter::repeat;
use syntax::ast::{NodeId, CRATE_NODE_ID};
use syntax_pos::Span;

/// A Visitor that walks over the HIR and collects Nodes into a HIR map
pub struct NodeCollector<'ast> {
    /// The crate
    pub krate: &'ast Crate,
    /// The node map
    pub map: Vec<MapEntry<'ast>>,
    /// The parent of this node
    pub parent_node: NodeId,
    /// If true, completely ignore nested items. We set this when loading
    /// HIR from metadata, since in that case we only want the HIR for
    /// one specific item (and not the ones nested inside of it).
    pub ignore_nested_items: bool
}

impl<'ast> NodeCollector<'ast> {
    pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> {
        let mut collector = NodeCollector {
            krate: krate,
            map: vec![],
            parent_node: CRATE_NODE_ID,
            ignore_nested_items: false
        };
        collector.insert_entry(CRATE_NODE_ID, RootCrate);

        collector
    }

    pub fn extend(krate: &'ast Crate,
                  parent: &'ast InlinedItem,
                  parent_node: NodeId,
                  parent_def_path: DefPath,
                  parent_def_id: DefId,
                  map: Vec<MapEntry<'ast>>)
                  -> NodeCollector<'ast> {
        let mut collector = NodeCollector {
            krate: krate,
            map: map,
            parent_node: parent_node,
            ignore_nested_items: true
        };

        assert_eq!(parent_def_path.krate, parent_def_id.krate);
        collector.insert_entry(parent_node, RootInlinedParent(parent));

        collector
    }

    fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
        debug!("ast_map: {:?} => {:?}", id, entry);
        let len = self.map.len();
        if id.as_usize() >= len {
            self.map.extend(repeat(NotPresent).take(id.as_usize() - len + 1));
        }
        self.map[id.as_usize()] = entry;
    }

    fn insert(&mut self, id: NodeId, node: Node<'ast>) {
        let entry = MapEntry::from_node(self.parent_node, node);
        self.insert_entry(id, entry);
    }

    fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_id: NodeId, f: F) {
        let parent_node = self.parent_node;
        self.parent_node = parent_id;
        f(self);
        self.parent_node = parent_node;
    }
}

impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
    /// Because we want to track parent items and so forth, enable
    /// deep walking so that we walk nested items in the context of
    /// their outer items.

    fn nested_visit_map(&mut self) -> Option<(&map::Map<'ast>, NestedVisitMode)> {
        panic!("visit_nested_xxx must be manually implemented in this visitor")
    }

    fn visit_nested_item(&mut self, item: ItemId) {
        debug!("visit_nested_item: {:?}", item);
        if !self.ignore_nested_items {
            self.visit_item(self.krate.item(item.id))
        }
    }

    fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
        self.visit_impl_item(self.krate.impl_item(item_id))
    }

    fn visit_body(&mut self, id: ExprId) {
        self.visit_expr(self.krate.expr(id))
    }

    fn visit_item(&mut self, i: &'ast Item) {
        debug!("visit_item: {:?}", i);

        self.insert(i.id, NodeItem(i));

        self.with_parent(i.id, |this| {
            match i.node {
                ItemEnum(ref enum_definition, _) => {
                    for v in &enum_definition.variants {
                        this.insert(v.node.data.id(), NodeVariant(v));
                    }
                }
                ItemStruct(ref struct_def, _) => {
                    // If this is a tuple-like struct, register the constructor.
                    if !struct_def.is_struct() {
                        this.insert(struct_def.id(), NodeStructCtor(struct_def));
                    }
                }
                _ => {}
            }
            intravisit::walk_item(this, i);
        });
    }

    fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
        self.insert(foreign_item.id, NodeForeignItem(foreign_item));

        self.with_parent(foreign_item.id, |this| {
            intravisit::walk_foreign_item(this, foreign_item);
        });
    }

    fn visit_generics(&mut self, generics: &'ast Generics) {
        for ty_param in generics.ty_params.iter() {
            self.insert(ty_param.id, NodeTyParam(ty_param));
        }

        intravisit::walk_generics(self, generics);
    }

    fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
        self.insert(ti.id, NodeTraitItem(ti));

        self.with_parent(ti.id, |this| {
            intravisit::walk_trait_item(this, ti);
        });
    }

    fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
        self.insert(ii.id, NodeImplItem(ii));

        self.with_parent(ii.id, |this| {
            intravisit::walk_impl_item(this, ii);
        });
    }

    fn visit_pat(&mut self, pat: &'ast Pat) {
        let node = if let PatKind::Binding(..) = pat.node {
            NodeLocal(pat)
        } else {
            NodePat(pat)
        };
        self.insert(pat.id, node);

        self.with_parent(pat.id, |this| {
            intravisit::walk_pat(this, pat);
        });
    }

    fn visit_expr(&mut self, expr: &'ast Expr) {
        self.insert(expr.id, NodeExpr(expr));

        self.with_parent(expr.id, |this| {
            intravisit::walk_expr(this, expr);
        });
    }

    fn visit_stmt(&mut self, stmt: &'ast Stmt) {
        let id = stmt.node.id();
        self.insert(id, NodeStmt(stmt));

        self.with_parent(id, |this| {
            intravisit::walk_stmt(this, stmt);
        });
    }

    fn visit_ty(&mut self, ty: &'ast Ty) {
        self.insert(ty.id, NodeTy(ty));

        self.with_parent(ty.id, |this| {
            intravisit::walk_ty(this, ty);
        });
    }

    fn visit_trait_ref(&mut self, tr: &'ast TraitRef) {
        self.insert(tr.ref_id, NodeTraitRef(tr));

        self.with_parent(tr.ref_id, |this| {
            intravisit::walk_trait_ref(this, tr);
        });
    }

    fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl,
                b: ExprId, s: Span, id: NodeId) {
        assert_eq!(self.parent_node, id);
        intravisit::walk_fn(self, fk, fd, b, s, id);
    }

    fn visit_block(&mut self, block: &'ast Block) {
        self.insert(block.id, NodeBlock(block));
        self.with_parent(block.id, |this| {
            intravisit::walk_block(this, block);
        });
    }

    fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
        self.insert(lifetime.id, NodeLifetime(lifetime));
    }

    fn visit_vis(&mut self, visibility: &'ast Visibility) {
        match *visibility {
            Visibility::Public |
            Visibility::Crate |
            Visibility::Inherited => {}
            Visibility::Restricted { id, .. } => {
                self.insert(id, NodeVisibility(visibility));
                self.with_parent(id, |this| {
                    intravisit::walk_vis(this, visibility);
                });
            }
        }
    }

    fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
        self.insert_entry(macro_def.id, NotPresent);
    }

    fn visit_struct_field(&mut self, field: &'ast StructField) {
        self.insert(field.id, NodeField(field));
        self.with_parent(field.id, |this| {
            intravisit::walk_struct_field(this, field);
        });
    }
}
<commit_msg>Remove unused import<commit_after>// Copyright 2015-2016 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.

use super::*;

use hir::intravisit::{Visitor, NestedVisitMode};
use hir::def_id::DefId;
use middle::cstore::InlinedItem;
use std::iter::repeat;
use syntax::ast::{NodeId, CRATE_NODE_ID};
use syntax_pos::Span;

/// A Visitor that walks over the HIR and collects Nodes into a HIR map
pub struct NodeCollector<'ast> {
    /// The crate
    pub krate: &'ast Crate,
    /// The node map
    pub map: Vec<MapEntry<'ast>>,
    /// The parent of this node
    pub parent_node: NodeId,
    /// If true, completely ignore nested items. We set this when loading
    /// HIR from metadata, since in that case we only want the HIR for
    /// one specific item (and not the ones nested inside of it).
    pub ignore_nested_items: bool
}

impl<'ast> NodeCollector<'ast> {
    pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> {
        let mut collector = NodeCollector {
            krate: krate,
            map: vec![],
            parent_node: CRATE_NODE_ID,
            ignore_nested_items: false
        };
        collector.insert_entry(CRATE_NODE_ID, RootCrate);

        collector
    }

    pub fn extend(krate: &'ast Crate,
                  parent: &'ast InlinedItem,
                  parent_node: NodeId,
                  parent_def_path: DefPath,
                  parent_def_id: DefId,
                  map: Vec<MapEntry<'ast>>)
                  -> NodeCollector<'ast> {
        let mut collector = NodeCollector {
            krate: krate,
            map: map,
            parent_node: parent_node,
            ignore_nested_items: true
        };

        assert_eq!(parent_def_path.krate, parent_def_id.krate);
        collector.insert_entry(parent_node, RootInlinedParent(parent));

        collector
    }

    fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
        debug!("ast_map: {:?} => {:?}", id, entry);
        let len = self.map.len();
        if id.as_usize() >= len {
            self.map.extend(repeat(NotPresent).take(id.as_usize() - len + 1));
        }
        self.map[id.as_usize()] = entry;
    }

    fn insert(&mut self, id: NodeId, node: Node<'ast>) {
        let entry = MapEntry::from_node(self.parent_node, node);
        self.insert_entry(id, entry);
    }

    fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_id: NodeId, f: F) {
        let parent_node = self.parent_node;
        self.parent_node = parent_id;
        f(self);
        self.parent_node = parent_node;
    }
}

impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
    /// Because we want to track parent items and so forth, enable
    /// deep walking so that we walk nested items in the context of
    /// their outer items.

    fn nested_visit_map(&mut self) -> Option<(&map::Map<'ast>, NestedVisitMode)> {
        panic!("visit_nested_xxx must be manually implemented in this visitor")
    }

    fn visit_nested_item(&mut self, item: ItemId) {
        debug!("visit_nested_item: {:?}", item);
        if !self.ignore_nested_items {
            self.visit_item(self.krate.item(item.id))
        }
    }

    fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
        self.visit_impl_item(self.krate.impl_item(item_id))
    }

    fn visit_body(&mut self, id: ExprId) {
        self.visit_expr(self.krate.expr(id))
    }

    fn visit_item(&mut self, i: &'ast Item) {
        debug!("visit_item: {:?}", i);

        self.insert(i.id, NodeItem(i));

        self.with_parent(i.id, |this| {
            match i.node {
                ItemEnum(ref enum_definition, _) => {
                    for v in &enum_definition.variants {
                        this.insert(v.node.data.id(), NodeVariant(v));
                    }
                }
                ItemStruct(ref struct_def, _) => {
                    // If this is a tuple-like struct, register the constructor.
                    if !struct_def.is_struct() {
                        this.insert(struct_def.id(), NodeStructCtor(struct_def));
                    }
                }
                _ => {}
            }
            intravisit::walk_item(this, i);
        });
    }

    fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
        self.insert(foreign_item.id, NodeForeignItem(foreign_item));

        self.with_parent(foreign_item.id, |this| {
            intravisit::walk_foreign_item(this, foreign_item);
        });
    }

    fn visit_generics(&mut self, generics: &'ast Generics) {
        for ty_param in generics.ty_params.iter() {
            self.insert(ty_param.id, NodeTyParam(ty_param));
        }

        intravisit::walk_generics(self, generics);
    }

    fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
        self.insert(ti.id, NodeTraitItem(ti));

        self.with_parent(ti.id, |this| {
            intravisit::walk_trait_item(this, ti);
        });
    }

    fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
        self.insert(ii.id, NodeImplItem(ii));

        self.with_parent(ii.id, |this| {
            intravisit::walk_impl_item(this, ii);
        });
    }

    fn visit_pat(&mut self, pat: &'ast Pat) {
        let node = if let PatKind::Binding(..) = pat.node {
            NodeLocal(pat)
        } else {
            NodePat(pat)
        };
        self.insert(pat.id, node);

        self.with_parent(pat.id, |this| {
            intravisit::walk_pat(this, pat);
        });
    }

    fn visit_expr(&mut self, expr: &'ast Expr) {
        self.insert(expr.id, NodeExpr(expr));

        self.with_parent(expr.id, |this| {
            intravisit::walk_expr(this, expr);
        });
    }

    fn visit_stmt(&mut self, stmt: &'ast Stmt) {
        let id = stmt.node.id();
        self.insert(id, NodeStmt(stmt));

        self.with_parent(id, |this| {
            intravisit::walk_stmt(this, stmt);
        });
    }

    fn visit_ty(&mut self, ty: &'ast Ty) {
        self.insert(ty.id, NodeTy(ty));

        self.with_parent(ty.id, |this| {
            intravisit::walk_ty(this, ty);
        });
    }

    fn visit_trait_ref(&mut self, tr: &'ast TraitRef) {
        self.insert(tr.ref_id, NodeTraitRef(tr));

        self.with_parent(tr.ref_id, |this| {
            intravisit::walk_trait_ref(this, tr);
        });
    }

    fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl,
                b: ExprId, s: Span, id: NodeId) {
        assert_eq!(self.parent_node, id);
        intravisit::walk_fn(self, fk, fd, b, s, id);
    }

    fn visit_block(&mut self, block: &'ast Block) {
        self.insert(block.id, NodeBlock(block));
        self.with_parent(block.id, |this| {
            intravisit::walk_block(this, block);
        });
    }

    fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
        self.insert(lifetime.id, NodeLifetime(lifetime));
    }

    fn visit_vis(&mut self, visibility: &'ast Visibility) {
        match *visibility {
            Visibility::Public |
            Visibility::Crate |
            Visibility::Inherited => {}
            Visibility::Restricted { id, .. } => {
                self.insert(id, NodeVisibility(visibility));
                self.with_parent(id, |this| {
                    intravisit::walk_vis(this, visibility);
                });
            }
        }
    }

    fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
        self.insert_entry(macro_def.id, NotPresent);
    }

    fn visit_struct_field(&mut self, field: &'ast StructField) {
        self.insert(field.id, NodeField(field));
        self.with_parent(field.id, |this| {
            intravisit::walk_struct_field(this, field);
        });
    }
}
<|endoftext|>


<commit_before><commit_msg>cleaned up code<commit_after><|endoftext|>


<commit_before><commit_msg>Remove identical conversion<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: Also print if runtime ignores IDs<commit_after><|endoftext|>