<commit_before>/**
 *   Mles server
 *
 *   Copyright (C) 2017  Juhamatti Kuusisaari / Mles developers
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
extern crate tokio_core;
extern crate tokio_io;
extern crate futures;
extern crate mles_utils;

use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::iter;
use std::io::{Error, ErrorKind};
use std::{process, env};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::thread;

use tokio_core::net::TcpListener;
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use tokio_io::io;
use tokio_io::AsyncRead;

use futures::Future;
use futures::stream::{self, Stream};
use futures::sync::mpsc::unbounded;
use mles_utils::*;

const HDRL: usize = 4; //hdr len
const KEYL: usize = 8; //key len

fn main() {
    let mut peer = "".to_string();
    let mut argcnt = 0;
    for arg in env::args() {
        argcnt += 1;
        if 2 == argcnt {
            peer = arg;
            peer += ":8077";
            match peer.parse::<SocketAddr>() {
                Ok(_) => {},
                    Err(err) => {
                        println!("Error: {}\nUsage: mles [peer-address]", err);
                        process::exit(1);
                    },
            }
        }
        if argcnt > 2 {
            println!("Usage: mles [peer-address]");
            process::exit(1);
        }
    }

    let peer = match peer.parse::<SocketAddr>() {
        Ok(addr) => addr,
        Err(_) => {
            SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0)
        },
    };

    let keyval = match env::var("MLES_KEY") {
        Ok(val) => val,
        Err(_) => "".to_string(),
    };

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let address = "0.0.0.0:8077".parse().unwrap();
    let socket = match TcpListener::bind(&address, &handle) {
        Ok(listener) => listener,
        Err(err) => {
            println!("Error: {}", err);
            process::exit(1);
        },
    };
    println!("Listening on: {}", address);

    let spawned = Rc::new(RefCell::new(HashMap::new()));
    let channelmsgs = Rc::new(RefCell::new(HashMap::new()));
    let mut cnt = 0;

    let srv = socket.incoming().for_each(move |(stream, addr)| {
        println!("New Connection: {}", addr);
        let paddr = match stream.peer_addr() {
                Ok(paddr) => paddr,
                Err(_) => {
                    let addr = "0.0.0.0:0";
                    let addr = addr.parse::<SocketAddr>().unwrap();
                    addr
                }
        };
        let _val = stream.set_nodelay(true).map_err(|_| panic!("Cannot set to no delay"));;

        let (reader, writer) = stream.split();
        let (tx, rx) = unbounded();
        cnt += 1;

        let (tx_peer, rx_peer) = unbounded();

        let frame = io::read_exact(reader, vec![0;HDRL]);
        let frame = frame.and_then(move |(reader, payload)| {
            if payload.len() == 0 {
                Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
            } else {
                if read_hdr_type(payload.as_slice()) != 'M' as u32 {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header"));
                }
                let hdr_len = read_hdr_len(payload.as_slice());
                if 0 == hdr_len {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header len"));
                }
                Ok((reader, hdr_len))
            }
        });

        let paddr_inner = paddr.clone();
        let keyval_inner = keyval.clone();
        let frame = frame.and_then(move |(reader, hdr_len)| {
            let tframe = io::read_exact(reader, vec![0;KEYL]);
            // verify key
            let tframe = tframe.and_then(move |(reader, key)| {
                let hkey;
                let key = read_key(key);
                if 0 == keyval_inner.len() {
                    hkey = do_hash(&paddr_inner);
                }
                else {
                    hkey = do_hash(&keyval_inner);
                }
                if hkey != key {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect remote key"));
                }
                Ok((reader, hdr_len))
            });
            tframe
        });

        let tx_once = tx.clone();
        let spawned_inner = spawned.clone();
        let chanmsgs_inner = channelmsgs.clone();
        let socket_once = frame.and_then(move |(reader, hdr_len)| {
            let tframe = io::read_exact(reader, vec![0;hdr_len]);
            let tframe = tframe.and_then(move |(reader, message)| {
                if 0 == message.len() {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect message len"));
                }
                else {
                    let mut spawned_once = spawned_inner.borrow_mut();
                    let mut chanmsgs_once = chanmsgs_inner.borrow_mut();
                    let decoded_message = message_decode(message.as_slice());
                    let channel = decoded_message.channel.clone();

                    if !spawned_once.contains_key(&channel) {
                        let chancp = channel.clone();
                        println!("Spawning peer channel thread");
                        thread::spawn(move || peer_conn(peer, chancp, tx_peer, tx));

                        let mut channel_entry = HashMap::new();
                        channel_entry.insert(cnt, tx_once.clone());
                        spawned_once.insert(channel.clone(), channel_entry);

                        let messages: Vec<Vec<u8>> = Vec::new();
                        chanmsgs_once.insert(channel.clone(), messages);
                    }
                    else {
                        let mut channel_entry = spawned_once.get_mut(&channel).unwrap();
                        channel_entry.insert(cnt, tx_once.clone());
                        let chanmsgs = chanmsgs_once.get(&channel).unwrap();
                        // send history to client
                        for msg in chanmsgs {
                            tx_once.send(msg.clone()).unwrap();
                        }
                    }
                    // todo: add empty message to history list too
                    println!("User {}:{} joined channel {}", cnt, decoded_message.uid, channel);
                    // forward to peer
                    Ok((reader, channel))
                }
            });
            tframe
        });

        let spawned_inner = spawned.clone();
        let chanmsgs_inner = channelmsgs.clone();
        let socket_next = socket_once.and_then(move |(reader, channel)| {
            let channel_next = channel.clone();
            let iter = stream::iter(iter::repeat(()).map(Ok::<(), Error>));
            iter.fold(reader, move |reader, _| {
                let frame = io::read_exact(reader, vec![0;HDRL]);
                let frame = frame.and_then(move |(reader, payload)| {
                    if payload.len() == 0 {
                        Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
                    } else {
                        if read_hdr_type(payload.as_slice()) != 'M' as u32 {
                            return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header"));
                        }
                        let hdr_len = read_hdr_len(payload.as_slice());
                        if 0 == hdr_len {
                            return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header len"));
                        }
                        Ok((reader, payload, hdr_len))
                    }
                });

                //todo: optimize, read hdr and key with one pass
                let frame = frame.and_then(move |(reader, hdr, hdr_len)| {
                    //dummy read key
                    let tframe = io::read_exact(reader, vec![0;KEYL]);
                    let tframe = tframe.and_then(move |(reader, key)| {
                        Ok((reader, hdr, key, hdr_len))
                    });
                    tframe
                });

                let frame = frame.and_then(move |(reader, hdr, key, hdr_len)| {
                    let tframe = io::read_exact(reader, vec![0;hdr_len]);
                    let tframe = tframe.and_then(move |(reader, message)| {
                        if 0 == message.len() {
                            return Err(Error::new(ErrorKind::BrokenPipe, "incorrect message len"));
                        }
                        else {
                            Ok((reader, hdr, key, message))
                        }
                    });
                    tframe
                });

                let spawned = spawned_inner.clone();
                let chanmsgs = chanmsgs_inner.clone();
                let channel = channel_next.clone();
                frame.map(move |(reader, mut hdr, mut key, message)| {
                    key.extend(message);
                    hdr.extend(key);

                    // add to history
                    let mut channel_msgs = chanmsgs.borrow_mut();
                    let mut channel_msg = channel_msgs.get_mut(&channel).unwrap();
                    channel_msg.push(hdr.clone());

                    //distribute
                    let spawned = spawned.borrow();
                    let channels = spawned.get(&channel).unwrap();
                    for (ocnt, tx) in channels {
                        if *ocnt != cnt {
                            tx.send(hdr.clone()).map_err(|err| { println!("Failed to send to channel: {}", err); () });
                        }
                    }
                    reader
                })
            })
        });

        //try to get tx to peer
        let spawned_inner = spawned.clone();
        let peer_writer = rx_peer.for_each(move |(channel, peer_tx)| {
            let mut spawned_once = spawned_inner.borrow_mut();
            let mut channel_entry = spawned_once.get_mut(&channel).unwrap();
            //todo fix cnt
            channel_entry.insert(0, peer_tx);
            Ok(())
        });

        //let peer_writer = peer_writer.map_err(|_| ());
        let peer_writer = peer_writer.map(|_| ());

        handle.spawn(peer_writer.then(|_| {
            println!("Got tx peer");
            Ok(())
        }));

        let socket_writer = rx.fold(writer, |writer, msg| {
            let amt = io::write_all(writer, msg);
            let amt = amt.map(|(writer, _)| writer);
            amt.map_err(|_| ())
        });

        //let socket_writer = socket_writer.join(peer_writer);

        let channels = spawned.clone();
        let chanmsgs = channelmsgs.clone();
        let socket_reader = socket_next.map_err(|_| ());
        let connection = socket_reader.map(|_| ()).select2(socket_writer.map(|_| ()));
        //let connection = socket_reader.map(|_| ()).select(peer_writer.map(|_| ()));
        handle.spawn(connection.then(move |_| {
            let mut chans = channels.borrow_mut();
            for (cname, channel) in chans.iter_mut() {
                if channel.contains_key(&cnt) {
                    channel.remove(&cnt);
                    if 0 == channel.len() {
                        let mut channelmsgs = chanmsgs.borrow_mut();
                        channelmsgs.remove(cname);
                        println!("Channel {} dropped.", cname);
                        drop(channel);
                    }
                    break;
                }
            }
            println!("Connection {} for user {} closed.", addr, cnt);
            Ok(())
        }));
        Ok(())
    });

    // execute server
    core.run(srv).unwrap();
}

fn peer_conn(peer: SocketAddr, channel: String, tx_peer_for_rcv: futures::sync::mpsc::UnboundedSender<(String, futures::sync::mpsc::UnboundedSender<Vec<u8>>)>, tx_peer: futures::sync::mpsc::UnboundedSender<Vec<u8>>) {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let tcp = TcpStream::connect(&peer, &handle);
    let tx_peer = Rc::new(RefCell::new(tx_peer));

    let client = tcp.and_then(move |pstream| {
        let _val = pstream.set_nodelay(true).map_err(|_| panic!("Cannot set peer to no delay"));
        println!("Successfully connected to peer");

        //save writes to db
        let (reader, writer) = pstream.split();
        let (tx, rx) = unbounded();
        tx_peer_for_rcv.send((channel, tx)).map_err(|err| { println!("Cannot send: {}", err); () });

        let psocket_writer = rx.fold(writer, |writer, msg| {
            let amt = io::write_all(writer, msg);
            let amt = amt.map(|(writer, _)| writer);
            amt.map_err(|_| ())
        });
        let psocket_writer = psocket_writer.map_err(|_| ());
        let psocket_writer = psocket_writer.map(|_| ());

        handle.spawn(psocket_writer.then(|_| {
            println!("Peer socket writer closed");
            Ok(())
        }));

        let tx_peer_inner = tx_peer.clone();
        let iter = stream::iter(iter::repeat(()).map(Ok::<(), Error>));
        iter.fold(reader, move |reader, _| {

            //todo: read hdr and key with one pass
            let frame = io::read_exact(reader, vec![0;HDRL]);
            let frame = frame.and_then(move |(reader, payload)| {
                if payload.len() == 0 {
                    Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
                } else {
                    if read_hdr_type(payload.as_slice()) != 'M' as u32 {
                        return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header"));
                    }
                    let hdr_len = read_hdr_len(payload.as_slice());
                    if 0 == hdr_len {
                        return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header len"));
                    }
                    Ok((reader, payload, hdr_len))
                }
            });

            let frame = frame.and_then(move |(reader, hdr, hdr_len)| {
                //dummy read key
                let tframe = io::read_exact(reader, vec![0;KEYL]);
                let tframe = tframe.and_then(move |(reader, key)| {
                    Ok((reader, hdr, key, hdr_len))
                });
                tframe
            });

            let frame = frame.and_then(move |(reader, hdr, key, hdr_len)| {
                let tframe = io::read_exact(reader, vec![0;hdr_len]);
                let tframe = tframe.and_then(move |(reader, message)| {
                    if 0 == message.len() {
                        return Err(Error::new(ErrorKind::BrokenPipe, "incorrect message len"));
                    }
                    Ok((reader, hdr, key, message))
                });
                tframe
            });

            let tx_peer_frame = tx_peer_inner.clone();
            frame.map(move |(reader, mut hdr, mut key, message)| {
                let tx_peer = tx_peer_frame.borrow();
                key.extend(message);
                hdr.extend(key);
                tx_peer.send(hdr.clone()).unwrap();
                reader
            })
        })
    });

    core.run(client).unwrap();
}

<commit_msg>Fix joining with first message to peer server.<commit_after>/**
 *   Mles server
 *
 *   Copyright (C) 2017  Juhamatti Kuusisaari / Mles developers
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
extern crate tokio_core;
extern crate tokio_io;
extern crate futures;
extern crate mles_utils;

use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
use std::iter;
use std::io::{Error, ErrorKind};
use std::{process, env};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::thread;

use tokio_core::net::TcpListener;
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use tokio_io::io;
use tokio_io::AsyncRead;

use futures::Future;
use futures::stream::{self, Stream};
use futures::sync::mpsc::unbounded;
use mles_utils::*;

const HDRL: usize = 4; //hdr len
const KEYL: usize = 8; //key len

fn main() {
    let mut peer = "".to_string();
    let mut argcnt = 0;
    for arg in env::args() {
        argcnt += 1;
        if 2 == argcnt {
            peer = arg;
            peer += ":8077";
            match peer.parse::<SocketAddr>() {
                Ok(_) => {},
                    Err(err) => {
                        println!("Error: {}\nUsage: mles [peer-address]", err);
                        process::exit(1);
                    },
            }
        }
        if argcnt > 2 {
            println!("Usage: mles [peer-address]");
            process::exit(1);
        }
    }

    let peer = match peer.parse::<SocketAddr>() {
        Ok(addr) => addr,
        Err(_) => {
            SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0)
        },
    };

    let keyval = match env::var("MLES_KEY") {
        Ok(val) => val,
        Err(_) => "".to_string(),
    };

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let address = "0.0.0.0:8077".parse().unwrap();
    let socket = match TcpListener::bind(&address, &handle) {
        Ok(listener) => listener,
        Err(err) => {
            println!("Error: {}", err);
            process::exit(1);
        },
    };
    println!("Listening on: {}", address);

    let spawned = Rc::new(RefCell::new(HashMap::new()));
    let channelmsgs = Rc::new(RefCell::new(HashMap::new()));
    let mut cnt = 0;

    let srv = socket.incoming().for_each(move |(stream, addr)| {
        println!("New Connection: {}", addr);
        let paddr = match stream.peer_addr() {
                Ok(paddr) => paddr,
                Err(_) => {
                    let addr = "0.0.0.0:0";
                    let addr = addr.parse::<SocketAddr>().unwrap();
                    addr
                }
        };
        let _val = stream.set_nodelay(true).map_err(|_| panic!("Cannot set to no delay"));;

        let (reader, writer) = stream.split();
        let (tx, rx) = unbounded();
        cnt += 1;

        let (tx_peer, rx_peer) = unbounded();

        let frame = io::read_exact(reader, vec![0;HDRL]);
        let frame = frame.and_then(move |(reader, payload)| {
            if payload.len() == 0 {
                Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
            } else {
                if read_hdr_type(payload.as_slice()) != 'M' as u32 {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header"));
                }
                let hdr_len = read_hdr_len(payload.as_slice());
                if 0 == hdr_len {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header len"));
                }
                Ok((reader, payload, hdr_len))
            }
        });

        let paddr_inner = paddr.clone();
        let keyval_inner = keyval.clone();
        let frame = frame.and_then(move |(reader, hdr, hdr_len)| {
            let tframe = io::read_exact(reader, vec![0;KEYL]);
            // verify key
            let tframe = tframe.and_then(move |(reader, key)| {
                let hkey;
                let keyx = read_key(key.clone());
                if 0 == keyval_inner.len() {
                    hkey = do_hash(&paddr_inner);
                }
                else {
                    hkey = do_hash(&keyval_inner);
                }
                if hkey != keyx {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect remote key"));
                }
                Ok((reader, hdr, key, hdr_len))
            });
            tframe
        });

        let tx_once = tx.clone();
        let spawned_inner = spawned.clone();
        let chanmsgs_inner = channelmsgs.clone();
        let socket_once = frame.and_then(move |(reader, mut hdr, key, hdr_len)| {
            let tframe = io::read_exact(reader, vec![0;hdr_len]);
            let tframe = tframe.and_then(move |(reader, message)| {
                if 0 == message.len() {
                    return Err(Error::new(ErrorKind::BrokenPipe, "incorrect message len"));
                }
                else {
                    let mut spawned_once = spawned_inner.borrow_mut();
                    let mut chanmsgs_once = chanmsgs_inner.borrow_mut();
                    let decoded_message = message_decode(message.as_slice());
                    let channel = decoded_message.channel.clone();

                    if !spawned_once.contains_key(&channel) {
                        hdr.extend(key);
                        hdr.extend(message);
                        let chan = channel.clone();
                        println!("Spawning peer channel thread");
                        thread::spawn(move || peer_conn(peer, chan, hdr, tx_peer, tx));

                        let mut channel_entry = HashMap::new();
                        channel_entry.insert(cnt, tx_once.clone());
                        spawned_once.insert(channel.clone(), channel_entry);

                        let messages: Vec<Vec<u8>> = Vec::new();
                        chanmsgs_once.insert(channel.clone(), messages);
                    }
                    else {
                        let mut channel_entry = spawned_once.get_mut(&channel).unwrap();
                        channel_entry.insert(cnt, tx_once.clone());
                        let chanmsgs = chanmsgs_once.get(&channel).unwrap();
                        // send history to client
                        for msg in chanmsgs {
                            tx_once.send(msg.clone()).unwrap();
                        }
                    }
                    // todo: add empty message to history list too
                    println!("User {}:{} joined channel {}", cnt, decoded_message.uid, channel);
                    // forward to peer
                    Ok((reader, channel))
                }
            });
            tframe
        });

        let spawned_inner = spawned.clone();
        let chanmsgs_inner = channelmsgs.clone();
        let socket_next = socket_once.and_then(move |(reader, channel)| {
            let channel_next = channel.clone();
            let iter = stream::iter(iter::repeat(()).map(Ok::<(), Error>));
            iter.fold(reader, move |reader, _| {
                let frame = io::read_exact(reader, vec![0;HDRL]);
                let frame = frame.and_then(move |(reader, payload)| {
                    if payload.len() == 0 {
                        Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
                    } else {
                        if read_hdr_type(payload.as_slice()) != 'M' as u32 {
                            return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header"));
                        }
                        let hdr_len = read_hdr_len(payload.as_slice());
                        if 0 == hdr_len {
                            return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header len"));
                        }
                        Ok((reader, payload, hdr_len))
                    }
                });

                //todo: optimize, read hdr and key with one pass
                let frame = frame.and_then(move |(reader, hdr, hdr_len)| {
                    //dummy read key
                    let tframe = io::read_exact(reader, vec![0;KEYL]);
                    let tframe = tframe.and_then(move |(reader, key)| {
                        Ok((reader, hdr, key, hdr_len))
                    });
                    tframe
                });

                let frame = frame.and_then(move |(reader, hdr, key, hdr_len)| {
                    let tframe = io::read_exact(reader, vec![0;hdr_len]);
                    let tframe = tframe.and_then(move |(reader, message)| {
                        if 0 == message.len() {
                            return Err(Error::new(ErrorKind::BrokenPipe, "incorrect message len"));
                        }
                        else {
                            Ok((reader, hdr, key, message))
                        }
                    });
                    tframe
                });

                let spawned = spawned_inner.clone();
                let chanmsgs = chanmsgs_inner.clone();
                let channel = channel_next.clone();
                frame.map(move |(reader, mut hdr, mut key, message)| {
                    key.extend(message);
                    hdr.extend(key);

                    // add to history
                    let mut channel_msgs = chanmsgs.borrow_mut();
                    let mut channel_msg = channel_msgs.get_mut(&channel).unwrap();
                    channel_msg.push(hdr.clone());

                    //distribute
                    let spawned = spawned.borrow();
                    let channels = spawned.get(&channel).unwrap();
                    for (ocnt, tx) in channels {
                        if *ocnt != cnt {
                            let _res = tx.send(hdr.clone()).map_err(|err| { println!("Failed to send to channel: {}", err); () });
                        }
                    }
                    reader
                })
            })
        });

        //try to get tx to peer
        let spawned_inner = spawned.clone();
        let peer_writer = rx_peer.for_each(move |(channel, peer_tx)| {
            let mut spawned_once = spawned_inner.borrow_mut();
            let mut channel_entry = spawned_once.get_mut(&channel).unwrap();
            //todo fix cnt
            channel_entry.insert(0, peer_tx);
            Ok(())
        });

        //let peer_writer = peer_writer.map_err(|_| ());
        let peer_writer = peer_writer.map(|_| ());

        handle.spawn(peer_writer.then(|_| {
            Ok(())
        }));

        let socket_writer = rx.fold(writer, |writer, msg| {
            let amt = io::write_all(writer, msg);
            let amt = amt.map(|(writer, _)| writer);
            amt.map_err(|_| ())
        });

        let channels = spawned.clone();
        let chanmsgs = channelmsgs.clone();
        let socket_reader = socket_next.map_err(|_| ());
        let connection = socket_reader.map(|_| ()).select2(socket_writer.map(|_| ()));
        handle.spawn(connection.then(move |_| {
            let mut chans = channels.borrow_mut();
            for (cname, channel) in chans.iter_mut() {
                if channel.contains_key(&cnt) {
                    channel.remove(&cnt);
                    if 0 == channel.len() {
                        let mut channelmsgs = chanmsgs.borrow_mut();
                        channelmsgs.remove(cname);
                        println!("Channel {} dropped.", cname);
                        drop(channel);
                    }
                    break;
                }
            }
            println!("Connection {} for user {} closed.", addr, cnt);
            Ok(())
        }));
        Ok(())
    });

    // execute server
    core.run(srv).unwrap();
}

fn peer_conn(peer: SocketAddr, channel: String, msg: Vec<u8>,
             tx_peer_for_rcv: futures::sync::mpsc::UnboundedSender<(String, futures::sync::mpsc::UnboundedSender<Vec<u8>>)>,
             tx_peer: futures::sync::mpsc::UnboundedSender<Vec<u8>>)
{
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let tcp = TcpStream::connect(&peer, &handle);
    let tx_peer = Rc::new(RefCell::new(tx_peer));

    let client = tcp.and_then(move |pstream| {
        let _val = pstream.set_nodelay(true).map_err(|_| panic!("Cannot set peer to no delay"));
        println!("Successfully connected to peer");

        //save writes to db
        let (reader, writer) = pstream.split();
        let (tx, rx) = unbounded();
        let _res = tx_peer_for_rcv.send((channel, tx.clone())).map_err(|err| { println!("Cannot send: {}", err); () });
        let _res = tx.send(msg).map_err(|err| { println!("Cannot write to tx: {}", err); });

        let psocket_writer = rx.fold(writer, |writer, msg| {
            let amt = io::write_all(writer, msg);
            let amt = amt.map(|(writer, _)| writer);
            amt.map_err(|_| ())
        });
        let psocket_writer = psocket_writer.map_err(|_| ());
        let psocket_writer = psocket_writer.map(|_| ());

        handle.spawn(psocket_writer.then(|_| {
            println!("Peer socket writer closed");
            Ok(())
        }));

        let tx_peer_inner = tx_peer.clone();
        let iter = stream::iter(iter::repeat(()).map(Ok::<(), Error>));
        iter.fold(reader, move |reader, _| {

            //todo: read hdr and key with one pass
            let frame = io::read_exact(reader, vec![0;HDRL]);
            let frame = frame.and_then(move |(reader, payload)| {
                if payload.len() == 0 {
                    Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"))
                } else {
                    if read_hdr_type(payload.as_slice()) != 'M' as u32 {
                        return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header"));
                    }
                    let hdr_len = read_hdr_len(payload.as_slice());
                    if 0 == hdr_len {
                        return Err(Error::new(ErrorKind::BrokenPipe, "incorrect header len"));
                    }
                    Ok((reader, payload, hdr_len))
                }
            });

            let frame = frame.and_then(move |(reader, hdr, hdr_len)| {
                //dummy read key
                let tframe = io::read_exact(reader, vec![0;KEYL]);
                let tframe = tframe.and_then(move |(reader, key)| {
                    Ok((reader, hdr, key, hdr_len))
                });
                tframe
            });

            let frame = frame.and_then(move |(reader, hdr, key, hdr_len)| {
                let tframe = io::read_exact(reader, vec![0;hdr_len]);
                let tframe = tframe.and_then(move |(reader, message)| {
                    if 0 == message.len() {
                        return Err(Error::new(ErrorKind::BrokenPipe, "incorrect message len"));
                    }
                    Ok((reader, hdr, key, message))
                });
                tframe
            });

            let tx_peer_frame = tx_peer_inner.clone();
            frame.map(move |(reader, mut hdr, mut key, message)| {
                let tx_peer = tx_peer_frame.borrow();
                key.extend(message);
                hdr.extend(key);
                tx_peer.send(hdr.clone()).unwrap();
                reader
            })
        })
    });

    core.run(client).unwrap();
}

<|endoftext|>


<commit_before><commit_msg>remove obsolete creation of WakerRegistration<commit_after><|endoftext|>


<commit_before>use memory::paging::{self, Page, PageIter, ActivePageTable};
use memory::{PAGE_SIZE, FrameAllocator};

pub fn new_stack_allocator(page_range: PageIter) -> StackAllocator {
    StackAllocator { range: page_range }
}

pub struct StackAllocator {
    range: PageIter,
}

impl StackAllocator {
    pub fn alloc_stack<FA: FrameAllocator>(&mut self,
                                           active_table: &mut ActivePageTable,
                                           frame_allocator: &mut FA,
                                           size_in_pages: usize)
                                           -> Option<Stack> {
        if size_in_pages == 0 {
            return None;
        }

        let mut range = self.range.clone();

        // try to allocate the stack pages and a guard page
        let guard_page = range.next();
        let stack_start = range.next();
        let stack_end = if size_in_pages == 1 {
            stack_start
        } else {
            range.nth(size_in_pages - 2)
        };

        match (guard_page, stack_start, stack_end) {
            (Some(_), Some(start), Some(end)) => {
                // success! write back updated range
                self.range = range;

                // map stack pages to physical frames
                for page in Page::range_inclusive(start, end) {
                    active_table.map(page, paging::WRITABLE, frame_allocator);
                }

                // create a new stack
                let top_of_stack = end.start_address() + PAGE_SIZE;
                Some(Stack::new(top_of_stack, start.start_address()))
            }
            _ => None, /* not enough pages */
        }
    }
}

