<commit_before>use core::clone::Clone;
use core::mem::size_of;
use core::option::Option;

use common::memory::*;
use common::safeptr::*;
use common::string::*;
use common::vector::*;

use drivers::disk::*;

#[derive(Copy, Clone)]
pub struct Block {
    address: u64
}

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

pub struct Header {
    pub signature: [u8; 4],
    pub version: u32,
    pub root_sector_list: Block,
    pub free_sector_list: Block,
    pub name: [u8; 256],
    reserved: [u8; 232]
}

struct Node {
    parent_collection: Block,
    data_sector_list: Block,
    data_size: u64,
    user_id: u64,
    group_id: u64,
    mode: u64,
    create_time: u64,
    modify_time: u64,
    access_time: u64,
    name: [u8; 256],
    reserved: [u8; 184]
}

struct SectorList {
    parent_node: Block,
    fragment_number: u64,
    last_fragment: Block,
    next_fragment: Block,
    extents: [Extent; 30]
}

pub struct UnFS {
    disk: Disk,
    pub header: &'static Header
}

impl UnFS {
    pub fn new() -> UnFS{
        unsafe{
            return UnFS::from_disk(Disk::new());
        }
    }

    pub unsafe fn from_disk(disk: Disk) -> UnFS{
        // TODO: Do not use header loaded in memory
        UnFS { disk:disk, header: &*(0x7E00 as *const Header) }
    }

    pub unsafe fn node(&self, filename: String) -> *const Node{
        let mut ret: *const Node = 0 as *const Node;
        let mut node_matches = false;

        let root_sector_list = alloc(size_of::<SectorList>()) as *const SectorList;
        let mut root_sector_list_address = self.header.root_sector_list.address;
        while root_sector_list_address > 0 {
            self.disk.read(root_sector_list_address, 1, root_sector_list as usize);

            for extent_i in 0..30 {
                let extent = (*root_sector_list).extents[extent_i];
                if extent.block.address > 0 {
                    for node_address in extent.block.address..extent.block.address + extent.length {
                        let node = alloc(size_of::<Node>()) as *const Node;
                        self.disk.read(node_address, 1, node as usize);

                        node_matches = true;
                        let mut i = 0;
                        for c in filename.chars()  {
                            if !(i < 256 && (*node).name[i] == c as u8) {
                                node_matches = false;
                                break;
                            }
                            i += 1;
                        }
                        if !(i < 256 && (*node).name[i] == 0) {
                            node_matches = false;
                        }

                        unalloc(node as usize);

                        if node_matches {
                            ret = node;
                            break;
                        }
                    }
                }

                if node_matches {
                    break;
                }
            }

            root_sector_list_address = (*root_sector_list).next_fragment.address;

            if node_matches{
                break;
            }
        }

        unalloc(root_sector_list as usize);

        ret
    }

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

        unsafe{
            let root_sector_list = alloc(size_of::<SectorList>()) as *const SectorList;
            let mut root_sector_list_address = self.header.root_sector_list.address;
            while root_sector_list_address > 0 {
                self.disk.read(root_sector_list_address, 1, root_sector_list as usize);

                for extent_i in 0..30 {
                    let extent = (*root_sector_list).extents[extent_i];
                    if extent.block.address > 0 {
                        for node_address in extent.block.address..extent.block.address + extent.length {
                            let node = alloc(size_of::<Node>()) as *const Node;
                            self.disk.read(node_address, 1, node as usize);

                            let node_name = String::from_c_slice(&(*node).name);
                            if node_name.starts_with(directory.clone()) {
                                ret = ret + node_name;
                            }

                            unalloc(node as usize);
                        }
                    }
                }

                root_sector_list_address = (*root_sector_list).next_fragment.address;
            }

            unalloc(root_sector_list as usize);
        }

        ret
    }

    pub unsafe fn load(&self, filename: String) -> usize{
        let mut destination = 0;

        let node = self.node(filename);

        if node as usize > 0{
            if (*node).data_sector_list.address > 0 {
                let sector_list_ptr: SafePtr<SectorList> = SafePtr::new();
                match sector_list_ptr.get() {
                    Option::Some(sector_list) => {
                        self.disk.read((*node).data_sector_list.address, 1, sector_list_ptr.unsafe_ptr() as usize);

                        //TODO: More than one extent, extent sector count > 64K
                        let mut size = 0;
                        for i in 0..1 {
                            if sector_list.extents[i].block.address > 0 && sector_list.extents[i].length > 0{
                                size += (*sector_list).extents[i].length * 512;
                            }
                        }

                        destination = alloc(size as usize);
                        if destination > 0 {
                            for i in 0..1 {
                                if sector_list.extents[i].block.address > 0 && sector_list.extents[i].length > 0{
                                    self.disk.read(sector_list.extents[i].block.address, sector_list.extents[i].length as u16, destination);
                                }
                            }
                        }
                    },
                    Option::None => ()
                }
            }

            unalloc(node as usize);
        }

        return destination;
    }

    // TODO: Support realloc of LBAs
    pub unsafe fn save(&self, filename: String, source: usize){
        let node = self.node(filename);

        if node as usize > 0{
            if (*node).data_sector_list.address > 0 {
                let sector_list_ptr: SafePtr<SectorList> = SafePtr::new();
                match sector_list_ptr.get() {
                    Option::Some(sector_list) => {
                        self.disk.read((*node).data_sector_list.address, 1, sector_list_ptr.unsafe_ptr() as usize);

                        if source > 0 {
                            for i in 0..1 {
                                if sector_list.extents[i].block.address > 0 && sector_list.extents[i].length > 0{
                                    self.disk.write(sector_list.extents[i].block.address, sector_list.extents[i].length as u16, source);
                                }
                            }
                        }
                    },
                    Option::None => ()
                }
            }

            unalloc(node as usize);
        }
    }
}
<commit_msg>Finally! Fixed the bug in unfs.rs The bug was a use after free Stuff that my new safeptr class would have protected me against, had I used it there<commit_after>use core::clone::Clone;
use core::mem::size_of;
use core::option::Option;

use common::memory::*;
use common::safeptr::*;
use common::string::*;
use common::vector::*;

use drivers::disk::*;

#[derive(Copy, Clone)]
pub struct Block {
    address: u64
}

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

pub struct Header {
    pub signature: [u8; 4],
    pub version: u32,
    pub root_sector_list: Block,
    pub free_sector_list: Block,
    pub name: [u8; 256],
    reserved: [u8; 232]
}

