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

use tink::keyset::{Reader, Writer};

#[test]
fn test_binary_io_unencrypted() {
    tink_mac::init();

    let manager = tink_testutil::new_hmac_keyset_manager();
    let h = manager.handle().expect("cannot get keyset handle");
    let ks1 = tink::keyset::insecure::keyset_material(&h);

    let mut buf = Vec::new();
    {
        let mut w = tink::keyset::BinaryWriter::new(&mut buf);
        w.write(&ks1).expect("cannot write keyset");
    }

    let mut r = tink::keyset::BinaryReader::new(&buf[..]);
    let ks2 = r.read().expect("cannot read keyset");
    assert_eq!(
        ks1, ks2,
        "written keyset ({:?}) doesn't match read keyset ({:?})",
        ks1, ks2
    );
}

#[test]
fn test_binary_io_encrypted() {
    let kse1 = tink::proto::EncryptedKeyset {
        encrypted_keyset: vec![b'A'; 32],
        keyset_info: None,
    };

    let mut buf = Vec::new();
    {
        let mut w = tink::keyset::BinaryWriter::new(&mut buf);
        w.write_encrypted(&kse1)
            .expect("cannot write encrypted keyset");
    }

    let mut r = tink::keyset::BinaryReader::new(&buf[..]);
    let kse2 = r.read_encrypted().expect("cannot read encrypted keyset");
    assert_eq!(
        kse1, kse2,
        "written encrypted keyset ({:?}) doesn't match read encrypted keyset ({:?})",
        kse1, kse2
    );
}
<commit_msg>tink::keyset: more binary IO tests<commit_after>// Copyright 2020 The Tink-Rust Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

use tink::keyset::{Reader, Writer};

#[test]
fn test_binary_io_unencrypted() {
    tink_mac::init();

    let manager = tink_testutil::new_hmac_keyset_manager();
    let h = manager.handle().expect("cannot get keyset handle");
    let ks1 = tink::keyset::insecure::keyset_material(&h);

    let mut buf = Vec::new();
    {
        let mut w = tink::keyset::BinaryWriter::new(&mut buf);
        w.write(&ks1).expect("cannot write keyset");
    }

    let mut r = tink::keyset::BinaryReader::new(&buf[..]);
    let ks2 = r.read().expect("cannot read keyset");
    assert_eq!(
        ks1, ks2,
        "written keyset ({:?}) doesn't match read keyset ({:?})",
        ks1, ks2
    );
}

#[test]
fn test_binary_io_encrypted() {
    let kse1 = tink::proto::EncryptedKeyset {
        encrypted_keyset: vec![b'A'; 32],
        keyset_info: None,
    };

    let mut buf = Vec::new();
    {
        let mut w = tink::keyset::BinaryWriter::new(&mut buf);
        w.write_encrypted(&kse1)
            .expect("cannot write encrypted keyset");
    }

    let mut r = tink::keyset::BinaryReader::new(&buf[..]);
    let kse2 = r.read_encrypted().expect("cannot read encrypted keyset");
    assert_eq!(
        kse1, kse2,
        "written encrypted keyset ({:?}) doesn't match read encrypted keyset ({:?})",
        kse1, kse2
    );
}

#[test]
fn test_binary_io_read_fail() {
    let mut r = tink::keyset::BinaryReader::new(tink_testutil::IoFailure {});
    let result = r.read();
    tink_testutil::expect_err(result, "read failed");

    let buf = vec![1, 2, 3];
    let mut r = tink::keyset::BinaryReader::new(&buf[..]);
    let result = r.read();
    tink_testutil::expect_err(result, "decode failed");
}

#[test]
fn test_binary_io_write_fail() {
    tink_mac::init();
    let manager = tink_testutil::new_hmac_keyset_manager();
    let h = manager.handle().expect("cannot get keyset handle");
    let ks = tink::keyset::insecure::keyset_material(&h);

    let mut failing_writer = tink_testutil::IoFailure {};
    let mut w = tink::keyset::BinaryWriter::new(&mut failing_writer);
    let result = w.write(&ks);
    tink_testutil::expect_err(result, "write failed");
}
<|endoftext|>


<commit_before>use futures::{Async, Future, Poll};
use futures_cpupool::{CpuFuture, CpuPool};
use postgres_protocol::message::frontend;
use state_machine_future::RentToOwn;
use std::error::Error as StdError;
use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
use std::time::{Duration, Instant};
use std::vec;
use tokio_io::io::{read_exact, write_all, ReadExact, WriteAll};
use tokio_tcp::{self, TcpStream};
use tokio_timer::Delay;

#[cfg(unix)]
use tokio_uds::{self, UnixStream};

use params::{ConnectParams, Host};
use proto::socket::Socket;
use tls::{self, TlsConnect, TlsStream};
use {Error, TlsMode};

lazy_static! {
    static ref DNS_POOL: CpuPool = CpuPool::new(2);
}

#[derive(StateMachineFuture)]
pub enum Connect {
    #[state_machine_future(start)]
    #[cfg_attr(
        unix,
        state_machine_future(transitions(ResolvingDns, ConnectingUnix))
    )]
    #[cfg_attr(not(unix), state_machine_future(transitions(ResolvingDns)))]
    Start { params: ConnectParams, tls: TlsMode },
    #[state_machine_future(transitions(ConnectingTcp))]
    ResolvingDns {
        future: CpuFuture<vec::IntoIter<SocketAddr>, io::Error>,
        timeout: Option<Duration>,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[state_machine_future(transitions(PreparingSsl))]
    ConnectingTcp {
        addrs: vec::IntoIter<SocketAddr>,
        future: tokio_tcp::ConnectFuture,
        timeout: Option<(Duration, Delay)>,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[cfg(unix)]
    #[state_machine_future(transitions(PreparingSsl))]
    ConnectingUnix {
        future: tokio_uds::ConnectFuture,
        timeout: Option<Delay>,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[state_machine_future(transitions(Ready, SendingSsl))]
    PreparingSsl {
        socket: Socket,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[state_machine_future(transitions(ReadingSsl))]
    SendingSsl {
        future: WriteAll<Socket, Vec<u8>>,
        params: ConnectParams,
        connector: Box<TlsConnect>,
        required: bool,
    },
    #[state_machine_future(transitions(ConnectingTls, Ready))]
    ReadingSsl {
        future: ReadExact<Socket, [u8; 1]>,
        params: ConnectParams,
        connector: Box<TlsConnect>,
        required: bool,
    },
    #[state_machine_future(transitions(Ready))]
    ConnectingTls {
        future:
            Box<Future<Item = Box<TlsStream>, Error = Box<StdError + Sync + Send>> + Sync + Send>,
        params: ConnectParams,
    },
    #[state_machine_future(ready)]
    Ready(Box<TlsStream>),
    #[state_machine_future(error)]
    Failed(Error),
}

impl PollConnect for Connect {
    fn poll_start<'a>(state: &'a mut RentToOwn<'a, Start>) -> Poll<AfterStart, Error> {
        let state = state.take();

        let timeout = state.params.connect_timeout();
        let port = state.params.port();

        match state.params.host().clone() {
            Host::Tcp(host) => transition!(ResolvingDns {
                future: DNS_POOL.spawn_fn(move || (&*host, port).to_socket_addrs()),
                params: state.params,
                tls: state.tls,
                timeout,
            }),
            #[cfg(unix)]
            Host::Unix(mut path) => {
                path.push(format!(".s.PGSQL.{}", port));
                transition!(ConnectingUnix {
                    future: UnixStream::connect(path),
                    timeout: timeout.map(|t| Delay::new(Instant::now() + t)),
                    params: state.params,
                    tls: state.tls,
                })
            }
        }
    }

    fn poll_resolving_dns<'a>(
        state: &'a mut RentToOwn<'a, ResolvingDns>,
    ) -> Poll<AfterResolvingDns, Error> {
        let mut addrs = try_ready!(state.future.poll().map_err(Error::connect));
        let state = state.take();

        let addr = match addrs.next() {
            Some(addr) => addr,
            None => {
                return Err(Error::connect(io::Error::new(
                    io::ErrorKind::Other,
                    "resolved to 0 addresses",
                )))
            }
        };

        transition!(ConnectingTcp {
            addrs,
            future: TcpStream::connect(&addr),
            timeout: state.timeout.map(|t| (t, Delay::new(Instant::now() + t))),
            params: state.params,
            tls: state.tls,
        })
    }

    fn poll_connecting_tcp<'a>(
        state: &'a mut RentToOwn<'a, ConnectingTcp>,
    ) -> Poll<AfterConnectingTcp, Error> {
        let socket = loop {
            let error = match state.future.poll() {
                Ok(Async::Ready(socket)) => break socket,
                Ok(Async::NotReady) => match state.timeout {
                    Some((_, ref mut delay)) => {
                        try_ready!(delay.poll().map_err(Error::timer));
                        io::Error::new(io::ErrorKind::TimedOut, "connection timed out")
                    }
                    None => return Ok(Async::NotReady),
                },
                Err(e) => e,
            };

            let addr = match state.addrs.next() {
                Some(addr) => addr,
                None => return Err(Error::connect(error)),
            };

            state.future = TcpStream::connect(&addr);
            if let Some((timeout, ref mut delay)) = state.timeout {
                delay.reset(Instant::now() + timeout);
            }
        };

        // Our read/write patterns may trigger Nagle's algorithm since we're pipelining which
        // we don't want. Each individual write should be a full command we want the backend to
        // see immediately.
        socket.set_nodelay(true).map_err(Error::connect)?;

        let state = state.take();
        transition!(PreparingSsl {
            socket: Socket::Tcp(socket),
            params: state.params,
            tls: state.tls,
        })
    }

    #[cfg(unix)]
    fn poll_connecting_unix<'a>(
        state: &'a mut RentToOwn<'a, ConnectingUnix>,
    ) -> Poll<AfterConnectingUnix, Error> {
        match state.future.poll().map_err(Error::connect)? {
            Async::Ready(socket) => {
                let state = state.take();
                transition!(PreparingSsl {
                    socket: Socket::Unix(socket),
                    params: state.params,
                    tls: state.tls,
                })
            }
            Async::NotReady => match state.timeout {
                Some(ref mut delay) => {
                    try_ready!(delay.poll().map_err(Error::timer));
                    Err(Error::connect(io::Error::new(
                        io::ErrorKind::TimedOut,
                        "connection timed out",
                    )))
                }
                None => Ok(Async::NotReady),
            },
        }
    }

    fn poll_preparing_ssl<'a>(
        state: &'a mut RentToOwn<'a, PreparingSsl>,
    ) -> Poll<AfterPreparingSsl, Error> {
        let state = state.take();

        let (connector, required) = match state.tls {
            TlsMode::None => {
                transition!(Ready(Box::new(state.socket)));
            }
            TlsMode::Prefer(connector) => (connector, false),
            TlsMode::Require(connector) => (connector, true),
        };

        let mut buf = vec![];
        frontend::ssl_request(&mut buf);
        transition!(SendingSsl {
            future: write_all(state.socket, buf),
            params: state.params,
            connector,
            required,
        })
    }

    fn poll_sending_ssl<'a>(
        state: &'a mut RentToOwn<'a, SendingSsl>,
    ) -> Poll<AfterSendingSsl, Error> {
        let (stream, _) = try_ready_closed!(state.future.poll());
        let state = state.take();
        transition!(ReadingSsl {
            future: read_exact(stream, [0]),
            params: state.params,
            connector: state.connector,
            required: state.required,
        })
    }

    fn poll_reading_ssl<'a>(
        state: &'a mut RentToOwn<'a, ReadingSsl>,
    ) -> Poll<AfterReadingSsl, Error> {
        let (stream, buf) = try_ready_closed!(state.future.poll());
        let state = state.take();

        match buf[0] {
            b'S' => {
                let future = match state.params.host() {
                    Host::Tcp(domain) => state.connector.connect(domain, tls::Socket(stream)),
                    Host::Unix(_) => {
                        return Err(Error::tls("TLS over unix sockets not supported".into()))
                    }
                };
                transition!(ConnectingTls {
                    future,
                    params: state.params,
                })
            }
            b'N' if !state.required => transition!(Ready(Box::new(stream))),
            b'N' => Err(Error::tls("TLS was required but not supported".into())),
            _ => Err(Error::unexpected_message()),
        }
    }

    fn poll_connecting_tls<'a>(
        state: &'a mut RentToOwn<'a, ConnectingTls>,
    ) -> Poll<AfterConnectingTls, Error> {
        let stream = try_ready!(state.future.poll().map_err(Error::tls));
        transition!(Ready(stream))
    }
}