#[derive(Debug)]
pub struct Stack {
    top: usize,
    bottom: usize,
}

impl Stack {
    fn new(top: usize, bottom: usize) -> Stack {
        assert!(top > bottom);
        Stack {
            top: top,
            bottom: bottom,
        }
    }

    pub fn top(&self) -> usize {
        self.top
    }

    pub fn bottom(&self) -> usize {
        self.bottom
    }
}
<commit_msg>Silence dead code warning<commit_after>use memory::paging::{self, Page, PageIter, ActivePageTable};
use memory::{PAGE_SIZE, FrameAllocator};

pub fn new_stack_allocator(page_range: PageIter) -> StackAllocator {
    StackAllocator { range: page_range }
}

pub struct StackAllocator {
    range: PageIter,
}

impl StackAllocator {
    pub fn alloc_stack<FA: FrameAllocator>(&mut self,
                                           active_table: &mut ActivePageTable,
                                           frame_allocator: &mut FA,
                                           size_in_pages: usize)
                                           -> Option<Stack> {
        if size_in_pages == 0 {
            return None;
        }

        let mut range = self.range.clone();

        // try to allocate the stack pages and a guard page
        let guard_page = range.next();
        let stack_start = range.next();
        let stack_end = if size_in_pages == 1 {
            stack_start
        } else {
            range.nth(size_in_pages - 2)
        };

        match (guard_page, stack_start, stack_end) {
            (Some(_), Some(start), Some(end)) => {
                // success! write back updated range
                self.range = range;

                // map stack pages to physical frames
                for page in Page::range_inclusive(start, end) {
                    active_table.map(page, paging::WRITABLE, frame_allocator);
                }

                // create a new stack
                let top_of_stack = end.start_address() + PAGE_SIZE;
                Some(Stack::new(top_of_stack, start.start_address()))
            }
            _ => None, /* not enough pages */
        }
    }
}

