<commit_before>use std::io::net::ip::{Ipv4Addr, SocketAddr};

mod libtorresmo {
    extern crate time;

    use std::io::net::udp::UdpSocket;
    use std::io::net::ip::SocketAddr;
    use std::io::IoResult;
    use std::mem::transmute;
    use std::rand::random;
    use std::fmt;

    #[allow(dead_code,non_camel_case_types)]
    enum UtpPacketType {
        ST_DATA  = 0,
        ST_FIN   = 1,
        ST_STATE = 2,
        ST_RESET = 3,
        ST_SYN   = 4,
    }

    impl fmt::Show for UtpPacketType {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let s = match *self {
                ST_DATA  => "ST_DATA",
                ST_FIN   => "ST_FIN",
                ST_STATE => "ST_STATE",
                ST_RESET => "ST_RESET",
                ST_SYN   => "ST_SYN",
            };
            write!(f, "{}", s)
        }
    }

    #[allow(dead_code)]
    #[packed]
    struct UtpPacketHeader {
        type_ver: u8, // type: u4, ver: u4
        extension: u8,
        connection_id: u16,
        timestamp_microseconds: u32,
        timestamp_difference_microseconds: u32,
        wnd_size: u32,
        seq_nr: u16,
        ack_nr: u16,
    }

    impl UtpPacketHeader {
        fn set_type(&mut self, t: UtpPacketType) {
            let version = 0x0F & self.type_ver;
            self.type_ver = t as u8 << 4 | version;
        }

        fn get_type(self) -> UtpPacketType {
            let t: UtpPacketType = unsafe { transmute(self.type_ver >> 4) };
            t
        }

        fn bytes(&self) -> &[u8] {
            unsafe {
                let buf: &[u8, ..20] = transmute(self);
                return buf.as_slice();
            }
        }

        fn len(&self) -> uint {
            static HEADER_SIZE: uint = 20;
            return HEADER_SIZE;
        }

        fn decode(buf: &[u8]) -> UtpPacketHeader {
            UtpPacketHeader {
                type_ver: buf[0],
                extension: buf[1],
                connection_id: buf[2] as u16 << 8 | buf[3] as u16,
                timestamp_microseconds: buf[4] as u32 << 24 | buf[5] as u32 << 16 | buf[6] as u32 << 8 | buf[7] as u32,
                timestamp_difference_microseconds: buf[8] as u32 << 24 | buf[9] as u32 << 16 | buf[10] as u32 << 8 | buf[11] as u32,
                wnd_size: buf[12] as u32 << 24 | buf[13] as u32 << 16 | buf[14] as u32 << 8 | buf[15] as u32,
                seq_nr: buf[16] as u16 << 8 | buf[17] as u16,
                ack_nr: buf[18] as u16 << 8 | buf[19] as u16,
            }
        }
    }

    impl fmt::Show for UtpPacketHeader {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let t: UtpPacketType = self.get_type();
            write!(f, "(type: {}, version: {}, extension: {}, connection_id: {}, timestamp_microseconds: {}, timestamp_difference_microseconds: {}, wnd_size: {}, seq_nr: {}, ack_nr: {})", t, self.type_ver & 0x0F, self.extension, self.connection_id, self.timestamp_microseconds, self.timestamp_difference_microseconds, self.wnd_size, self.seq_nr, self.ack_nr)
        }
    }

    #[allow(dead_code)]
    struct UtpPacket {
        header: UtpPacketHeader,
        payload: Vec<u8>,
    }

    impl UtpPacket {
        /// Constructs a new, empty UtpPacket.
        fn new() -> UtpPacket {
            UtpPacket {
                header: UtpPacketHeader {
                    type_ver: ST_DATA as u8 << 4 | 1,
                    extension: 0,
                    connection_id: 0,
                    timestamp_microseconds: 0,
                    timestamp_difference_microseconds: 0,
                    wnd_size: 0,
                    seq_nr: 0,
                    ack_nr: 0,
                },
                payload: Vec::new(),
            }
        }

        fn set_type(&mut self, t: UtpPacketType) {
            self.header.set_type(t);
        }

        fn get_type(self) -> UtpPacketType {
            self.header.get_type()
        }

        fn bytes(&self) -> Vec<u8> {
            let mut buf: Vec<u8> = Vec::with_capacity(self.len());
            buf.push_all(self.header.bytes());
            buf.push_all(self.payload.as_slice());
            return buf;
        }

        fn len(&self) -> uint {
            self.header.len() + self.payload.len()
        }

        fn decode(buf: &[u8]) -> UtpPacket {
            let header = UtpPacketHeader::decode(buf);
            UtpPacket { header: header, payload: Vec::from_slice(buf.slice(20, buf.len())) }
        }
    }

    pub struct UtpSocket {
        socket: UdpSocket,
    }

    impl UtpSocket {
        pub fn bind(addr: SocketAddr) -> IoResult<UtpSocket> {
            let skt = UdpSocket::bind(addr);
            match skt {
                Ok(x)  => Ok(UtpSocket { socket: x }),
                Err(e) => Err(e)
            }
        }

        pub fn connect(self, other: SocketAddr) -> UtpStream {
            let stream = UtpStream::new(self.socket, other);
            stream.connect()
        }

        pub fn recvfrom(&mut self, buf: &mut[u8]) -> IoResult<(uint,SocketAddr)> {
            self.socket.recvfrom(buf)
        }
    }

    impl Clone for UtpSocket {
        fn clone(&self) -> UtpSocket {
            UtpSocket {
                socket: self.socket.clone(),
            }
        }
    }

    #[allow(dead_code)]
    pub struct UtpStream {
        socket: UdpSocket,
        connected_to: SocketAddr,
        connection_id: u16,
        seq_nr: u16,
        ack_nr: u16,
    }

    #[allow(dead_code)]
    impl UtpStream {
        pub fn new(socket: UdpSocket, conn: SocketAddr) -> UtpStream {
            let r: u16 = random();
            UtpStream {
                socket: socket,
                connected_to: conn,
                connection_id: r.to_be(),
                seq_nr: 1,
                ack_nr: 0,
            }
        }

        pub fn connect(mut self) -> UtpStream {
            let mut packet = UtpPacket::new();
            packet.set_type(ST_SYN);
            packet.header.connection_id = self.connection_id;
            packet.header.seq_nr = self.seq_nr.to_be();
            let t = time::get_time();
            packet.header.timestamp_microseconds = ((t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32).to_be();

            // Send packet
            let _result = self.socket.sendto(packet.bytes().as_slice(), self.connected_to);

            self.seq_nr += 1;

            self
        }

        pub fn terminate(mut self) -> UtpStream {
            let mut packet = UtpPacket::new();
            packet.set_type(ST_FIN);
            packet.header.connection_id = self.connection_id;
            packet.header.seq_nr = self.seq_nr.to_be();
            let t = time::get_time();
            packet.header.timestamp_microseconds = ((t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32).to_be();

            // Send packet
            let _result = self.socket.sendto(packet.bytes().as_slice(), self.connected_to);

            self.seq_nr += 1;

            self
        }

        pub fn disconnect(self) -> UdpSocket {
            self.socket
        }
    }

    impl Reader for UtpStream {
        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
            match self.socket.recvfrom(buf) {
                Ok((_nread, src)) if src != self.connected_to => Ok(0),
                Ok((nread, _src)) => Ok(nread),
                Err(e) => Err(e),
            }
        }
    }
    impl Writer for UtpStream {
        fn write(&mut self, buf: &[u8]) -> IoResult<()> {
            let mut packet = UtpPacket::new();
            packet.payload = Vec::from_slice(buf);
            packet.header.connection_id = self.connection_id;
            packet.header.seq_nr = self.seq_nr.to_be();
            let t = time::get_time();
            packet.header.timestamp_microseconds = ((t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32).to_be();

            // Send packet
            let result = self.socket.sendto(packet.bytes().as_slice(), self.connected_to);

            self.seq_nr += 1;
            result
        }
    }
}

fn usage() {
    println!("Usage: torresmo [-s|-c] <address> <port>");
}

fn main() {
    use libtorresmo::UtpSocket;
    use std::from_str::FromStr;

    // Defaults
    let mut addr = SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 };

    let args = std::os::args();

    if args.len() == 4 {
        let ip = FromStr::from_str(args.get(2).as_slice()).unwrap();
        let port = FromStr::from_str(args.get(3).as_slice()).unwrap();
        addr = SocketAddr { ip: ip, port: port };
    }

    match args.get(1).as_slice() {
        "-s" => {
            let mut buf = [0, ..512];
            let sock = UtpSocket::bind(addr).unwrap();
            println!("Serving on {}", addr);

            loop {
                let mut sock = sock.clone();
                match sock.recvfrom(buf) {
                    Ok((_, src)) => {
                        spawn(proc() {
                            let mut stream = sock.connect(src);
                            let payload = String::from_str("Hello\n").into_bytes();

                            // Send uTP packet
                            let _ = stream.write(payload.as_slice());
                        })
                    }
                    Err(_) => {}
                }
            }
        }
        "-c" => {
            let sock = UtpSocket::bind(SocketAddr { ip: Ipv4Addr(127,0,0,1), port: std::rand::random() }).unwrap();
            let mut stream = sock.connect(addr);
            let _ = stream.write([0]);
            let stream = stream.terminate();
            drop(stream);
        }
        _ => usage(),
    }
}
<commit_msg>Allow comparing UtpPacketType instances.<commit_after>use std::io::net::ip::{Ipv4Addr, SocketAddr};

mod libtorresmo {
    extern crate time;

    use std::io::net::udp::UdpSocket;
    use std::io::net::ip::SocketAddr;
    use std::io::IoResult;
    use std::mem::transmute;
    use std::rand::random;
    use std::fmt;

    #[allow(dead_code,non_camel_case_types)]
    #[deriving(PartialEq,Eq)]
    enum UtpPacketType {
        ST_DATA  = 0,
        ST_FIN   = 1,
        ST_STATE = 2,
        ST_RESET = 3,
        ST_SYN   = 4,
    }