struct Node {
    parent_collection: Block,
    data_sector_list: Block,
    data_size: u64,
    user_id: u64,
    group_id: u64,
    mode: u64,
    create_time: u64,
    modify_time: u64,
    access_time: u64,
    name: [u8; 256],
    reserved: [u8; 184]
}

struct SectorList {
    parent_node: Block,
    fragment_number: u64,
    last_fragment: Block,
    next_fragment: Block,
    extents: [Extent; 30]
}

pub struct UnFS {
    disk: Disk,
    pub header: &'static Header
}

impl UnFS {
    pub fn new() -> UnFS{
        unsafe{
            return UnFS::from_disk(Disk::new());
        }
    }

    pub unsafe fn from_disk(disk: Disk) -> UnFS{
        // TODO: Do not use header loaded in memory
        UnFS { disk:disk, header: &*(0x7E00 as *const Header) }
    }

    pub unsafe fn node(&self, filename: String) -> *const Node{
        let mut ret: *const Node = 0 as *const Node;
        let mut node_matches = false;

        let root_sector_list_ptr: SafePtr<SectorList> = SafePtr::new();
        match root_sector_list_ptr.get() {
            Option::Some(root_sector_list) => {
                let mut root_sector_list_address = self.header.root_sector_list.address;
                while root_sector_list_address > 0 {
                    self.disk.read(root_sector_list_address, 1, root_sector_list_ptr.unsafe_ptr() as usize);

                    for extent_i in 0..30 {
                        let extent = (*root_sector_list).extents[extent_i];
                        if extent.block.address > 0 {
                            for node_address in extent.block.address..extent.block.address + extent.length {
                                let node = alloc(size_of::<Node>()) as *const Node;
                                self.disk.read(node_address, 1, node as usize);

                                node_matches = true;
                                let mut i = 0;
                                for c in filename.chars()  {
                                    if !(i < 256 && (*node).name[i] == c as u8) {
                                        node_matches = false;
                                        break;
                                    }
                                    i += 1;
                                }
                                if !(i < 256 && (*node).name[i] == 0) {
                                    node_matches = false;
                                }

                                if node_matches {
                                    ret = node;
                                    break;
                                }else{
                                    unalloc(node as usize);
                                }
                            }
                        }

                        if node_matches {
                            break;
                        }
                    }

                    root_sector_list_address = (*root_sector_list).next_fragment.address;

                    if node_matches{
                        break;
                    }
                }
            },
            Option::None => ()
        }
        ret
    }

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

        unsafe{
            let root_sector_list_ptr: SafePtr<SectorList> = SafePtr::new();
            match root_sector_list_ptr.get() {
                Option::Some(root_sector_list) => {
                    let mut root_sector_list_address = self.header.root_sector_list.address;
                    while root_sector_list_address > 0 {
                        self.disk.read(root_sector_list_address, 1, root_sector_list_ptr.unsafe_ptr() as usize);

                        for extent_i in 0..30 {
                            let extent = (*root_sector_list).extents[extent_i];
                            if extent.block.address > 0 {
                                for node_address in extent.block.address..extent.block.address + extent.length {
                                    let node = alloc(size_of::<Node>()) as *const Node;
                                    self.disk.read(node_address, 1, node as usize);

                                    let node_name = String::from_c_slice(&(*node).name);
                                    if node_name.starts_with(directory.clone()) {
                                        ret = ret + node_name;
                                    }

                                    unalloc(node as usize);
                                }
                            }
                        }

                        root_sector_list_address = (*root_sector_list).next_fragment.address;
                    }
                },
                Option::None => ()
            }
        }