#[derive(Debug)]
pub struct Stack {
    top: usize,
    bottom: usize,
}

impl Stack {
    fn new(top: usize, bottom: usize) -> Stack {
        assert!(top > bottom);
        Stack {
            top: top,
            bottom: bottom,
        }
    }

    pub fn top(&self) -> usize {
        self.top
    }

    #[allow(dead_code)]
    pub fn bottom(&self) -> usize {
        self.bottom
    }
}
<|endoftext|>


<commit_before>use std::rc::*;

use super::treenode::*;
use super::tree_ref::*;

pub trait TreeNodeBuilder {
    ///
    /// Sets the children of a tree node to a set of tree node references
    ///
    fn set_children_refs<'a>(&mut self, new_children: &'a Vec<Rc<TreeNode>>);
}

type ChildList = Rc<Vec<Rc<TreeNode>>>;

impl<T: MutableTreeNode> TreeNodeBuilder for T {
    fn set_children_refs<'a>(&mut self, new_children: &'a Vec<Rc<TreeNode>>) {
        let num_new_children = new_children.len();

        if num_new_children > 0 {
            // Build the final child node backwards
            let mut new_child = new_children[num_new_children-1].with_no_sibling();

            for child_num in (0..(num_new_children-1)).rev() {
                new_child = new_children[child_num].with_sibling_ref(&new_child);
            }

            self.set_child(new_child);
        } else {
            // No children
            self.clear_child();
        }
    }
}