    impl fmt::Show for UtpPacketType {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let s = match *self {
                ST_DATA  => "ST_DATA",
                ST_FIN   => "ST_FIN",
                ST_STATE => "ST_STATE",
                ST_RESET => "ST_RESET",
                ST_SYN   => "ST_SYN",
            };
            write!(f, "{}", s)
        }
    }

    #[allow(dead_code)]
    #[packed]
    struct UtpPacketHeader {
        type_ver: u8, // type: u4, ver: u4
        extension: u8,
        connection_id: u16,
        timestamp_microseconds: u32,
        timestamp_difference_microseconds: u32,
        wnd_size: u32,
        seq_nr: u16,
        ack_nr: u16,
    }

    impl UtpPacketHeader {
        fn set_type(&mut self, t: UtpPacketType) {
            let version = 0x0F & self.type_ver;
            self.type_ver = t as u8 << 4 | version;
        }

        fn get_type(self) -> UtpPacketType {
            let t: UtpPacketType = unsafe { transmute(self.type_ver >> 4) };
            t
        }

        fn bytes(&self) -> &[u8] {
            unsafe {
                let buf: &[u8, ..20] = transmute(self);
                return buf.as_slice();
            }
        }

        fn len(&self) -> uint {
            static HEADER_SIZE: uint = 20;
            return HEADER_SIZE;
        }

        fn decode(buf: &[u8]) -> UtpPacketHeader {
            UtpPacketHeader {
                type_ver: buf[0],
                extension: buf[1],
                connection_id: buf[2] as u16 << 8 | buf[3] as u16,
                timestamp_microseconds: buf[4] as u32 << 24 | buf[5] as u32 << 16 | buf[6] as u32 << 8 | buf[7] as u32,
                timestamp_difference_microseconds: buf[8] as u32 << 24 | buf[9] as u32 << 16 | buf[10] as u32 << 8 | buf[11] as u32,
                wnd_size: buf[12] as u32 << 24 | buf[13] as u32 << 16 | buf[14] as u32 << 8 | buf[15] as u32,
                seq_nr: buf[16] as u16 << 8 | buf[17] as u16,
                ack_nr: buf[18] as u16 << 8 | buf[19] as u16,
            }
        }
    }

    impl fmt::Show for UtpPacketHeader {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let t: UtpPacketType = self.get_type();
            write!(f, "(type: {}, version: {}, extension: {}, connection_id: {}, timestamp_microseconds: {}, timestamp_difference_microseconds: {}, wnd_size: {}, seq_nr: {}, ack_nr: {})", t, self.type_ver & 0x0F, self.extension, self.connection_id, self.timestamp_microseconds, self.timestamp_difference_microseconds, self.wnd_size, self.seq_nr, self.ack_nr)
        }
    }

    #[allow(dead_code)]
    struct UtpPacket {
        header: UtpPacketHeader,
        payload: Vec<u8>,
    }

    impl UtpPacket {
        /// Constructs a new, empty UtpPacket.
        fn new() -> UtpPacket {
            UtpPacket {
                header: UtpPacketHeader {
                    type_ver: ST_DATA as u8 << 4 | 1,
                    extension: 0,
                    connection_id: 0,
                    timestamp_microseconds: 0,
                    timestamp_difference_microseconds: 0,
                    wnd_size: 0,
                    seq_nr: 0,
                    ack_nr: 0,
                },
                payload: Vec::new(),
            }
        }

        fn set_type(&mut self, t: UtpPacketType) {
            self.header.set_type(t);
        }

        fn get_type(self) -> UtpPacketType {
            self.header.get_type()
        }

        fn bytes(&self) -> Vec<u8> {
            let mut buf: Vec<u8> = Vec::with_capacity(self.len());
            buf.push_all(self.header.bytes());
            buf.push_all(self.payload.as_slice());
            return buf;
        }

        fn len(&self) -> uint {
            self.header.len() + self.payload.len()
        }

        fn decode(buf: &[u8]) -> UtpPacket {
            let header = UtpPacketHeader::decode(buf);
            UtpPacket { header: header, payload: Vec::from_slice(buf.slice(20, buf.len())) }
        }
    }

    pub struct UtpSocket {
        socket: UdpSocket,
    }

    impl UtpSocket {
        pub fn bind(addr: SocketAddr) -> IoResult<UtpSocket> {
            let skt = UdpSocket::bind(addr);
            match skt {
                Ok(x)  => Ok(UtpSocket { socket: x }),
                Err(e) => Err(e)
            }
        }

        pub fn connect(self, other: SocketAddr) -> UtpStream {
            let stream = UtpStream::new(self.socket, other);
            stream.connect()
        }

        pub fn recvfrom(&mut self, buf: &mut[u8]) -> IoResult<(uint,SocketAddr)> {
            self.socket.recvfrom(buf)
        }
    }

    impl Clone for UtpSocket {
        fn clone(&self) -> UtpSocket {
            UtpSocket {
                socket: self.socket.clone(),
            }
        }
    }

    #[allow(dead_code)]
    pub struct UtpStream {
        socket: UdpSocket,
        connected_to: SocketAddr,
        connection_id: u16,
        seq_nr: u16,
        ack_nr: u16,
    }

    #[allow(dead_code)]
    impl UtpStream {
        pub fn new(socket: UdpSocket, conn: SocketAddr) -> UtpStream {
            let r: u16 = random();
            UtpStream {
                socket: socket,
                connected_to: conn,
                connection_id: r.to_be(),
                seq_nr: 1,
                ack_nr: 0,
            }
        }

        pub fn connect(mut self) -> UtpStream {
            let mut packet = UtpPacket::new();
            packet.set_type(ST_SYN);
            packet.header.connection_id = self.connection_id;
            packet.header.seq_nr = self.seq_nr.to_be();
            let t = time::get_time();
            packet.header.timestamp_microseconds = ((t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32).to_be();

            // Send packet
            let _result = self.socket.sendto(packet.bytes().as_slice(), self.connected_to);

            self.seq_nr += 1;

            self
        }

        pub fn terminate(mut self) -> UtpStream {
            let mut packet = UtpPacket::new();
            packet.set_type(ST_FIN);
            packet.header.connection_id = self.connection_id;
            packet.header.seq_nr = self.seq_nr.to_be();
            let t = time::get_time();
            packet.header.timestamp_microseconds = ((t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32).to_be();

            // Send packet
            let _result = self.socket.sendto(packet.bytes().as_slice(), self.connected_to);

            self.seq_nr += 1;

            self
        }

        pub fn disconnect(self) -> UdpSocket {
            self.socket
        }
    }

    impl Reader for UtpStream {
        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
            match self.socket.recvfrom(buf) {
                Ok((_nread, src)) if src != self.connected_to => Ok(0),
                Ok((nread, _src)) => Ok(nread),
                Err(e) => Err(e),
            }
        }
    }
    impl Writer for UtpStream {
        fn write(&mut self, buf: &[u8]) -> IoResult<()> {
            let mut packet = UtpPacket::new();
            packet.payload = Vec::from_slice(buf);
            packet.header.connection_id = self.connection_id;
            packet.header.seq_nr = self.seq_nr.to_be();
            let t = time::get_time();
            packet.header.timestamp_microseconds = ((t.sec * 1_000_000) as u32 + (t.nsec/1000) as u32).to_be();

            // Send packet
            let result = self.socket.sendto(packet.bytes().as_slice(), self.connected_to);

            self.seq_nr += 1;
            result
        }
    }
}

fn usage() {
    println!("Usage: torresmo [-s|-c] <address> <port>");
}

fn main() {
    use libtorresmo::UtpSocket;
    use std::from_str::FromStr;

    // Defaults
    let mut addr = SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 };

    let args = std::os::args();

    if args.len() == 4 {
        let ip = FromStr::from_str(args.get(2).as_slice()).unwrap();
        let port = FromStr::from_str(args.get(3).as_slice()).unwrap();
        addr = SocketAddr { ip: ip, port: port };
    }

    match args.get(1).as_slice() {
        "-s" => {
            let mut buf = [0, ..512];
            let sock = UtpSocket::bind(addr).unwrap();
            println!("Serving on {}", addr);

            loop {
                let mut sock = sock.clone();
                match sock.recvfrom(buf) {
                    Ok((_, src)) => {
                        spawn(proc() {
                            let mut stream = sock.connect(src);
                            let payload = String::from_str("Hello\n").into_bytes();

                            // Send uTP packet
                            let _ = stream.write(payload.as_slice());
                        })
                    }
                    Err(_) => {}
                }
            }
        }
        "-c" => {
            let sock = UtpSocket::bind(SocketAddr { ip: Ipv4Addr(127,0,0,1), port: std::rand::random() }).unwrap();
            let mut stream = sock.connect(addr);
            let _ = stream.write([0]);
            let stream = stream.terminate();
            drop(stream);
        }
        _ => usage(),
    }
}
<|endoftext|>


<commit_before>
extern crate nccl;

use nccl::{Pair, Scanner, NcclError, ErrorKind};

#[test]
fn pair_new() {
    assert_eq!(Pair::new("hello"), Pair {
        key: "hello".into(),
        value: vec![]
    });
}

#[test]
fn pair_add() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p, Pair {
        key: "top_level".into(),
        value: vec![Pair {
            key: "key".into(),
            value: vec![]
        }]
    });
}

#[test]
fn pair_get() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p.get("key").unwrap(), &mut Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_index() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p["key"], Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_keys() {
    let mut p = Pair::new("top");
    p.add("numbers");
    p["numbers"].add("1");
    p["numbers"].add("2");
    p["numbers"].add("3");
    p["numbers"].add("4");
    p["numbers"].add("5");
    assert_eq!(p["numbers"].keys(), vec!["1", "2", "3", "4", "5"]);
}

#[test]
fn pair_value_parse() {
    let mut p = Pair::new("top");
    p.add("bools");
    p["bools"].add("true");
    assert!(p["bools"].value_as::<bool>().unwrap());
}

#[test]
fn scanner_literal() {
    let mut s = Scanner::new("\"this: is neato\": burrito 64\n    yes.".into());
    s.scan_tokens().unwrap();
}

#[test]
#[should_panic]
fn error_key_not_found() {
    let mut p = Pair::new("jjj");
    p.get("jwiofiojwaef jio").unwrap();
}

#[test]
fn readme() {
    let mut config = Pair::new("top_level");

    // server
    //     domain
    //         example.com
    //         www.example.com
    //     port
    //         80
    //         443
    //     root
    //         /var/www/html

    config.add("server");
    config["server"].add("domain");
    config["server"].add("port");
    config["server"].add("root");
    config["server"]["domain"].add("example.com");
    config["server"]["domain"].add("www.example.com");
    config["server"]["port"].add("80");
    config["server"]["port"].add("443");
    config["server"]["root"].add("/var/www/html");

    let ports = config["server"]["port"].keys_as::<i32>().unwrap();
    assert_eq!(ports, vec![80, 443]);
}

<commit_msg>update tests<commit_after>
extern crate nccl;

use nccl::{Pair, Scanner, NcclError, ErrorKind};

#[test]
fn pair_new() {
    assert_eq!(Pair::new("hello"), Pair {
        key: "hello".into(),
        value: vec![]
    });
}

#[test]
fn pair_add() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p, Pair {
        key: "top_level".into(),
        value: vec![Pair {
            key: "key".into(),
            value: vec![]
        }]
    });
}

#[test]
fn pair_get() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p.get("key").unwrap(), &mut Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_index() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p["key"], Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_keys() {
    let mut p = Pair::new("top");
    p.add("numbers");
    p["numbers"].add("1");
    p["numbers"].add("2");
    p["numbers"].add("3");
    p["numbers"].add("4");
    p["numbers"].add("5");
    assert_eq!(p["numbers"].keys(), vec!["1", "2", "3", "4", "5"]);
}

#[test]
fn pair_value_parse() {
    let mut p = Pair::new("top");
    p.add("bools");
    p["bools"].add("true");
    assert!(p["bools"].value_as::<bool>().unwrap());
}

#[test]
fn scanner_literal() {
    let mut s = Scanner::new("\"this: is neato\": burrito 64\n    yes.".into());
    s.scan_tokens().unwrap();
}

#[test]
#[should_panic]
fn error_key_not_found() {
    let mut p = Pair::new("jjj");
    p.get("jwiofiojwaef jio").unwrap();
}

#[test]
fn scan_file() {
    println!("{:?}", nccl::parse_file("config.nccl"));
    panic!();
}

#[test]
fn readme() {
    let mut config = Pair::new("top_level");

    // server
    //     domain
    //         example.com
    //         www.example.com
    //     port
    //         80
    //         443
    //     root
    //         /var/www/html

    config.add("server");
    config["server"].add("domain");
    config["server"].add("port");
    config["server"].add("root");
    config["server"]["domain"].add("example.com");
    config["server"]["domain"].add("www.example.com");
    config["server"]["port"].add("80");
    config["server"]["port"].add("443");
    config["server"]["root"].add("/var/www/html");

    let ports = config["server"]["port"].keys_as::<i32>().unwrap();
    assert_eq!(ports, vec![80, 443]);
}