impl ConnectFuture {
    pub fn new(params: ConnectParams, tls: TlsMode) -> ConnectFuture {
        Connect::start(params, tls)
    }
}
<commit_msg>Allow to build on Windows<commit_after>use futures::{Async, Future, Poll};
use futures_cpupool::{CpuFuture, CpuPool};
use postgres_protocol::message::frontend;
use state_machine_future::RentToOwn;
use std::error::Error as StdError;
use std::io;
use std::net::{SocketAddr, ToSocketAddrs};
use std::time::{Duration, Instant};
use std::vec;
use tokio_io::io::{read_exact, write_all, ReadExact, WriteAll};
use tokio_tcp::{self, TcpStream};
use tokio_timer::Delay;

#[cfg(unix)]
use tokio_uds::{self, UnixStream};

use params::{ConnectParams, Host};
use proto::socket::Socket;
use tls::{self, TlsConnect, TlsStream};
use {Error, TlsMode};

lazy_static! {
    static ref DNS_POOL: CpuPool = CpuPool::new(2);
}

#[derive(StateMachineFuture)]
pub enum Connect {
    #[state_machine_future(start)]
    #[cfg_attr(
        unix,
        state_machine_future(transitions(ResolvingDns, ConnectingUnix))
    )]
    #[cfg_attr(not(unix), state_machine_future(transitions(ResolvingDns)))]
    Start { params: ConnectParams, tls: TlsMode },
    #[state_machine_future(transitions(ConnectingTcp))]
    ResolvingDns {
        future: CpuFuture<vec::IntoIter<SocketAddr>, io::Error>,
        timeout: Option<Duration>,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[state_machine_future(transitions(PreparingSsl))]
    ConnectingTcp {
        addrs: vec::IntoIter<SocketAddr>,
        future: tokio_tcp::ConnectFuture,
        timeout: Option<(Duration, Delay)>,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[cfg(unix)]
    #[state_machine_future(transitions(PreparingSsl))]
    ConnectingUnix {
        future: tokio_uds::ConnectFuture,
        timeout: Option<Delay>,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[state_machine_future(transitions(Ready, SendingSsl))]
    PreparingSsl {
        socket: Socket,
        params: ConnectParams,
        tls: TlsMode,
    },
    #[state_machine_future(transitions(ReadingSsl))]
    SendingSsl {
        future: WriteAll<Socket, Vec<u8>>,
        params: ConnectParams,
        connector: Box<TlsConnect>,
        required: bool,
    },
    #[state_machine_future(transitions(ConnectingTls, Ready))]
    ReadingSsl {
        future: ReadExact<Socket, [u8; 1]>,
        params: ConnectParams,
        connector: Box<TlsConnect>,
        required: bool,
    },
    #[state_machine_future(transitions(Ready))]
    ConnectingTls {
        future:
            Box<Future<Item = Box<TlsStream>, Error = Box<StdError + Sync + Send>> + Sync + Send>,
        params: ConnectParams,
    },
    #[state_machine_future(ready)]
    Ready(Box<TlsStream>),
    #[state_machine_future(error)]
    Failed(Error),
}

impl PollConnect for Connect {
    fn poll_start<'a>(state: &'a mut RentToOwn<'a, Start>) -> Poll<AfterStart, Error> {
        let state = state.take();

        let timeout = state.params.connect_timeout();
        let port = state.params.port();

        match state.params.host().clone() {
            Host::Tcp(host) => transition!(ResolvingDns {
                future: DNS_POOL.spawn_fn(move || (&*host, port).to_socket_addrs()),
                params: state.params,
                tls: state.tls,
                timeout,
            }),
            #[cfg(unix)]
            Host::Unix(mut path) => {
                path.push(format!(".s.PGSQL.{}", port));
                transition!(ConnectingUnix {
                    future: UnixStream::connect(path),
                    timeout: timeout.map(|t| Delay::new(Instant::now() + t)),
                    params: state.params,
                    tls: state.tls,
                })
            },
            #[cfg(not(unix))]
            Host::Unix(_) => {
                Err(Error::connect(io::Error::new(
                    io::ErrorKind::Other,
                    "unix sockets are not supported on this platform",
                )))
            },
        }
    }

    fn poll_resolving_dns<'a>(
        state: &'a mut RentToOwn<'a, ResolvingDns>,
    ) -> Poll<AfterResolvingDns, Error> {
        let mut addrs = try_ready!(state.future.poll().map_err(Error::connect));
        let state = state.take();

        let addr = match addrs.next() {
            Some(addr) => addr,
            None => {
                return Err(Error::connect(io::Error::new(
                    io::ErrorKind::Other,
                    "resolved to 0 addresses",
                )))
            }
        };

        transition!(ConnectingTcp {
            addrs,
            future: TcpStream::connect(&addr),
            timeout: state.timeout.map(|t| (t, Delay::new(Instant::now() + t))),
            params: state.params,
            tls: state.tls,
        })
    }

    fn poll_connecting_tcp<'a>(
        state: &'a mut RentToOwn<'a, ConnectingTcp>,
    ) -> Poll<AfterConnectingTcp, Error> {
        let socket = loop {
            let error = match state.future.poll() {
                Ok(Async::Ready(socket)) => break socket,
                Ok(Async::NotReady) => match state.timeout {
                    Some((_, ref mut delay)) => {
                        try_ready!(delay.poll().map_err(Error::timer));
                        io::Error::new(io::ErrorKind::TimedOut, "connection timed out")
                    }
                    None => return Ok(Async::NotReady),
                },
                Err(e) => e,
            };

            let addr = match state.addrs.next() {
                Some(addr) => addr,
                None => return Err(Error::connect(error)),
            };

            state.future = TcpStream::connect(&addr);
            if let Some((timeout, ref mut delay)) = state.timeout {
                delay.reset(Instant::now() + timeout);
            }
        };

        // Our read/write patterns may trigger Nagle's algorithm since we're pipelining which
        // we don't want. Each individual write should be a full command we want the backend to
        // see immediately.
        socket.set_nodelay(true).map_err(Error::connect)?;

        let state = state.take();
        transition!(PreparingSsl {
            socket: Socket::Tcp(socket),
            params: state.params,
            tls: state.tls,
        })
    }

    #[cfg(unix)]
    fn poll_connecting_unix<'a>(
        state: &'a mut RentToOwn<'a, ConnectingUnix>,
    ) -> Poll<AfterConnectingUnix, Error> {
        match state.future.poll().map_err(Error::connect)? {
            Async::Ready(socket) => {
                let state = state.take();
                transition!(PreparingSsl {
                    socket: Socket::Unix(socket),
                    params: state.params,
                    tls: state.tls,
                })
            }
            Async::NotReady => match state.timeout {
                Some(ref mut delay) => {
                    try_ready!(delay.poll().map_err(Error::timer));
                    Err(Error::connect(io::Error::new(
                        io::ErrorKind::TimedOut,
                        "connection timed out",
                    )))
                }
                None => Ok(Async::NotReady),
            },
        }
    }

    fn poll_preparing_ssl<'a>(
        state: &'a mut RentToOwn<'a, PreparingSsl>,
    ) -> Poll<AfterPreparingSsl, Error> {
        let state = state.take();

        let (connector, required) = match state.tls {
            TlsMode::None => {
                transition!(Ready(Box::new(state.socket)));
            }
            TlsMode::Prefer(connector) => (connector, false),
            TlsMode::Require(connector) => (connector, true),
        };

        let mut buf = vec![];
        frontend::ssl_request(&mut buf);
        transition!(SendingSsl {
            future: write_all(state.socket, buf),
            params: state.params,
            connector,
            required,
        })
    }

    fn poll_sending_ssl<'a>(
        state: &'a mut RentToOwn<'a, SendingSsl>,
    ) -> Poll<AfterSendingSsl, Error> {
        let (stream, _) = try_ready_closed!(state.future.poll());
        let state = state.take();
        transition!(ReadingSsl {
            future: read_exact(stream, [0]),
            params: state.params,
            connector: state.connector,
            required: state.required,
        })
    }

    fn poll_reading_ssl<'a>(
        state: &'a mut RentToOwn<'a, ReadingSsl>,
    ) -> Poll<AfterReadingSsl, Error> {
        let (stream, buf) = try_ready_closed!(state.future.poll());
        let state = state.take();

        match buf[0] {
            b'S' => {
                let future = match state.params.host() {
                    Host::Tcp(domain) => state.connector.connect(domain, tls::Socket(stream)),
                    Host::Unix(_) => {
                        return Err(Error::tls("TLS over unix sockets not supported".into()))
                    }
                };
                transition!(ConnectingTls {
                    future,
                    params: state.params,
                })
            }
            b'N' if !state.required => transition!(Ready(Box::new(stream))),
            b'N' => Err(Error::tls("TLS was required but not supported".into())),
            _ => Err(Error::unexpected_message()),
        }
    }

    fn poll_connecting_tls<'a>(
        state: &'a mut RentToOwn<'a, ConnectingTls>,
    ) -> Poll<AfterConnectingTls, Error> {
        let stream = try_ready!(state.future.poll().map_err(Error::tls));
        transition!(Ready(stream))
    }
}