///
/// Macro that will create a tree from a set of expressions that support the ToTreeNode trait
///
/// The first parameter is the root item, followed by the child items
///
macro_rules! tree {
    ( $root: expr, $( $child: expr ), * ) => {
        {
            let mut root        = BasicTree::from($root);
            let mut child_list  = Vec::new();

            $(
                child_list.push($child.to_tree_node());
            )*

            root.set_children_refs(&child_list);

            root
        }
    }
}

#[cfg(test)]
mod treenode_builder_tests {
    use super::super::treenode::*;
    use super::super::basictree::*;

    #[test]
    fn can_build_tree() {
        let mut root = BasicTree::new("test", ());
        let child_list = vec!["child1".to_tree_node(), "child2".to_tree_node(), "child3".to_tree_node()];

        root.set_children_refs(&child_list);

        assert!(root.get_child_ref().is_some());
        assert!(root.get_child_ref_at(0).map(|x| x.get_tag() == "child1").unwrap_or(false));
        assert!(root.get_child_ref_at(1).map(|x| x.get_tag() == "child2").unwrap_or(false));
        assert!(root.get_child_ref_at(2).map(|x| x.get_tag() == "child3").unwrap_or(false));
        assert!(root.get_child_ref_at(3).is_none());
    }

    #[test]
    fn can_build_tree_macro() {
        let root = tree!("root", "child1", ("child2", "value"), tree!("child3", "grandchild1")).to_tree_node();

        assert!((*root).get_child_ref().is_some());
        assert!((*root).get_child_ref_at(0).map(|x| x.get_tag() == "child1").unwrap_or(false));
        assert!((*root).get_child_ref_at(1).map(|x| x.get_tag() == "child2").unwrap_or(false));
        assert!((*root).get_child_ref_at(2).map(|x| x.get_tag() == "child3").unwrap_or(false));
        assert!((*root).get_child_ref_at(2).and_then(|x| (**x).get_child_ref_at(0)).map(|x| x.get_tag() == "grandchild1").unwrap_or(false));
        assert!((*root).get_child_ref_at(3).is_none());
    }
}
<commit_msg>Make tree! return a Rc<TreeNode> instead of a BasicTree<commit_after>use std::rc::*;

use super::treenode::*;
use super::tree_ref::*;

pub trait TreeNodeBuilder {
    ///
    /// Sets the children of a tree node to a set of tree node references
    ///
    fn set_children_refs<'a>(&mut self, new_children: &'a Vec<Rc<TreeNode>>);
}

type ChildList = Rc<Vec<Rc<TreeNode>>>;

impl<T: MutableTreeNode> TreeNodeBuilder for T {
    fn set_children_refs<'a>(&mut self, new_children: &'a Vec<Rc<TreeNode>>) {
        let num_new_children = new_children.len();

        if num_new_children > 0 {
            // Build the final child node backwards
            let mut new_child = new_children[num_new_children-1].with_no_sibling();

            for child_num in (0..(num_new_children-1)).rev() {
                new_child = new_children[child_num].with_sibling_ref(&new_child);
            }

            self.set_child(new_child);
        } else {
            // No children
            self.clear_child();
        }
    }
}

///
/// Macro that will create a tree from a set of expressions that support the ToTreeNode trait
///
/// The first parameter is the root item, followed by the child items
///
macro_rules! tree {
    ( $root: expr, $( $child: expr ), * ) => {
        {
            use std::rc::*;

            let mut root        = BasicTree::from($root);
            let mut child_list  = Vec::new();

            $(
                child_list.push($child.to_tree_node());
            )*

            root.set_children_refs(&child_list);

            let result: Rc<TreeNode> = Rc::new(root);
            result
        }
    }
}

#[cfg(test)]
mod treenode_builder_tests {
    use super::super::treenode::*;
    use super::super::basictree::*;

    #[test]
    fn can_build_tree() {
        let mut root = BasicTree::new("test", ());
        let child_list = vec!["child1".to_tree_node(), "child2".to_tree_node(), "child3".to_tree_node()];

        root.set_children_refs(&child_list);

        assert!(root.get_child_ref().is_some());
        assert!(root.get_child_ref_at(0).map(|x| x.get_tag() == "child1").unwrap_or(false));
        assert!(root.get_child_ref_at(1).map(|x| x.get_tag() == "child2").unwrap_or(false));
        assert!(root.get_child_ref_at(2).map(|x| x.get_tag() == "child3").unwrap_or(false));
        assert!(root.get_child_ref_at(3).is_none());
    }

    #[test]
    fn can_build_tree_macro() {
        let root = tree!("root", "child1", ("child2", "value"), tree!("child3", "grandchild1"));

        assert!((*root).get_child_ref().is_some());
        assert!((*root).get_child_ref_at(0).map(|x| x.get_tag() == "child1").unwrap_or(false));
        assert!((*root).get_child_ref_at(1).map(|x| x.get_tag() == "child2").unwrap_or(false));
        assert!((*root).get_child_ref_at(2).map(|x| x.get_tag() == "child3").unwrap_or(false));
        assert!((*root).get_child_ref_at(2).and_then(|x| (**x).get_child_ref_at(0)).map(|x| x.get_tag() == "grandchild1").unwrap_or(false));
        assert!((*root).get_child_ref_at(3).is_none());
    }
}
<|endoftext|>


<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

use gtk::ffi;

pub struct TreeIter {
    pointer: *mut ffi::C_GtkTreeIter
}

impl TreeIter {
    pub fn new() -> Option<TreeIter> {
        let tmp_pointer = unsafe { ffi::gtk_tree_iter_copy(::std::mem::uninitialized()) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(TreeIter {
                pointer: tmp_pointer
            })
        }
    }

    pub fn copy(&self) -> Option<TreeIter> {
        let tmp_pointer = unsafe { ffi::gtk_tree_iter_copy(self.pointer) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(TreeIter {
                pointer: tmp_pointer
            })
        }
    }

    #[doc(hidden)]
    pub fn get_pointer(&self) -> *mut ffi::C_GtkTreeIter {
        self.pointer
    }

    #[doc(hidden)]
    pub fn wrap_pointer(c_treeiter: *mut ffi::C_GtkTreeIter) -> TreeIter {
        TreeIter {
            pointer: c_treeiter
        }
    }
}

impl Drop for TreeIter {
    fn drop(&mut self) {
        if !self.pointer.is_null() {
            unsafe { ffi::gtk_tree_iter_free(self.pointer) };
            self.pointer = ::std::ptr::null_mut();
        }
    }
}
<commit_msg>Don't drop TreeIter created by wrap_pointer<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

use gtk::ffi;

pub struct TreeIter {
    pointer: *mut ffi::C_GtkTreeIter,
    is_owned: bool,
}

impl TreeIter {
    pub fn new() -> Option<TreeIter> {
        let tmp_pointer = unsafe { ffi::gtk_tree_iter_copy(::std::mem::uninitialized()) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(TreeIter {
                pointer: tmp_pointer,
                is_owned: true,
            })
        }
    }

    pub fn copy(&self) -> Option<TreeIter> {
        let tmp_pointer = unsafe { ffi::gtk_tree_iter_copy(self.pointer) };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(TreeIter {
                pointer: tmp_pointer,
                is_owned: true,
            })
        }
    }

    #[doc(hidden)]
    pub fn get_pointer(&self) -> *mut ffi::C_GtkTreeIter {
        self.pointer
    }

    #[doc(hidden)]
    pub fn wrap_pointer(c_treeiter: *mut ffi::C_GtkTreeIter) -> TreeIter {
        TreeIter {
            pointer: c_treeiter,
            is_owned: false,
        }
    }
}

impl Drop for TreeIter {
    fn drop(&mut self) {
        if !self.pointer.is_null() && self.is_owned {
            unsafe { ffi::gtk_tree_iter_free(self.pointer) };
            self.pointer = ::std::ptr::null_mut();
        }
    }
}
<|endoftext|>


<commit_before>use std::iter;
use super::stacks_and_queues::bag::{Bag, Iter};
use super::stacks_and_queues::{Stack, Queue};
use super::stacks_and_queues::linked_stack;
use super::stacks_and_queues::resizing_array_queue::ResizingArrayQueue;

#[derive(Clone, Debug)]
pub struct Graph {
    v: usize,
    e: usize,
    adj: Vec<Bag<usize>>
}

impl Graph {
    pub fn new(v: usize) -> Graph {
        Graph {
            v: v,
            e: 0,
            adj: iter::repeat(Bag::<usize>::new()).take(v).collect()
        }
    }

    fn validate_vertex(&self, v: usize) {
        assert!(v < self.v, "vertex is not between 0 and {}", self.v - 1)
    }

    pub fn vertices(&self) -> usize {
        self.v
    }

    pub fn edges(&self) -> usize {
        self.e
    }

    pub fn add_edge(&mut self, v: usize, w: usize) {
        self.validate_vertex(v);
        self.validate_vertex(w);

        self.e += 1;
        self.adj[v].add(w);
        self.adj[w].add(v);
    }

    // FIXME: should this be a global function
    pub fn degree(&self, v: usize) -> usize {
        self.validate_vertex(v);
        self.adj[v].len()
    }

    pub fn max_degree(&self) -> usize {
        (0 .. self.vertices()).map(|v| self.degree(v)).max().unwrap_or(0)
    }

    pub fn average_degree(&self) -> f64 {
        // (0 .. self.vertices()) .map(|v| self.degree(v)).sum::<usize>() as f64 / self.vertices() as f64
        2.0 * self.edges() as f64 / self.vertices() as f64
    }

    pub fn number_of_self_loops(&self) -> usize {
        let mut count = 0;
        for v in 0 .. self.vertices() {
            for w in self.adj(v) {
                if v == *w {
                    count += 1;
                }
            }
        }
        count / 2
    }

    pub fn to_dot(&self) -> String {
        let mut dot = String::new();

        dot.push_str("graph G {\n");
        for i in 0 .. self.v {
            dot.push_str(&format!("  {};\n", i));
        }

        for (v, adj) in self.adj.iter().enumerate() {
            for w in adj.iter() {
                dot.push_str(&format!("  {} -- {};\n", v, w));
            }
        }
        dot.push_str("}\n");
        dot
    }