<|endoftext|>


<commit_before>use compositor::{self, Action, Server, Shell, View};
use std::time::Duration;
use compositor::seat::Seat;
use wlroots::types::Cursor;
use wlroots::{CompositorHandle, HandleResult, KeyboardHandle, Origin, PointerHandle,
              PointerHandler, XdgV6ShellState::*, pointer_events::*, WLR_BUTTON_RELEASED};

#[derive(Debug, Default)]
pub struct Pointer;

impl PointerHandler for Pointer {

    fn on_motion_absolute(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &AbsoluteMotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.data.downcast_mut().unwrap();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.pos();
                cursor.warp_absolute(event.device(), x, y);
                update_cursor_position(cursor, seat, views);
            }).expect("Cursor was destroyed");
        }).unwrap();
    }

    fn on_motion(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &MotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.delta();
                cursor.move_to(event.device(), x, y);
                update_cursor_position(cursor, seat, views);
            }).expect("Cursor was destroyed");
        }).unwrap();
    }

    fn on_button(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &ButtonEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut views,
                         ref mut seat,
                         ref mut keyboards,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                if event.state() == WLR_BUTTON_RELEASED {
                    seat.action = None;
                    send_pointer_button(seat, event).expect("Could not send pointer button");
                    return
                }
                if let Some(view) = view_at_pointer(views, cursor) {
                    focus_under_pointer(seat, &mut **keyboards, { &mut *view }).expect("Could not focus \
                                                                                view");
                    let meta_held_down = seat.meta;
                    if meta_held_down && event.button() == BTN_LEFT {
                        move_view(seat, cursor, view, None);
                    }
                    send_pointer_button(seat, event).expect("Could not send pointer button");
                } else {
                    focus_under_pointer(seat, &mut **keyboards, None).expect("Could not focus view");
                }
            }).unwrap()
        }).unwrap()
    }
}

/// After the cursor has been warped, do all the things needed to change the cursor from the old
/// position to the new position.
fn update_cursor_position(cursor: &mut Cursor, seat: &mut Seat, views: &mut [View]) {
    match seat.action {
        Some(Action::Moving { start }) => {
            if let Some(mut view) = view_at_pointer(views, cursor) {
                let meta_held_down = seat.meta;
                if meta_held_down {
                    move_view(seat, cursor, &mut view, start);
                }
            }
        }
        _ => { /* TODO */ }
    }
}

fn view_at_pointer<'view>(views: &'view mut [View],
                          cursor: &mut Cursor)
                          -> Option<&'view mut View> {
    for view in views {
        match view.shell.clone() {
            Shell::XdgV6(ref mut shell) => {
                let (mut sx, mut sy) = (0.0, 0.0);
                let seen = with_handles!([(shell: {&mut *shell})] => {
                    let (lx, ly) = cursor.coords();
                    let Origin {x: shell_x, y: shell_y} = view.origin;
                    let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                    shell.surface_at(view_sx, view_sy, &mut sx, &mut sy).is_some()
                }).ok()?;
                if seen {
                    return Some(view)
                }
            }
        }
    }
    None
}

/// Focus the view under the pointer.
fn focus_under_pointer<'view, V>(seat: &mut compositor::Seat,
                                 keyboards: &mut [KeyboardHandle],
                                 view: V)
                                 -> HandleResult<()>
    where V: Into<Option<&'view mut View>>
{
    // TODO Use those surface level coordinates to send events and shit
    match view.into() {
        None => {
            if let Some(mut focused_view) = seat.focused.take() {
                match focused_view.shell {
                    Shell::XdgV6(ref mut shell) => {
                        with_handles!([(shell: {shell})] => {
                            match shell.state() {
                                Some(&mut TopLevel(ref mut toplevel)) => {
                                    toplevel.set_activated(false)
                                },
                                _ => unimplemented!()
                            }
                        })?;
                    }
                }
            }
            with_handles!([(seat: {&mut seat.seat})] => {
                seat.keyboard_clear_focus()
            })
        }
        Some(view) => {
            seat.focused = Some(view.clone());
            for keyboard in { &mut *keyboards } {
                match &mut view.shell {
                    &mut Shell::XdgV6(ref mut shell) => {
                        with_handles!([(seat: {&mut seat.seat}),
                                      (shell: {&mut *shell}),
                                      (surface: {shell.surface()}),
                                      (keyboard: {keyboard})] => {
                    match shell.state() {
                        Some(&mut TopLevel(ref mut toplevel)) => {
                            // TODO Don't send this for each keyboard!
                            toplevel.set_activated(true);
                        },
                        _ => unimplemented!()
                    }
                    seat.keyboard_notify_enter(surface,
                                               &mut keyboard.keycodes(),
                                               &mut keyboard.get_modifier_masks())
                })?;
                    }
                }
            }
            Ok(())
        }
    }
}

/// Start moving a view if you haven't already by passing `start: None`.
///
/// Otherwise, update the view position relative to where the move started,
/// which is provided by Action::Moving.
fn move_view<O>(seat: &mut compositor::Seat,
                cursor: &mut Cursor,
                view: &mut View,
                start: O)
    where O: Into<Option<Origin>>
{
    let Origin { x: shell_x,
    y: shell_y } = view.origin;
    let (lx, ly) = cursor.coords();
    match start.into() {
        None => {
            let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
            let start = Origin::new(view_sx as _, view_sy as _);
            seat.action = Some(Action::Moving{start});
        }
        Some(start) => {
            let pos = Origin::new(lx as i32 - start.x, ly as i32 - start.y);
            view.origin = pos;
        }
    };
}

fn send_pointer_button(seat: &mut compositor::Seat, event: &ButtonEvent) -> HandleResult<()> {
    with_handles!([(seat: {&mut seat.seat})] => {
        seat.pointer_notify_button(Duration::from_millis(event.time_msec() as _),
                                   event.button(),
                                   event.state() as u32);
    })
}
<commit_msg>rename function for interactive move/resize handling<commit_after>use compositor::{self, Action, Server, Shell, View};
use std::time::Duration;
use compositor::seat::Seat;
use wlroots::types::Cursor;
use wlroots::{CompositorHandle, HandleResult, KeyboardHandle, Origin, PointerHandle,
              PointerHandler, XdgV6ShellState::*, pointer_events::*, WLR_BUTTON_RELEASED};

#[derive(Debug, Default)]
pub struct Pointer;

impl PointerHandler for Pointer {

    fn on_motion_absolute(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &AbsoluteMotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.data.downcast_mut().unwrap();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.pos();
                cursor.warp_absolute(event.device(), x, y);
                update_view_position(cursor, seat, views);
            }).expect("Cursor was destroyed");
        }).unwrap();
    }

    fn on_motion(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &MotionEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut seat,
                         ref mut views,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                let (x, y) = event.delta();
                cursor.move_to(event.device(), x, y);
                update_view_position(cursor, seat, views);
            }).expect("Cursor was destroyed");
        }).unwrap();
    }

    fn on_button(&mut self, compositor: CompositorHandle, _: PointerHandle, event: &ButtonEvent) {
        with_handles!([(compositor: {compositor})] => {
            let server: &mut Server = compositor.into();
            let Server { ref mut cursor,
                         ref mut views,
                         ref mut seat,
                         ref mut keyboards,
                         .. } = *server;
            with_handles!([(cursor: {&mut *cursor})] => {
                if event.state() == WLR_BUTTON_RELEASED {
                    seat.action = None;
                    send_pointer_button(seat, event).expect("Could not send pointer button");
                    return
                }
                if let Some(view) = view_at_pointer(views, cursor) {
                    focus_under_pointer(seat, &mut **keyboards, { &mut *view }).expect("Could not focus \
                                                                                view");
                    let meta_held_down = seat.meta;
                    if meta_held_down && event.button() == BTN_LEFT {
                        move_view(seat, cursor, view, None);
                    }
                    send_pointer_button(seat, event).expect("Could not send pointer button");
                } else {
                    focus_under_pointer(seat, &mut **keyboards, None).expect("Could not focus view");
                }
            }).unwrap()
        }).unwrap()
    }
}

/// After the cursor has been warped, update the position of a view that might have been
/// affected by an ongoing interactive move/resize operation
fn update_view_position(cursor: &mut Cursor, seat: &mut Seat, views: &mut [View]) {
    match seat.action {
        Some(Action::Moving { start }) => {
            if let Some(mut view) = view_at_pointer(views, cursor) {
                let meta_held_down = seat.meta;
                if meta_held_down {
                    move_view(seat, cursor, &mut view, start);
                }
            }
        }
        _ => { /* TODO */ }
    }
}

fn view_at_pointer<'view>(views: &'view mut [View],
                          cursor: &mut Cursor)
                          -> Option<&'view mut View> {
    for view in views {
        match view.shell.clone() {
            Shell::XdgV6(ref mut shell) => {
                let (mut sx, mut sy) = (0.0, 0.0);
                let seen = with_handles!([(shell: {&mut *shell})] => {
                    let (lx, ly) = cursor.coords();
                    let Origin {x: shell_x, y: shell_y} = view.origin;
                    let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
                    shell.surface_at(view_sx, view_sy, &mut sx, &mut sy).is_some()
                }).ok()?;
                if seen {
                    return Some(view)
                }
            }
        }
    }
    None
}

/// Focus the view under the pointer.
fn focus_under_pointer<'view, V>(seat: &mut compositor::Seat,
                                 keyboards: &mut [KeyboardHandle],
                                 view: V)
                                 -> HandleResult<()>
    where V: Into<Option<&'view mut View>>
{
    // TODO Use those surface level coordinates to send events and shit
    match view.into() {
        None => {
            if let Some(mut focused_view) = seat.focused.take() {
                match focused_view.shell {
                    Shell::XdgV6(ref mut shell) => {
                        with_handles!([(shell: {shell})] => {
                            match shell.state() {
                                Some(&mut TopLevel(ref mut toplevel)) => {
                                    toplevel.set_activated(false)
                                },
                                _ => unimplemented!()
                            }
                        })?;
                    }
                }
            }
            with_handles!([(seat: {&mut seat.seat})] => {
                seat.keyboard_clear_focus()
            })
        }
        Some(view) => {
            seat.focused = Some(view.clone());
            for keyboard in { &mut *keyboards } {
                match &mut view.shell {
                    &mut Shell::XdgV6(ref mut shell) => {
                        with_handles!([(seat: {&mut seat.seat}),
                                      (shell: {&mut *shell}),
                                      (surface: {shell.surface()}),
                                      (keyboard: {keyboard})] => {
                    match shell.state() {
                        Some(&mut TopLevel(ref mut toplevel)) => {
                            // TODO Don't send this for each keyboard!
                            toplevel.set_activated(true);
                        },
                        _ => unimplemented!()
                    }
                    seat.keyboard_notify_enter(surface,
                                               &mut keyboard.keycodes(),
                                               &mut keyboard.get_modifier_masks())
                })?;
                    }
                }
            }
            Ok(())
        }
    }
}