        ret
    }

    pub unsafe fn load(&self, filename: String) -> usize{
        let mut destination = 0;

        let node = self.node(filename);

        if node as usize > 0{
            if (*node).data_sector_list.address > 0 {
                let sector_list_ptr: SafePtr<SectorList> = SafePtr::new();
                match sector_list_ptr.get() {
                    Option::Some(sector_list) => {
                        self.disk.read((*node).data_sector_list.address, 1, sector_list_ptr.unsafe_ptr() as usize);

                        //TODO: More than one extent, extent sector count > 64K
                        let mut size = 0;
                        for i in 0..1 {
                            if sector_list.extents[i].block.address > 0 && sector_list.extents[i].length > 0{
                                size += (*sector_list).extents[i].length * 512;
                            }
                        }

                        destination = alloc(size as usize);
                        if destination > 0 {
                            for i in 0..1 {
                                if sector_list.extents[i].block.address > 0 && sector_list.extents[i].length > 0{
                                    self.disk.read(sector_list.extents[i].block.address, sector_list.extents[i].length as u16, destination);
                                }
                            }
                        }
                    },
                    Option::None => ()
                }
            }

            unalloc(node as usize);
        }

        return destination;
    }

    // TODO: Support realloc of LBAs
    pub unsafe fn save(&self, filename: String, source: usize){
        let node = self.node(filename);

        if node as usize > 0{
            if (*node).data_sector_list.address > 0 {
                let sector_list_ptr: SafePtr<SectorList> = SafePtr::new();
                match sector_list_ptr.get() {
                    Option::Some(sector_list) => {
                        self.disk.read((*node).data_sector_list.address, 1, sector_list_ptr.unsafe_ptr() as usize);

                        if source > 0 {
                            for i in 0..1 {
                                if sector_list.extents[i].block.address > 0 && sector_list.extents[i].length > 0{
                                    self.disk.write(sector_list.extents[i].block.address, sector_list.extents[i].length as u16, source);
                                }
                            }
                        }
                    },
                    Option::None => ()
                }
            }

            unalloc(node as usize);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Clarify that currently used uniform buffer strides are array strides, and set the default to 16<commit_after><|endoftext|>


<commit_before>/*!

Sendable hash maps.  Very much a work in progress.

*/

use cmp::Eq;
use hash::Hash;
use to_bytes::IterBytes;

trait SendMap<K:Eq Hash, V: Copy> {
    // FIXME(#3148)  ^^^^ once find_ref() works, we can drop V:copy

    fn insert(&mut self, +k: K, +v: V) -> bool;
    fn remove(&mut self, k: &K) -> bool;
    fn clear(&mut self);
    pure fn len(&const self) -> uint;
    pure fn is_empty(&const self) -> bool;
    fn contains_key(&const self, k: &K) -> bool;
    fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool);
    fn each_key_ref(&self, blk: fn(k: &K) -> bool);
    fn each_value_ref(&self, blk: fn(v: &V) -> bool);
    fn find(&const self, k: &K) -> Option<V>;
    fn get(&const self, k: &K) -> V;
    fn with_find_ref<T>(&const self, k: &K, blk: fn(Option<&V>) -> T) -> T;
    fn with_get_ref<T>(&const self, k: &K, blk: fn(v: &V) -> T) -> T;
}

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    struct Bucket<K:Eq Hash,V> {
        hash: uint,
        key: K,
        value: V,
    }
    struct LinearMap<K:Eq Hash,V> {
        k0: u64,
        k1: u64,
        resize_at: uint,
        size: uint,
        buckets: ~[Option<Bucket<K,V>>],
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn LinearMap<K:Eq Hash,V>() -> LinearMap<K,V> {
        linear_map_with_capacity(32)
    }

    fn linear_map_with_capacity<K:Eq Hash,V>(
        initial_capacity: uint) -> LinearMap<K,V> {
        let r = rand::Rng();
        linear_map_with_capacity_and_keys(r.gen_u64(), r.gen_u64(),
                                          initial_capacity)
    }

    fn linear_map_with_capacity_and_keys<K:Eq Hash,V> (
        k0: u64, k1: u64,
        initial_capacity: uint) -> LinearMap<K,V> {
        LinearMap {
            k0: k0, k1: k1,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| None)
        }
    }

    priv impl<K:Hash IterBytes Eq, V> LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(&const self,
                          h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(&const self,
                            idx: uint,
                            len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(&const self,
                                hash: uint,
                                op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(&const self,
                               buckets: &[Option<Bucket<K,V>>],
                               k: &K) -> SearchResult {
            let hash = k.hash_keyed(self.k0, self.k1) as uint;
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(&const self,
                                         buckets: &[Option<Bucket<K,V>>],
                                         hash: uint,
                                         k: &K) -> SearchResult {
            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                    Some(bkt) => if bkt.hash == hash && *k == bkt.key {
                        return FoundEntry(i);
                    },
                    None => return FoundHole(i)
                }
            };
            return TableFull;
        }

        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand(&mut self) {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| None);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = None;
                bucket <-> old_buckets[i];
                self.insert_opt_bucket(move bucket);
            }
        }

        fn insert_opt_bucket(&mut self, +bucket: Option<Bucket<K,V>>) {
            match move bucket {
                Some(Bucket {hash: move hash,
                             key: move key,
                             value: move value}) => {
                    self.insert_internal(hash, move key, move value);
                }
                None => {}
            }
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
                TableFull => { fail ~"Internal logic error"; }
                FoundHole(idx) => {
                    debug!("insert fresh (%?->%?) at idx %?, hash %?",
                           k, v, idx, hash);
                    self.buckets[idx] = Some(Bucket {hash: hash,
                                                     key: k,
                                                     value: v});
                    self.size += 1;
                    true
                }
                FoundEntry(idx) => {
                    debug!("insert overwrite (%?->%?) at idx %?, hash %?",
                           k, v, idx, hash);
                    self.buckets[idx] = Some(Bucket {hash: hash,
                                                     key: k,
                                                     value: v});
                    false
                }
            }
        }

        fn search(&self,
                  hash: uint,
                  op: fn(x: &Option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K:Hash IterBytes Eq,V> LinearMap<K,V> {
        fn insert(&mut self, +k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = k.hash_keyed(self.k0, self.k1) as uint;
            self.insert_internal(hash, move k, move v)
        }

        fn remove(&mut self, k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
                TableFull | FoundHole(_) => return false,
                FoundEntry(idx) => idx
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = None;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = None;
                bucket <-> self.buckets[idx];
                self.insert_opt_bucket(move bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear(&mut self) {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = None;
            }
            self.size = 0;
        }

        pure fn len(&const self) -> uint {
            self.size
        }

        pure fn is_empty(&const self) -> bool {
            self.len() == 0
        }

        fn contains_key(&const self,
                        k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
                FoundEntry(_) => {true}
                TableFull | FoundHole(_) => {false}
            }
        }

        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(&self, k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn with_find_ref<T>(&self, k: &K, blk: fn(Option<&V>) -> T) -> T {
            match self.bucket_for_key(self.buckets, k) {
                FoundEntry(idx) => {
                    match self.buckets[idx] {
                        Some(bkt) => blk(Some(&bkt.value)),
                        None => fail ~"LinearMap::find: internal logic error"
                    }
                }
                TableFull | FoundHole(_) => blk(None),
            }
        }

        fn with_get_ref<T>(&self, k: &K, blk: fn(v: &V) -> T) -> T {
            do self.with_find_ref(k) |v| {
                match v {
                    Some(v) => blk(v),
                    None => fail fmt!("No entry found for key: %?", k),
                }
            }
        }

        fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }

        fn each_key_ref(&self, blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }

        fn each_value_ref(&self, blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K:Hash IterBytes Eq, V: Copy> LinearMap<K,V> {
        fn find(&const self, k: &K) -> Option<V> {
            match self.bucket_for_key(self.buckets, k) {
                FoundEntry(idx) => {
                    // FIXME (#3148): Once we rewrite found_entry, this
                    // failure case won't be necessary
                    match self.buckets[idx] {
                        Some(bkt) => {Some(copy bkt.value)}
                        None => fail ~"LinearMap::find: internal logic error"
                    }
                }
                TableFull | FoundHole(_) => {
                    None
                }
            }
        }

        fn get(&const self, k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!("No entry found for key: %?", k);
            }
            option::unwrap(move value)
        }

    }

    impl<K: Hash IterBytes Eq Copy, V: Copy> LinearMap<K,V> {
        fn each(&self, blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: Hash IterBytes Eq Copy, V> LinearMap<K,V> {
        fn each_key(&self, blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K: Hash IterBytes Eq, V: Copy> LinearMap<K,V> {
        fn each_value(&self, blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    use linear::LinearMap;

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return LinearMap();
    }

    #[test]
    fn inserts() {
        let mut m = int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = linear::linear_map_with_capacity(4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = linear::linear_map_with_capacity(4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = linear::linear_map_with_capacity(4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(4);
        for uint::range(0, 32) |i| {
            assert m.insert(i, i*2);
        }
        let mut observed = 0;
        for m.each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }

    #[test]
    fn with_find_ref() {
        let mut m = ~LinearMap();
        m.with_find_ref(&1, |v| assert v.is_none());
        m.insert(1, 2);
        m.with_find_ref(&1, |v| assert *v.get() == 2);
    }
}
<commit_msg>replace with_find_ref() with find_ref(), which is just nicer to use<commit_after>/*!

Sendable hash maps.  Very much a work in progress.

*/

use cmp::Eq;
use hash::Hash;
use to_bytes::IterBytes;

trait SendMap<K:Eq Hash, V: Copy> {
    // FIXME(#3148)  ^^^^ once find_ref() works, we can drop V:copy

    fn insert(&mut self, +k: K, +v: V) -> bool;
    fn remove(&mut self, k: &K) -> bool;
    fn clear(&mut self);
    pure fn len(&const self) -> uint;
    pure fn is_empty(&const self) -> bool;
    fn contains_key(&const self, k: &K) -> bool;
    fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool);
    fn each_key_ref(&self, blk: fn(k: &K) -> bool);
    fn each_value_ref(&self, blk: fn(v: &V) -> bool);
    fn find(&const self, k: &K) -> Option<V>;
    fn get(&const self, k: &K) -> V;
    fn with_find_ref<T>(&const self, k: &K, blk: fn(Option<&V>) -> T) -> T;
    fn with_get_ref<T>(&const self, k: &K, blk: fn(v: &V) -> T) -> T;
}

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    struct Bucket<K:Eq Hash,V> {
        hash: uint,
        key: K,
        value: V,
    }
    struct LinearMap<K:Eq Hash,V> {
        k0: u64,
        k1: u64,
        resize_at: uint,
        size: uint,
        buckets: ~[Option<Bucket<K,V>>],
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn LinearMap<K:Eq Hash,V>() -> LinearMap<K,V> {
        linear_map_with_capacity(32)
    }

    fn linear_map_with_capacity<K:Eq Hash,V>(
        initial_capacity: uint) -> LinearMap<K,V> {
        let r = rand::Rng();
        linear_map_with_capacity_and_keys(r.gen_u64(), r.gen_u64(),
                                          initial_capacity)
    }

    fn linear_map_with_capacity_and_keys<K:Eq Hash,V> (
        k0: u64, k1: u64,
        initial_capacity: uint) -> LinearMap<K,V> {
        LinearMap {
            k0: k0, k1: k1,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| None)
        }
    }

    priv impl<K:Hash IterBytes Eq, V> LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(&const self,
                          h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(&const self,
                            idx: uint,
                            len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(&const self,
                                hash: uint,
                                op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(&const self,
                               buckets: &[Option<Bucket<K,V>>],
                               k: &K) -> SearchResult {
            let hash = k.hash_keyed(self.k0, self.k1) as uint;
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(&const self,
                                         buckets: &[Option<Bucket<K,V>>],
                                         hash: uint,
                                         k: &K) -> SearchResult {
            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                    Some(bkt) => if bkt.hash == hash && *k == bkt.key {
                        return FoundEntry(i);
                    },
                    None => return FoundHole(i)
                }
            };
            return TableFull;
        }

        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand(&mut self) {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| None);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = None;
                bucket <-> old_buckets[i];
                self.insert_opt_bucket(move bucket);
            }
        }

        fn insert_opt_bucket(&mut self, +bucket: Option<Bucket<K,V>>) {
            match move bucket {
                Some(Bucket {hash: move hash,
                             key: move key,
                             value: move value}) => {
                    self.insert_internal(hash, move key, move value);
                }
                None => {}
            }
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
                TableFull => { fail ~"Internal logic error"; }
                FoundHole(idx) => {
                    debug!("insert fresh (%?->%?) at idx %?, hash %?",
                           k, v, idx, hash);
                    self.buckets[idx] = Some(Bucket {hash: hash,
                                                     key: k,
                                                     value: v});
                    self.size += 1;
                    true
                }
                FoundEntry(idx) => {
                    debug!("insert overwrite (%?->%?) at idx %?, hash %?",
                           k, v, idx, hash);
                    self.buckets[idx] = Some(Bucket {hash: hash,
                                                     key: k,
                                                     value: v});
                    false
                }
            }
        }

        fn search(&self,
                  hash: uint,
                  op: fn(x: &Option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K:Hash IterBytes Eq,V> LinearMap<K,V> {
        fn insert(&mut self, +k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = k.hash_keyed(self.k0, self.k1) as uint;
            self.insert_internal(hash, move k, move v)
        }

        fn remove(&mut self, k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
                TableFull | FoundHole(_) => return false,
                FoundEntry(idx) => idx
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = None;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = None;
                bucket <-> self.buckets[idx];
                self.insert_opt_bucket(move bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear(&mut self) {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = None;
            }
            self.size = 0;
        }

        pure fn len(&const self) -> uint {
            self.size
        }

        pure fn is_empty(&const self) -> bool {
            self.len() == 0
        }

        fn contains_key(&const self,
                        k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
                FoundEntry(_) => {true}
                TableFull | FoundHole(_) => {false}
            }
        }

        fn find_ref(&self, k: &K) -> Option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
                FoundEntry(idx) => {
                    match self.buckets[idx] {
                        Some(ref bkt) => {
                            let ptr = unsafe {
                                // FIXME(#3148)--region inference
                                // fails to capture needed deps.
                                // Here, the bucket value is known to
                                // live as long as self, because self
                                // is immutable.  But the region
                                // inference stupidly infers a
                                // lifetime for `ref bkt` that is
                                // shorter than it needs to be.
                                unsafe::copy_lifetime(self, &bkt.value)
                            };
                            Some(ptr)
                        }
                        None => {
                            fail ~"LinearMap::find: internal logic error"
                        }
                    }
                }
                TableFull | FoundHole(_) => {
                    None
                }
            }
        }

        fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }

        fn each_key_ref(&self, blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }

        fn each_value_ref(&self, blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K:Hash IterBytes Eq, V: Copy> LinearMap<K,V> {
        fn find(&const self, k: &K) -> Option<V> {
            match self.bucket_for_key(self.buckets, k) {
                FoundEntry(idx) => {
                    // FIXME (#3148): Once we rewrite found_entry, this
                    // failure case won't be necessary
                    match self.buckets[idx] {
                        Some(bkt) => {Some(copy bkt.value)}
                        None => fail ~"LinearMap::find: internal logic error"
                    }
                }
                TableFull | FoundHole(_) => {
                    None
                }
            }
        }

        fn get(&const self, k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!("No entry found for key: %?", k);
            }
            option::unwrap(move value)
        }

    }

    impl<K: Hash IterBytes Eq Copy, V: Copy> LinearMap<K,V> {
        fn each(&self, blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: Hash IterBytes Eq Copy, V> LinearMap<K,V> {
        fn each_key(&self, blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K: Hash IterBytes Eq, V: Copy> LinearMap<K,V> {
        fn each_value(&self, blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    use linear::LinearMap;

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return LinearMap();
    }

    #[test]
    fn inserts() {
        let mut m = int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = linear::linear_map_with_capacity(4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = linear::linear_map_with_capacity(4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = linear::linear_map_with_capacity(4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(4);
        for uint::range(0, 32) |i| {
            assert m.insert(i, i*2);
        }
        let mut observed = 0;
        for m.each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }

    #[test]
    fn find_ref() {
        let mut m = ~LinearMap();
        assert m.find_ref(&1).is_none();
        m.insert(1, 2);
        match m.find_ref(&1) {
            None => fail,
            Some(v) => assert *v == 2
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Another test for typestate and expr_fn<commit_after>// error-pattern:Unsatisfied precondition
// xfail-stage0

fn main() {
  auto j = (fn () -> int {
        let int i;
        ret i;
    })();
  log_err j;
}
<|endoftext|>


<commit_before><commit_msg>add ToImage<commit_after>use std;

use std::cmp::PartialOrd;

extern crate num;
use self::num::traits::{Zero, One, FromPrimitive, ToPrimitive, Float};

extern crate nalgebra;
use self::nalgebra::{DMat};

extern crate image;
use self::image::{ImageBuffer, Luma, DynamicImage};

quick_error! {
    #[derive(Debug)]
    pub enum ImageSaveError {
        /// an error has occured when opening the file
        Io(err: std::io::Error) {}
        /// an error has occured when writing the image into the file
        Image(err: image::ImageError) {}
    }
}

pub trait ToImage {
    /// # Panics
    /// panics unless all the values in `self` are between
    /// `0` (inclusive) and `1` (inclusive)
    fn to_image(&self) -> DynamicImage;
    /// # Panics
    /// panics unless all the values in `self` are between
    /// `0` (inclusive) and `1` (inclusive)
    fn save_to_png(&self, filename: &str) -> Result<(), ImageSaveError>;
}

impl<T: Zero + One + FromPrimitive + ToPrimitive + PartialOrd + Float> ToImage for DMat<T> {
    fn to_image(&self) -> DynamicImage {
        let mut image_buffer = ImageBuffer::new(self.ncols() as u32, self.nrows() as u32);
        for (x, y, pixel) in image_buffer.enumerate_pixels_mut() {
            let value = self[(y as usize, x as usize)];
            assert!(T::zero() <= value);
            assert!(value <= T::one());
            let max = T::from_u8(std::u8::MAX).unwrap();
            let byte = (value * max).round().to_u8().unwrap();
            *pixel = Luma([byte]);
        }
        DynamicImage::ImageLuma8(image_buffer)
    }

    fn save_to_png(&self, filename: &str) -> Result<(), ImageSaveError> {
        let image = self.to_image();
        let path = std::path::Path::new(filename);
        let mut file = try!(std::fs::File::create(&path).map_err(ImageSaveError::Io));
        image.save(&mut file, image::PNG).map_err(ImageSaveError::Image)
    }
}
<|endoftext|>


<commit_before>use core::ops::{Deref, DerefMut};
use core::{mem, slice};

use super::error::*;
use super::syscall::*;
use super::c_string_to_str;

#[derive(Copy, Clone, Debug, Default)]
#[repr(packed)]
pub struct Packet {
    pub id: usize,
    pub a: usize,
    pub b: usize,
    pub c: usize,
    pub d: usize
}

impl Deref for Packet {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::<Packet>()) as &[u8]
        }
    }
}

impl DerefMut for Packet {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::<Packet>()) as &mut [u8]
        }
    }
}

pub trait Scheme {
    fn handle(&mut self, packet: &mut Packet) {
        packet.a = Error::mux(match packet.a {
            SYS_OPEN => self.open(c_string_to_str(packet.b as *const u8), packet.c, packet.d),
            SYS_MKDIR => self.mkdir(c_string_to_str(packet.b as *const u8), packet.c),
            SYS_RMDIR => self.rmdir(c_string_to_str(packet.b as *const u8)),
            SYS_STAT => self.stat(c_string_to_str(packet.b as *const u8), unsafe { &mut *(packet.c as *mut Stat) }),
            SYS_UNLINK => self.unlink(c_string_to_str(packet.b as *const u8)),

            SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
            SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
            SYS_LSEEK => self.seek(packet.b, packet.c, packet.d),
            SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
            SYS_FSTAT => self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }),
            SYS_FSYNC => self.fsync(packet.b),
            SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c),
            SYS_CLOSE => self.close(packet.b),

            _ => Err(Error::new(ENOSYS))
        });
    }

    /* Scheme operations */

    #[allow(unused_variables)]
    fn open(&mut self, path: &str, flags: usize, mode: usize) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn mkdir(&mut self, path: &str, mode: usize) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn rmdir(&mut self, path: &str) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn stat(&mut self, path: &str, stat: &mut Stat) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn unlink(&mut self, path: &str) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    /* Resource operations */
    #[allow(unused_variables)]
    fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn fsync(&mut self, id: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn ftruncate(&mut self, id: usize, len: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn close(&mut self, id: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }
}
<commit_msg>Dup in system crate<commit_after>use core::ops::{Deref, DerefMut};
use core::{mem, slice};

use super::error::*;
use super::syscall::*;
use super::c_string_to_str;

#[derive(Copy, Clone, Debug, Default)]
#[repr(packed)]
pub struct Packet {
    pub id: usize,
    pub a: usize,
    pub b: usize,
    pub c: usize,
    pub d: usize
}

impl Deref for Packet {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::<Packet>()) as &[u8]
        }
    }
}

impl DerefMut for Packet {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::<Packet>()) as &mut [u8]
        }
    }
}

pub trait Scheme {
    fn handle(&mut self, packet: &mut Packet) {
        packet.a = Error::mux(match packet.a {
            SYS_OPEN => self.open(c_string_to_str(packet.b as *const u8), packet.c, packet.d),
            SYS_MKDIR => self.mkdir(c_string_to_str(packet.b as *const u8), packet.c),
            SYS_RMDIR => self.rmdir(c_string_to_str(packet.b as *const u8)),
            SYS_STAT => self.stat(c_string_to_str(packet.b as *const u8), unsafe { &mut *(packet.c as *mut Stat) }),
            SYS_UNLINK => self.unlink(c_string_to_str(packet.b as *const u8)),

            SYS_DUP => self.dup(packet.b),
            SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
            SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
            SYS_LSEEK => self.seek(packet.b, packet.c, packet.d),
            SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
            SYS_FSTAT => self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }),
            SYS_FSYNC => self.fsync(packet.b),
            SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c),
            SYS_CLOSE => self.close(packet.b),

            _ => Err(Error::new(ENOSYS))
        });
    }

    /* Scheme operations */

    #[allow(unused_variables)]
    fn open(&mut self, path: &str, flags: usize, mode: usize) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn mkdir(&mut self, path: &str, mode: usize) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn rmdir(&mut self, path: &str) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn stat(&mut self, path: &str, stat: &mut Stat) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    #[allow(unused_variables)]
    fn unlink(&mut self, path: &str) -> Result<usize> {
        Err(Error::new(ENOENT))
    }

    /* Resource operations */
    #[allow(unused_variables)]
    fn dup(&mut self, id: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn fsync(&mut self, id: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn ftruncate(&mut self, id: usize, len: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    #[allow(unused_variables)]
    fn close(&mut self, id: usize) -> Result<usize> {
        Err(Error::new(EBADF))
    }
}
<|endoftext|>


<commit_before><commit_msg>Add UFCS privacy test.<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.

// Test to ensure private traits are inaccessible with UFCS angle-bracket syntax.

mod foo {
    trait Bar {
        fn baz() {}
    }

    impl Bar for i32 {}
}

fn main() {
    <i32 as ::foo::Bar>::baz(); //~ERROR method `baz` is inaccessible
                                //~^NOTE: trait `Bar` is private
}
<|endoftext|>


<commit_before><commit_msg>Flush I/O on shutdown.<commit_after><|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>fix #24367<commit_after><|endoftext|>


<commit_before><commit_msg>Add example of model parameter for a child relm widget<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#![feature(proc_macro)]

extern crate gtk;
#[macro_use]
extern crate relm;
extern crate relm_attributes;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::Widget;
use relm_attributes::widget;

use self::Msg::*;

#[derive(Clone)]
pub struct ButtonModel {
    text: String,
}

#[widget]
impl Widget for Button {
    fn model(text: String) -> ButtonModel {
        ButtonModel {
            text: text,
        }
    }

    fn update(&mut self, _event: Msg, _model: &mut ButtonModel) {
    }

    view! {
        gtk::Button {
            label: &model.text,
        },
    }
}

// Define the structure of the model.
#[derive(Clone)]
pub struct Model {
    counter: i32,
}

// The messages that can be sent to the update function.
#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
}

#[widget]
impl Widget for Win {
    // The initial model.
    fn model(counter: i32) -> Model {
        Model {
            counter: counter,
        }
    }

    // Update the model according to the message received.
    fn update(&mut self, event: Msg, model: &mut Model) {
        match event {
            Decrement => model.counter -= 1,
            Increment => model.counter += 1,
            Quit => gtk::main_quit(),
        }
    }

    view! {
        gtk::Window {
            gtk::Box {
                // Set the orientation property of the Box.
                orientation: Vertical,
                // Create a Button inside the Box.
                gtk::Button {
                    // Send the message Increment when the button is clicked.
                    clicked => Increment,
                    // TODO: check if using two events of the same name work.
                    label: "+",
                },
                gtk::Label {
                    // Bind the text property of the label to the counter attribute of the model.
                    text: &model.counter.to_string(),
                },
                gtk::Button {
                    clicked => Decrement,
                    label: "-",
                },
                Button("Button text attribute".to_string()),
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    Win::run(42).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>created octree w/ insert functionality & ascii art diagram. Currently acceptably performant but too heavy on memory usage<commit_after>// Octree Data Structure
extern crate rand;

use rand::{weak_rng, Rng};

#[deriving(Show)]
struct Point {
  x: f32,
  y: f32,
  z: f32
}

impl Point {
  fn new(x: f32, y: f32, z: f32) -> Point {
    Point {
      x: x,
      y: y,
      z: z
    }
  }
}

#[deriving(Show)]
enum Node {
  Leaf,
  INode(~[~Octree])
}

#[deriving(Show)]
struct Octree {
  origin: Point, // center of node
  size: f32, // size of node
  data: Option<Point>,
  children: Node
}

impl Octree {
  fn new_root() -> Octree {
    Octree{
      origin: Point::new(0.0,0.0,0.0),
      size: 200000000000.0,
      data: None,
      children: Leaf
    }
  }
  fn new(pnt: Point, size: f32) -> Octree {
    Octree{
      origin: pnt,
      size: size,
      data: None,
      children: Leaf
    }
  }

  /*   My First attempt at the noble art of ascii
   *   This is the top level of the octree,
   *   the bottom level is the same +4
   *        ^        ___________________
   *        |       /        / |       /|
   *        |      /|  0    /  |   1  / |
   *        |     /_|______/___|_____/  |
   * z-axis |    /   |    / |  |    /|  |
   *        |   /    |   /  |  |   / |  |
   *        |   |----|--+---|--/--/  |  |
   *        |   |    |_ |___|_/___|__|_/     ^
   *        |   |   / 2 |   |/ 3  |  |/     / y-axis
   *        |   |  /    |   /     |  /     /
   *        |   | /     |  /      | /     /
   *        |   |_______|_/_______|/     /
   *        --------------------------> /
   *                x-axis
   *
   */

  fn insert(&mut self, pnt : Point) {
//    println!("Attempting to insert {} into {}", pnt, self.origin);
    match self.children {
      Leaf =>
        match self.data {
          None => self.data = Some(pnt),
          Some(oldPoint) => {
//            println!("Leafnode to be split into octree {}", self.origin);
            let mut childNodes = ~[];
            for i in range(0 as uint, 8) {
              let new_x = self.origin.x + self.size * (if i & 4 == 0 { 0.5 } else {-0.5});
              let new_y = self.origin.y + self.size * (if i & 2 == 0 { 0.5 } else {-0.5});
              let new_z = self.origin.z + self.size * (if i & 1 == 0 { 0.5 } else {-0.5});
              let new_octree = ~Octree::new(Point::new(new_x, new_y, new_z), self.size/2.0);
//              println!("made Leafnode {}", new_octree);
              childNodes.push(new_octree);
            }

//TODO easy optimization, just add from here instead of root
//            childNodes[getOctant(self.origin, pnt)].insert(pnt);
//            childNodes[getOctant(self.origin, pnt)].insert(oldPoint);
            self.children = INode(childNodes);
            self.insert(pnt);
          }
        },
      INode(ref mut children) => {
        let index = getOctant(self.origin, pnt);
        children[index].insert(pnt);//.insert(pnt);
      }
    }
  }
}

fn getOctant(origin: Point, pnt: Point) -> uint {
  let mut octant = 0;
  if pnt.x <= origin.x {
    octant |= 4;
  }
  if pnt.y <= origin.y {
    octant |= 2;
  }
  if pnt.z <= origin.z {
    octant |= 1;
  }
  octant
}

fn main() {

  let mut tree = Octree::new_root();
  let mut rng = rand::weak_rng();
  for x in range(0,10000000000){
    if x%10000 == 0 {
      println!("added {} nodes", x);
    }
    let x: f32 = rng.gen_range(0.0 as f32, 144000000000.0);
    let y: f32 = rng.gen_range(0.0 as f32, 144000000000.0);
    let z: f32 = rng.gen_range(0.0 as f32, 144000000000.0);
    tree.insert(Point::new(x,y,z));
  }

}
<|endoftext|>


<commit_before><commit_msg>Export type of CapR function output<commit_after><|endoftext|>


<commit_before>// 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.

// Utility Functions.

use super::{CrateDebugContext};
use super::namespace::item_namespace;

use rustc::hir::def_id::DefId;

use llvm;
use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray};
use machine;
use common::{CrateContext};
use type_::Type;

use syntax_pos::{self, Span};
use syntax::ast;

pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
{
    // The is_local_to_unit flag indicates whether a function is local to the
    // current compilation unit (i.e. if it is *static* in the C-sense). The
    // *reachable* set should provide a good approximation of this, as it
    // contains everything that might leak out of the current crate (by being
    // externally visible or by being inlined into something externally
    // visible). It might better to use the `exported_items` set from
    // `driver::CrateAnalysis` in the future, but (atm) this set is not
    // available in the translation pass.
    !cx.exported_symbols().contains(&node_id)
}

#[allow(non_snake_case)]
pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
    return unsafe {
        llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
    };
}

/// Return syntax_pos::Loc corresponding to the beginning of the span
pub fn span_start(cx: &CrateContext, span: Span) -> syntax_pos::Loc {
    cx.sess().codemap().lookup_char_pos(span.lo)
}

pub fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
    (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type) as u64)
}

pub fn bytes_to_bits(bytes: u64) -> u64 {
    bytes * 8
}

#[inline]
pub fn debug_context<'a, 'tcx>(cx: &'a CrateContext<'a, 'tcx>)
                           -> &'a CrateDebugContext<'tcx> {
    let debug_context: &'a CrateDebugContext<'tcx> = cx.dbg_cx().as_ref().unwrap();
    debug_context
}

#[inline]
#[allow(non_snake_case)]
pub fn DIB(cx: &CrateContext) -> DIBuilderRef {
    cx.dbg_cx().as_ref().unwrap().builder
}

pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId)
                                   -> (DIScope, Span) {
    let containing_scope = item_namespace(cx, DefId {
        krate: def_id.krate,
        index: cx.tcx().def_key(def_id).parent
                 .expect("get_namespace_and_span_for_item: missing parent?")
    });

    // Try to get some span information, if we have an inlined item.
    let definition_span = cx.tcx().def_span(def_id);

    (containing_scope, definition_span)
}
<commit_msg>trans::debuginfo: simplify<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.

// Utility Functions.

use super::{CrateDebugContext};
use super::namespace::item_namespace;

use rustc::hir::def_id::DefId;

use llvm;
use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray};
use machine;
use common::{CrateContext};
use type_::Type;

use syntax_pos::{self, Span};
use syntax::ast;

pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
{
    // The is_local_to_unit flag indicates whether a function is local to the
    // current compilation unit (i.e. if it is *static* in the C-sense). The
    // *reachable* set should provide a good approximation of this, as it
    // contains everything that might leak out of the current crate (by being
    // externally visible or by being inlined into something externally
    // visible). It might better to use the `exported_items` set from
    // `driver::CrateAnalysis` in the future, but (atm) this set is not
    // available in the translation pass.
    !cx.exported_symbols().contains(&node_id)
}

#[allow(non_snake_case)]
pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
    return unsafe {
        llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
    };
}

/// Return syntax_pos::Loc corresponding to the beginning of the span
pub fn span_start(cx: &CrateContext, span: Span) -> syntax_pos::Loc {
    cx.sess().codemap().lookup_char_pos(span.lo)
}

pub fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
    (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type) as u64)
}