    pub fn adj(&self, v: usize) -> Iter<usize> {
        self.adj[v].iter()
    }

    pub fn dfs<'a>(&'a self, s: usize) -> SearchPaths<'a> {
        let mut path = SearchPaths::new(self, s);
        path.dfs(s);
        path
    }

    pub fn bfs<'a>(&'a self, s: usize) -> SearchPaths<'a> {
        let mut path = SearchPaths::new(self, s);
        path.bfs(s);
        path
    }
}

pub struct SearchPaths<'a> {
    graph: &'a Graph,
    marked: Vec<bool>,
    edge_to: Vec<Option<usize>>,
    s: usize
}

impl<'a> SearchPaths<'a> {
    fn new<'b>(graph: &'b Graph, s: usize) -> SearchPaths<'b> {
        let marked = iter::repeat(false).take(graph.vertices()).collect();
        let edge_to = iter::repeat(None).take(graph.vertices()).collect();
        SearchPaths {
            graph: graph,
            marked: marked,
            edge_to: edge_to,
            s: s
        }
    }

    fn dfs(&mut self, v: usize) {
        self.marked[v] = true;
        for w in self.graph.adj(v) {
            if !self.marked[*w] {
                self.dfs(*w);
                self.edge_to[*w] = Some(v);
            }
        }
    }

    fn bfs(&mut self, s: usize) {
        let mut q = ResizingArrayQueue::new();
        q.enqueue(s);
        self.marked[s] = true;
        while !q.is_empty() {
            let v = q.dequeue().unwrap();
            for w in self.graph.adj(v) {
                if !self.marked[*w] {
                    self.edge_to[*w] = Some(v);
                    q.enqueue(*w);
                    self.marked[*w] = true;
                }
            }
        }
    }

    pub fn has_path_to(&self, v: usize) -> bool {
        self.marked[v]
    }

    pub fn path_to(&self, v: usize) -> Option<Vec<usize>> {
        if !self.has_path_to(v) {
            None
        } else {
            let mut path = linked_stack::LinkedStack::new();
            let mut x = v;
            while x != self.s {
                path.push(x);
                x = self.edge_to[x].unwrap();
            }
            path.push(self.s);
            Some(path.into_iter().collect())
        }
    }
}

#[test]
fn test_graph_visit() {
    let mut g = Graph::new(13);
    g.add_edge(0, 1);
    g.add_edge(0, 2);
    g.add_edge(0, 6);
    g.add_edge(0, 5);
    g.add_edge(5, 3);
    g.add_edge(5, 4);
    g.add_edge(3, 4);
    g.add_edge(4, 6);

    g.add_edge(7, 8);

    g.add_edge(9, 10);
    g.add_edge(9, 11);
    g.add_edge(9, 12);
    g.add_edge(11, 12);

    println!("dot => \n {}", g.to_dot());
    assert_eq!(format!("{:?}", g.dfs(0).path_to(3).unwrap()), "[0, 5, 4, 3]");
    assert_eq!(format!("{:?}", g.bfs(0).path_to(3).unwrap()), "[0, 5, 3]");
}

#[test]
fn test_graph() {
    let mut g = Graph::new(10);
    g.add_edge(0, 3);
    g.add_edge(0, 5);
    g.add_edge(4, 5);
    g.add_edge(2, 9);
    g.add_edge(2, 8);
    g.add_edge(3, 7);

    g.add_edge(1, 6);
    g.add_edge(6, 9);
    g.add_edge(5, 8);

    // println!("got => \n{}", g.to_dot());

    assert_eq!(10, g.vertices());
    assert_eq!(9, g.edges());
    assert_eq!(3, g.degree(5));

    for w in g.adj(5) {
        assert!(vec![8, 4, 0].contains(w));
    }

    assert_eq!(g.max_degree(), 3);
    assert!(g.average_degree() < 2.0);
    assert_eq!(g.number_of_self_loops(), 0);
}

#[test]
fn test_graph_functions() {
    let mut g = Graph::new(5);
    for i in 0 .. 5 {
        for j in 0 .. 5 {
            g.add_edge(i, j);
        }
    }

    assert_eq!(10, g.max_degree());
    assert_eq!(5, g.number_of_self_loops());
}
<commit_msg>undirected_graphs: add ConnectedComponents support for Graph<commit_after>use std::iter;
use super::stacks_and_queues::bag::{Bag, Iter};
use super::stacks_and_queues::{Stack, Queue};
use super::stacks_and_queues::linked_stack;
use super::stacks_and_queues::resizing_array_queue::ResizingArrayQueue;

#[derive(Clone, Debug)]
pub struct Graph {
    v: usize,
    e: usize,
    adj: Vec<Bag<usize>>
}

impl Graph {
    pub fn new(v: usize) -> Graph {
        Graph {
            v: v,
            e: 0,
            adj: iter::repeat(Bag::<usize>::new()).take(v).collect()
        }
    }

    fn validate_vertex(&self, v: usize) {
        assert!(v < self.v, "vertex is not between 0 and {}", self.v - 1)
    }

    pub fn vertices(&self) -> usize {
        self.v
    }

    pub fn edges(&self) -> usize {
        self.e
    }

    pub fn add_edge(&mut self, v: usize, w: usize) {
        self.validate_vertex(v);
        self.validate_vertex(w);

        self.e += 1;
        self.adj[v].add(w);
        self.adj[w].add(v);
    }

    // FIXME: should this be a global function
    pub fn degree(&self, v: usize) -> usize {
        self.validate_vertex(v);
        self.adj[v].len()
    }

    pub fn max_degree(&self) -> usize {
        (0 .. self.vertices()).map(|v| self.degree(v)).max().unwrap_or(0)
    }

    pub fn average_degree(&self) -> f64 {
        // (0 .. self.vertices()) .map(|v| self.degree(v)).sum::<usize>() as f64 / self.vertices() as f64
        2.0 * self.edges() as f64 / self.vertices() as f64
    }

    pub fn number_of_self_loops(&self) -> usize {
        let mut count = 0;
        for v in 0 .. self.vertices() {
            for w in self.adj(v) {
                if v == *w {
                    count += 1;
                }
            }
        }
        count / 2
    }

    pub fn to_dot(&self) -> String {
        let mut dot = String::new();

        dot.push_str("graph G {\n");
        for i in 0 .. self.v {
            dot.push_str(&format!("  {};\n", i));
        }

        for (v, adj) in self.adj.iter().enumerate() {
            for w in adj.iter() {
                dot.push_str(&format!("  {} -- {};\n", v, w));
            }
        }
        dot.push_str("}\n");
        dot
    }

    pub fn adj(&self, v: usize) -> Iter<usize> {
        self.adj[v].iter()
    }

    pub fn dfs<'a>(&'a self, s: usize) -> SearchPaths<'a> {
        let mut path = SearchPaths::new(self, s);
        path.dfs(s);
        path
    }

    pub fn bfs<'a>(&'a self, s: usize) -> SearchPaths<'a> {
        let mut path = SearchPaths::new(self, s);
        path.bfs(s);
        path
    }

    pub fn cc<'a>(&'a self) -> ConnectedComponents<'a> {
        ConnectedComponents::new(self)
    }
}

pub struct SearchPaths<'a> {
    graph: &'a Graph,
    marked: Vec<bool>,
    edge_to: Vec<Option<usize>>,
    s: usize
}

impl<'a> SearchPaths<'a> {
    fn new<'b>(graph: &'b Graph, s: usize) -> SearchPaths<'b> {
        let marked = iter::repeat(false).take(graph.vertices()).collect();
        let edge_to = iter::repeat(None).take(graph.vertices()).collect();
        SearchPaths {
            graph: graph,
            marked: marked,
            edge_to: edge_to,
            s: s
        }
    }

    fn dfs(&mut self, v: usize) {
        self.marked[v] = true;
        for w in self.graph.adj(v) {
            if !self.marked[*w] {
                self.dfs(*w);
                self.edge_to[*w] = Some(v);
            }
        }
    }

    fn bfs(&mut self, s: usize) {
        let mut q = ResizingArrayQueue::new();
        q.enqueue(s);
        self.marked[s] = true;
        while !q.is_empty() {
            let v = q.dequeue().unwrap();
            for w in self.graph.adj(v) {
                if !self.marked[*w] {
                    self.edge_to[*w] = Some(v);
                    q.enqueue(*w);
                    self.marked[*w] = true;
                }
            }
        }
    }

    pub fn has_path_to(&self, v: usize) -> bool {
        self.marked[v]
    }

    pub fn path_to(&self, v: usize) -> Option<Vec<usize>> {
        if !self.has_path_to(v) {
            None
        } else {
            let mut path = linked_stack::LinkedStack::new();
            let mut x = v;
            while x != self.s {
                path.push(x);
                x = self.edge_to[x].unwrap();
            }
            path.push(self.s);
            Some(path.into_iter().collect())
        }
    }
}

pub struct ConnectedComponents<'a> {
    graph: &'a Graph,
    marked: Vec<bool>,
    id: Vec<Option<usize>>,
    n: usize,
    count: usize,
}

impl<'a> ConnectedComponents<'a> {
    fn new<'b>(graph: &'b Graph) -> ConnectedComponents<'b> {
        let n = graph.vertices();
        let mut cc = ConnectedComponents {
            graph: graph,
            marked: iter::repeat(false).take(n).collect(),
            id: iter::repeat(None).take(n).collect(),
            n: n,
            count: 0
        };
        cc.init();
        cc
    }

    fn init(&mut self) {
        for v in 0 .. self.n {
            if !self.marked[v] {
                self.dfs(v);
                self.count += 1;
            }
        }
    }

    pub fn count(&self) -> usize {
        self.count
    }

    pub fn id(&self, v: usize) -> usize {
        self.id[v].unwrap()
    }

    fn dfs(&mut self, v: usize) {
        self.marked[v] = true;
        self.id[v] = Some(self.count);
        for w in self.graph.adj(v) {
            if !self.marked[*w] {
                self.dfs(*w)
            }
        }
    }
}