/// Start moving a view if you haven't already by passing `start: None`.
///
/// Otherwise, update the view position relative to where the move started,
/// which is provided by Action::Moving.
fn move_view<O>(seat: &mut compositor::Seat,
                cursor: &mut Cursor,
                view: &mut View,
                start: O)
    where O: Into<Option<Origin>>
{
    let Origin { x: shell_x,
    y: shell_y } = view.origin;
    let (lx, ly) = cursor.coords();
    match start.into() {
        None => {
            let (view_sx, view_sy) = (lx - shell_x as f64, ly - shell_y as f64);
            let start = Origin::new(view_sx as _, view_sy as _);
            seat.action = Some(Action::Moving{start});
        }
        Some(start) => {
            let pos = Origin::new(lx as i32 - start.x, ly as i32 - start.y);
            view.origin = pos;
        }
    };
}

fn send_pointer_button(seat: &mut compositor::Seat, event: &ButtonEvent) -> HandleResult<()> {
    with_handles!([(seat: {&mut seat.seat})] => {
        seat.pointer_notify_button(Duration::from_millis(event.time_msec() as _),
                                   event.button(),
                                   event.state() as u32);
    })
}
<|endoftext|>


<commit_before>///! fff-lang
///! Some utils

mod date_time;

pub use date_time::DateTime;

/// Macro for printing to the standard error.
///
/// Equivalent to `print!` macro except that print to stderr
///
/// Standard error unsually is not buffered and displayed immediately, and
/// default rust test configuration shut down stdout and keeps stderror open
///
/// # Panics
///
/// Panics if writing to io::stderr() fails.
///
/// # Examples
/// ```rust
/// # #[macro_use] extern crate util;
/// # fn main() {
/// perror!("Hello ");
/// perror!("{}", "World");
/// perror!("!");      // Get `Hello World!` at stderr immediately
/// # }
/// ```
#[macro_export]
macro_rules! perror {
    ($($arg:tt)*) => ({
        use std::io::Write;
        let _ = write!(&mut ::std::io::stderr(), $($arg)* );
    })
}

/// Macros for printing to the standard output, with a newline
///
/// Use the `format!` syntax to write data to the standard error, see
/// `std::fmt` for more information
///
/// # Panics
///
/// Panics if writing to `io::stderr()` fails
///
/// # Examples
/// ```rust
/// # #[macro_use] extern crate util;
/// # fn main() {
/// perrorln!("Hello world!");
/// perrorln!("format {} arguments", "some");
/// # }
/// ```
#[macro_export]
macro_rules! perrorln {
    ($($arg:tt)*) => ({
        use std::io::Write;
        let _ = writeln!(&mut ::std::io::stderr(), $($arg)* );
    })
}

use std::fmt;
pub fn format_vector_display<T: fmt::Display>(items: &Vec<T>, sep: &str) -> String {
    let length = items.len();
    let mut buf = String::new();
    for (index, item) in items.iter().enumerate() {
        buf.push_str(&format!("{}", item));
        if index != length - 1 {
            buf.push_str(sep);
        }
    }
    buf
}
pub fn format_vector_debug<T: fmt::Debug>(items: &Vec<T>, sep: &str) -> String {
    let length = items.len();
    let mut buf = String::new();
    for (index, item) in items.iter().enumerate() {
        buf.push_str(&format!("{:?}", item));
        if index != length - 1 {
            buf.push_str(sep);
        }
    }
    buf
}

/// Implement `fmt::Display` by previous implementation of `fmt::Debug`
#[macro_export]
macro_rules! impl_display_by_debug {
    ($t: ty) => (
        impl fmt::Display for $t {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{:?}", self)
            }
        }
    )
}

/// Try convert from
pub trait TryFrom<T>
    where Self: Sized {
    fn try_from(t: T) -> Option<Self>;
}

/// ID type requires From<{integer}>
#[macro_export]
macro_rules! make_id {
    ($id: expr) => (From::from($id))
}<commit_msg>[util] remove print to stderr macros<commit_after>///! fff-lang
///! Some utils

mod date_time;

pub use date_time::DateTime;

use std::fmt;
pub fn format_vector_display<T: fmt::Display>(items: &Vec<T>, sep: &str) -> String {
    let length = items.len();
    let mut buf = String::new();
    for (index, item) in items.iter().enumerate() {
        buf.push_str(&format!("{}", item));
        if index != length - 1 {
            buf.push_str(sep);
        }
    }
    buf
}
pub fn format_vector_debug<T: fmt::Debug>(items: &Vec<T>, sep: &str) -> String {
    let length = items.len();
    let mut buf = String::new();
    for (index, item) in items.iter().enumerate() {
        buf.push_str(&format!("{:?}", item));
        if index != length - 1 {
            buf.push_str(sep);
        }
    }
    buf
}

/// Implement `fmt::Display` by previous implementation of `fmt::Debug`
#[macro_export]
macro_rules! impl_display_by_debug {
    ($t: ty) => (
        impl fmt::Display for $t {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{:?}", self)
            }
        }
    )
}

/// Try convert from
pub trait TryFrom<T>
    where Self: Sized {
    fn try_from(t: T) -> Option<Self>;
}

/// ID type requires From<{integer}>
#[macro_export]
macro_rules! make_id {
    ($id: expr) => (From::from($id))
}<|endoftext|>


<commit_before>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::result;

use libc::__errno_location;

/// An error number, retrieved from [errno](http://man7.org/linux/man-pages/man3/errno.3.html), set
/// by a libc function that returned an error.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Error(i32);
pub type Result<T> = result::Result<T, Error>;

impl Error {
    /// Constructs a new error with the given errno.
    pub fn new(e: i32) -> Error {
        Error(e)
    }

    /// Constructs an error from the current errno.
    ///
    /// The result of this only has any meaning just after a libc call that returned a value
    /// indicating errno was set.
    pub fn last() -> Error {
        Error(unsafe { *__errno_location() })
    }

    /// Gets the errno for this error
    pub fn errno(&self) -> i32 {
        self.0
    }
}

/// Returns the last errno as a Result that is always an error.
pub fn errno_result<T>() -> Result<T> {
    Err(Error::last())
}
<commit_msg>sys_util: Add conversion from errno io::Error.<commit_after>// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::result;
use std::io;

use libc::__errno_location;

/// An error number, retrieved from errno (man 3 errno), set by a libc
/// function that returned an error.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Error(i32);
pub type Result<T> = result::Result<T, Error>;

impl Error {
    /// Constructs a new error with the given errno.
    pub fn new(e: i32) -> Error {
        Error(e)
    }

    /// Constructs an error from the current errno.
    ///
    /// The result of this only has any meaning just after a libc call that returned a value
    /// indicating errno was set.
    pub fn last() -> Error {
        Error(unsafe { *__errno_location() })
    }

    /// Gets the errno for this error
    pub fn errno(&self) -> i32 {
        self.0
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error::new(e.raw_os_error().unwrap_or_default())
    }
}

/// Returns the last errno as a Result that is always an error.
pub fn errno_result<T>() -> Result<T> {
    Err(Error::last())
}
<|endoftext|>


<commit_before>//! For the lack of a better name, this module is to hold the analogous to
//! the "parser" module, but for encoding in a way which supports text
//! encoding.
//!

use crate::error::{Error, Result};
use dicom_encoding::encode::EncodeTo;
use dicom_encoding::text::{SpecificCharacterSet, TextCodec};
use dicom_encoding::TransferSyntax;
use std::io::Write;

/// A mid-level abstraction for writing DICOM content. Unlike `Encode`,
/// the printer also knows how to write text values.
/// `W` is the write target, `E` is the encoder, and `T` is the text formatter.
#[derive(Debug)]
pub struct Printer<W, E, T> {
    to: W,
    encoder: E,
    text: T,
    bytes_written: u64,
}

pub type DynamicDicomPrinter =
    Printer<Box<dyn Write>, Box<dyn EncodeTo<dyn Write>>, Box<dyn TextCodec>>;

impl<W, E, T> Printer<W, E, T> {
    pub fn new(to: W, encoder: E, text: T) -> Self {
        Printer {
            to,
            encoder,
            text,
            bytes_written: 0,
        }
    }

    pub fn with_text<U>(self, text: U) -> Printer<W, E, U> {
        Printer {
            to: self.to,
            encoder: self.encoder,
            text,
            bytes_written: 0,
        }
    }
}

impl DynamicDicomPrinter {
    pub fn from_transfer_syntax(
        to: Box<dyn Write>,
        ts: TransferSyntax,
        cs: SpecificCharacterSet,
    ) -> Result<Self> {
        let encoder = ts
            .encoder()
            .ok_or_else(|| Error::UnsupportedTransferSyntax)?;
        let text = cs.codec().ok_or_else(|| Error::UnsupportedCharacterSet)?;

        Ok(Printer::new(to, encoder, text))
    }
}
<commit_msg>[parser] implement more of printer abstraction<commit_after>//! For the lack of a better name, this module is to hold the analogous to
//! the "parser" module, but for encoding in a way which supports text
//! encoding.
//!

use crate::error::{Error, Result};
use dicom_core::{value::PrimitiveValue, DataElementHeader, VR};
use dicom_encoding::{
    encode::EncodeTo,
    text::{DefaultCharacterSetCodec, SpecificCharacterSet, TextCodec},
    TransferSyntax,
};
use std::io::Write;

/// A mid-level abstraction for writing DICOM content. Unlike `Encode`,
/// the printer also knows how to write text values.
/// `W` is the write target, `E` is the encoder, and `T` is the text formatter.
#[derive(Debug)]
pub struct Printer<W, E, T> {
    to: W,
    encoder: E,
    text: T,
    bytes_written: u64,
}

pub type DynamicDicomPrinter =
    Printer<Box<dyn Write>, Box<dyn EncodeTo<dyn Write>>, Box<dyn TextCodec>>;

impl<W, E, T> Printer<W, E, T> {
    pub fn new(to: W, encoder: E, text: T) -> Self {
        Printer {
            to,
            encoder,
            text,
            bytes_written: 0,
        }
    }

    pub fn with_text<U>(self, text: U) -> Printer<W, E, U> {
        Printer {
            to: self.to,
            encoder: self.encoder,
            text,
            bytes_written: 0,
        }
    }
}

impl DynamicDicomPrinter {
    pub fn from_transfer_syntax(
        to: Box<dyn Write>,
        ts: TransferSyntax,
        cs: SpecificCharacterSet,
    ) -> Result<Self> {
        let encoder = ts
            .encoder()
            .ok_or_else(|| Error::UnsupportedTransferSyntax)?;
        let text = cs.codec().ok_or_else(|| Error::UnsupportedCharacterSet)?;

        Ok(Printer::new(to, encoder, text))
    }
}