impl ConnectFuture {
    pub fn new(params: ConnectParams, tls: TlsMode) -> ConnectFuture {
        Connect::start(params, tls)
    }
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct VariablePair {
    id: i32,
    variable_id: i32,
    variable_value: String
}

pub fn table_create_variable_pair(conn: &Connection) {
    let load_table = conn.execute("CREATE TABLE  VARIABLE_PAIR (
                  id            INTEGER PRIMARY KEY ASC,
                  variable_id   INTEGER NOT NULL,
                  variable_value  TEXT,
                  FOREIGN KEY(variable_id) REFERENCES VARIABLE_NAME(id) ON UPDATE CASCADE
                  )", &[]);
    if load_table.is_err() {
        println!("table_create_job Failed {:?}", load_table);
        return;
    }
    load_table.unwrap();
}

pub fn insert_job_variable_pair(conn: &Connection, variable_id: i32, value: String) {

    let me = VariablePair {
        id: 0,
        variable_id: variable_id,
        variable_value: value,
    };
    conn.execute("INSERT INTO VARIABLE_PAIR (variable_id, variable_value)
                  VALUES (?1, ?2)",
                 &[&me.variable_id, &me.variable_value]).unwrap();
}
<commit_msg>Reorganise interface<commit_after>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct VariablePair {
    id: i32,
    fk_variable: i32,
    variable_value: String
}

pub fn table_create_variable_pair(conn: &Connection) {
    let load_table = conn.execute("CREATE TABLE  VARIABLE_PAIR (
                  id            INTEGER PRIMARY KEY ASC,
                  fk_variable   INTEGER NOT NULL,
                  variable_value  TEXT,
                  FOREIGN KEY(fk_variable) REFERENCES VARIABLE_NAME(id) ON UPDATE CASCADE
                  )", &[]);
    if load_table.is_err() {
        println!("table_create_job Failed {:?}", load_table);
        return;
    }
    load_table.unwrap();
}

pub fn insert_variable_pair(conn: &Connection, fk_variable :i32, name: &String) -> Result<i32, &'static str> {
    let bill = fk_variable;
    let me = VariablePair {
        id : 0,
        fk_variable: bill,
        variable_value: name.clone(),
    };
    let variable_pair_instance = conn.execute("INSERT INTO VARIABLE_PAIR (fk_variable, variable_value)
                  VALUES (?1 ?2)",
                 &[&me.fk_variable, &me.variable_value]);
    if variable_pair_instance.is_err() {
        return Err("Insert failed");
    }
    variable_pair_instance.unwrap();
    return Ok(0);
}

pub fn list_variable_pair(conn: &Connection)-> Vec<VariablePair> {
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value  FROM VARIABLE_PAIR").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    });
    let mut items = Vec::<VariablePair>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn variable_pair_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value FROM VARIABLE_PAIR").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found variable_pair {:?}", person.unwrap());
    }
}

pub fn pk_variable_pair_by_name(conn: &Connection, name: &String, pk: &mut i32) -> Result<i32, &'static str>{
    let mut stmt = conn.prepare("SELECT id, fk_variable, variable_value  FROM VARIABLE_PAIR WHERE name = ?1").unwrap();
    let variable_pair_iter = stmt.query_map(&[name], |row| {
        VariablePair {
            id: row.get(0),
            fk_variable: row.get(1),
            variable_value: row.get(2),
        }
    });
    if variable_pair_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = variable_pair_iter.unwrap();
    let mut found = 0;
    let mut items = Vec::<i32>::new();
    for person in result {
        let bill= person.unwrap();
        *pk = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<|endoftext|>


<commit_before>use redox::Vec;

pub struct AvlNode<T> {
    value: T,
    left: Option<AvlNodeId>, // ID for left node
    right: Option<AvlNodeId>, // ID for right node
}

#[derive(Copy, Clone)]
pub struct AvlNodeId {
    index: usize,
    time_stamp: u64,
}

impl AvlNodeId {
    pub fn get<'a, T: PartialOrd>(&self, avl: &'a AvlTree<T>) -> &'a AvlNode<T> {
        let ref slot = avl.nodes[self.index];
        if slot.time_stamp == self.time_stamp {
            slot.node.as_ref().unwrap()
        } else {
            panic!("AvlNodeId had invalid time_stamp");
        }
    }

    pub fn try_get<'a, T: PartialOrd>(&self, avl: &'a AvlTree<T>) -> Option<&'a AvlNode<T>> {
        avl.nodes
           .get(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_ref()
               } else {
                   None
               }
           })
    }

    pub fn get_mut<'a, T: PartialOrd>(&self, avl: &'a mut AvlTree<T>) -> &'a mut AvlNode<T> {
        let ref mut slot = avl.nodes[self.index];
        if slot.time_stamp == self.time_stamp {
            slot.node.as_mut().unwrap()
        } else {
            panic!("AvlNodeId had invalid time_stamp");
        }
    }

    pub fn try_get_mut<'a, T: PartialOrd>(&self, avl: &'a mut AvlTree<T>) -> Option<&'a mut AvlNode<T>> {
        avl.nodes
           .get_mut(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_mut()
               } else {
                   None
               }
           })
    }
}

pub struct AvlTree<T: PartialOrd> {
    root: Option<AvlNodeId>, // Index of the root node
    nodes: Vec<AvlSlot<T>>,
    free_list: Vec<usize>,
}

impl<T: PartialOrd> AvlTree<T> {
    pub fn new() -> Self {
        AvlTree {
            root: None,
            nodes: Vec::new(),
            free_list: Vec::new(),
        }
    }

    // Inserts a value into the tree, keeping it balanced. Lesser values will be stored on
    // the left, while greater values will be stored on the right. No duplicates are allowed.
    pub fn insert(&mut self, value: T) {
        let root = self.root;
        self.root = Some(self._insert(value, root));
    }

    pub fn in_order<F: Fn(&AvlNode<T>)>(&self, f: &F) {
        if let Some(root) = self.root {
            self._in_order(f, root);
        }
    }

    // Implementation of insert
    fn _insert(&mut self, value: T, node_index: Option<AvlNodeId>) -> AvlNodeId {
        let node =
            match node_index {
                Some(node) => {
                    // Node exists, check which way to branch.
                    if value == node.get(self).value {
                        return node;
                    } else if value < node.get(self).value {
                        let l = node.get(self).left;
                        node.get_mut(self).left = Some(self._insert(value, l));
                    } else if value > node.get(self).value {
                        let r = node.get(self).right;
                        node.get_mut(self).right = Some(self._insert(value, r));
                    }

                    node
                },
                None => {
                    // The node doesn't exist, create it here.
                    self.allocate_node(value)
                },
            };

        self.rebalance(node)
    }

    pub fn _in_order<F: Fn(&AvlNode<T>)>(&self, f: &F, node: AvlNodeId) {
        if let Some(l) = node.get(self).left {
            self._in_order(f, l);
        }
        f(node.get(self));
        if let Some(r) = node.get(self).right {
            self._in_order(f, r);
        }
    }

    // Performs a left rotation on a tree/subtree.
    // Returns the replace the specified node with
    fn rotate_left(&mut self, node: AvlNodeId) -> AvlNodeId {
        // Keep track of the original node positions
        // For a rotate left, the right child node must exist
        let r = node.get(self).right.unwrap();
        let rl = r.get(self).left;

        let ret = r;
        node.get_mut(self).right = rl;
        ret.get_mut(self).left = Some(node);

        ret
    }

    // Performs a right rotation on a tree/subtree.
    // Returns the replace the specified node with
    fn rotate_right(&mut self, node: AvlNodeId) -> AvlNodeId {
        // Keep track of the original node positions
        // For a rotate right, the left child node must exist
        let l = node.get(self).left.unwrap();
        let lr = l.get(self).right;

        let ret = l;
        node.get_mut(self).left = lr;
        ret.get_mut(self).right = Some(node);

        ret
    }

    // performs a left-right double rotation on a tree/subtree.
    fn rotate_leftright(&mut self, node: AvlNodeId) -> AvlNodeId {
        let l = node.get(self).left.unwrap();
        let new_l = self.rotate_left(l); // Left node needs to exist
        node.get_mut(self).left = Some(new_l);
        self.rotate_right(node)
    }

    // performs a right-left double rotation on a tree/subtree.
    fn rotate_rightleft(&mut self, node: AvlNodeId) -> AvlNodeId {
        let r = node.get(self).right.unwrap();
        let new_r = self.rotate_right(r); // Right node needs to exist
        node.get_mut(self).right = Some(new_r);
        self.rotate_left(node)
    }

    // _rebalance rebalances the provided node
    fn rebalance(&mut self, node: AvlNodeId) -> AvlNodeId {
        let balance = self.height(node.get(self).left) - self.height(node.get(self).right);
        if balance == 2 { // left
            let lbalance = self.height(node.get(self).left.unwrap().get(self).left) -
                           self.height(node.get(self).left.unwrap().get(self).right);
            if lbalance == 0 || lbalance == 1 { // left left - need to rotate right
                return self.rotate_right(node);
            } else if lbalance == -1 { // left right
                return self.rotate_leftright(node); // function name is just a coincidence
            }
        } else if balance == -2 { // right
            let rbalance = self.height(node.get(self).right.unwrap().get(self).left) -
                           self.height(node.get(self).right.unwrap().get(self).right);
            if rbalance == 1 { // right left
                return self.rotate_rightleft(node); // function name is just a coincidence
            } else if rbalance == 0 || rbalance == -1 { // right right - need to rotate left
                return self.rotate_left(node);
            }
        }

        node
    }

    // height gets the height of a tree or subtree
    fn height(&self, node: Option<AvlNodeId>) -> i64 {
        match node {
            Some(node) => {
                let left_height = self.height(node.get(self).left);
                let right_height = self.height(node.get(self).right);

                if left_height > right_height {
                    left_height+1
                } else {
                    right_height+1
                }
            },
            None => { -1 },
        }
    }

    fn allocate_node(&mut self, value: T) -> AvlNodeId {
        match self.free_list.pop() {
            Some(index) => {
                AvlNodeId { time_stamp: self.nodes[index].time_stamp+1, index: index }
            },
            None => {
                // No free slots, create a new one
                let id = AvlNodeId { index: self.nodes.len(), time_stamp: 0 };
                self.nodes.push(AvlSlot { time_stamp: 0,
                                          node: Some(AvlNode { value: value, left: None, right: None }) });
                id
            },
        }
    }

    fn free_node(&mut self, id: AvlNodeId) -> AvlNode<T> {
        self.free_list.push(id.index);

        // NOTE: We unwrap here, because we trust that `id` points to a valid node, because
        // only we can create and free AvlNodes and their AvlNodeIds
        self.nodes[id.index].node.take().unwrap()
    }
}

struct AvlSlot<T> {
    time_stamp: u64,
    node: Option<AvlNode<T>>,
}
<commit_msg>AvlTree now uses usize instead of AvlNodeId internally<commit_after>use redox::Vec;