#[test]
fn test_graph_visit() {
    let mut g = Graph::new(13);
    g.add_edge(0, 1);
    g.add_edge(0, 2);
    g.add_edge(0, 6);
    g.add_edge(0, 5);
    g.add_edge(5, 3);
    g.add_edge(5, 4);
    g.add_edge(3, 4);
    g.add_edge(4, 6);

    g.add_edge(7, 8);

    g.add_edge(9, 10);
    g.add_edge(9, 11);
    g.add_edge(9, 12);
    g.add_edge(11, 12);

    // println!("dot => \n {}", g.to_dot());
    assert_eq!(format!("{:?}", g.dfs(0).path_to(3).unwrap()), "[0, 5, 4, 3]");
    assert_eq!(format!("{:?}", g.bfs(0).path_to(3).unwrap()), "[0, 5, 3]");

    assert_eq!(g.cc().id(4), 0);
    assert_eq!(g.cc().id(8), 1);
    assert_eq!(g.cc().id(11), 2);
}

#[test]
fn test_graph() {
    let mut g = Graph::new(10);
    g.add_edge(0, 3);
    g.add_edge(0, 5);
    g.add_edge(4, 5);
    g.add_edge(2, 9);
    g.add_edge(2, 8);
    g.add_edge(3, 7);

    g.add_edge(1, 6);
    g.add_edge(6, 9);
    g.add_edge(5, 8);

    // println!("got => \n{}", g.to_dot());

    assert_eq!(10, g.vertices());
    assert_eq!(9, g.edges());
    assert_eq!(3, g.degree(5));

    for w in g.adj(5) {
        assert!(vec![8, 4, 0].contains(w));
    }

    assert_eq!(g.max_degree(), 3);
    assert!(g.average_degree() < 2.0);
    assert_eq!(g.number_of_self_loops(), 0);
}

#[test]
fn test_graph_functions() {
    let mut g = Graph::new(5);
    for i in 0 .. 5 {
        for j in 0 .. 5 {
            g.add_edge(i, j);
        }
    }

    assert_eq!(10, g.max_degree());
    assert_eq!(5, g.number_of_self_loops());
}
<|endoftext|>


<commit_before>use std::io;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::collections::HashMap;
use std::process::{Command, Stdio};

use clap::{App, Arg, ArgMatches};
use hyper::method::Method;
use multipart::client::Multipart;
use serde_json;
use walkdir::{WalkDir, Iter as WalkDirIter};
use zip;
use which::which;

use super::super::CliResult;
use super::super::utils::TempFile;
use super::Config;
use super::super::macho::is_macho_file;

enum UploadTarget {
    Global,
    Project {
        org: String,
        project: String
    }
}

impl UploadTarget {

    pub fn get_api_path(&self) -> String {
        match *self {
            UploadTarget::Global => "/system/global-dsyms/".to_owned(),
            UploadTarget::Project { ref org, ref project } => {
                format!("/projects/{}/{}/files/dsyms/", org, project)
            }
        }
    }
}

// XXX: when serde 0.7 lands we can remove the unused ones here.
// Currently we need them as it does otherwise error out on parsing :(
#[derive(Debug, Deserialize)]
struct DSymFile {
    id: String,
    sha1: String,
    uuid: String,
    size: i64,
    #[serde(rename="objectName")]
    object_name: String,
    #[serde(rename="symbolType")]
    symbol_type: String,
    headers: HashMap<String, String>,
    #[serde(rename="dateCreated")]
    date_created: String,
    #[serde(rename="cpuName")]
    cpu_name: String,
}

fn invoke_dsymutil(path: &Path) -> CliResult<TempFile> {
    let tf = try!(TempFile::new());
    let out = try!(Command::new("dsymutil")
        .arg("-o")
        .arg(&tf.path())
        .arg("--flat")
        .arg(&path)
        .stderr(Stdio::null())
        .output());
    if out.status.success() {
        Ok(tf)
    } else {
        fail!("dsymutil failed to extract symbols");
    }
}

struct BatchIterTarget {
    pub tf: TempFile,
    pub zip: zip::ZipWriter<File>,
    pub item_count: u32,
}

struct BatchIter {
    path: PathBuf,
    wd_iter: WalkDirIter,
    use_dsymutil: bool,
    target: Option<BatchIterTarget>,
}

impl BatchIter {
    pub fn new<P: AsRef<Path>>(path: P, use_dsymutil: bool) -> BatchIter {
        BatchIter {
            path: path.as_ref().to_path_buf(),
            wd_iter: WalkDir::new(&path).into_iter(),
            use_dsymutil: use_dsymutil,
            target: None,
        }
    }

    fn ensure_target(&mut self) -> CliResult<()> {
        match self.target {
            Some(_) => Ok(()),
            None => {
                println!("Creating new batch:");
                let tf = try!(TempFile::new());
                let f = try!(File::create(tf.path()));
                self.target = Some(BatchIterTarget {
                    tf: tf,
                    zip: zip::ZipWriter::new(f),
                    item_count: 0,
                });
                Ok(())
            }
        }
    }
}

impl Iterator for BatchIter {
    type Item = CliResult<TempFile>;

    fn next(&mut self) -> Option<CliResult<TempFile>> {
        loop {
            if let Some(dent_res) = self.wd_iter.next() {
                let dent = iter_try!(dent_res);
                let md = iter_try!(dent.metadata());
                if md.is_file() && is_macho_file(dent.path()) {
                    iter_try!(self.ensure_target());
                    {
                        let target = &mut self.target.as_mut().unwrap();
                        let arc_base = Path::new("DebugSymbols");
                        let name = arc_base.join(dent.path().strip_prefix(&self.path).unwrap());
                        iter_try!(target.zip.start_file(
                            name.to_string_lossy().into_owned(),
                            zip::CompressionMethod::Deflated));
                        println!("  {}", name.display());
                        if self.use_dsymutil {
                            let sf = iter_try!(invoke_dsymutil(dent.path()));
                            let mut f = iter_try!(File::open(sf.path()));
                            iter_try!(io::copy(&mut f, &mut target.zip));
                        } else {
                            let mut f = iter_try!(File::open(dent.path()));
                            iter_try!(io::copy(&mut f, &mut target.zip));
                        }
                        target.item_count += 1;
                    }
                    if self.target.as_ref().unwrap().item_count > 10 {
                        return Some(Ok(self.target.take().unwrap().tf));
                    }
                }
            } else {
                break;
            }
        }
        None
    }
}