impl<W, E, T> Printer<W, E, T>
where
    W: Write,
    E: EncodeTo<W>,
    T: TextCodec,
{
    /// Encode and write a data element header.
    pub fn encode_element_header(&mut self, de: DataElementHeader) -> Result<()> {
        let bytes = self.encoder.encode_element_header(&mut self.to, de)?;
        self.bytes_written += bytes as u64;
        Ok(())
    }

    /// Encode and write an item header.
    pub fn encode_item_header(&mut self, len: u32) -> Result<()> {
        self.encoder.encode_item_header(&mut self.to, len)?;
        self.bytes_written += 8;
        Ok(())
    }

    /// Encode and write an item delimiter.
    pub fn encode_item_delimiter(&mut self) -> Result<()> {
        self.encoder.encode_item_delimiter(&mut self.to)?;
        self.bytes_written += 8;
        Ok(())
    }

    /// Encode and write a sequence delimiter.
    pub fn encode_sequence_delimiter(&mut self) -> Result<()> {
        self.encoder.encode_sequence_delimiter(&mut self.to)?;
        self.bytes_written += 8;
        Ok(())
    }

    /// Retrieve the number of bytes written by this printer.
    pub fn bytes_written(&self) -> u64 {
        self.bytes_written
    }

    /// Encode and write a primitive value. Where applicable, this printer
    /// will use the inner text codec for textual values.
    pub fn encode_primitive(
        &mut self,
        de: &DataElementHeader,
        value: &PrimitiveValue,
    ) -> Result<()> {
        // intercept string encoding calls to use the text codec
        match value {
            PrimitiveValue::Str(text) => {
                self.encode_text(text, de.vr())?;
                Ok(())
            }
            PrimitiveValue::Strs(texts) => {
                self.encode_texts(&texts[..], de.vr())?;
                Ok(())
            }
            _ => {
                let bytes = self.encoder.encode_primitive(&mut self.to, value)?;
                self.bytes_written += bytes as u64;
                Ok(())
            }
        }
    }

    fn encode_text(&mut self, text: &str, vr: VR) -> Result<()> {
        let bytes = self.encode_text_untrailed(text, vr)?;
        if bytes % 2 == 1 {
            self.to.write_all(b" ")?;
            self.bytes_written += 1;
        }
        Ok(())
    }

    fn encode_texts<S>(&mut self, texts: &[S], vr: VR) -> Result<()>
    where
        S: AsRef<str>,
    {
        let mut acc = 0;
        for (i, text) in texts.iter().enumerate() {
            acc += self.encode_text_untrailed(text.as_ref(), vr)?;
            if i < texts.len() - 1 {
                self.to.write_all(b"\\")?;
                acc += 1;
                self.bytes_written += 1;
            }
        }
        if acc % 2 == 1 {
            self.to.write_all(b" ")?;
            self.bytes_written += 1;
        }
        Ok(())
    }

    fn encode_text_untrailed(&mut self, text: &str, vr: VR) -> Result<usize> {
        let data = match vr {
            VR::AE | VR::AS | VR::CS | VR::DA | VR::DS | VR::DT | VR::IS | VR::TM | VR::UI => {
                // these VRs always use the default character repertoire
                DefaultCharacterSetCodec.encode(text)?
            }
            _ => self.text.encode(text)?,
        };
        self.to.write_all(&data)?;
        self.bytes_written += data.len() as u64;
        Ok(data.len())
    }
}
<|endoftext|>


<commit_before>extern crate clap;

use self::clap::{App, ArgMatches};

pub struct Cli<'a: 'b, 'b> {
    app: App<'a, 'b>
}

impl<'a: 'b, 'b> Cli<'a, 'b>{
    pub fn new() -> Cli<'a, 'b> {
        Cli {
            app: App::new("Reverse proxy")
                .version("0.1.0")
                .author("Valeryi Savich <relrin78@gmail.com>")
                .about("WebSocket-over-Kafka reverse proxy")
                .args_from_usage(
                    "-c, --config=[FILE]      'Path to a custom settings file'
                    -i, --ip=[IP]             'The used IP for a server'
                    -p, --port=[PORT]         'The listened port'
                    -C, --cert=[CERTIFICATE]  'Path to a used certificate'
                    -K, --key=[KEY]           'Path to a public key'"
                )
        }
    }

    pub fn get_value(self, key: &'a str, default: &'a str) -> &'a str {
        let matches = self.app.get_matches();
        matches.value_of(key).unwrap_or(default)
    }
}

<commit_msg>Updated methods for work with clap-rs<commit_after>extern crate clap;

use std::cell::RefCell;
use self::clap::{App, ArgMatches};

pub fn cli<'a>() -> ArgMatches<'a> {
    App::new("Pathfinder")
        .version("0.1.0")
        .author("Valeryi Savich <relrin78@gmail.com>")
        .about("WebSocket-over-Kafka reverse proxy")
        .args_from_usage(
           "-c, --config=[FILE]       'Path to a custom settings file'
            -i, --ip=[IP]             'The used IP for a server'
            -p, --port=[PORT]         'The listened port'
            -C, --cert=[CERTIFICATE]  'Path to a used certificate'
            -K, --key=[KEY]           'Path to a public key'",
        )
        .get_matches()
}

pub fn get_value<'a>(cli: &'a ArgMatches<'a>, key: &'a str, default: &'a str) -> &'a str {
    let cli = RefCell::new(cli);
    let cli = cli.into_inner();
    cli.value_of(key).unwrap_or(default)
}
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate platformtree;

use platformtree::node;
<commit_msg>Removed platformtree/test. Never used it.<commit_after><|endoftext|>


<commit_before>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#![feature(convert,str_char)]

//extern crate libc;
//use libc::geteuid;

use std::fs;
use std::io::{Error, ErrorKind};

const PROC_PATH: &'static str = "/proc";

struct CmdInfo {
    name: &'static str,
    pss: f32,
    shared: f32,
    heap: f32,
    swap: f32,
}

fn is_digit(d: char) -> bool {
    d >= '0' && d <= '9'
}

fn not_dir<T>() -> Result<T, Error> {
    Err(Error::new(ErrorKind::NotFound, "not a directory"))
}

fn get_pids<'a>() -> Result<Vec<i32>, String> {
    let mut dir = fs::read_dir(PROC_PATH);
    if dir.is_err() {
	return Err(format!("read_dir({}): {}", PROC_PATH, dir.err().unwrap()));
    }

    // TODO: look at filter_map
    let pids: Vec<i32> = dir.unwrap()
	.filter(|e| e.is_ok()) // ignore bad dirent results
	.map(|e| e.unwrap())   // make this a list of dirents
	.filter(|e| is_digit(e.file_name().to_str().unwrap().char_at(0)))
	.filter(|e| fs::metadata(e.path()).and_then(|md| if md.is_dir() { Ok("") } else { not_dir() }).is_ok())
	.map(|e| i32::from_str_radix(e.file_name().to_str().unwrap(), 10).unwrap())
	.collect();

    Ok(pids)
}

fn cmdinfos_for(pids: Vec<i32>) -> Vec<CmdInfo> {
    let mut infos: Vec<CmdInfo> = Vec::with_capacity(pids.len());

    for pid in pids {
	println!("pid: {}", pid);
    }

    return infos;
}

fn main() {

    // command line flag parsing

    // check euid
    // unsafe {
    // 	let uid = geteuid();
    // 	if uid != 0 {
    // 	    println!("we aren't root");
    // 	}
    // }

    let pids_r = get_pids();
    if pids_r.is_err() {
	println!("get_pids: {}", pids_r.err().unwrap());
	return;
    }

    let pids = pids_r.unwrap();
    // get details of all pids (possibly in parallel)
    let infos = cmdinfos_for(pids);

    // sort pid details

    // find total

    // print_results

    println!("Hello, world!");
}
<commit_msg>psm-rust: cleanup<commit_after>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#![feature(str_char)]

//extern crate libc;
//use libc::geteuid;

use std::fs;
use std::io::{Error, ErrorKind};

const PROC_PATH: &'static str = "/proc";

struct CmdInfo {
    name: &'static str,
    pss: f32,
    shared: f32,
    heap: f32,
    swap: f32,
}

#[inline(never)]
fn is_digit(d: char) -> bool {
    d >= '0' && d <= '9'
}

#[inline(never)]
fn first_char(name: std::ffi::OsString) -> char {
    name.to_str().unwrap().char_at(0)
}

fn is_dir(md: fs::Metadata) -> Result<fs::Metadata, Error> {
    if md.is_dir() {
	Ok(md)
    } else {
	Err(Error::new(ErrorKind::NotFound, "not a directory"))
    }
}

#[inline(never)]
fn get_pids() -> Result<Vec<i32>, String> {
    let mut dir = fs::read_dir(PROC_PATH);
    if let Err(err)= dir {
	return Err(format!("read_dir({}): {}", PROC_PATH, err));
    }

    // TODO: look at filter_map
    let pids: Vec<i32> = dir.unwrap()
	.filter(|e| e.is_ok()) // ignore bad dirent results
	.map(|e| e.unwrap())   // make this a list of dirents
	.filter(|e| is_digit(first_char(e.file_name())))
	.filter(|e| fs::metadata(e.path()).and_then(|md| is_dir(md)).is_ok())
	.map(|e| i32::from_str_radix(e.file_name().to_str().unwrap(), 10).unwrap())
	.collect();

    Ok(pids)
}

fn cmdinfos_for(pids: Vec<i32>) -> Vec<CmdInfo> {
    let mut infos: Vec<CmdInfo> = Vec::with_capacity(pids.len());

    for pid in pids {
	println!("pid: {}", pid);
    }

    return infos;
}

fn main() {

    // command line flag parsing

    // check euid
    // unsafe {
    // 	let uid = geteuid();
    // 	if uid != 0 {
    // 	    println!("we aren't root");
    // 	}
    // }

    let pids_r = get_pids();
    if let Err(err) = pids_r {
	println!("get_pids: {}", err);
	return;
    }

    let pids = pids_r.unwrap();
    // get details of all pids (possibly in parallel)
    let infos = cmdinfos_for(pids);

    // sort pid details

    // find total

    // print_results

    println!("Hello, world!");
}
<|endoftext|>


<commit_before>use crate::common::{get_stem_from_path, TIMESTAMP_SECONDS_FORMAT};
use chrono::prelude::*;
use std::fs::read_dir;
use std::path::PathBuf;
use std::thread;
use thread_priority::{set_current_thread_priority, ThreadPriority};

pub const BACKUP_FILE_PREFIX: &str = "hub_backup_";
pub const DEFAULT_BACKUP_INTERVAL_MIN: u32 = 1440;

pub fn get_next_backup_timestamp(backup_interval_min: Option<u32>) -> i64 {
    let backup_interval_min: i64 = backup_interval_min
        .unwrap_or(DEFAULT_BACKUP_INTERVAL_MIN)
        .into();
    let next_backup = Utc::now() + chrono::Duration::minutes(backup_interval_min);
    log::debug!("Next backup timestamp: {}", next_backup);
    next_backup.timestamp_millis()
}

pub fn get_next_backup_timestamp_on_launch(
    backup_dir: Option<PathBuf>,
    backup_interval_min: Option<u32>,
) -> Option<i64> {
    if let Some(backup_dir) = backup_dir {
        let backup_interval_min: i64 = backup_interval_min
            .unwrap_or(DEFAULT_BACKUP_INTERVAL_MIN)
            .into();
        let mut paths = read_dir(backup_dir.to_str().unwrap())
            .unwrap()
            .map(|res| res.map(|e| e.path()))
            .filter(|path| {
                if let Ok(path) = path {
                    return path.is_file()
                        && get_stem_from_path(&path).starts_with(BACKUP_FILE_PREFIX);
                }
                false
            })
            .collect::<Result<Vec<_>, std::io::Error>>()
            .unwrap();
        paths.sort();
        let next_backup = if paths.is_empty() {
            // There are no backups, the next one is interval from now
            Utc::now() + chrono::Duration::minutes(backup_interval_min)
        } else {
            let previous_backup_timestamp = get_stem_from_path(paths.get(paths.len() - 1).unwrap())
                [(BACKUP_FILE_PREFIX.len())..]
                .to_string();
            let previous_backup = Utc
                .datetime_from_str(
                    &previous_backup_timestamp.as_str(),
                    TIMESTAMP_SECONDS_FORMAT,
                )
                .unwrap();
            previous_backup + chrono::Duration::minutes(backup_interval_min)
        };
        log::debug!("Next backup timestamp is after: {}", next_backup);
        return Some(next_backup.timestamp_millis());
    }
    None
}