pub struct AvlNode<T> {
    value: T,
    left: Option<usize>, // ID for left node
    right: Option<usize>, // ID for right node
}

impl<T: PartialOrd> AvlNode<T> {
    pub fn value(&self) -> &T { &self.value }
    pub fn left(&self, tree: &AvlTree<T>) -> Option<AvlNodeId> {
        self.left.map(|l| AvlNodeId { index: l, time_stamp: tree.nodes[l].time_stamp })
    }
    pub fn right(&self, tree: &AvlTree<T>) -> Option<AvlNodeId> {
        self.right.map(|r| AvlNodeId { index: r, time_stamp: tree.nodes[r].time_stamp })
    }
}

#[derive(Copy, Clone)]
pub struct AvlNodeId {
    index: usize,
    time_stamp: u64,
}

impl AvlNodeId {
    pub fn get<'a, T: PartialOrd>(&self, avl: &'a AvlTree<T>) -> &'a AvlNode<T> {
        let ref slot = avl.nodes[self.index];
        if slot.time_stamp == self.time_stamp {
            slot.node.as_ref().unwrap()
        } else {
            panic!("AvlNodeId had invalid time_stamp");
        }
    }

    pub fn try_get<'a, T: PartialOrd>(&self, avl: &'a AvlTree<T>) -> Option<&'a AvlNode<T>> {
        avl.nodes
           .get(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_ref()
               } else {
                   None
               }
           })
    }

    pub fn get_mut<'a, T: PartialOrd>(&self, avl: &'a mut AvlTree<T>) -> &'a mut AvlNode<T> {
        let ref mut slot = avl.nodes[self.index];
        if slot.time_stamp == self.time_stamp {
            slot.node.as_mut().unwrap()
        } else {
            panic!("AvlNodeId had invalid time_stamp");
        }
    }

    pub fn try_get_mut<'a, T: PartialOrd>(&self, avl: &'a mut AvlTree<T>) -> Option<&'a mut AvlNode<T>> {
        avl.nodes
           .get_mut(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_mut()
               } else {
                   None
               }
           })
    }
}

pub struct AvlTree<T: PartialOrd> {
    root: Option<usize>, // Index of the root node
    nodes: Vec<AvlSlot<T>>,
    free_list: Vec<usize>,
}

impl<T: PartialOrd> AvlTree<T> {
    pub fn new() -> Self {
        AvlTree {
            root: None,
            nodes: Vec::new(),
            free_list: Vec::new(),
        }
    }

    // Inserts a value into the tree, keeping it balanced. Lesser values will be stored on
    // the left, while greater values will be stored on the right. No duplicates are allowed.
    pub fn insert(&mut self, value: T) {
        let root = self.root;
        self.root = Some(self._insert(value, root));
    }

    pub fn in_order<F: Fn(&AvlNode<T>)>(&self, f: &F) {
        if let Some(root) = self.root {
            self._in_order(f, root);
        }
    }

    // Implementation of insert
    fn _insert(&mut self, value: T, node: Option<usize>) -> usize {
        let node =
            match node{
                Some(node) => {
                    // Node exists, check which way to branch.
                    if value == self.node(node).value {
                        return node;
                    } else if value < self.node(node).value {
                        let l = self.node(node).left;
                        self.node_mut(node).left = Some(self._insert(value, l));
                    } else if value > self.node(node).value {
                        let r = self.node(node).right;
                        self.node_mut(node).right = Some(self._insert(value, r));
                    }

                    node
                },
                None => {
                    // The node doesn't exist, create it here.
                    self.allocate_node(value)
                },
            };

        self.rebalance(node)
    }

    pub fn _in_order<F: Fn(&AvlNode<T>)>(&self, f: &F, node: usize) {
        if let Some(l) = self.node(node).left {
            self._in_order(f, l);
        }
        f(self.node(node));
        if let Some(r) = self.node(node).right {
            self._in_order(f, r);
        }
    }

    // Performs a left rotation on a tree/subtree.
    // Returns the replace the specified node with
    fn rotate_left(&mut self, node: usize) -> usize {
        // Keep track of the original node positions
        // For a rotate left, the right child node must exist
        let r = self.node(node).right.unwrap();
        let rl = self.node(r).left;

        let ret = r;
        self.node_mut(node).right = rl;
        self.node_mut(ret).left = Some(node);

        ret
    }

    // Performs a right rotation on a tree/subtree.
    // Returns the replace the specified node with
    fn rotate_right(&mut self, node: usize) -> usize {
        // Keep track of the original node positions
        // For a rotate right, the left child node must exist
        let l = self.node(node).left.unwrap();
        let lr = self.node(l).right;

        let ret = l;
        self.node_mut(node).left = lr;
        self.node_mut(ret).right = Some(node);

        ret
    }

    // performs a left-right double rotation on a tree/subtree.
    fn rotate_leftright(&mut self, node: usize) -> usize {
        let l = self.node(node).left.unwrap();
        let new_l = self.rotate_left(l); // Left node needs to exist
        self.node_mut(node).left = Some(new_l);
        self.rotate_right(node)
    }

    // performs a right-left double rotation on a tree/subtree.
    fn rotate_rightleft(&mut self, node: usize) -> usize {
        let r = self.node(node).right.unwrap();
        let new_r = self.rotate_right(r); // Right node needs to exist
        self.node_mut(node).right = Some(new_r);
        self.rotate_left(node)
    }

    // _rebalance rebalances the provided node
    fn rebalance(&mut self, node: usize) -> usize {
        let balance = self.height(self.node(node).left) - self.height(self.node(node).right);
        if balance == 2 { // left
            let lbalance = self.height(self.node(self.node(node).left.unwrap()).left) -
                           self.height(self.node(self.node(node).left.unwrap()).right);
            if lbalance == 0 || lbalance == 1 { // left left - need to rotate right
                return self.rotate_right(node);
            } else if lbalance == -1 { // left right
                return self.rotate_leftright(node); // function name is just a coincidence
            }
        } else if balance == -2 { // right
            let rbalance = self.height(self.node(self.node(node).right.unwrap()).left) -
                           self.height(self.node(self.node(node).right.unwrap()).right);
            if rbalance == 1 { // right left
                return self.rotate_rightleft(node); // function name is just a coincidence
            } else if rbalance == 0 || rbalance == -1 { // right right - need to rotate left
                return self.rotate_left(node);
            }
        }

        node
    }

    // height gets the height of a tree or subtree
    fn height(&self, node: Option<usize>) -> i64 {
        match node {
            Some(node) => {
                let left_height = self.height(self.node(node).left);
                let right_height = self.height(self.node(node).right);

                if left_height > right_height {
                    left_height+1
                } else {
                    right_height+1
                }
            },
            None => { -1 },
        }
    }

    fn allocate_node(&mut self, value: T) -> usize {
        match self.free_list.pop() {
            Some(index) => {
                self.nodes[index].time_stamp += 1;
                index
            },
            None => {
                // No free slots, create a new one
                let index = self.nodes.len();
                self.nodes.push(AvlSlot { time_stamp: 0,
                                          node: Some(AvlNode { value: value, left: None, right: None }) });
                index
            },
        }
    }

    fn free_node(&mut self, id: AvlNodeId) -> AvlNode<T> {
        self.free_list.push(id.index);

        // NOTE: We unwrap here, because we trust that `id` points to a valid node, because
        // only we can create and free AvlNodes and their AvlNodeIds
        self.nodes[id.index].node.take().unwrap()
    }

    fn node(&self, index: usize) -> &AvlNode<T> {
        self.nodes[index].node.as_ref().unwrap()
    }

    fn node_mut(&mut self, index: usize) -> &mut AvlNode<T> {
        self.nodes[index].node.as_mut().unwrap()
    }
}

struct AvlSlot<T> {
    time_stamp: u64,
    node: Option<AvlNode<T>>,
}
<|endoftext|>


<commit_before>use redox::*;

use super::FromBytes;

const MZAP_ENT_LEN: usize = 64;
const MZAP_NAME_LEN: usize = MZAP_ENT_LEN - 8 - 4 - 2;

#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub enum ZapObjectType {
    Micro = (1 << 63) + 3,
    Header = (1 << 63) + 1,
    Leaf = 1 << 63,
}

/// Microzap
#[repr(packed)]
pub struct MZapPhys {
    block_type: ZapObjectType, // ZapObjectType::Micro
    salt: u64,
    norm_flags: u64,
    pad: [u64; 5],
    chunk: [MZapEntPhys; 1],
    // actually variable size depending on block size
}

impl FromBytes for MZapPhys {
    fn from_bytes(data: &[u8]) -> Option<Self> {
        if data.len() >= mem::size_of::<MZapPhys>() {
            let mzap_phys = unsafe { ptr::read(data.as_ptr() as *const MZapPhys) };
            Some(mzap_phys)
        } else {
            Option::None
        }
    }
}

impl fmt::Debug for MZapPhys {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "MZapPhys {{\nblock_type: {:?},\nsalt: {:X},\nnorm_flags: {:X},\nchunk: [\n",
                    self.block_type, self.salt, self.norm_flags));
        for chunk in &self.chunk {
            try!(write!(f, "{:?}", chunk));
        }
        try!(write!(f, "] }}\n"));
        Ok(())
    }
}

#[repr(packed)]
pub struct MZapEntPhys{
    pub value: u64,
    pub cd: u32,
    pub pad: u16,
    pub name: [u8; MZAP_NAME_LEN],
}

impl fmt::Debug for MZapEntPhys {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "MZapEntPhys {{\nvalue: {:X},\ncd: {:X},\n",
                    self.value, self.cd));
        try!(write!(f, "}}\n"));
        Ok(())
    }
}

/// Fatzap
#[repr(packed)]
pub struct ZapPhys {
    pub block_type: ZapObjectType, // ZapObjectType::Header
    pub magic: u64,
    pub ptr_table: ZapTablePhys,
    pub free_block: u64,
    pub num_leafs: u64,
    pub num_entries: u64,
    pub salt: u64,
    pub pad: [u64; 8181],
    pub leafs: [u64; 8192],
}

#[repr(packed)]
pub struct ZapTablePhys {
     pub block: u64,
     pub num_blocks: u64,
     pub shift: u64,
     pub next_block: u64,
     pub block_copied: u64,
}

const ZAP_LEAF_MAGIC: u32 = 0x2AB1EAF;
const ZAP_LEAF_CHUNKSIZE: usize = 24;

// The amount of space within the chunk available for the array is:
// chunk size - space for type (1) - space for next pointer (2)
const ZAP_LEAF_ARRAY_BYTES: usize = ZAP_LEAF_CHUNKSIZE - 3;

/*pub struct ZapLeafPhys {
    pub header: ZapLeafHeader,
    hash: [u16; ZAP_LEAF_HASH_NUMENTRIES],
    union zap_leaf_chunk {
        entry,
        array,
        free,
    } chunks[ZapLeafChunk; ZAP_LEAF_NUMCHUNKS],
}*/