pub fn bytes_to_bits(bytes: u64) -> u64 {
    bytes * 8
}

#[inline]
pub fn debug_context<'a, 'tcx>(cx: &'a CrateContext<'a, 'tcx>)
                           -> &'a CrateDebugContext<'tcx> {
    cx.dbg_cx().as_ref().unwrap()
}

#[inline]
#[allow(non_snake_case)]
pub fn DIB(cx: &CrateContext) -> DIBuilderRef {
    cx.dbg_cx().as_ref().unwrap().builder
}

pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId)
                                   -> (DIScope, Span) {
    let containing_scope = item_namespace(cx, DefId {
        krate: def_id.krate,
        index: cx.tcx().def_key(def_id).parent
                 .expect("get_namespace_and_span_for_item: missing parent?")
    });

    // Try to get some span information, if we have an inlined item.
    let definition_span = cx.tcx().def_span(def_id);

    (containing_scope, definition_span)
}
<|endoftext|>


<commit_before><commit_msg>Bind value and simplify condition with it<commit_after><|endoftext|>


<commit_before><commit_msg>Adds Rust Problem 12<commit_after>/// Problem 12
/// The sequence of triangle numbers is generated by adding the natural numbers.
/// So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The
/// first ten terms would be:
///
/// 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
///
/// Let us list the factors of the first seven triangle numbers:
///
///  1: 1
///  3: 1,3
///  6: 1,2,3,6
/// 10: 1,2,5,10
/// 15: 1,3,5,15
/// 21: 1,3,7,21
/// 28: 1,2,4,7,14,28
/// We can see that 28 is the first triangle number to have over five divisors.
///
/// What is the value of the first triangle number to have over
/// five hundred divisors?
fn main() {
    let mut addend: u64 = 2;
    let mut triangle: u64 = 1;

    loop {
        triangle += addend;
        addend += 1;

        if num_divisors(triangle) > 500 {
            println!("Answer: {}", triangle);
            break
        }
    }
}