pub fn is_now_after(timestamp: i64) -> bool {
    let now = Utc::now();
    now.timestamp_millis() > timestamp
}

pub fn create_backup(backup_dir: PathBuf, metrics_dir: PathBuf) {
    thread::spawn(move || {
        set_current_thread_priority(ThreadPriority::Min).unwrap();
        let metrics_dir = metrics_dir.canonicalize().unwrap();
        let timestamp_seconds = chrono::Utc::now().format(TIMESTAMP_SECONDS_FORMAT);
        let backup_tar_file = std::fs::File::create(format!(
            "{}/{}{}.tar",
            backup_dir.display(),
            BACKUP_FILE_PREFIX,
            timestamp_seconds
        ))
        .unwrap();
        let mut a = tar::Builder::new(backup_tar_file);
        a.append_dir_all(
            metrics_dir.as_path().file_name().unwrap(),
            metrics_dir.as_path(),
        )
        .unwrap();
        a.finish().unwrap();
    });
}
<commit_msg>Gzip the backup archive<commit_after>use crate::common::{get_stem_from_path, TIMESTAMP_SECONDS_FORMAT};
use chrono::prelude::*;
use flate2::write::GzEncoder;
use flate2::Compression;
use std::fs::read_dir;
use std::path::PathBuf;
use std::thread;
use thread_priority::{set_current_thread_priority, ThreadPriority};

pub const BACKUP_FILE_PREFIX: &str = "hub_backup_";
pub const DEFAULT_BACKUP_INTERVAL_MIN: u32 = 1440;

pub fn get_next_backup_timestamp(backup_interval_min: Option<u32>) -> i64 {
    let backup_interval_min: i64 = backup_interval_min
        .unwrap_or(DEFAULT_BACKUP_INTERVAL_MIN)
        .into();
    let next_backup = Utc::now() + chrono::Duration::minutes(backup_interval_min);
    log::debug!("Next backup timestamp: {}", next_backup);
    next_backup.timestamp_millis()
}

pub fn get_next_backup_timestamp_on_launch(
    backup_dir: Option<PathBuf>,
    backup_interval_min: Option<u32>,
) -> Option<i64> {
    if let Some(backup_dir) = backup_dir {
        let backup_interval_min: i64 = backup_interval_min
            .unwrap_or(DEFAULT_BACKUP_INTERVAL_MIN)
            .into();
        let mut paths = read_dir(backup_dir.to_str().unwrap())
            .unwrap()
            .map(|res| res.map(|e| e.path()))
            .filter(|path| {
                if let Ok(path) = path {
                    return path.is_file()
                        && get_stem_from_path(&path).starts_with(BACKUP_FILE_PREFIX);
                }
                false
            })
            .collect::<Result<Vec<_>, std::io::Error>>()
            .unwrap();
        paths.sort();
        let next_backup = if paths.is_empty() {
            // There are no backups, the next one is interval from now
            Utc::now() + chrono::Duration::minutes(backup_interval_min)
        } else {
            let previous_backup_timestamp = get_stem_from_path(paths.get(paths.len() - 1).unwrap())
                [(BACKUP_FILE_PREFIX.len())..]
                .to_string();
            let previous_backup = Utc
                .datetime_from_str(
                    &previous_backup_timestamp.as_str(),
                    TIMESTAMP_SECONDS_FORMAT,
                )
                .unwrap();
            previous_backup + chrono::Duration::minutes(backup_interval_min)
        };
        log::debug!("Next backup timestamp is after: {}", next_backup);
        return Some(next_backup.timestamp_millis());
    }
    None
}

pub fn is_now_after(timestamp: i64) -> bool {
    let now = Utc::now();
    now.timestamp_millis() > timestamp
}

pub fn create_backup(backup_dir: PathBuf, metrics_dir: PathBuf) {
    thread::spawn(move || {
        set_current_thread_priority(ThreadPriority::Min).unwrap();
        let metrics_dir = metrics_dir.canonicalize().unwrap();
        let timestamp_seconds = chrono::Utc::now().format(TIMESTAMP_SECONDS_FORMAT);
        let backup_file = std::fs::File::create(format!(
            "{}/{}{}.tar.gz",
            backup_dir.display(),
            BACKUP_FILE_PREFIX,
            timestamp_seconds
        ))
        .unwrap();
        let enc = GzEncoder::new(backup_file, Compression::default());
        let mut a = tar::Builder::new(enc);
        a.append_dir_all(
            metrics_dir.as_path().file_name().unwrap(),
            metrics_dir.as_path(),
        )
        .unwrap();
        a.finish().unwrap();
    });
}
<|endoftext|>


<commit_before>#![allow(clippy::new_without_default)]

//! Interprets the terminal events we care about (keyboard input).
//!
//! Keyboard events are read from stdin. We look for byte strings of key combinations that we care
//! about. E.g. Alt-arrow keys, C-w etc.

#[cfg(test)]
mod tests;

use std::char;
use std::collections::VecDeque;
use std::pin::Pin;
use std::task::{Context, Poll};

use futures::stream::Stream;
use tokio::io::PollEvented;

use term_input_macros::byte_seq_parser;

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public types
////////////////////////////////////////////////////////////////////////////////////////////////////

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Key {
    AltArrow(Arrow),
    AltChar(char),
    Arrow(Arrow),
    Backspace,
    Char(char),
    Ctrl(char),
    CtrlArrow(Arrow),
    Del,
    End,
    Esc,
    Home,
    PageDown,
    PageUp,
    ShiftDown,
    ShiftUp,
    Tab,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Arrow {
    Left,
    Right,
    Up,
    Down,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Event {
    /// A single key input.
    Key(Key),

    /// Usually a paste.
    String(String),

    // These are not generated anymore. I needed these for a feature, but never really got around
    // implementing it.
    // FocusGained,
    // FocusLost,
    /// An unknown sequence of bytes (probably for a key combination that we don't care about).
    Unknown(Vec<u8>),
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Byte sequences of key presses we want to capture
////////////////////////////////////////////////////////////////////////////////////////////////////

byte_seq_parser! {
    parse_key_bytes -> Key, // Function name. Generation function type is
                            // fn(&[u8]) -> Option<(Key, usize)>.

    [27, 91, 49, 59, 51, 66] => Key::AltArrow(Arrow::Down),
    [27, 91, 49, 59, 51, 68] => Key::AltArrow(Arrow::Left),
    [27, 91, 49, 59, 51, 67] => Key::AltArrow(Arrow::Right),
    [27, 91, 49, 59, 51, 65] => Key::AltArrow(Arrow::Up),
    [27, 91, 66] => Key::Arrow(Arrow::Down),
    [27, 79, 66] => Key::Arrow(Arrow::Down),
    [27, 91, 68] => Key::Arrow(Arrow::Left),
    [27, 79, 68] => Key::Arrow(Arrow::Left),
    [27, 91, 67] => Key::Arrow(Arrow::Right),
    [27, 79, 67] => Key::Arrow(Arrow::Right),
    [27, 91, 65] => Key::Arrow(Arrow::Up),
    [27, 79, 65] => Key::Arrow(Arrow::Up),
    [27, 91, 49, 59, 53, 66] => Key::Arrow(Arrow::Down),
    [27, 91, 49, 59, 53, 68] => Key::Arrow(Arrow::Left),
    [27, 91, 49, 59, 53, 67] => Key::Arrow(Arrow::Right),
    [27, 91, 49, 59, 53, 65] => Key::CtrlArrow(Arrow::Up),
    [27, 91, 51, 126] => Key::Del,
    [27, 91, 54, 126] => Key::PageDown,
    [27, 91, 53, 126] => Key::PageUp,
    [27, 91, 49, 59, 50, 65] => Key::ShiftUp,
    [27, 91, 49, 59, 50, 66] => Key::ShiftDown,
    [27, 91, 72] => Key::Home,
    [27, 91, 70] => Key::End,
    [27, 79, 72] => Key::Home,
    [27, 79, 70] => Key::End,
    [27, 91, 52, 126] => Key::End,
    [9] => Key::Tab,
    [127] => Key::Backspace,
    [1] => Key::Ctrl('a'),
    [5] => Key::Ctrl('e'),
    [23] => Key::Ctrl('w'),
    [11] => Key::Ctrl('k'),
    [4] => Key::Ctrl('d'),
    [3] => Key::Ctrl('c'),
    [17] => Key::Ctrl('q'),
    [16] => Key::Ctrl('p'),
    [14] => Key::Ctrl('n'),
    [21] => Key::Ctrl('u'),
    [24] => Key::Ctrl('x'),
}

// static XTERM_FOCUS_GAINED: [u8; 3] = [27, 91, 73];
// static XTERM_FOCUS_LOST: [u8; 3] = [27, 91, 79];

////////////////////////////////////////////////////////////////////////////////////////////////////

pub struct Input {
    /// Queue of events waiting to be polled.
    evs: VecDeque<Event>,

    /// Used when reading from stdin.
    buf: Vec<u8>,

    stdin: PollEvented<mio::unix::EventedFd<'static>>,
}

impl Input {
    pub fn new() -> Input {
        Input {
            evs: VecDeque::new(),
            buf: Vec::with_capacity(100),
            stdin: PollEvented::new(mio::unix::EventedFd(&libc::STDIN_FILENO)).unwrap(),
        }
    }
}

impl Stream for Input {
    type Item = std::io::Result<Event>;

    fn poll_next(mut self: Pin<&mut Input>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        let self_: &mut Input = &mut *self;

        // Try to parse any bytes in the input buffer from the last poll
        {
            let mut buf_slice: &[u8] = &self_.buf;

            while !buf_slice.is_empty() {
                // Special treatment for 127 (backspace, 0x1B) and 13 ('\r', 0xD)
                let fst = buf_slice[0];
                let parse_fn = if (fst < 32 && fst != 13) || fst == 127 {
                    parse_key_comb
                } else {
                    parse_chars
                };

                match parse_fn(buf_slice) {
                    Some((ev, used)) => {
                        buf_slice = &buf_slice[used..];
                        self_.evs.push_back(ev);
                    }
                    None => {
                        self_.evs.push_back(Event::Unknown(buf_slice.to_owned()));
                        break;
                    }
                }
            }
        }

        self_.buf.clear();

        // Yield pending events
        if let Some(ev) = self_.evs.pop_front() {
            return Poll::Ready(Some(Ok(ev)));
        }

        // Otherwise read stdin and loop if successful
        match self_.stdin.poll_read_ready(cx, mio::Ready::readable()) {
            Poll::Ready(Ok(_)) => {
                if read_stdin(&mut self_.buf) {
                    Input::poll_next(self, cx)
                } else {
                    self_
                        .stdin
                        .clear_read_ready(cx, mio::Ready::readable())
                        .unwrap();
                    Poll::Pending
                }
            }
            Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))),
            Poll::Pending => Poll::Pending,
        }
    }
}

#[cfg(test)]
pub(crate) fn parse_single_event(buf: &[u8]) -> Event {
    let fst = buf[0];
    let parse_fn = if (fst < 32 && fst != 13) || fst == 127 {
        parse_key_comb
    } else {
        parse_chars
    };

    let (ev, used) = match parse_fn(buf) {
        Some((ev, used)) => (ev, used),
        None => (Event::Unknown(buf.to_owned()), buf.len()),
    };

    assert_eq!(buf.len(), used);

    ev
}