#[repr(packed)]
pub struct ZapLeafHeader {
    pub block_type: ZapObjectType, // ZapObjectType::Leaf
    pub next: u64,
    pub prefix: u64,
    pub magic: u32,
    pub n_free: u16,
    pub n_entries: u16,
    pub prefix_len: u16,
    pub free_list: u16,
    pad2: [u8; 12],
}

#[repr(packed)]
struct ZapLeafEntry {
    leaf_type: u8,
    int_size: u8,
    next: u16,
    name_chunk: u16,
    name_length: u16,
    value_chunk: u16,
    value_length: u16,
    cd: u16,
    pad: [u8; 2],
    hash: u64,
}

#[repr(packed)]
struct ZapLeafArray {
    leaf_type: u8,
    array: [u8; ZAP_LEAF_ARRAY_BYTES],
    next: u16,
}

#[repr(packed)]
struct ZapLeafFree{
    free_type: u8,
    pad: [u8; ZAP_LEAF_ARRAY_BYTES],
    next: u16,
}
<commit_msg>Show MZapEntPhys::name<commit_after>use redox::*;

use super::FromBytes;

const MZAP_ENT_LEN: usize = 64;
const MZAP_NAME_LEN: usize = MZAP_ENT_LEN - 8 - 4 - 2;

#[repr(u64)]
#[derive(Copy, Clone, Debug)]
pub enum ZapObjectType {
    Micro = (1 << 63) + 3,
    Header = (1 << 63) + 1,
    Leaf = 1 << 63,
}

/// Microzap
#[repr(packed)]
pub struct MZapPhys {
    block_type: ZapObjectType, // ZapObjectType::Micro
    salt: u64,
    norm_flags: u64,
    pad: [u64; 5],
    chunk: [MZapEntPhys; 1],
    // actually variable size depending on block size
}

impl FromBytes for MZapPhys {
    fn from_bytes(data: &[u8]) -> Option<Self> {
        if data.len() >= mem::size_of::<MZapPhys>() {
            let mzap_phys = unsafe { ptr::read(data.as_ptr() as *const MZapPhys) };
            Some(mzap_phys)
        } else {
            Option::None
        }
    }
}

impl fmt::Debug for MZapPhys {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "MZapPhys {{\nblock_type: {:?},\nsalt: {:X},\nnorm_flags: {:X},\nchunk: [\n",
                    self.block_type, self.salt, self.norm_flags));
        for chunk in &self.chunk {
            try!(write!(f, "{:?}", chunk));
        }
        try!(write!(f, "] }}\n"));
        Ok(())
    }
}

#[repr(packed)]
pub struct MZapEntPhys{
    pub value: u64,
    pub cd: u32,
    pub pad: u16,
    pub name: [u8; MZAP_NAME_LEN],
}

impl fmt::Debug for MZapEntPhys {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "MZapEntPhys {{\nvalue: {:X},\ncd: {:X},\nname: ",
                    self.value, self.cd));
        for i in 0..MZAP_NAME_LEN {
            if self.name[i] == 0 {
                break;
            }
            try!(write!(f, "{}", self.name[i] as char));
        }
        try!(write!(f, "\n}}\n"));
        Ok(())
    }
}

/// Fatzap
#[repr(packed)]
pub struct ZapPhys {
    pub block_type: ZapObjectType, // ZapObjectType::Header
    pub magic: u64,
    pub ptr_table: ZapTablePhys,
    pub free_block: u64,
    pub num_leafs: u64,
    pub num_entries: u64,
    pub salt: u64,
    pub pad: [u64; 8181],
    pub leafs: [u64; 8192],
}

#[repr(packed)]
pub struct ZapTablePhys {
     pub block: u64,
     pub num_blocks: u64,
     pub shift: u64,
     pub next_block: u64,
     pub block_copied: u64,
}

const ZAP_LEAF_MAGIC: u32 = 0x2AB1EAF;
const ZAP_LEAF_CHUNKSIZE: usize = 24;

// The amount of space within the chunk available for the array is:
// chunk size - space for type (1) - space for next pointer (2)
const ZAP_LEAF_ARRAY_BYTES: usize = ZAP_LEAF_CHUNKSIZE - 3;

/*pub struct ZapLeafPhys {
    pub header: ZapLeafHeader,
    hash: [u16; ZAP_LEAF_HASH_NUMENTRIES],
    union zap_leaf_chunk {
        entry,
        array,
        free,
    } chunks[ZapLeafChunk; ZAP_LEAF_NUMCHUNKS],
}*/

#[repr(packed)]
pub struct ZapLeafHeader {
    pub block_type: ZapObjectType, // ZapObjectType::Leaf
    pub next: u64,
    pub prefix: u64,
    pub magic: u32,
    pub n_free: u16,
    pub n_entries: u16,
    pub prefix_len: u16,
    pub free_list: u16,
    pad2: [u8; 12],
}

#[repr(packed)]
struct ZapLeafEntry {
    leaf_type: u8,
    int_size: u8,
    next: u16,
    name_chunk: u16,
    name_length: u16,
    value_chunk: u16,
    value_length: u16,
    cd: u16,
    pad: [u8; 2],
    hash: u64,
}

#[repr(packed)]
struct ZapLeafArray {
    leaf_type: u8,
    array: [u8; ZAP_LEAF_ARRAY_BYTES],
    next: u16,
}

#[repr(packed)]
struct ZapLeafFree{
    free_type: u8,
    pad: [u8; ZAP_LEAF_ARRAY_BYTES],
    next: u16,
}
<|endoftext|>


<commit_before>fn on_osmain(f: fn~()) {
    let builder = task::builder();
    task::set_opts(builder, {
        sched: some({
            mode: task::osmain,
            native_stack_size: none
        })
        with task::get_opts(builder)
    });
    let po = comm::port();
    let ch = comm::chan(po);
    task::run(builder) {||
        f();
        comm::send(ch, ());
    }
    comm::recv(po);
}

// FIXME: Needs additional cocoa setup on OS X. rust-cocoa should probably just
// be a dependency
#[test]
#[ignore(cfg(target_os = "macos"))]
fn test_everything() {

    on_osmain() {||
        init([init_video, init_timer]);
        run_tests([
            general::test_was_init,
            general::test_set_error,
            general::test_error,
            general::test_clear_error,
            video::test_set_video_mode,
            // FIXME: Doesn't work when called from a directory that
            // doesn't contain the test image file
            //video::test_blit,
            test_event::test_poll_event_none
            // FIXME: This test is interactive
            //test_event::test_keyboard
        ]);
        quit();
    }
}

fn run_tests(tests: [fn()]) {
    vec::iter(tests) {|test| test()}
}

mod general {
    fn test_was_init() {
        assert vec::contains(was_init([init_timer]), init_timer);
    }

    fn test_set_error() {
        set_error("test");
        assert get_error() == "test";
    }

    fn test_error() {
        clear_error();
        assert str::is_empty(get_error());
        error(enomem);
        assert str::is_not_empty(get_error());
    }

    fn test_clear_error() {
        set_error("test");
        clear_error();
        assert str::is_empty(get_error());
    }
}

mod test_event {
    fn test_poll_event_none() {
        ::event::poll_event {|event|
            assert event == ::event::no_event;
        }
    }

    fn test_keyboard() {
        io::println("press a key in the window");
        let surface = ::video::set_video_mode(320, 200, 32,
            [::video::swsurface], [::video::doublebuf, ::video::resizable]);
        let mut keydown = false;
        let mut keyup = false;
        while !keydown || !keyup {
            ::event::poll_event {|event|
                alt event {
                  event::keyup_event(_) { keyup = true; }
                  event::keydown_event(_) { keydown = true; }
                  _ { }
                }
            }
        }
        ::video::free_surface(surface);
    }
}

mod video {

    fn test_set_video_mode() {
        let surface = ::video::set_video_mode(320, 200, 32,
            [::video::hwsurface], [::video::doublebuf]);
        assert surface != ptr::null();
        ::video::free_surface(surface);
    }

    fn test_blit() {
        let screen = ::video::set_video_mode(320, 200, 32,
            [::video::swsurface], [::video::doublebuf]);
        assert screen != ptr::null();

        let image = {
            // FIXME: We need to load this from the crate instead of
            // off the filesystem
            let tmp = ::video::load_bmp("rust-logo-128x128-blk.bmp");
            assert tmp != ptr::null();
            let image = ::video::display_format(tmp);
            assert image != ptr::null();
            ::video::free_surface(tmp);
            image
        };

        iter::repeat(1u) {||
            ::video::blit_surface(image, ptr::null(),
                                  screen, ptr::null());
            ::video::flip(screen);
            ::event::poll_event {|_event|
            }
        }

        ::video::free_surface(image);
        ::video::free_surface(screen);
    }
}
<commit_msg>Update for task API changes<commit_after>fn on_osmain(f: fn~()) {
    let builder = task::builder();
    task::set_opts(builder, {
        sched: some({
            mode: task::osmain,
            foreign_stack_size: none
        })
        with task::get_opts(builder)
    });
    let po = comm::port();
    let ch = comm::chan(po);
    task::run(builder) {||
        f();
        comm::send(ch, ());
    }
    comm::recv(po);
}

// FIXME: Needs additional cocoa setup on OS X. rust-cocoa should probably just
// be a dependency
#[test]
#[ignore(cfg(target_os = "macos"))]
fn test_everything() {

    on_osmain() {||
        init([init_video, init_timer]);
        run_tests([
            general::test_was_init,
            general::test_set_error,
            general::test_error,
            general::test_clear_error,
            video::test_set_video_mode,
            // FIXME: Doesn't work when called from a directory that
            // doesn't contain the test image file
            //video::test_blit,
            test_event::test_poll_event_none
            // FIXME: This test is interactive
            //test_event::test_keyboard
        ]);
        quit();
    }
}

fn run_tests(tests: [fn()]) {
    vec::iter(tests) {|test| test()}
}

mod general {
    fn test_was_init() {
        assert vec::contains(was_init([init_timer]), init_timer);
    }

    fn test_set_error() {
        set_error("test");
        assert get_error() == "test";
    }

    fn test_error() {
        clear_error();
        assert str::is_empty(get_error());
        error(enomem);
        assert str::is_not_empty(get_error());
    }

    fn test_clear_error() {
        set_error("test");
        clear_error();
        assert str::is_empty(get_error());
    }
}

mod test_event {
    fn test_poll_event_none() {
        ::event::poll_event {|event|
            assert event == ::event::no_event;
        }
    }

    fn test_keyboard() {
        io::println("press a key in the window");
        let surface = ::video::set_video_mode(320, 200, 32,
            [::video::swsurface], [::video::doublebuf, ::video::resizable]);
        let mut keydown = false;
        let mut keyup = false;
        while !keydown || !keyup {
            ::event::poll_event {|event|
                alt event {
                  event::keyup_event(_) { keyup = true; }
                  event::keydown_event(_) { keydown = true; }
                  _ { }
                }
            }
        }
        ::video::free_surface(surface);
    }
}