fn num_divisors(n: u64) -> u64 {
    if n == 1 {
        return 1;
    }
    let mut num: u64 = 0;
    let mut top: u64 = n;
    let mut i: u64 = 1;
    loop {
        if n % i == 0 {
            num += 2;
            top = n/i;
        }
        i += 1;
        if i >= top {
            break
        }
    }
    num
}
<|endoftext|>


<commit_before><commit_msg>chore: OO<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 http://mozilla.org/MPL/2.0/. */

use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::HTMLElementBinding;
use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFrameSetElementDerived};
use dom::bindings::codegen::InheritTypes::EventTargetCast;
use dom::bindings::codegen::InheritTypes::{HTMLElementDerived, HTMLBodyElementDerived};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
use dom::element::{Element, ElementTypeId, ElementTypeId_, HTMLElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetHelpers, NodeTargetTypeId};
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;

use servo_util::str::DOMString;

use string_cache::Atom;

#[dom_struct]
pub struct HTMLElement {
    element: Element
}

impl HTMLElementDerived for EventTarget {
    fn is_htmlelement(&self) -> bool {
        match *self.type_id() {
            NodeTargetTypeId(ElementNodeTypeId(ElementTypeId_)) => false,
            NodeTargetTypeId(ElementNodeTypeId(_)) => true,
            _ => false
        }
    }
}