fn parse_chars(buf: &[u8]) -> Option<(Event, usize)> {
    debug_assert!(!buf.is_empty());

    // Use a fast path for the common case: Single utf-8 character.
    // (TODO: What about other encodings?)

    utf8_char_len(buf[0]).map(|char_len| {
        if char_len as usize == buf.len() {
            // Fast path: single character
            let ev = Event::Key(Key::Char(get_utf8_char(buf, char_len)));
            (ev, char_len as usize)
        } else {
            // Probably a paste: allocate a string and collect chars
            let mut string = String::with_capacity(1000);
            let mut start_idx = 0;
            loop {
                if start_idx == buf.len() {
                    break;
                }
                match utf8_char_len(buf[start_idx]) {
                    Some(char_len) => {
                        string.push(get_utf8_char(&buf[start_idx..], char_len));
                        start_idx += char_len as usize;
                    }
                    None => {
                        break;
                    }
                }
            }
            let ev = Event::String(string);
            (ev, start_idx)
        }
    })
}

fn parse_key_comb(buf: &[u8]) -> Option<(Event, usize)> {
    debug_assert!(!buf.is_empty());

    if let Some((key, used)) = parse_key_bytes(buf) {
        return Some((Event::Key(key), used));
    }

    if buf[0] == 27 {
        // 0x1B, ESC
        // 27 not followed by anything is an actual ESC
        if buf.len() == 1 {
            return Some((Event::Key(Key::Esc), 1));
        }
        // otherwise it's probably alt + key
        else {
            debug_assert!(buf.len() >= 2);
            return utf8_char_len(buf[1]).map(|char_len| {
                let ev = Event::Key(Key::AltChar(get_utf8_char(&buf[1..], char_len)));
                (ev, char_len as usize + 1)
            });
        }
    }

    None
}

fn utf8_char_len(byte: u8) -> Option<u8> {
    if byte >> 7 == 0b0 {
        Some(1)
    } else if byte >> 5 == 0b110 {
        Some(2)
    } else if byte >> 4 == 0b1110 {
        Some(3)
    } else if byte >> 3 == 0b11110 {
        Some(4)
    } else {
        None
    }
}

fn get_utf8_char(buf: &[u8], len: u8) -> char {
    let codepoint: u32 = {
        if len == 1 {
            u32::from(buf[0] & 0b0111_1111)
        } else if len == 2 {
            ((u32::from(buf[0] & 0b0001_1111)) << 6) + (u32::from(buf[1] & 0b0011_1111))
        } else if len == 3 {
            ((u32::from(buf[0] & 0b0000_1111)) << 12)
                + ((u32::from(buf[1] & 0b0011_1111)) << 6)
                + (u32::from(buf[2] & 0b0011_1111))
        } else {
            debug_assert!(len == 4);
            ((u32::from(buf[0] & 0b0000_0111)) << 18)
                + ((u32::from(buf[1] & 0b0011_1111)) << 12)
                + ((u32::from(buf[2] & 0b0011_1111)) << 6)
                + (u32::from(buf[3] & 0b0011_1111))
        }
    };

    char::from_u32(codepoint).unwrap()
}

/// Read stdin contents if it's ready for reading. Returns true when it was able to read. Buffer is
/// not modified when return value is 0.
pub fn read_stdin(buf: &mut Vec<u8>) -> bool {
    let mut bytes_available: i32 = 0; // this really needs to be a 32-bit value
    let ioctl_ret =
        unsafe { libc::ioctl(libc::STDIN_FILENO, libc::FIONREAD, &mut bytes_available) };
    // println!("ioctl_ret: {}", ioctl_ret);
    // println!("bytes_available: {}", bytes_available);
    if ioctl_ret < 0 || bytes_available == 0 {
        false
    } else {
        buf.clear();
        buf.reserve(bytes_available as usize);

        let buf_ptr: *mut libc::c_void = buf.as_ptr() as *mut libc::c_void;
        let bytes_read =
            unsafe { libc::read(libc::STDIN_FILENO, buf_ptr, bytes_available as usize) };
        debug_assert!(bytes_read == bytes_available as isize);

        unsafe {
            buf.set_len(bytes_read as usize);
        }
        true
    }
}
<commit_msg>Fix C-arrow key combs broken in the previous commit<commit_after>#![allow(clippy::new_without_default)]

//! Interprets the terminal events we care about (keyboard input).
//!
//! Keyboard events are read from stdin. We look for byte strings of key combinations that we care
//! about. E.g. Alt-arrow keys, C-w etc.

#[cfg(test)]
mod tests;

use std::char;
use std::collections::VecDeque;
use std::pin::Pin;
use std::task::{Context, Poll};

use futures::stream::Stream;
use tokio::io::PollEvented;

use term_input_macros::byte_seq_parser;

////////////////////////////////////////////////////////////////////////////////////////////////////
// Public types
////////////////////////////////////////////////////////////////////////////////////////////////////

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Key {
    AltArrow(Arrow),
    AltChar(char),
    Arrow(Arrow),
    Backspace,
    Char(char),
    Ctrl(char),
    CtrlArrow(Arrow),
    Del,
    End,
    Esc,
    Home,
    PageDown,
    PageUp,
    ShiftDown,
    ShiftUp,
    Tab,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Arrow {
    Left,
    Right,
    Up,
    Down,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Event {
    /// A single key input.
    Key(Key),

    /// Usually a paste.
    String(String),

    // These are not generated anymore. I needed these for a feature, but never really got around
    // implementing it.
    // FocusGained,
    // FocusLost,
    /// An unknown sequence of bytes (probably for a key combination that we don't care about).
    Unknown(Vec<u8>),
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Byte sequences of key presses we want to capture
////////////////////////////////////////////////////////////////////////////////////////////////////

byte_seq_parser! {
    parse_key_bytes -> Key, // Function name. Generation function type is
                            // fn(&[u8]) -> Option<(Key, usize)>.

    [27, 91, 49, 59, 51, 66] => Key::AltArrow(Arrow::Down),
    [27, 91, 49, 59, 51, 68] => Key::AltArrow(Arrow::Left),
    [27, 91, 49, 59, 51, 67] => Key::AltArrow(Arrow::Right),
    [27, 91, 49, 59, 51, 65] => Key::AltArrow(Arrow::Up),
    [27, 91, 66] => Key::Arrow(Arrow::Down),
    [27, 79, 66] => Key::Arrow(Arrow::Down),
    [27, 91, 68] => Key::Arrow(Arrow::Left),
    [27, 79, 68] => Key::Arrow(Arrow::Left),
    [27, 91, 67] => Key::Arrow(Arrow::Right),
    [27, 79, 67] => Key::Arrow(Arrow::Right),
    [27, 91, 65] => Key::Arrow(Arrow::Up),
    [27, 79, 65] => Key::Arrow(Arrow::Up),
    [27, 91, 49, 59, 53, 66] => Key::CtrlArrow(Arrow::Down),
    [27, 91, 49, 59, 53, 68] => Key::CtrlArrow(Arrow::Left),
    [27, 91, 49, 59, 53, 67] => Key::CtrlArrow(Arrow::Right),
    [27, 91, 49, 59, 53, 65] => Key::CtrlArrow(Arrow::Up),
    [27, 91, 51, 126] => Key::Del,
    [27, 91, 54, 126] => Key::PageDown,
    [27, 91, 53, 126] => Key::PageUp,
    [27, 91, 49, 59, 50, 65] => Key::ShiftUp,
    [27, 91, 49, 59, 50, 66] => Key::ShiftDown,
    [27, 91, 72] => Key::Home,
    [27, 91, 70] => Key::End,
    [27, 79, 72] => Key::Home,
    [27, 79, 70] => Key::End,
    [27, 91, 52, 126] => Key::End,
    [9] => Key::Tab,
    [127] => Key::Backspace,
    [1] => Key::Ctrl('a'),
    [5] => Key::Ctrl('e'),
    [23] => Key::Ctrl('w'),
    [11] => Key::Ctrl('k'),
    [4] => Key::Ctrl('d'),
    [3] => Key::Ctrl('c'),
    [17] => Key::Ctrl('q'),
    [16] => Key::Ctrl('p'),
    [14] => Key::Ctrl('n'),
    [21] => Key::Ctrl('u'),
    [24] => Key::Ctrl('x'),
}

// static XTERM_FOCUS_GAINED: [u8; 3] = [27, 91, 73];
// static XTERM_FOCUS_LOST: [u8; 3] = [27, 91, 79];

////////////////////////////////////////////////////////////////////////////////////////////////////

pub struct Input {
    /// Queue of events waiting to be polled.
    evs: VecDeque<Event>,

    /// Used when reading from stdin.
    buf: Vec<u8>,

    stdin: PollEvented<mio::unix::EventedFd<'static>>,
}

impl Input {
    pub fn new() -> Input {
        Input {
            evs: VecDeque::new(),
            buf: Vec::with_capacity(100),
            stdin: PollEvented::new(mio::unix::EventedFd(&libc::STDIN_FILENO)).unwrap(),
        }
    }
}

impl Stream for Input {
    type Item = std::io::Result<Event>;

    fn poll_next(mut self: Pin<&mut Input>, cx: &mut Context) -> Poll<Option<Self::Item>> {
        let self_: &mut Input = &mut *self;

        // Try to parse any bytes in the input buffer from the last poll
        {
            let mut buf_slice: &[u8] = &self_.buf;

            while !buf_slice.is_empty() {
                // Special treatment for 127 (backspace, 0x1B) and 13 ('\r', 0xD)
                let fst = buf_slice[0];
                let parse_fn = if (fst < 32 && fst != 13) || fst == 127 {
                    parse_key_comb
                } else {
                    parse_chars
                };

                match parse_fn(buf_slice) {
                    Some((ev, used)) => {
                        buf_slice = &buf_slice[used..];
                        self_.evs.push_back(ev);
                    }
                    None => {
                        self_.evs.push_back(Event::Unknown(buf_slice.to_owned()));
                        break;
                    }
                }
            }
        }

        self_.buf.clear();

        // Yield pending events
        if let Some(ev) = self_.evs.pop_front() {
            return Poll::Ready(Some(Ok(ev)));
        }

        // Otherwise read stdin and loop if successful
        match self_.stdin.poll_read_ready(cx, mio::Ready::readable()) {
            Poll::Ready(Ok(_)) => {
                if read_stdin(&mut self_.buf) {
                    Input::poll_next(self, cx)
                } else {
                    self_
                        .stdin
                        .clear_read_ready(cx, mio::Ready::readable())
                        .unwrap();
                    Poll::Pending
                }
            }
            Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))),
            Poll::Pending => Poll::Pending,
        }
    }
}

#[cfg(test)]
pub(crate) fn parse_single_event(buf: &[u8]) -> Event {
    let fst = buf[0];
    let parse_fn = if (fst < 32 && fst != 13) || fst == 127 {
        parse_key_comb
    } else {
        parse_chars
    };

    let (ev, used) = match parse_fn(buf) {
        Some((ev, used)) => (ev, used),
        None => (Event::Unknown(buf.to_owned()), buf.len()),
    };

    assert_eq!(buf.len(), used);

    ev
}