mod video {

    fn test_set_video_mode() {
        let surface = ::video::set_video_mode(320, 200, 32,
            [::video::hwsurface], [::video::doublebuf]);
        assert surface != ptr::null();
        ::video::free_surface(surface);
    }

    fn test_blit() {
        let screen = ::video::set_video_mode(320, 200, 32,
            [::video::swsurface], [::video::doublebuf]);
        assert screen != ptr::null();

        let image = {
            // FIXME: We need to load this from the crate instead of
            // off the filesystem
            let tmp = ::video::load_bmp("rust-logo-128x128-blk.bmp");
            assert tmp != ptr::null();
            let image = ::video::display_format(tmp);
            assert image != ptr::null();
            ::video::free_surface(tmp);
            image
        };

        iter::repeat(1u) {||
            ::video::blit_surface(image, ptr::null(),
                                  screen, ptr::null());
            ::video::flip(screen);
            ::event::poll_event {|_event|
            }
        }

        ::video::free_surface(image);
        ::video::free_surface(screen);
    }
}
<|endoftext|>


<commit_before>use netsurfcss::stylesheet::CssStylesheet;
use netsurfcss::select::{CssSelectCtx, css_select_ctx_create, CssSelectResults, CssSelectHandler, CssPseudoElementNone};
use netsurfcss::types::{CssQName, CssColor};
use netsurfcss::properties::{CssProperty, CssColorInherit, CssColorValue};
use netsurfcss::ll::types::{CSS_ORIGIN_AUTHOR, CSS_MEDIA_SCREEN};
use netsurfcss::hint::{CssHint, CssHintDefault};
use netsurfcss::computed::CssComputedStyle;
use wapcaplet::from_rust_string;
use util::DataStream;
use std::net::url::Url;
use values::{CSSValue, Inherit, Specified};
use color::{Color, rgba};

pub struct Stylesheet {
    inner: CssStylesheet
}

impl Stylesheet {
    static fn new(url: Url, input: DataStream) -> Stylesheet {
        Stylesheet {
            inner: parser::parse_stylesheet(move url, input)
        }
    }
}

pub struct SelectCtx {
    inner: CssSelectCtx
}

impl SelectCtx {
    static fn new() -> SelectCtx {
        SelectCtx {
            inner: css_select_ctx_create()
        }
    }

    fn append_sheet(&mut self, sheet: Stylesheet) {
        let sheet = match move sheet {
            Stylesheet { inner: move inner } => move inner
        };

        self.inner.append_sheet(move sheet, CSS_ORIGIN_AUTHOR, CSS_MEDIA_SCREEN)
    }

    fn select_style<N, H: SelectHandler<N>>(&self, node: &N, handler: &H) -> SelectResults {
        let inner_handler = InnerHandler {
            inner: ptr::to_unsafe_ptr(handler)
        };
        SelectResults {
            inner: self.inner.select_style::<N, InnerHandler<N, H>>(node, CSS_MEDIA_SCREEN, None, &inner_handler)
        }
    }
}

pub struct SelectResults {
    inner: CssSelectResults
}

impl SelectResults {
    fn computed_style(&self) -> ComputedStyle/&self {
        ComputedStyle {
            inner: self.inner.computed_style(CssPseudoElementNone)
        }
    }
}

pub trait SelectHandler<N> {
    fn node_name(node: &N) -> ~str;
}

struct InnerHandler<N, H: SelectHandler<N>> {
    // FIXME: Can't encode region variables
    inner: *H
}

priv impl<N, H: SelectHandler<N>> InnerHandler<N, H> {
    priv fn inner_ref() -> &self/H {
        unsafe { &*self.inner }
    }
}

impl<N, H: SelectHandler<N>> InnerHandler<N, H>: CssSelectHandler<N> {
    fn node_name(node: &N) -> CssQName {
        CssQName {
            ns: None,
            name: from_rust_string(self.inner_ref().node_name(node))
        }
    }
    fn ua_default_for_property(property: CssProperty) -> CssHint {
        warn!("not specifiying ua default for property %?", property);
        CssHintDefault
    }
}

pub struct ComputedStyle {
    inner: CssComputedStyle
}

impl ComputedStyle {
    pub fn background_color() -> CSSValue<Color> {
        match self.inner.background_color() {
            CssColorInherit => Inherit,
            CssColorValue(v) => Specified(netcolor_to_color(v))
        }
    }
}

fn netcolor_to_color(color: CssColor) -> Color {
    rgba(color.r, color.g, color.b, (color.a as float) / 255.0)
}<commit_msg>Update rust-netsurfcss<commit_after>use netsurfcss::stylesheet::CssStylesheet;
use netsurfcss::select::{CssSelectCtx, css_select_ctx_create, CssSelectResults, CssSelectHandler, CssPseudoElementNone};
use netsurfcss::types::{CssQName, CssColor};
use netsurfcss::properties::CssProperty;
use netsurfcss::values::{CssColorInherit, CssColorColor};
use netsurfcss::ll::types::{CSS_ORIGIN_AUTHOR, CSS_MEDIA_SCREEN};
use netsurfcss::hint::{CssHint, CssHintDefault};
use netsurfcss::computed::CssComputedStyle;
use wapcaplet::from_rust_string;
use util::DataStream;
use std::net::url::Url;
use values::{CSSValue, Inherit, Specified};
use color::{Color, rgba};

pub struct Stylesheet {
    inner: CssStylesheet
}

impl Stylesheet {
    static fn new(url: Url, input: DataStream) -> Stylesheet {
        Stylesheet {
            inner: parser::parse_stylesheet(move url, input)
        }
    }
}

pub struct SelectCtx {
    inner: CssSelectCtx
}

impl SelectCtx {
    static fn new() -> SelectCtx {
        SelectCtx {
            inner: css_select_ctx_create()
        }
    }

    fn append_sheet(&mut self, sheet: Stylesheet) {
        let sheet = match move sheet {
            Stylesheet { inner: move inner } => move inner
        };

        self.inner.append_sheet(move sheet, CSS_ORIGIN_AUTHOR, CSS_MEDIA_SCREEN)
    }

    fn select_style<N, H: SelectHandler<N>>(&self, node: &N, handler: &H) -> SelectResults {
        let inner_handler = InnerHandler {
            inner: ptr::to_unsafe_ptr(handler)
        };
        SelectResults {
            inner: self.inner.select_style::<N, InnerHandler<N, H>>(node, CSS_MEDIA_SCREEN, None, &inner_handler)
        }
    }
}

pub struct SelectResults {
    inner: CssSelectResults
}

impl SelectResults {
    fn computed_style(&self) -> ComputedStyle/&self {
        ComputedStyle {
            inner: self.inner.computed_style(CssPseudoElementNone)
        }
    }
}

pub trait SelectHandler<N> {
    fn node_name(node: &N) -> ~str;
}

struct InnerHandler<N, H: SelectHandler<N>> {
    // FIXME: Can't encode region variables
    inner: *H
}

priv impl<N, H: SelectHandler<N>> InnerHandler<N, H> {
    priv fn inner_ref() -> &self/H {
        unsafe { &*self.inner }
    }
}

impl<N, H: SelectHandler<N>> InnerHandler<N, H>: CssSelectHandler<N> {
    fn node_name(node: &N) -> CssQName {
        CssQName {
            ns: None,
            name: from_rust_string(self.inner_ref().node_name(node))
        }
    }
    fn ua_default_for_property(property: CssProperty) -> CssHint {
        warn!("not specifiying ua default for property %?", property);
        CssHintDefault
    }
}

pub struct ComputedStyle {
    inner: CssComputedStyle
}

impl ComputedStyle {
    pub fn background_color() -> CSSValue<Color> {
        match self.inner.background_color() {
            CssColorInherit => Inherit,
            CssColorColor(v) => Specified(netcolor_to_color(v))
        }
    }
}

fn netcolor_to_color(color: CssColor) -> Color {
    rgba(color.r, color.g, color.b, (color.a as float) / 255.0)
}<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[crate_id = "github.com/mozilla-servo/rust-geom#geom:0.1"];

extern crate extra;
extern crate serialize;
extern crate std;

pub use matrix::Matrix4;
pub use matrix2d::Matrix2D;
pub use point::Point2D;
pub use rect::Rect;
pub use side_offsets::SideOffsets2D;
pub use size::Size2D;

pub mod approxeq;
pub mod matrix;
pub mod matrix2d;
pub mod point;
pub mod rect;
pub mod side_offsets;
pub mod size;

<commit_msg>Update to current rust: import the logging macros.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[crate_id = "github.com/mozilla-servo/rust-geom#geom:0.1"];

#[feature(phase)];
#[phase(syntax, link)] extern crate log;

extern crate serialize;
extern crate std;

pub use matrix::Matrix4;
pub use matrix2d::Matrix2D;
pub use point::Point2D;
pub use rect::Rect;
pub use side_offsets::SideOffsets2D;
pub use size::Size2D;

pub mod approxeq;
pub mod matrix;
pub mod matrix2d;
pub mod point;
pub mod rect;
pub mod side_offsets;
pub mod size;

<|endoftext|>


<commit_before>use ffi;
#[cfg(feature = "use_glib")]
use glib::translate::*;
use libc::{c_char, c_int};
use std::ffi::{CStr, CString};
#[cfg(not(feature = "use_glib"))]
use std::ptr;

use enums::{FontSlant, FontType, FontWeight};

#[cfg(any(feature = "use_freetype", feature = "dox"))]
use enums::FtSynthesize;

use utils::status_to_result;

#[cfg(feature = "use_glib")]
glib_wrapper! {
    #[derive(Debug)]
    pub struct FontFace(Shared<ffi::cairo_font_face_t>);

    match fn {
        ref => |ptr| ffi::cairo_font_face_reference(ptr),
        unref => |ptr| ffi::cairo_font_face_destroy(ptr),
        get_type => || ffi::gobject::cairo_gobject_font_face_get_type(),
    }
}

#[cfg(not(feature = "use_glib"))]
#[derive(Debug)]
pub struct FontFace(ptr::NonNull<ffi::cairo_font_face_t>);