impl HTMLElement {
    pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLElement {
        HTMLElement {
            element: Element::new_inherited(type_id, tag_name, ns!(HTML), prefix, document)
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLElement> {
        let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, prefix, document);
        Node::reflect_node(box element, document, HTMLElementBinding::Wrap)
    }

    #[inline]
    pub fn element<'a>(&'a self) -> &'a Element {
        &self.element
    }
}

trait PrivateHTMLElementHelpers {
    fn is_body_or_frameset(self) -> bool;
}

impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> {
    fn is_body_or_frameset(self) -> bool {
        let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(self);
        eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement()
    }
}

impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
    make_getter!(Title)
    make_setter!(SetTitle, "title")

    make_getter!(Lang)
    make_setter!(SetLang, "lang")

    event_handler!(click, GetOnclick, SetOnclick)

    fn GetOnload(self) -> Option<EventHandlerNonNull> {
        if self.is_body_or_frameset() {
            let win = window_from_node(self).root();
            win.GetOnload()
        } else {
            None
        }
    }

    fn SetOnload(self, listener: Option<EventHandlerNonNull>) {
        if self.is_body_or_frameset() {
            let win = window_from_node(self).root();
            win.SetOnload(listener)
        }
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
    fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
        let element: &JSRef<Element> = ElementCast::from_borrowed_ref(self);
        Some(element as &VirtualMethods)
    }

    fn after_set_attr(&self, attr: JSRef<Attr>) {
        match self.super_type() {
            Some(ref s) => s.after_set_attr(attr),
            _ => ()
        }

        let name = attr.local_name().as_slice();
        if name.starts_with("on") {
            let window = window_from_node(*self).root();
            let (cx, url, reflector) = (window.get_cx(),
                                        window.get_url(),
                                        window.reflector().get_jsobject());
            let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
            evtarget.set_event_handler_uncompiled(cx, url, reflector,
                                                  name.slice_from(2),
                                                  attr.value().as_slice().to_string());
        }
    }
}