fn parse_chars(buf: &[u8]) -> Option<(Event, usize)> {
    debug_assert!(!buf.is_empty());

    // Use a fast path for the common case: Single utf-8 character.
    // (TODO: What about other encodings?)

    utf8_char_len(buf[0]).map(|char_len| {
        if char_len as usize == buf.len() {
            // Fast path: single character
            let ev = Event::Key(Key::Char(get_utf8_char(buf, char_len)));
            (ev, char_len as usize)
        } else {
            // Probably a paste: allocate a string and collect chars
            let mut string = String::with_capacity(1000);
            let mut start_idx = 0;
            loop {
                if start_idx == buf.len() {
                    break;
                }
                match utf8_char_len(buf[start_idx]) {
                    Some(char_len) => {
                        string.push(get_utf8_char(&buf[start_idx..], char_len));
                        start_idx += char_len as usize;
                    }
                    None => {
                        break;
                    }
                }
            }
            let ev = Event::String(string);
            (ev, start_idx)
        }
    })
}

fn parse_key_comb(buf: &[u8]) -> Option<(Event, usize)> {
    debug_assert!(!buf.is_empty());

    if let Some((key, used)) = parse_key_bytes(buf) {
        return Some((Event::Key(key), used));
    }

    if buf[0] == 27 {
        // 0x1B, ESC
        // 27 not followed by anything is an actual ESC
        if buf.len() == 1 {
            return Some((Event::Key(Key::Esc), 1));
        }
        // otherwise it's probably alt + key
        else {
            debug_assert!(buf.len() >= 2);
            return utf8_char_len(buf[1]).map(|char_len| {
                let ev = Event::Key(Key::AltChar(get_utf8_char(&buf[1..], char_len)));
                (ev, char_len as usize + 1)
            });
        }
    }

    None
}

fn utf8_char_len(byte: u8) -> Option<u8> {
    if byte >> 7 == 0b0 {
        Some(1)
    } else if byte >> 5 == 0b110 {
        Some(2)
    } else if byte >> 4 == 0b1110 {
        Some(3)
    } else if byte >> 3 == 0b11110 {
        Some(4)
    } else {
        None
    }
}

fn get_utf8_char(buf: &[u8], len: u8) -> char {
    let codepoint: u32 = {
        if len == 1 {
            u32::from(buf[0] & 0b0111_1111)
        } else if len == 2 {
            ((u32::from(buf[0] & 0b0001_1111)) << 6) + (u32::from(buf[1] & 0b0011_1111))
        } else if len == 3 {
            ((u32::from(buf[0] & 0b0000_1111)) << 12)
                + ((u32::from(buf[1] & 0b0011_1111)) << 6)
                + (u32::from(buf[2] & 0b0011_1111))
        } else {
            debug_assert!(len == 4);
            ((u32::from(buf[0] & 0b0000_0111)) << 18)
                + ((u32::from(buf[1] & 0b0011_1111)) << 12)
                + ((u32::from(buf[2] & 0b0011_1111)) << 6)
                + (u32::from(buf[3] & 0b0011_1111))
        }
    };

    char::from_u32(codepoint).unwrap()
}

/// Read stdin contents if it's ready for reading. Returns true when it was able to read. Buffer is
/// not modified when return value is 0.
pub fn read_stdin(buf: &mut Vec<u8>) -> bool {
    let mut bytes_available: i32 = 0; // this really needs to be a 32-bit value
    let ioctl_ret =
        unsafe { libc::ioctl(libc::STDIN_FILENO, libc::FIONREAD, &mut bytes_available) };
    // println!("ioctl_ret: {}", ioctl_ret);
    // println!("bytes_available: {}", bytes_available);
    if ioctl_ret < 0 || bytes_available == 0 {
        false
    } else {
        buf.clear();
        buf.reserve(bytes_available as usize);

        let buf_ptr: *mut libc::c_void = buf.as_ptr() as *mut libc::c_void;
        let bytes_read =
            unsafe { libc::read(libc::STDIN_FILENO, buf_ptr, bytes_available as usize) };
        debug_assert!(bytes_read == bytes_available as isize);

        unsafe {
            buf.set_len(bytes_read as usize);
        }
        true
    }
}
<|endoftext|>


<commit_before>
use CreationError;
use GlAttributes;
use GlProfile;
use GlRequest;
use PixelFormatRequirements;
use ReleaseBehavior;
use cocoa::appkit::*;

pub fn build_nsattributes<T>(pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&T>)
    -> Result<Vec<u32>, CreationError> {

    let profile = match (opengl.version, opengl.version.to_gl_version(), opengl.profile) {

        // Note: we are not using ranges because of a rust bug that should be fixed here:
        // https://github.com/rust-lang/rust/pull/27050

        (GlRequest::Latest, _, Some(GlProfile::Compatibility)) => NSOpenGLProfileVersionLegacy as u32,
        (GlRequest::Latest, _, _) => unsafe {
            if NSAppKitVersionNumber.floor() >= NSAppKitVersionNumber10_9 {
                NSOpenGLProfileVersion4_1Core as u32
            } else if NSAppKitVersionNumber.floor() >= NSAppKitVersionNumber10_7 {
                NSOpenGLProfileVersion3_2Core as u32
            } else {
                NSOpenGLProfileVersionLegacy as u32
            }
        },

        (_, Some((1, _)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((2, _)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((3, 0)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((3, 1)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((3, 2)), _) => NSOpenGLProfileVersion3_2Core as u32,
        (_, Some((3, _)), Some(GlProfile::Compatibility)) => return Err(CreationError::OpenGlVersionNotSupported),
        (_, Some((3, _)), _) => NSOpenGLProfileVersion4_1Core as u32,
        (_, Some((4, _)), Some(GlProfile::Compatibility)) => return Err(CreationError::OpenGlVersionNotSupported),
        (_, Some((4, _)), _) => NSOpenGLProfileVersion4_1Core as u32,
        _ => return Err(CreationError::OpenGlVersionNotSupported),
    };

    // NOTE: OS X no longer has the concept of setting individual
    // color component's bit size. Instead we can only specify the
    // full color size and hope for the best. Another hiccup is that
    // `NSOpenGLPFAColorSize` also includes `NSOpenGLPFAAlphaSize`,
    // so we have to account for that as well.
    let alpha_depth = pf_reqs.alpha_bits.unwrap_or(8);
    let color_depth = pf_reqs.color_bits.unwrap_or(24) + alpha_depth;

    // TODO: handle hardware_accelerated parameter of pf_reqs

    let mut attributes = vec![
        NSOpenGLPFADoubleBuffer as u32,
        NSOpenGLPFAClosestPolicy as u32,
        NSOpenGLPFAColorSize as u32, color_depth as u32,
        NSOpenGLPFAAlphaSize as u32, alpha_depth as u32,
        NSOpenGLPFADepthSize as u32, pf_reqs.depth_bits.unwrap_or(24) as u32,
        NSOpenGLPFAStencilSize as u32, pf_reqs.stencil_bits.unwrap_or(8) as u32,
        NSOpenGLPFAOpenGLProfile as u32, profile,
    ];

    if pf_reqs.release_behavior != ReleaseBehavior::Flush {
        return Err(CreationError::NoAvailablePixelFormat);
    }

    if pf_reqs.stereoscopy {
        unimplemented!();   // TODO:
    }

    if pf_reqs.double_buffer == Some(false) {
        unimplemented!();   // TODO:
    }

    if pf_reqs.float_color_buffer {
        attributes.push(NSOpenGLPFAColorFloat as u32);
    }

    pf_reqs.multisampling.map(|samples| {
        attributes.push(NSOpenGLPFAMultisample as u32);
        attributes.push(NSOpenGLPFASampleBuffers as u32); attributes.push(1);
        attributes.push(NSOpenGLPFASamples as u32); attributes.push(samples as u32);
    });

    // attribute list must be null terminated.
    attributes.push(0);

    Ok(attributes)
}
<commit_msg>Specify the NSOpenGLPFAAllowOfflineRenderers attribute.<commit_after>
use CreationError;
use GlAttributes;
use GlProfile;
use GlRequest;
use PixelFormatRequirements;
use ReleaseBehavior;
use cocoa::appkit::*;

pub fn build_nsattributes<T>(pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&T>)
    -> Result<Vec<u32>, CreationError> {

    let profile = match (opengl.version, opengl.version.to_gl_version(), opengl.profile) {

        // Note: we are not using ranges because of a rust bug that should be fixed here:
        // https://github.com/rust-lang/rust/pull/27050

        (GlRequest::Latest, _, Some(GlProfile::Compatibility)) => NSOpenGLProfileVersionLegacy as u32,
        (GlRequest::Latest, _, _) => unsafe {
            if NSAppKitVersionNumber.floor() >= NSAppKitVersionNumber10_9 {
                NSOpenGLProfileVersion4_1Core as u32
            } else if NSAppKitVersionNumber.floor() >= NSAppKitVersionNumber10_7 {
                NSOpenGLProfileVersion3_2Core as u32
            } else {
                NSOpenGLProfileVersionLegacy as u32
            }
        },

        (_, Some((1, _)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((2, _)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((3, 0)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((3, 1)), _) => NSOpenGLProfileVersionLegacy as u32,
        (_, Some((3, 2)), _) => NSOpenGLProfileVersion3_2Core as u32,
        (_, Some((3, _)), Some(GlProfile::Compatibility)) => return Err(CreationError::OpenGlVersionNotSupported),
        (_, Some((3, _)), _) => NSOpenGLProfileVersion4_1Core as u32,
        (_, Some((4, _)), Some(GlProfile::Compatibility)) => return Err(CreationError::OpenGlVersionNotSupported),
        (_, Some((4, _)), _) => NSOpenGLProfileVersion4_1Core as u32,
        _ => return Err(CreationError::OpenGlVersionNotSupported),
    };

    // NOTE: OS X no longer has the concept of setting individual
    // color component's bit size. Instead we can only specify the
    // full color size and hope for the best. Another hiccup is that
    // `NSOpenGLPFAColorSize` also includes `NSOpenGLPFAAlphaSize`,
    // so we have to account for that as well.
    let alpha_depth = pf_reqs.alpha_bits.unwrap_or(8);
    let color_depth = pf_reqs.color_bits.unwrap_or(24) + alpha_depth;

    // TODO: handle hardware_accelerated parameter of pf_reqs

    let mut attributes = vec![
        NSOpenGLPFADoubleBuffer as u32,
        NSOpenGLPFAClosestPolicy as u32,
        NSOpenGLPFAColorSize as u32, color_depth as u32,
        NSOpenGLPFAAlphaSize as u32, alpha_depth as u32,
        NSOpenGLPFADepthSize as u32, pf_reqs.depth_bits.unwrap_or(24) as u32,
        NSOpenGLPFAStencilSize as u32, pf_reqs.stencil_bits.unwrap_or(8) as u32,
        NSOpenGLPFAAllowOfflineRenderers as u32,
        NSOpenGLPFAOpenGLProfile as u32, profile,
    ];

    if pf_reqs.release_behavior != ReleaseBehavior::Flush {
        return Err(CreationError::NoAvailablePixelFormat);
    }

    if pf_reqs.stereoscopy {
        unimplemented!();   // TODO:
    }

    if pf_reqs.double_buffer == Some(false) {
        unimplemented!();   // TODO:
    }

    if pf_reqs.float_color_buffer {
        attributes.push(NSOpenGLPFAColorFloat as u32);
    }

    pf_reqs.multisampling.map(|samples| {
        attributes.push(NSOpenGLPFAMultisample as u32);
        attributes.push(NSOpenGLPFASampleBuffers as u32); attributes.push(1);
        attributes.push(NSOpenGLPFASamples as u32); attributes.push(samples as u32);
    });

    // attribute list must be null terminated.
    attributes.push(0);

    Ok(attributes)
}
<|endoftext|>