impl FontFace {
    pub fn toy_create(family: &str, slant: FontSlant, weight: FontWeight) -> FontFace {
        let font_face: FontFace = unsafe {
            let family = CString::new(family).unwrap();
            FontFace::from_raw_full(ffi::cairo_toy_font_face_create(
                family.as_ptr(),
                slant.into(),
                weight.into(),
            ))
        };
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    // Safety: the FT_Face must be valid and not be freed until the `FontFace` is dropped.
    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub unsafe fn create_from_ft(face: freetype::freetype::FT_Face) -> FontFace {
        let font_face = FontFace::from_raw_full(ffi::cairo_ft_font_face_create_for_ft_face(
            face as *mut _,
            0,
        ));
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    // Safety: the FT_Face must be valid and not be freed until the `FontFace` is dropped.
    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub unsafe fn create_from_ft_with_flags(
        face: freetype::freetype::FT_Face,
        load_flags: c_int,
    ) -> FontFace {
        let font_face = FontFace::from_raw_full(ffi::cairo_ft_font_face_create_for_ft_face(
            face as *mut _,
            load_flags,
        ));
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_full(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_none(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.to_glib_none().0
    }

    #[cfg(not(feature = "use_glib"))]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.0.as_ptr()
    }

    pub fn toy_get_family(&self) -> Option<String> {
        unsafe { to_optional_string(ffi::cairo_toy_font_face_get_family(self.to_raw_none())) }
    }

    pub fn toy_get_slant(&self) -> FontSlant {
        unsafe { FontSlant::from(ffi::cairo_toy_font_face_get_slant(self.to_raw_none())) }
    }

    pub fn toy_get_weight(&self) -> FontWeight {
        unsafe { FontWeight::from(ffi::cairo_toy_font_face_get_weight(self.to_raw_none())) }
    }

    pub fn get_type(&self) -> FontType {
        unsafe { FontType::from(ffi::cairo_font_face_get_type(self.to_raw_none())) }
    }

    pub fn get_reference_count(&self) -> usize {
        unsafe { ffi::cairo_font_face_get_reference_count(self.to_raw_none()) as usize }
    }

    #[cfg(any(
        feature = "use_
            reetype",
        feature = "dox"
    ))]
    pub fn get_synthesize(&self) -> FtSynthesize {
        unsafe { FtSynthesize::from(ffi::cairo_ft_font_face_get_synthesize(self.to_raw_none())) }
    }

    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub fn set_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_set_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub fn unset_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_unset_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    user_data_methods! {
        ffi::cairo_font_face_get_user_data,
        ffi::cairo_font_face_set_user_data,
    }
}

#[cfg(not(feature = "use_glib"))]
impl Drop for FontFace {
    fn drop(&mut self) {
        unsafe {
            ffi::cairo_font_face_destroy(self.to_raw_none());
        }
    }
}

#[cfg(not(feature = "use_glib"))]
impl Clone for FontFace {
    fn clone(&self) -> FontFace {
        unsafe { FontFace::from_raw_none(self.to_raw_none()) }
    }
}

pub(crate) unsafe fn to_optional_string(str: *const c_char) -> Option<String> {
    if str.is_null() {
        None
    } else {
        Some(String::from_utf8_lossy(CStr::from_ptr(str).to_bytes()).into_owned())
    }
}
<commit_msg>Fix strange artefact from find-replace.<commit_after>use ffi;
#[cfg(feature = "use_glib")]
use glib::translate::*;
use libc::{c_char, c_int};
use std::ffi::{CStr, CString};
#[cfg(not(feature = "use_glib"))]
use std::ptr;

use enums::{FontSlant, FontType, FontWeight};

#[cfg(any(feature = "use_freetype", feature = "dox"))]
use enums::FtSynthesize;

use utils::status_to_result;

#[cfg(feature = "use_glib")]
glib_wrapper! {
    #[derive(Debug)]
    pub struct FontFace(Shared<ffi::cairo_font_face_t>);

    match fn {
        ref => |ptr| ffi::cairo_font_face_reference(ptr),
        unref => |ptr| ffi::cairo_font_face_destroy(ptr),
        get_type => || ffi::gobject::cairo_gobject_font_face_get_type(),
    }
}

#[cfg(not(feature = "use_glib"))]
#[derive(Debug)]
pub struct FontFace(ptr::NonNull<ffi::cairo_font_face_t>);

impl FontFace {
    pub fn toy_create(family: &str, slant: FontSlant, weight: FontWeight) -> FontFace {
        let font_face: FontFace = unsafe {
            let family = CString::new(family).unwrap();
            FontFace::from_raw_full(ffi::cairo_toy_font_face_create(
                family.as_ptr(),
                slant.into(),
                weight.into(),
            ))
        };
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    // Safety: the FT_Face must be valid and not be freed until the `FontFace` is dropped.
    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub unsafe fn create_from_ft(face: freetype::freetype::FT_Face) -> FontFace {
        let font_face = FontFace::from_raw_full(ffi::cairo_ft_font_face_create_for_ft_face(
            face as *mut _,
            0,
        ));
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    // Safety: the FT_Face must be valid and not be freed until the `FontFace` is dropped.
    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub unsafe fn create_from_ft_with_flags(
        face: freetype::freetype::FT_Face,
        load_flags: c_int,
    ) -> FontFace {
        let font_face = FontFace::from_raw_full(ffi::cairo_ft_font_face_create_for_ft_face(
            face as *mut _,
            load_flags,
        ));
        let status = unsafe { ffi::cairo_font_face_status(font_face.to_raw_none()) };
        status_to_result(status).expect("Failed to create a FontFace");
        font_face
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_full(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        from_glib_none(ptr)
    }

    #[cfg(not(feature = "use_glib"))]
    pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_font_face_t) -> FontFace {
        assert!(!ptr.is_null());
        FontFace(ptr::NonNull::new_unchecked(ptr))
    }

    #[cfg(feature = "use_glib")]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.to_glib_none().0
    }

    #[cfg(not(feature = "use_glib"))]
    pub fn to_raw_none(&self) -> *mut ffi::cairo_font_face_t {
        self.0.as_ptr()
    }

    pub fn toy_get_family(&self) -> Option<String> {
        unsafe { to_optional_string(ffi::cairo_toy_font_face_get_family(self.to_raw_none())) }
    }

    pub fn toy_get_slant(&self) -> FontSlant {
        unsafe { FontSlant::from(ffi::cairo_toy_font_face_get_slant(self.to_raw_none())) }
    }

    pub fn toy_get_weight(&self) -> FontWeight {
        unsafe { FontWeight::from(ffi::cairo_toy_font_face_get_weight(self.to_raw_none())) }
    }

    pub fn get_type(&self) -> FontType {
        unsafe { FontType::from(ffi::cairo_font_face_get_type(self.to_raw_none())) }
    }

    pub fn get_reference_count(&self) -> usize {
        unsafe { ffi::cairo_font_face_get_reference_count(self.to_raw_none()) as usize }
    }

    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub fn get_synthesize(&self) -> FtSynthesize {
        unsafe { FtSynthesize::from(ffi::cairo_ft_font_face_get_synthesize(self.to_raw_none())) }
    }

    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub fn set_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_set_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    #[cfg(any(feature = "use_freetype", feature = "dox"))]
    pub fn unset_synthesize(&self, synth_flags: FtSynthesize) {
        unsafe { ffi::cairo_ft_font_face_unset_synthesize(self.to_raw_none(), synth_flags.into()) }
    }

    user_data_methods! {
        ffi::cairo_font_face_get_user_data,
        ffi::cairo_font_face_set_user_data,
    }
}

#[cfg(not(feature = "use_glib"))]
impl Drop for FontFace {
    fn drop(&mut self) {
        unsafe {
            ffi::cairo_font_face_destroy(self.to_raw_none());
        }
    }
}

#[cfg(not(feature = "use_glib"))]
impl Clone for FontFace {
    fn clone(&self) -> FontFace {
        unsafe { FontFace::from_raw_none(self.to_raw_none()) }
    }
}

pub(crate) unsafe fn to_optional_string(str: *const c_char) -> Option<String> {
    if str.is_null() {
        None
    } else {
        Some(String::from_utf8_lossy(CStr::from_ptr(str).to_bytes()).into_owned())
    }
}
<|endoftext|>


<commit_before>#![allow(missing_doc)]
#![allow(dead_code)]

//! A First Person Shooter controller.

use std::num::{One, Zero};
use input::keyboard;
use {
    input,
    Camera,
};

bitflags!(flags Keys: u8 {
    static MoveForward = 0b00000001,
    static MoveBack    = 0b00000010,
    static StrafeLeft  = 0b00000100,
    static StrafeRight = 0b00001000,
    static FlyUp       = 0b00010000,
    static FlyDown     = 0b00100000
})

/// FPS controller settings.
pub struct FPSControllerSettings {
    /// Which key to press to move forward.
    pub move_forward_key: keyboard::Key,
    /// Which key to press to move backward.
    pub move_backward_key: keyboard::Key,
    /// Which key to press to strafe left.
    pub strafe_left_key: keyboard::Key,
    /// Which key to press to strafe right.
    pub strafe_right_key: keyboard::Key,
    /// Which key to press to fly up.
    pub fly_up_key: keyboard::Key,
    /// Which key to press to fly down.
    pub fly_down_key: keyboard::Key,
    /// Which key to press to move faster.
    pub move_faster_key: keyboard::Key,
}

impl FPSControllerSettings {
    /// Creates new FPS controller settings with defaults.
    pub fn default() -> FPSControllerSettings {
        FPSControllerSettings {
            move_forward_key: keyboard::W,
            move_backward_key: keyboard::S,
            strafe_left_key: keyboard::A,
            strafe_right_key: keyboard::D,
            fly_up_key: keyboard::Space,
            fly_down_key: keyboard::LShift,
            move_faster_key: keyboard::LCtrl,
        }
    }
}

/// Models a First Person Shooter (FPS) controller.
pub struct FPSController<T=f32> {
    /// The FPS controller settings.
    pub settings: FPSControllerSettings,
    /// The yaw angle (in radians).
    pub yaw: T,
    /// The pitch angle (in radians).
    pub pitch: T,
    /// The direction we are heading.
    pub direction: [T, ..3],
    /// The velocity we are moving in the direction.
    pub velocity: T,
    /// The keys that are pressed.
    keys: Keys,
}

impl<T: Float + FromPrimitive + Copy + FloatMath> FPSController<T> {
    /// Creates a new FPS controller.
    pub fn new(settings: FPSControllerSettings) -> FPSController<T> {
        let _0: T = Zero::zero();
        FPSController {
            settings: settings,
            yaw: _0,
            pitch: _0,
            keys: Keys::empty(),
            direction: [_0, _0, _0],
            velocity: One::one(),
        }
    }

    /// Updates camera.
    pub fn update(&self, dt: f64, camera: &mut Camera<T>) {
        let _3: T = FromPrimitive::from_int(3).unwrap();
        let _4: T = FromPrimitive::from_int(4).unwrap();
        let dt: T = FromPrimitive::from_f64(dt).unwrap();
        let dh = dt * self.velocity * _3;
        let [dx, dy, dz] = self.direction;
        let (s, c) = (self.yaw.sin(), self.yaw.cos());
        camera.position = [
            camera.position[0] + (s * dx - c * dz) * dh,
            camera.position[1] + dy * dt * _4,
            camera.position[2] + (s * dz + c * dx) * dh
        ];
    }