impl Reflectable for HTMLElement {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.element.reflector()
    }
}
<commit_msg>Remove HTMLElement.element().<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 http://mozilla.org/MPL/2.0/. */

use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::HTMLElementBinding;
use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFrameSetElementDerived};
use dom::bindings::codegen::InheritTypes::EventTargetCast;
use dom::bindings::codegen::InheritTypes::{HTMLElementDerived, HTMLBodyElementDerived};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
use dom::element::{Element, ElementTypeId, ElementTypeId_, HTMLElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetHelpers, NodeTargetTypeId};
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;

use servo_util::str::DOMString;

use string_cache::Atom;

#[dom_struct]
pub struct HTMLElement {
    element: Element
}

impl HTMLElementDerived for EventTarget {
    fn is_htmlelement(&self) -> bool {
        match *self.type_id() {
            NodeTargetTypeId(ElementNodeTypeId(ElementTypeId_)) => false,
            NodeTargetTypeId(ElementNodeTypeId(_)) => true,
            _ => false
        }
    }
}

impl HTMLElement {
    pub fn new_inherited(type_id: ElementTypeId, tag_name: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLElement {
        HTMLElement {
            element: Element::new_inherited(type_id, tag_name, ns!(HTML), prefix, document)
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLElement> {
        let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, prefix, document);
        Node::reflect_node(box element, document, HTMLElementBinding::Wrap)
    }
}

trait PrivateHTMLElementHelpers {
    fn is_body_or_frameset(self) -> bool;
}

impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> {
    fn is_body_or_frameset(self) -> bool {
        let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(self);
        eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement()
    }
}

impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
    make_getter!(Title)
    make_setter!(SetTitle, "title")

    make_getter!(Lang)
    make_setter!(SetLang, "lang")

    event_handler!(click, GetOnclick, SetOnclick)

    fn GetOnload(self) -> Option<EventHandlerNonNull> {
        if self.is_body_or_frameset() {
            let win = window_from_node(self).root();
            win.GetOnload()
        } else {
            None
        }
    }

    fn SetOnload(self, listener: Option<EventHandlerNonNull>) {
        if self.is_body_or_frameset() {
            let win = window_from_node(self).root();
            win.SetOnload(listener)
        }
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
    fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
        let element: &JSRef<Element> = ElementCast::from_borrowed_ref(self);
        Some(element as &VirtualMethods)
    }

    fn after_set_attr(&self, attr: JSRef<Attr>) {
        match self.super_type() {
            Some(ref s) => s.after_set_attr(attr),
            _ => ()
        }

        let name = attr.local_name().as_slice();
        if name.starts_with("on") {
            let window = window_from_node(*self).root();
            let (cx, url, reflector) = (window.get_cx(),
                                        window.get_url(),
                                        window.reflector().get_jsobject());
            let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
            evtarget.set_event_handler_uncompiled(cx, url, reflector,
                                                  name.slice_from(2),
                                                  attr.value().as_slice().to_string());
        }
    }
}

impl Reflectable for HTMLElement {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.element.reflector()
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix bug in grain.<commit_after><|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>