fn upload_dsyms(tf: &TempFile, config: &Config,
                target: &UploadTarget) -> CliResult<Vec<DSymFile>> {
    let req = try!(config.api_request(Method::Post, &target.get_api_path()));
    let mut mp = try!(Multipart::from_request_sized(req));
    mp.write_file("file", &tf.path());
    let mut resp = try!(mp.send());
    Ok(try!(serde_json::from_reader(&mut resp)))
}

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b>
{
    app
        .about("uploads debug symbols to a project")
        .arg(Arg::with_name("org")
             .value_name("ORG")
             .long("org")
             .short("o")
             .help("The organization slug"))
        .arg(Arg::with_name("project")
             .value_name("PROJECT")
             .long("project")
             .short("p")
             .help("The project slug"))
        .arg(Arg::with_name("global")
             .long("global")
             .short("g")
             .help("Uploads the dsyms globally. This can only be done \
                    with super admin access for the Sentry installation"))
        .arg(Arg::with_name("use_dsymutil")
             .long("use-dsymutil")
             .help("Invoke dsymutil on encountered macho binaries to extract \
                    the symbols before uploading.  This requires the dsymutil \
                    binary to be available."))
        .arg(Arg::with_name("path")
             .value_name("PATH")
             .help("The path to the debug symbols")
             .required(true)
             .index(1))
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> CliResult<()> {
    let path = matches.value_of("path").unwrap();
    let target = if matches.is_present("global") {
        UploadTarget::Global
    } else {
        if !matches.is_present("org") || !matches.is_present("project") {
            fail!("For non global uploads both organization and project are required");
        }
        UploadTarget::Project {
            org: matches.value_of("org").unwrap().to_owned(),
            project: matches.value_of("project").unwrap().to_owned(),
        }
    };
    let use_dsymutil = matches.is_present("use_dsymutil");

    if use_dsymutil {
        if let Err(_) = which("dsymutil") {
            fail!("dsymutil not installed but required for operation.");
        } else {
            println!("Extracting symbols with dsymutil.");
        }
    }

    println!("Creating archives from {}...", path);

    let iter = BatchIter::new(path, use_dsymutil);
    for tf_res in iter {
        let tf = try!(tf_res);
        println!("Uploading archive ...");
        let rv = try!(upload_dsyms(&tf, config, &target));
        if rv.len() == 0 {
            fail!("Server did not accept any debug symbols.");
        } else {
            println!("Accepted debug symbols:");
            for df in rv {
                println!("  {} ({}; {})", df.uuid, df.object_name, df.cpu_name);
            }
        }
    }

    Ok(())
}
<commit_msg>Clear out remaining batch items<commit_after>use std::io;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::collections::HashMap;
use std::process::{Command, Stdio};

use clap::{App, Arg, ArgMatches};
use hyper::method::Method;
use multipart::client::Multipart;
use serde_json;
use walkdir::{WalkDir, Iter as WalkDirIter};
use zip;
use which::which;

use super::super::CliResult;
use super::super::utils::TempFile;
use super::Config;
use super::super::macho::is_macho_file;

const BATCH_SIZE : u32 = 10;

enum UploadTarget {
    Global,
    Project {
        org: String,
        project: String
    }
}

impl UploadTarget {

    pub fn get_api_path(&self) -> String {
        match *self {
            UploadTarget::Global => "/system/global-dsyms/".to_owned(),
            UploadTarget::Project { ref org, ref project } => {
                format!("/projects/{}/{}/files/dsyms/", org, project)
            }
        }
    }
}

// XXX: when serde 0.7 lands we can remove the unused ones here.
// Currently we need them as it does otherwise error out on parsing :(
#[derive(Debug, Deserialize)]
struct DSymFile {
    id: String,
    sha1: String,
    uuid: String,
    size: i64,
    #[serde(rename="objectName")]
    object_name: String,
    #[serde(rename="symbolType")]
    symbol_type: String,
    headers: HashMap<String, String>,
    #[serde(rename="dateCreated")]
    date_created: String,
    #[serde(rename="cpuName")]
    cpu_name: String,
}

fn invoke_dsymutil(path: &Path) -> CliResult<TempFile> {
    let tf = try!(TempFile::new());
    let out = try!(Command::new("dsymutil")
        .arg("-o")
        .arg(&tf.path())
        .arg("--flat")
        .arg(&path)
        .stderr(Stdio::null())
        .output());
    if out.status.success() {
        Ok(tf)
    } else {
        fail!("dsymutil failed to extract symbols");
    }
}

struct BatchIterTarget {
    pub tf: TempFile,
    pub zip: zip::ZipWriter<File>,
    pub item_count: u32,
}

struct BatchIter {
    path: PathBuf,
    wd_iter: WalkDirIter,
    use_dsymutil: bool,
    target: Option<BatchIterTarget>,
}

impl BatchIter {
    pub fn new<P: AsRef<Path>>(path: P, use_dsymutil: bool) -> BatchIter {
        BatchIter {
            path: path.as_ref().to_path_buf(),
            wd_iter: WalkDir::new(&path).into_iter(),
            use_dsymutil: use_dsymutil,
            target: None,
        }
    }

    fn ensure_target(&mut self) -> CliResult<()> {
        match self.target {
            Some(_) => Ok(()),
            None => {
                println!("Creating new batch:");
                let tf = try!(TempFile::new());
                let f = try!(File::create(tf.path()));
                self.target = Some(BatchIterTarget {
                    tf: tf,
                    zip: zip::ZipWriter::new(f),
                    item_count: 0,
                });
                Ok(())
            }
        }
    }
}

impl Iterator for BatchIter {
    type Item = CliResult<TempFile>;

    fn next(&mut self) -> Option<CliResult<TempFile>> {
        loop {
            if let Some(dent_res) = self.wd_iter.next() {
                let dent = iter_try!(dent_res);
                let md = iter_try!(dent.metadata());
                if md.is_file() && is_macho_file(dent.path()) {
                    iter_try!(self.ensure_target());
                    {
                        let target = &mut self.target.as_mut().unwrap();
                        let arc_base = Path::new("DebugSymbols");
                        let name = arc_base.join(dent.path().strip_prefix(&self.path).unwrap());
                        iter_try!(target.zip.start_file(
                            name.to_string_lossy().into_owned(),
                            zip::CompressionMethod::Deflated));
                        println!("  {}", name.display());
                        if self.use_dsymutil {
                            let sf = iter_try!(invoke_dsymutil(dent.path()));
                            let mut f = iter_try!(File::open(sf.path()));
                            iter_try!(io::copy(&mut f, &mut target.zip));
                        } else {
                            let mut f = iter_try!(File::open(dent.path()));
                            iter_try!(io::copy(&mut f, &mut target.zip));
                        }
                        target.item_count += 1;
                    }
                    if self.target.as_ref().unwrap().item_count > BATCH_SIZE {
                        return Some(Ok(self.target.take().unwrap().tf));
                    }
                }
            } else {
                break;
            }
        }
        self.target.take().map(|val| Ok(val.tf))
    }
}

fn upload_dsyms(tf: &TempFile, config: &Config,
                target: &UploadTarget) -> CliResult<Vec<DSymFile>> {
    let req = try!(config.api_request(Method::Post, &target.get_api_path()));
    let mut mp = try!(Multipart::from_request_sized(req));
    mp.write_file("file", &tf.path());
    let mut resp = try!(mp.send());
    Ok(try!(serde_json::from_reader(&mut resp)))
}

pub fn make_app<'a, 'b: 'a>(app: App<'a, 'b>) -> App<'a, 'b>
{
    app
        .about("uploads debug symbols to a project")
        .arg(Arg::with_name("org")
             .value_name("ORG")
             .long("org")
             .short("o")
             .help("The organization slug"))
        .arg(Arg::with_name("project")
             .value_name("PROJECT")
             .long("project")
             .short("p")
             .help("The project slug"))
        .arg(Arg::with_name("global")
             .long("global")
             .short("g")
             .help("Uploads the dsyms globally. This can only be done \
                    with super admin access for the Sentry installation"))
        .arg(Arg::with_name("use_dsymutil")
             .long("use-dsymutil")
             .help("Invoke dsymutil on encountered macho binaries to extract \
                    the symbols before uploading.  This requires the dsymutil \
                    binary to be available."))
        .arg(Arg::with_name("path")
             .value_name("PATH")
             .help("The path to the debug symbols")
             .required(true)
             .index(1))
}

pub fn execute<'a>(matches: &ArgMatches<'a>, config: &Config) -> CliResult<()> {
    let path = matches.value_of("path").unwrap();
    let target = if matches.is_present("global") {
        UploadTarget::Global
    } else {
        if !matches.is_present("org") || !matches.is_present("project") {
            fail!("For non global uploads both organization and project are required");
        }
        UploadTarget::Project {
            org: matches.value_of("org").unwrap().to_owned(),
            project: matches.value_of("project").unwrap().to_owned(),
        }
    };
    let use_dsymutil = matches.is_present("use_dsymutil");

    if use_dsymutil {
        if let Err(_) = which("dsymutil") {
            fail!("dsymutil not installed but required for operation.");
        } else {
            println!("Extracting symbols with dsymutil.");
        }
    }

    println!("Creating archives from {}...", path);

    let iter = BatchIter::new(path, use_dsymutil);
    for tf_res in iter {
        let tf = try!(tf_res);
        println!("Uploading archive ...");
        let rv = try!(upload_dsyms(&tf, config, &target));
        if rv.len() == 0 {
            fail!("Server did not accept any debug symbols.");
        } else {
            println!("Accepted debug symbols:");
            for df in rv {
                println!("  {} ({}; {})", df.uuid, df.object_name, df.cpu_name);
            }
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>use token;

// Calculate accepts input tokens that are
// ordered according to Reverse Polish Notation
// and returns a result
pub fn calculate(input: &Vec<token::Token>) -> f64 {
    let mut input = input.clone();
    let mut stack = Vec::new();
    let mut len = input.len();

    // Iterate over the tokens and calculate a result
    while len > 0 {
        let tok = input.remove(0);
        match tok {
            token::Token::DecimalNumber(n) => stack.push(token::Token::DecimalNumber(n)),
            token::Token::Operator(o, _, _) => {
                let left = stack.pop();
                let right = stack.pop();

                match (left, right) {
                    (Some(token::Token::DecimalNumber(n1)), Some(token::Token::DecimalNumber(n2))) => stack.push(token::Token::DecimalNumber(operate(o, n1, n2))),
                    _ => break
                }
            },
            token::Token::WholeNumber(n) => stack.push(token::Token::DecimalNumber(n as f64)),
            token::Token::FunctionCall(_, _) => break,
            token::Token::LeftParenthesis => (),
            token::Token::RightParenthesis => ()
        }
        len = input.len();
    }

    let result = stack.pop();

    match result {
        Some(token::Token::DecimalNumber(n)) => n,
        _ => -1f64
    }
}

fn operate(operator: char, left: f64, right: f64) -> f64 {
    match operator {
        '+' => left + right,
        '-' => left - right,
        '*' => left * right,
        '/' => left / right,
        _ => 0f64
    }
}
<commit_msg>Fixed the left and right token popping<commit_after>use token;

// Calculate accepts input tokens that are
// ordered according to Reverse Polish Notation
// and returns a result
pub fn calculate(input: &Vec<token::Token>) -> f64 {
    let mut input = input.clone();
    let mut stack = Vec::new();
    let mut len = input.len();

    // Iterate over the tokens and calculate a result
    while len > 0 {
        let tok = input.remove(0);
        match tok {
            token::Token::DecimalNumber(n) => stack.push(token::Token::DecimalNumber(n)),
            token::Token::Operator(o, _, _) => {
                let right = stack.pop();
                let left = stack.pop();

                match (left, right) {
                    (Some(token::Token::DecimalNumber(n1)), Some(token::Token::DecimalNumber(n2))) => stack.push(token::Token::DecimalNumber(operate(o, n1, n2))),
                    _ => break
                }
            },
            token::Token::WholeNumber(n) => stack.push(token::Token::DecimalNumber(n as f64)),
            token::Token::FunctionCall(_, _) => break,
            token::Token::LeftParenthesis => (),
            token::Token::RightParenthesis => ()
        }
        len = input.len();
    }

    let result = stack.pop();

    match result {
        Some(token::Token::DecimalNumber(n)) => n,
        _ => -1f64
    }
}

fn operate(operator: char, left: f64, right: f64) -> f64 {
    match operator {
        '+' => left + right,
        '-' => left - right,
        '*' => left * right,
        '/' => left / right,
        _ => 0f64
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate slog;

extern crate futures;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_uds;

extern crate rdmcommon;

use slog::Logger;

use futures::{Future, Stream, Sink};
use tokio_core::reactor::{Core, Handle};
use tokio_io::AsyncRead;
use tokio_uds::UnixStream;

use rdmcommon::ipc;
use rdmcommon::util;

pub struct RdmGreeter {
    core: Core,
    receiver: Box<Stream<Item = ipc::IpcMessage, Error = ipc::IpcError>>,
    sender: Box<Sink<SinkItem = ipc::IpcMessage, SinkError = ipc::IpcError>>,
    log: Logger
}

impl RdmGreeter {
    pub fn new<L : Into<Option<Logger>>>(logger: L) -> Result<RdmGreeter, ipc::IpcError> {
        let log = logger.into().unwrap_or(util::plain_logger());
        let mut core = Core::new()
            .expect("[rdmgreeter] Failed to instantiate new Core");
        let handle = core.handle();
        // TODO: move this into private fn
        debug!(log, "[RdmGreeter::new] Connecting server socket");
        let sock = UnixStream::connect("/home/florian/tmp/sock", &handle)?;
        let (tx, rx) = sock.framed(ipc::IpcMessageCodec).split();
        debug!(log, "[RdmGreeter::new] Sending ClientHello");
        let tx = core.run(tx.send(ipc::IpcMessage::ClientHello))?;
        debug!(log, "[RdmGreeter::new] Reading server response");
        let (resp, rx) = core.run(rx.take(1).into_future()).expect("[rdmgreeter] Failed to receive handshake");

        debug!(log, "[RdmGreeter::new] Got server response"; "response" => ?resp);
        match resp {
            Some(ipc::IpcMessage::ServerHello) => Ok(RdmGreeter {
                                                core: core,
                                                receiver: Box::new(rx),
                                                sender: Box::new(tx),
                                                log: log,
                                            }),
            _ => Err(ipc::IpcError::UnknownMessageType)
        }
    }
}

impl Drop for RdmGreeter {
    fn drop(&mut self) {
        debug!(self.log, "[RdmGreeter::drop] Dropping RdmGreeter..");
    }
}<commit_msg>[libgreeter] Add RdmGreeterError and make RdmGreeter::new never panic<commit_after>#[macro_use]
extern crate slog;

extern crate futures;
extern crate tokio_core;
extern crate tokio_io;
extern crate tokio_uds;

extern crate rdmcommon;

use slog::Logger;

use futures::{Future, Stream, Sink};

use tokio_core::reactor::{Core, Handle};
use tokio_io::AsyncRead;
use tokio_uds::UnixStream;

use std::io;

use rdmcommon::ipc;
use rdmcommon::util;

pub struct RdmGreeter {
    core: Core,
    receiver: Box<Stream<Item = ipc::IpcMessage, Error = ipc::IpcError>>,
    sender: Box<Sink<SinkItem = ipc::IpcMessage, SinkError = ipc::IpcError>>,
    log: Logger
}

pub enum RdmGreeterError {
    Ipc(ipc::IpcError),
    Io(io::Error),
    FailedHandshake
}

impl From<io::Error> for RdmGreeterError {
    fn from(err: io::Error) -> RdmGreeterError {
        RdmGreeterError::Io(err)
    }
}

impl From<ipc::IpcError> for RdmGreeterError {
    fn from(err: ipc::IpcError) -> RdmGreeterError {
        RdmGreeterError::Ipc(err)
    }
}

impl RdmGreeter {
    pub fn new<L : Into<Option<Logger>>>(logger: L) -> Result<RdmGreeter, RdmGreeterError> {
        let log = logger.into().unwrap_or(util::plain_logger());
        let mut core = Core::new()?;
        let handle = core.handle();
        // TODO: move this into private fn
        debug!(log, "[RdmGreeter::new] Connecting server socket");
        let sock = UnixStream::connect("/home/florian/tmp/sock", &handle)?;
        let (tx, rx) = sock.framed(ipc::IpcMessageCodec).split();
        debug!(log, "[RdmGreeter::new] Sending ClientHello");
        let tx = core.run(tx.send(ipc::IpcMessage::ClientHello))?;
        debug!(log, "[RdmGreeter::new] Reading server response");
        let (resp, rx) = core.run(rx.take(1).into_future().map_err(|(err, _)| err))?;

        debug!(log, "[RdmGreeter::new] Got server response"; "response" => ?resp);
        match resp {
            Some(ipc::IpcMessage::ServerHello) => Ok(RdmGreeter {
                                                        core: core,
                                                        receiver: Box::new(rx),
                                                        sender: Box::new(tx),
                                                        log: log,
                                                  }),
            _ => Err(RdmGreeterError::FailedHandshake)
        }
    }
}

impl Drop for RdmGreeter {
    fn drop(&mut self) {
        debug!(self.log, "[RdmGreeter::drop] Dropping RdmGreeter..");
    }
}<|endoftext|>


<commit_before>#[feature(phase)];

#[phase(syntax, link)]
extern mod mphf;

use mphf::MphfMap;

#[test]
fn test_empty() {
    let map: MphfMap<int> = mphf_map!();
    assert!(map.is_empty());
}

#[test]
fn test_two() {
    static map: MphfMap<int> = mphf_map!(
        "foo" => 10,
        "bar" => 11,
    );
    assert!(Some(&10) == map.find(& &"foo"));
    assert!(Some(&11) == map.find(& &"bar"));
    assert_eq!(None, map.find(& &"asdf"));
}
<commit_msg>A couple of more tests<commit_after>#[feature(phase)];

#[phase(syntax, link)]
extern mod mphf;

use mphf::MphfMap;

#[test]
fn test_trailing_comma() {
    #[allow(dead_code)]
    static _m: MphfMap<int> = mphf_map!(
        "foo" => 10,
    );
}

#[test]
fn test_no_trailing_comma() {
    #[allow(dead_code)]
    static _m: MphfMap<int> = mphf_map!(
        "foo" => 10
    );
}

#[test]
fn test_empty() {
    let map: MphfMap<int> = mphf_map!();
    assert!(map.is_empty());
}

#[test]
fn test_two() {
    static map: MphfMap<int> = mphf_map!(
        "foo" => 10,
        "bar" => 11,
    );
    assert!(Some(&10) == map.find(& &"foo"));
    assert!(Some(&11) == map.find(& &"bar"));
    assert_eq!(None, map.find(& &"asdf"));
    assert_eq!(2, map.len());
}
<|endoftext|>


<commit_before>use nannou::prelude::*;

fn main() {
    nannou::sketch(view).run()
}

fn view(app: &App, frame: Frame) {
    // Begin drawing
    let win = app.window_rect();
    let t = app.time;
    let draw = app.draw();

    // Clear the background to blue.
    draw.background().color(BLACK);

    // Use the mouse position to affect the frequency and amplitude.
    let hz = map_range(app.mouse.x, win.left(), win.right(), 0.0, 100.0);
    let amp = app.mouse.y;

    // Create an iterator yielding triangles for drawing a sine wave.
    let tris = (1..win.w() as usize)
        .flat_map(|i| {
            let l_fract = (i - 1) as f32 / win.w();
            let r_fract = i as f32 / win.w();

            // Map the vertices to the window.
            let l_x = map_range(l_fract, 0.0, 1.0, win.left(), win.right());
            let r_x = map_range(r_fract, 0.0, 1.0, win.left(), win.right());
            let l_y = (t * hz + l_fract * hz * TAU).sin() * amp;
            let r_y = (t * hz + r_fract * hz * TAU).sin() * amp;

            // Produce this slice of the triangle as a quad.
            let a = pt2(l_x, l_y);
            let b = pt2(r_x, r_y);
            let c = pt2(r_x, 0.0);
            let d = pt2(l_x, 0.0);
            geom::Quad([a, b, c, d]).triangles_iter()
        })
        .map(|tri| {
            // Color the vertices based on their amplitude.
            tri.map_vertices(|v| {
                let y_fract = map_range(v.y.abs(), 0.0, win.top(), 0.0, 1.0);
                let color = srgba(y_fract, 1.0 - y_fract, 1.0 - y_fract, 1.0);
                (v, color)
            })
        });

    // Draw the mesh!
    draw.mesh().tris_colored(tris);

    // Write the result of our drawing to the window's frame.
    draw.to_frame(app, &frame).unwrap();
}
<commit_msg>Fix wrong comment.<commit_after>use nannou::prelude::*;

fn main() {
    nannou::sketch(view).run()
}

fn view(app: &App, frame: Frame) {
    // Begin drawing
    let win = app.window_rect();
    let t = app.time;
    let draw = app.draw();

    // Clear the background to black.
    draw.background().color(BLACK);

    // Use the mouse position to affect the frequency and amplitude.
    let hz = map_range(app.mouse.x, win.left(), win.right(), 0.0, 100.0);
    let amp = app.mouse.y;

    // Create an iterator yielding triangles for drawing a sine wave.
    let tris = (1..win.w() as usize)
        .flat_map(|i| {
            let l_fract = (i - 1) as f32 / win.w();
            let r_fract = i as f32 / win.w();

            // Map the vertices to the window.
            let l_x = map_range(l_fract, 0.0, 1.0, win.left(), win.right());
            let r_x = map_range(r_fract, 0.0, 1.0, win.left(), win.right());
            let l_y = (t * hz + l_fract * hz * TAU).sin() * amp;
            let r_y = (t * hz + r_fract * hz * TAU).sin() * amp;

            // Produce this slice of the triangle as a quad.
            let a = pt2(l_x, l_y);
            let b = pt2(r_x, r_y);
            let c = pt2(r_x, 0.0);
            let d = pt2(l_x, 0.0);
            geom::Quad([a, b, c, d]).triangles_iter()
        })
        .map(|tri| {
            // Color the vertices based on their amplitude.
            tri.map_vertices(|v| {
                let y_fract = map_range(v.y.abs(), 0.0, win.top(), 0.0, 1.0);
                let color = srgba(y_fract, 1.0 - y_fract, 1.0 - y_fract, 1.0);
                (v, color)
            })
        });

    // Draw the mesh!
    draw.mesh().tris_colored(tris);

    // Write the result of our drawing to the window's frame.
    draw.to_frame(app, &frame).unwrap();
}
<|endoftext|>


<commit_before>extern crate metl;

use metl::extras::window::{Event, WindowBuilder};

fn main() {
    let window = WindowBuilder::new().build().unwrap();
    let _device = metl::Device::system_default_device().unwrap();

    'mainloop: loop {
        for event in window.poll_events() {
            match event {
                Event::Closed => {
                    break 'mainloop
                }
                _ => {}
            }
        }

        // drawing code here
    }
}
<commit_msg>Set window size<commit_after>extern crate metl;

use metl::extras::window::{Event, WindowBuilder};

fn main() {
    let window = WindowBuilder::new()
                     .with_dimensions(800, 600)
                     .build()
                     .unwrap();
    let _device = metl::Device::system_default_device().unwrap();

    'mainloop: loop {
        for event in window.poll_events() {
            match event {
                Event::Closed => {
                    break 'mainloop
                }
                _ => {}
            }
        }

        // drawing code here
    }
}
<|endoftext|>