    /// Handles game event and updates camera.
    pub fn input(&mut self, e: &input::InputEvent, camera: &mut Camera<T>) {
        let &FPSController {
            ref mut yaw,
            ref mut pitch,
            ref mut keys,
            ref mut direction,
            ref mut velocity,
            ref settings,
        } = self;

        let pi: T = Float::pi();
        let sqrt2: T = Float::sqrt2();
        let _0: T = Zero::zero();
        let _1: T = One::one();
        let _2: T = FromPrimitive::from_int(2).unwrap();
        let _3: T = FromPrimitive::from_int(3).unwrap();
        let _4: T = FromPrimitive::from_int(4).unwrap();
        let _360: T = FromPrimitive::from_int(360).unwrap();
        match *e {
            input::MouseRelativeMove { dx, dy, .. } => {
                let dx: T = FromPrimitive::from_f64(dx).unwrap();
                let dy: T = FromPrimitive::from_f64(dy).unwrap();
                *yaw = (*yaw - dx / _360 * pi / _4) % (_2 * pi);
                *pitch = *pitch + dy / _360 * pi / _4;
                *pitch = (*pitch).min(pi / _2).max(-pi / _2);
                camera.set_yaw_pitch(*yaw, *pitch);
            },
            input::KeyPress { key, .. } => {
                let [dx, dy, dz] = *direction;
                let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
                let set = |k, x: T, y: T, z: T| {
                    let (x, z) = (sgn(x), sgn(z));
                    let (x, z) = if x != _0 && z != _0 {
                        (x / sqrt2, z / sqrt2)
                    } else {
                        (x, z)
                    };
                    *direction = [x, y, z];
                    keys.insert(k);
                };
                match key {
                    x if x == settings.move_forward_key => set(MoveForward, -_1, dy, dz),
                    x if x == settings.move_backward_key => set(MoveBack, _1, dy, dz),
                    x if x == settings.strafe_left_key => set(StrafeLeft, dx, dy, _1),
                    x if x == settings.strafe_right_key => set(StrafeRight, dx, dy, -_1),
                    x if x == settings.fly_up_key => set(FlyUp, dx, _1, dz),
                    x if x == settings.fly_down_key => set(FlyDown, dx, -_1, dz),
                    x if x == settings.move_faster_key => *velocity = _2,
                    _ => {}
                }
            },
            input::KeyRelease { key, .. } => {
                let [dx, dy, dz] = *direction;
                let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
                let set = |x: T, y: T, z: T| {
                    let (x, z) = (sgn(x), sgn(z));
                    let (x, z) = if x != _0 && z != _0 {
                        (x / sqrt2, z / sqrt2)
                    } else {
                        (x, z)
                    };
                    *direction = [x, y, z];
                };
                let release = |key, rev_key, rev_val| {
                    keys.remove(key);
                    if keys.contains(rev_key) { rev_val } else { _0 }
                };
                match key {
                    x if x == settings.move_forward_key => set(release(MoveForward, MoveBack, _1), dy, dz),
                    x if x == settings.move_backward_key => set(release(MoveBack, MoveForward, -_1), dy, dz),
                    x if x == settings.strafe_left_key => set(dx, dy, release(StrafeLeft, StrafeRight, -_1)),
                    x if x == settings.strafe_right_key => set(dx, dy, release(StrafeRight, StrafeLeft, _1)),
                    x if x == settings.fly_up_key => set(dx, release(FlyUp, FlyDown, -_1), dz),
                    x if x == settings.fly_down_key => set(dx, release(FlyDown, FlyUp, _1), dz),
                    x if x == settings.move_faster_key => *velocity = _1,
                    _ => {}
                }
            },
            _ => {},
        }
    }
}

<commit_msg>Added settings for horizontal and vertical speed<commit_after>#![allow(missing_doc)]
#![allow(dead_code)]

//! A First Person Shooter controller.

use std::num::{One, Zero};
use input::keyboard;
use {
    input,
    Camera,
};

bitflags!(flags Keys: u8 {
    static MoveForward = 0b00000001,
    static MoveBack    = 0b00000010,
    static StrafeLeft  = 0b00000100,
    static StrafeRight = 0b00001000,
    static FlyUp       = 0b00010000,
    static FlyDown     = 0b00100000
})

/// FPS controller settings.
pub struct FPSControllerSettings<T=f32> {
    /// Which key to press to move forward.
    pub move_forward_key: keyboard::Key,
    /// Which key to press to move backward.
    pub move_backward_key: keyboard::Key,
    /// Which key to press to strafe left.
    pub strafe_left_key: keyboard::Key,
    /// Which key to press to strafe right.
    pub strafe_right_key: keyboard::Key,
    /// Which key to press to fly up.
    pub fly_up_key: keyboard::Key,
    /// Which key to press to fly down.
    pub fly_down_key: keyboard::Key,
    /// Which key to press to move faster.
    pub move_faster_key: keyboard::Key,
    /// The horizontal movement speed.
    ///
    /// This is measured in units per second.
    pub speed_horizontal: T,
    /// The vertical movement speed.
    ///
    /// This is measured in units per second.
    pub speed_vertical: T,
}

impl<T: One> FPSControllerSettings<T> {
    /// Creates new FPS controller settings with defaults.
    pub fn default() -> FPSControllerSettings<T> {
        FPSControllerSettings {
            move_forward_key: keyboard::W,
            move_backward_key: keyboard::S,
            strafe_left_key: keyboard::A,
            strafe_right_key: keyboard::D,
            fly_up_key: keyboard::Space,
            fly_down_key: keyboard::LShift,
            move_faster_key: keyboard::LCtrl,
            speed_horizontal: One::one(),
            speed_vertical: One::one(),
        }
    }
}

/// Models a First Person Shooter (FPS) controller.
pub struct FPSController<T=f32> {
    /// The FPS controller settings.
    pub settings: FPSControllerSettings<T>,
    /// The yaw angle (in radians).
    pub yaw: T,
    /// The pitch angle (in radians).
    pub pitch: T,
    /// The direction we are heading.
    pub direction: [T, ..3],
    /// The velocity we are moving in the direction.
    pub velocity: T,
    /// The keys that are pressed.
    keys: Keys,
}

impl<T: Float + FromPrimitive + Copy + FloatMath> FPSController<T> {
    /// Creates a new FPS controller.
    pub fn new(settings: FPSControllerSettings<T>) -> FPSController<T> {
        let _0: T = Zero::zero();
        FPSController {
            settings: settings,
            yaw: _0,
            pitch: _0,
            keys: Keys::empty(),
            direction: [_0, _0, _0],
            velocity: One::one(),
        }
    }

    /// Updates camera.
    pub fn update(&self, dt: f64, camera: &mut Camera<T>) {
        let dt: T = FromPrimitive::from_f64(dt).unwrap();
        let dh = dt * self.velocity * self.settings.speed_horizontal;
        let [dx, dy, dz] = self.direction;
        let (s, c) = (self.yaw.sin(), self.yaw.cos());
        camera.position = [
            camera.position[0] + (s * dx - c * dz) * dh,
            camera.position[1] + dy * dt * self.settings.speed_vertical,
            camera.position[2] + (s * dz + c * dx) * dh
        ];
    }

    /// Handles game event and updates camera.
    pub fn input(&mut self, e: &input::InputEvent, camera: &mut Camera<T>) {
        let &FPSController {
            ref mut yaw,
            ref mut pitch,
            ref mut keys,
            ref mut direction,
            ref mut velocity,
            ref settings,
        } = self;

        let pi: T = Float::pi();
        let sqrt2: T = Float::sqrt2();
        let _0: T = Zero::zero();
        let _1: T = One::one();
        let _2: T = FromPrimitive::from_int(2).unwrap();
        let _3: T = FromPrimitive::from_int(3).unwrap();
        let _4: T = FromPrimitive::from_int(4).unwrap();
        let _360: T = FromPrimitive::from_int(360).unwrap();
        match *e {
            input::MouseRelativeMove { dx, dy, .. } => {
                let dx: T = FromPrimitive::from_f64(dx).unwrap();
                let dy: T = FromPrimitive::from_f64(dy).unwrap();
                *yaw = (*yaw - dx / _360 * pi / _4) % (_2 * pi);
                *pitch = *pitch + dy / _360 * pi / _4;
                *pitch = (*pitch).min(pi / _2).max(-pi / _2);
                camera.set_yaw_pitch(*yaw, *pitch);
            },
            input::KeyPress { key, .. } => {
                let [dx, dy, dz] = *direction;
                let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
                let set = |k, x: T, y: T, z: T| {
                    let (x, z) = (sgn(x), sgn(z));
                    let (x, z) = if x != _0 && z != _0 {
                        (x / sqrt2, z / sqrt2)
                    } else {
                        (x, z)
                    };
                    *direction = [x, y, z];
                    keys.insert(k);
                };
                match key {
                    x if x == settings.move_forward_key => set(MoveForward, -_1, dy, dz),
                    x if x == settings.move_backward_key => set(MoveBack, _1, dy, dz),
                    x if x == settings.strafe_left_key => set(StrafeLeft, dx, dy, _1),
                    x if x == settings.strafe_right_key => set(StrafeRight, dx, dy, -_1),
                    x if x == settings.fly_up_key => set(FlyUp, dx, _1, dz),
                    x if x == settings.fly_down_key => set(FlyDown, dx, -_1, dz),
                    x if x == settings.move_faster_key => *velocity = _2,
                    _ => {}
                }
            },
            input::KeyRelease { key, .. } => {
                let [dx, dy, dz] = *direction;
                let sgn = |x: T| if x == _0 { _0 } else { x.signum() };
                let set = |x: T, y: T, z: T| {
                    let (x, z) = (sgn(x), sgn(z));
                    let (x, z) = if x != _0 && z != _0 {
                        (x / sqrt2, z / sqrt2)
                    } else {
                        (x, z)
                    };
                    *direction = [x, y, z];
                };
                let release = |key, rev_key, rev_val| {
                    keys.remove(key);
                    if keys.contains(rev_key) { rev_val } else { _0 }
                };
                match key {
                    x if x == settings.move_forward_key => set(release(MoveForward, MoveBack, _1), dy, dz),
                    x if x == settings.move_backward_key => set(release(MoveBack, MoveForward, -_1), dy, dz),
                    x if x == settings.strafe_left_key => set(dx, dy, release(StrafeLeft, StrafeRight, -_1)),
                    x if x == settings.strafe_right_key => set(dx, dy, release(StrafeRight, StrafeLeft, _1)),
                    x if x == settings.fly_up_key => set(dx, release(FlyUp, FlyDown, -_1), dz),
                    x if x == settings.fly_down_key => set(dx, release(FlyDown, FlyUp, _1), dz),
                    x if x == settings.move_faster_key => *velocity = _1,
                    _ => {}
                }
            },
            _ => {},
        }
    }
}

<|endoftext|>