<commit_before>// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.

// A simple wrapper around a build_script execution to generate file to reuse
// by rust_library/rust_binary.
extern crate cargo_build_script_output_parser;

use cargo_build_script_output_parser::{BuildScriptOutput, CompileAndLinkFlags};
use std::collections::BTreeMap;
use std::env;
use std::fs::{create_dir_all, read_to_string, write};
use std::path::Path;
use std::process::Command;

fn run_buildrs() -> Result<(), String> {
    // We use exec_root.join rather than std::fs::canonicalize, to avoid resolving symlinks, as
    // some execution strategies and remote execution environments may use symlinks in ways which
    // canonicalizing them may break them, e.g. by having input files be symlinks into a /cas
    // directory - resolving these may cause tools which inspect $0, or try to resolve files
    // relative to themselves, to fail.
    let exec_root = env::current_dir().expect("Failed to get current directory");
    let manifest_dir_env = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR was not set");
    let rustc_env = env::var("RUSTC").expect("RUSTC was not set");
    let manifest_dir = exec_root.join(&manifest_dir_env);
    let rustc = exec_root.join(&rustc_env);
    let Options {
        progname,
        crate_links,
        out_dir,
        env_file,
        compile_flags_file,
        link_flags_file,
        output_dep_env_path,
        stdout_path,
        stderr_path,
        input_dep_env_paths,
    } = parse_args()?;

    let out_dir_abs = exec_root.join(&out_dir);
    // For some reason Google's RBE does not create the output directory, force create it.
    create_dir_all(&out_dir_abs)
        .unwrap_or_else(|_| panic!("Failed to make output directory: {:?}", out_dir_abs));

    let target_env_vars =
        get_target_env_vars(&rustc_env).expect("Error getting target env vars from rustc");

    let mut command = Command::new(exec_root.join(&progname));
    command
        .current_dir(&manifest_dir)
        .envs(target_env_vars)
        .env("OUT_DIR", out_dir_abs)
        .env("CARGO_MANIFEST_DIR", manifest_dir)
        .env("RUSTC", rustc)
        .env("RUST_BACKTRACE", "full");

    for dep_env_path in input_dep_env_paths.iter() {
        if let Ok(contents) = read_to_string(dep_env_path) {
            for line in contents.split('\n') {
                // split on empty contents will still produce a single empty string in iterable.
                if line.is_empty() {
                    continue;
                }
                let mut key_val = line.splitn(2, '=');
                match (key_val.next(), key_val.next()) {
                    (Some(key), Some(value)) => {
                        command.env(key, value.replace("${pwd}", &exec_root.to_string_lossy()));
                    }
                    _ => {
                        return Err(
                            "error: Wrong environment file format, should not happen".to_owned()
                        )
                    }
                }
            }
        } else {
            return Err("error: Dependency environment file unreadable".to_owned());
        }
    }

    if let Some(cc_path) = env::var_os("CC") {
        let mut cc_path = exec_root.join(cc_path);
        if let Some(sysroot_path) = env::var_os("SYSROOT") {
            cc_path.push(" --sysroot=");
            cc_path.push(&exec_root.join(sysroot_path));
        }
        command.env("CC", cc_path);
    }

    if let Some(ar_path) = env::var_os("AR") {
        // The default OSX toolchain uses libtool as ar_executable not ar.
        // This doesn't work when used as $AR, so simply don't set it - tools will probably fall back to
        // /usr/bin/ar which is probably good enough.
        if Path::new(&ar_path).file_name() == Some("libtool".as_ref()) {
            command.env_remove("AR");
        } else {
            command.env("AR", exec_root.join(ar_path));
        }
    }

    // replace env vars with a ${pwd} prefix with the exec_root
    for (key, value) in env::vars() {
        let exec_root_str = exec_root.to_str().expect("exec_root not in utf8");
        if value.contains("${pwd}") {
            env::set_var(key, value.replace("${pwd}", exec_root_str));
        }
    }

    let (buildrs_outputs, process_output) = BuildScriptOutput::outputs_from_command(&mut command)
        .map_err(|process_output| {
        format!(
            "Build script process failed{}\n--stdout:\n{}\n--stderr:\n{}",
            if let Some(exit_code) = process_output.status.code() {
                format!(" with exit code {}", exit_code)
            } else {
                String::new()
            },
            String::from_utf8(process_output.stdout)
                .expect("Failed to parse stdout of child process"),
            String::from_utf8(process_output.stderr)
                .expect("Failed to parse stdout of child process"),
        )
    })?;

    write(
        &env_file,
        BuildScriptOutput::outputs_to_env(&buildrs_outputs, &exec_root.to_string_lossy())
            .as_bytes(),
    )
    .unwrap_or_else(|_| panic!("Unable to write file {:?}", env_file));
    write(
        &output_dep_env_path,
        BuildScriptOutput::outputs_to_dep_env(
            &buildrs_outputs,
            &crate_links,
            &exec_root.to_string_lossy(),
        )
        .as_bytes(),
    )
    .unwrap_or_else(|_| panic!("Unable to write file {:?}", output_dep_env_path));
    write(&stdout_path, process_output.stdout)
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", stdout_path));
    write(&stderr_path, process_output.stderr)
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", stderr_path));

    let CompileAndLinkFlags {
        compile_flags,
        link_flags,
    } = BuildScriptOutput::outputs_to_flags(&buildrs_outputs, &exec_root.to_string_lossy());

    write(&compile_flags_file, compile_flags.as_bytes())
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", compile_flags_file));
    write(&link_flags_file, link_flags.as_bytes())
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", link_flags_file));
    Ok(())
}

/// A representation of expected command line arguments.
struct Options {
    progname: String,
    crate_links: String,
    out_dir: String,
    env_file: String,
    compile_flags_file: String,
    link_flags_file: String,
    output_dep_env_path: String,
    stdout_path: String,
    stderr_path: String,
    input_dep_env_paths: Vec<String>,
}

/// Parses positional comamnd line arguments into a well defined struct
fn parse_args() -> Result<Options, String> {
    let mut args = env::args().skip(1);

    // TODO: we should consider an alternative to positional arguments.
    match (args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next()) {
        (
            Some(progname),
            Some(crate_links),
            Some(out_dir),
            Some(env_file),
            Some(compile_flags_file),
            Some(link_flags_file),
            Some(output_dep_env_path),
            Some(stdout_path),
            Some(stderr_path),
        ) => {
            Ok(Options{
                progname,
                crate_links,
                out_dir,
                env_file,
                compile_flags_file,
                link_flags_file,
                output_dep_env_path,
                stdout_path,
                stderr_path,
                input_dep_env_paths: args.collect(),
            })
        }
        _ => {
            Err(format!("Usage: $0 progname crate_links out_dir env_file compile_flags_file link_flags_file output_dep_env_path stdout_path stderr_path input_dep_env_paths[arg1...argn]\nArguments passed: {:?}", args.collect::<Vec<String>>()))
        }
    }
}

fn get_target_env_vars<P: AsRef<Path>>(rustc: &P) -> Result<BTreeMap<String, String>, String> {
    // As done by Cargo when constructing a cargo::core::compiler::build_context::target_info::TargetInfo.
    let output = Command::new(rustc.as_ref())
        .arg("--print=cfg")
        .arg(format!(
            "--target={}",
            env::var("TARGET").expect("missing TARGET")
        ))
        .output()
        .map_err(|err| format!("Error running rustc to get target information: {}", err))?;
    if !output.status.success() {
        return Err(format!(
            "Error running rustc to get target information: {:?}",
            output
        ));
    }
    let stdout = std::str::from_utf8(&output.stdout)
        .map_err(|err| format!("Non-UTF8 stdout from rustc: {:?}", err))?;

    let mut values = BTreeMap::new();

    for line in stdout.lines() {
        if line.starts_with("target_") && line.contains('=') {
            let mut parts = line.splitn(2, '=');
            // UNWRAP: Verified that line contains = and split into exactly 2 parts.
            let key = parts.next().unwrap();
            let value = parts.next().unwrap();
            if value.starts_with('"') && value.ends_with('"') && value.len() >= 2 {
                values
                    .entry(key)
                    .or_insert_with(Vec::new)
                    .push(value[1..(value.len() - 1)].to_owned());
            }
        }
    }

    Ok(values
        .into_iter()
        .map(|(key, value)| (format!("CARGO_CFG_{}", key.to_uppercase()), value.join(",")))
        .collect())
}

fn main() {
    std::process::exit(match run_buildrs() {
        Ok(_) => 0,
        Err(err) => {
            // Neatly print errors
            eprintln!("{}", err);
            1
        }
    });
}
<commit_msg>Fix `cargo_build_script` breakage when `SYSROOT` is specified (#976)<commit_after>// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.

// A simple wrapper around a build_script execution to generate file to reuse
// by rust_library/rust_binary.
extern crate cargo_build_script_output_parser;

use cargo_build_script_output_parser::{BuildScriptOutput, CompileAndLinkFlags};
use std::collections::BTreeMap;
use std::env;
use std::fs::{create_dir_all, read_to_string, write};
use std::path::Path;
use std::process::Command;

fn run_buildrs() -> Result<(), String> {
    // We use exec_root.join rather than std::fs::canonicalize, to avoid resolving symlinks, as
    // some execution strategies and remote execution environments may use symlinks in ways which
    // canonicalizing them may break them, e.g. by having input files be symlinks into a /cas
    // directory - resolving these may cause tools which inspect $0, or try to resolve files
    // relative to themselves, to fail.
    let exec_root = env::current_dir().expect("Failed to get current directory");
    let manifest_dir_env = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR was not set");
    let rustc_env = env::var("RUSTC").expect("RUSTC was not set");
    let manifest_dir = exec_root.join(&manifest_dir_env);
    let rustc = exec_root.join(&rustc_env);
    let Options {
        progname,
        crate_links,
        out_dir,
        env_file,
        compile_flags_file,
        link_flags_file,
        output_dep_env_path,
        stdout_path,
        stderr_path,
        input_dep_env_paths,
    } = parse_args()?;

    let out_dir_abs = exec_root.join(&out_dir);
    // For some reason Google's RBE does not create the output directory, force create it.
    create_dir_all(&out_dir_abs)
        .unwrap_or_else(|_| panic!("Failed to make output directory: {:?}", out_dir_abs));

    let target_env_vars =
        get_target_env_vars(&rustc_env).expect("Error getting target env vars from rustc");

    let mut command = Command::new(exec_root.join(&progname));
    command
        .current_dir(&manifest_dir)
        .envs(target_env_vars)
        .env("OUT_DIR", out_dir_abs)
        .env("CARGO_MANIFEST_DIR", manifest_dir)
        .env("RUSTC", rustc)
        .env("RUST_BACKTRACE", "full");

    for dep_env_path in input_dep_env_paths.iter() {
        if let Ok(contents) = read_to_string(dep_env_path) {
            for line in contents.split('\n') {
                // split on empty contents will still produce a single empty string in iterable.
                if line.is_empty() {
                    continue;
                }
                let mut key_val = line.splitn(2, '=');
                match (key_val.next(), key_val.next()) {
                    (Some(key), Some(value)) => {
                        command.env(key, value.replace("${pwd}", &exec_root.to_string_lossy()));
                    }
                    _ => {
                        return Err(
                            "error: Wrong environment file format, should not happen".to_owned()
                        )
                    }
                }
            }
        } else {
            return Err("error: Dependency environment file unreadable".to_owned());
        }
    }

    if let Some(cc_path) = env::var_os("CC") {
        let mut cc_path = exec_root.join(cc_path).into_os_string();
        if let Some(sysroot_path) = env::var_os("SYSROOT") {
            cc_path.push(" --sysroot=");
            cc_path.push(&exec_root.join(sysroot_path));
        }
        command.env("CC", cc_path);
    }

    if let Some(ar_path) = env::var_os("AR") {
        // The default OSX toolchain uses libtool as ar_executable not ar.
        // This doesn't work when used as $AR, so simply don't set it - tools will probably fall back to
        // /usr/bin/ar which is probably good enough.
        if Path::new(&ar_path).file_name() == Some("libtool".as_ref()) {
            command.env_remove("AR");
        } else {
            command.env("AR", exec_root.join(ar_path));
        }
    }

    // replace env vars with a ${pwd} prefix with the exec_root
    for (key, value) in env::vars() {
        let exec_root_str = exec_root.to_str().expect("exec_root not in utf8");
        if value.contains("${pwd}") {
            env::set_var(key, value.replace("${pwd}", exec_root_str));
        }
    }

    let (buildrs_outputs, process_output) = BuildScriptOutput::outputs_from_command(&mut command)
        .map_err(|process_output| {
        format!(
            "Build script process failed{}\n--stdout:\n{}\n--stderr:\n{}",
            if let Some(exit_code) = process_output.status.code() {
                format!(" with exit code {}", exit_code)
            } else {
                String::new()
            },
            String::from_utf8(process_output.stdout)
                .expect("Failed to parse stdout of child process"),
            String::from_utf8(process_output.stderr)
                .expect("Failed to parse stdout of child process"),
        )
    })?;

    write(
        &env_file,
        BuildScriptOutput::outputs_to_env(&buildrs_outputs, &exec_root.to_string_lossy())
            .as_bytes(),
    )
    .unwrap_or_else(|_| panic!("Unable to write file {:?}", env_file));
    write(
        &output_dep_env_path,
        BuildScriptOutput::outputs_to_dep_env(
            &buildrs_outputs,
            &crate_links,
            &exec_root.to_string_lossy(),
        )
        .as_bytes(),
    )
    .unwrap_or_else(|_| panic!("Unable to write file {:?}", output_dep_env_path));
    write(&stdout_path, process_output.stdout)
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", stdout_path));
    write(&stderr_path, process_output.stderr)
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", stderr_path));

    let CompileAndLinkFlags {
        compile_flags,
        link_flags,
    } = BuildScriptOutput::outputs_to_flags(&buildrs_outputs, &exec_root.to_string_lossy());

    write(&compile_flags_file, compile_flags.as_bytes())
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", compile_flags_file));
    write(&link_flags_file, link_flags.as_bytes())
        .unwrap_or_else(|_| panic!("Unable to write file {:?}", link_flags_file));
    Ok(())
}

/// A representation of expected command line arguments.
struct Options {
    progname: String,
    crate_links: String,
    out_dir: String,
    env_file: String,
    compile_flags_file: String,
    link_flags_file: String,
    output_dep_env_path: String,
    stdout_path: String,
    stderr_path: String,
    input_dep_env_paths: Vec<String>,
}

/// Parses positional comamnd line arguments into a well defined struct
fn parse_args() -> Result<Options, String> {
    let mut args = env::args().skip(1);

    // TODO: we should consider an alternative to positional arguments.
    match (args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next(), args.next()) {
        (
            Some(progname),
            Some(crate_links),
            Some(out_dir),
            Some(env_file),
            Some(compile_flags_file),
            Some(link_flags_file),
            Some(output_dep_env_path),
            Some(stdout_path),
            Some(stderr_path),
        ) => {
            Ok(Options{
                progname,
                crate_links,
                out_dir,
                env_file,
                compile_flags_file,
                link_flags_file,
                output_dep_env_path,
                stdout_path,
                stderr_path,
                input_dep_env_paths: args.collect(),
            })
        }
        _ => {
            Err(format!("Usage: $0 progname crate_links out_dir env_file compile_flags_file link_flags_file output_dep_env_path stdout_path stderr_path input_dep_env_paths[arg1...argn]\nArguments passed: {:?}", args.collect::<Vec<String>>()))
        }
    }
}

fn get_target_env_vars<P: AsRef<Path>>(rustc: &P) -> Result<BTreeMap<String, String>, String> {
    // As done by Cargo when constructing a cargo::core::compiler::build_context::target_info::TargetInfo.
    let output = Command::new(rustc.as_ref())
        .arg("--print=cfg")
        .arg(format!(
            "--target={}",
            env::var("TARGET").expect("missing TARGET")
        ))
        .output()
        .map_err(|err| format!("Error running rustc to get target information: {}", err))?;
    if !output.status.success() {
        return Err(format!(
            "Error running rustc to get target information: {:?}",
            output
        ));
    }
    let stdout = std::str::from_utf8(&output.stdout)
        .map_err(|err| format!("Non-UTF8 stdout from rustc: {:?}", err))?;

    let mut values = BTreeMap::new();

    for line in stdout.lines() {
        if line.starts_with("target_") && line.contains('=') {
            let mut parts = line.splitn(2, '=');
            // UNWRAP: Verified that line contains = and split into exactly 2 parts.
            let key = parts.next().unwrap();
            let value = parts.next().unwrap();
            if value.starts_with('"') && value.ends_with('"') && value.len() >= 2 {
                values
                    .entry(key)
                    .or_insert_with(Vec::new)
                    .push(value[1..(value.len() - 1)].to_owned());
            }
        }
    }

    Ok(values
        .into_iter()
        .map(|(key, value)| (format!("CARGO_CFG_{}", key.to_uppercase()), value.join(",")))
        .collect())
}

fn main() {
    std::process::exit(match run_buildrs() {
        Ok(_) => 0,
        Err(err) => {
            // Neatly print errors
            eprintln!("{}", err);
            1
        }
    });
}
<|endoftext|>


<commit_before>//! Murmur2, a suite of  non-cryptographic hash functions that was used for hash-based lookups.
//!
//! by Austin Appleby (aappleby (AT) gmail)
//!
//! https://sites.google.com/site/murmurhash/
//!
//! Extremely simple - compiles down to ~52 instructions on x86.
//!
//! Excellent distribution - Passes chi-squared tests for practically all keysets & bucket sizes.
//!
//! Excellent avalanche behavior - Maximum bias is under 0.5%.
//!
//! Excellent collision resistance - Passes Bob Jenkin's frog.c torture-test.
//! No collisions possible for 4-byte keys, no small (1- to 7-bit) differentials.
//!
//! Excellent performance - measured on an Intel Core 2 Duo @ 2.4 ghz
//!
//!    - OneAtATime - 354.163715 mb/sec
//!    - FNV - 443.668038 mb/sec
//!    - SuperFastHash - 985.335173 mb/sec
//!    - lookup3 - 988.080652 mb/sec
//!    - MurmurHash 1.0 - 1363.293480 mb/sec
//!    - MurmurHash 2.0 - 2056.885653 mb/sec
//!
//! # Variants
//!
//! The current version is `MurmurHash3`, which yields a 32-bit or 128-bit hash value.
//!
//! The older `MurmurHash2` yields a 32-bit or 64-bit value.
//! Slower versions of `MurmurHash2` are available for big-endian and aligned-only machines.
//! The `MurmurHash2A` variant adds the Merkle–Damgård construction
//! so that it can be called incrementally.
//! There are two variants which generate 64-bit values; `MurmurHash64A`,
//! which is optimized for 64-bit processors, and `MurmurHash64B`, for 32-bit ones.
//!
//! # Attacks
//!
//! MurmurHash was a recommended hash function for hash table implementations.
//! Jean-Philippe Aumasson and Daniel J. Bernstein were able to show
//! that even randomized implementations of MurmurHash are vulnerable to so-called [HashDoS attacks]
//! (https://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/).
//! With the use of differential cryptanalysis they were able to generate inputs
//! that would lead to a hash collision.
//! This can be abused to cause very slow operations of a hash table implementation.
//! The authors of the attack recommend to use `SipHash` instead.
//!
//! # Example
//!
//! ```
//! use std::hash::{Hash, Hasher};
//!
//! use fasthash::{murmur2, Murmur2Hasher};
//!
//! fn hash<T: Hash>(t: &T) -> u64 {
//!     let mut s = Murmur2Hasher::new();
//!     t.hash(&mut s);
//!     s.finish()
//! }
//!
//! let h = murmur2::hash64(b"hello world\xff");
//!
//! assert_eq!(h, hash(&"hello world"));
//! ```
//!
#![allow(non_camel_case_types)]
use std::os::raw::c_void;

use ffi;

use hasher::FastHash;

/// MurmurHash2 32-bit hash functions
pub struct Murmur2 {}

impl FastHash for Murmur2 {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHash2(bytes.as_ref().as_ptr() as *const c_void,
                             bytes.as_ref().len() as i32,
                             seed)
        }
    }
}

impl_hasher!(MurmurHasher2, Murmur2);

/// MurmurHash2A 32-bit hash functions
pub struct Murmur2A {}

impl FastHash for Murmur2A {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHash2A(bytes.as_ref().as_ptr() as *const c_void,
                              bytes.as_ref().len() as i32,
                              seed)
        }
    }
}

impl_hasher!(MurmurHasher2A, Murmur2A);

/// MurmurHash2 32-bit neutral hash functions for the (slower) endian-neutral implementation
pub struct MurmurNeutral2 {}

impl FastHash for MurmurNeutral2 {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHashNeutral2(bytes.as_ref().as_ptr() as *const c_void,
                                    bytes.as_ref().len() as i32,
                                    seed)
        }
    }
}

impl_hasher!(MurmurNeutral2Hasher, MurmurNeutral2);

/// MurmurHash2 32-bit aligned hash functions for the little-endian aligned-read-only implementation
pub struct MurmurAligned2 {}

impl FastHash for MurmurAligned2 {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHashAligned2(bytes.as_ref().as_ptr() as *const c_void,
                                    bytes.as_ref().len() as i32,
                                    seed)
        }
    }
}

impl_hasher!(MurmurAligned2Hasher, MurmurAligned2);

/// MurmurHash2 64-bit hash functions for 64-bit processors
pub struct Murmur2_x64_64 {}

impl FastHash for Murmur2_x64_64 {
    type Value = u64;
    type Seed = u64;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u64) -> u64 {
        unsafe {
            ffi::MurmurHash64A(bytes.as_ref().as_ptr() as *const c_void,
                               bytes.as_ref().len() as i32,
                               seed)
        }
    }
}

impl_hasher!(Murmur2Hasher_x64_64, Murmur2_x64_64);

/// MurmurHash2 64-bit hash functions for 32-bit processors
pub struct Murmur2_x86_64 {}

impl FastHash for Murmur2_x86_64 {
    type Value = u64;
    type Seed = u64;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u64) -> u64 {
        unsafe {
            ffi::MurmurHash64B(bytes.as_ref().as_ptr() as *const c_void,
                               bytes.as_ref().len() as i32,
                               seed)
        }
    }
}

impl_hasher!(Murmur2Hasher_x86_64, Murmur2_x86_64);

/// MurmurHash2 32-bit hash functions for a byte array.
#[inline]
pub fn hash32<T: AsRef<[u8]>>(v: &T) -> u32 {
    Murmur2::hash(v)
}

/// MurmurHash2 32-bit hash function for a byte array.
/// For convenience, a 32-bit seed is also hashed into the result.
#[inline]
pub fn hash32_with_seed<T: AsRef<[u8]>>(v: &T, seed: u32) -> u32 {
    Murmur2::hash_with_seed(v, seed)
}

/// MurmurHash2 64-bit hash functions for a byte array.
#[inline]
pub fn hash64<T: AsRef<[u8]>>(v: &T) -> u64 {
    Murmur2_x64_64::hash(v)
}

/// MurmurHash2 64-bit hash function for a byte array.
/// For convenience, a 64-bit seed is also hashed into the result.
#[inline]
pub fn hash64_with_seed<T: AsRef<[u8]>>(v: &T, seed: u64) -> u64 {
    Murmur2_x64_64::hash_with_seed(v, seed)
}

#[cfg(test)]
mod tests {
    use std::hash::Hasher;

    use hasher::FastHash;
    use super::*;

    #[test]
    fn test_murmur2() {
        assert_eq!(Murmur2::hash(b"hello"), 3848350155);
        assert_eq!(Murmur2::hash_with_seed(b"hello", 123), 2385981934);
        assert_eq!(Murmur2::hash(b"helloworld"), 2155944146);

        let mut h = MurmurHasher2::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 3848350155);

        h.write(b"world");
        assert_eq!(h.finish(), 2155944146);
    }

    #[test]
    fn test_murmur2a() {
        assert_eq!(Murmur2A::hash(b"hello"), 259931098);
        assert_eq!(Murmur2A::hash_with_seed(b"hello", 123), 509510832);
        assert_eq!(Murmur2A::hash(b"helloworld"), 403945221);

        let mut h = MurmurHasher2A::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 259931098);

        h.write(b"world");
        assert_eq!(h.finish(), 403945221);
    }

    #[test]
    fn test_murmur2_neutral() {
        assert_eq!(MurmurNeutral2::hash(b"hello"), 3848350155);
        assert_eq!(MurmurNeutral2::hash_with_seed(b"hello", 123), 2385981934);
        assert_eq!(MurmurNeutral2::hash(b"helloworld"), 2155944146);

        let mut h = MurmurNeutral2Hasher::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 3848350155);

        h.write(b"world");
        assert_eq!(h.finish(), 2155944146);
    }

    #[test]
    fn test_murmur2_aligned() {
        assert_eq!(MurmurAligned2::hash(b"hello"), 3848350155);
        assert_eq!(MurmurAligned2::hash_with_seed(b"hello", 123), 2385981934);
        assert_eq!(MurmurAligned2::hash(b"helloworld"), 2155944146);

        let mut h = MurmurAligned2Hasher::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 3848350155);

        h.write(b"world");
        assert_eq!(h.finish(), 2155944146);
    }

    #[test]
    fn test_murmur2_x64_64() {
        assert_eq!(Murmur2_x64_64::hash(b"hello"), 2191231550387646743);
        assert_eq!(Murmur2_x64_64::hash_with_seed(b"hello", 123),
                   2597646618390559622);
        assert_eq!(Murmur2_x64_64::hash(b"helloworld"), 2139823713852166039);

        let mut h = Murmur2Hasher_x64_64::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 2191231550387646743);

        h.write(b"world");
        assert_eq!(h.finish(), 2139823713852166039);
    }

    #[test]
    fn test_murmur2_x86_64() {
        assert_eq!(Murmur2_x86_64::hash(b"hello"), 17658855022785723775);
        assert_eq!(Murmur2_x86_64::hash_with_seed(b"hello", 123),
                   1883382312211796549);
        assert_eq!(Murmur2_x86_64::hash(b"helloworld"), 14017254558097603378);

        let mut h = Murmur2Hasher_x86_64::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 17658855022785723775);

        h.write(b"world");
        assert_eq!(h.finish(), 14017254558097603378);
    }
}
<commit_msg>Normalize naming<commit_after>//! Murmur2, a suite of  non-cryptographic hash functions that was used for hash-based lookups.
//!
//! by Austin Appleby (aappleby (AT) gmail)
//!
//! https://sites.google.com/site/murmurhash/
//!
//! Extremely simple - compiles down to ~52 instructions on x86.
//!
//! Excellent distribution - Passes chi-squared tests for practically all keysets & bucket sizes.
//!
//! Excellent avalanche behavior - Maximum bias is under 0.5%.
//!
//! Excellent collision resistance - Passes Bob Jenkin's frog.c torture-test.
//! No collisions possible for 4-byte keys, no small (1- to 7-bit) differentials.
//!
//! Excellent performance - measured on an Intel Core 2 Duo @ 2.4 ghz
//!
//!    - OneAtATime - 354.163715 mb/sec
//!    - FNV - 443.668038 mb/sec
//!    - SuperFastHash - 985.335173 mb/sec
//!    - lookup3 - 988.080652 mb/sec
//!    - MurmurHash 1.0 - 1363.293480 mb/sec
//!    - MurmurHash 2.0 - 2056.885653 mb/sec
//!
//! # Variants
//!
//! The current version is `MurmurHash3`, which yields a 32-bit or 128-bit hash value.
//!
//! The older `MurmurHash2` yields a 32-bit or 64-bit value.
//! Slower versions of `MurmurHash2` are available for big-endian and aligned-only machines.
//! The `MurmurHash2A` variant adds the Merkle–Damgård construction
//! so that it can be called incrementally.
//! There are two variants which generate 64-bit values; `MurmurHash64A`,
//! which is optimized for 64-bit processors, and `MurmurHash64B`, for 32-bit ones.
//!
//! # Attacks
//!
//! MurmurHash was a recommended hash function for hash table implementations.
//! Jean-Philippe Aumasson and Daniel J. Bernstein were able to show
//! that even randomized implementations of MurmurHash are vulnerable to so-called [HashDoS attacks]
//! (https://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/).
//! With the use of differential cryptanalysis they were able to generate inputs
//! that would lead to a hash collision.
//! This can be abused to cause very slow operations of a hash table implementation.
//! The authors of the attack recommend to use `SipHash` instead.
//!
//! # Example
//!
//! ```
//! use std::hash::{Hash, Hasher};
//!
//! use fasthash::{murmur2, Murmur2Hasher};
//!
//! fn hash<T: Hash>(t: &T) -> u64 {
//!     let mut s = Murmur2Hasher::new();
//!     t.hash(&mut s);
//!     s.finish()
//! }
//!
//! let h = murmur2::hash64(b"hello world\xff");
//!
//! assert_eq!(h, hash(&"hello world"));
//! ```
//!
#![allow(non_camel_case_types)]
use std::os::raw::c_void;

use ffi;

use hasher::FastHash;

/// MurmurHash2 32-bit hash functions
pub struct Murmur2 {}

impl FastHash for Murmur2 {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHash2(bytes.as_ref().as_ptr() as *const c_void,
                             bytes.as_ref().len() as i32,
                             seed)
        }
    }
}

impl_hasher!(Murmur2Hasher, Murmur2);

/// MurmurHash2A 32-bit hash functions
pub struct Murmur2A {}

impl FastHash for Murmur2A {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHash2A(bytes.as_ref().as_ptr() as *const c_void,
                              bytes.as_ref().len() as i32,
                              seed)
        }
    }
}

impl_hasher!(Murmur2AHasher, Murmur2A);

/// MurmurHash2 32-bit neutral hash functions for the (slower) endian-neutral implementation
pub struct MurmurNeutral2 {}

impl FastHash for MurmurNeutral2 {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHashNeutral2(bytes.as_ref().as_ptr() as *const c_void,
                                    bytes.as_ref().len() as i32,
                                    seed)
        }
    }
}

impl_hasher!(MurmurNeutral2Hasher, MurmurNeutral2);

/// MurmurHash2 32-bit aligned hash functions for the little-endian aligned-read-only implementation
pub struct MurmurAligned2 {}

impl FastHash for MurmurAligned2 {
    type Value = u32;
    type Seed = u32;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u32) -> u32 {
        unsafe {
            ffi::MurmurHashAligned2(bytes.as_ref().as_ptr() as *const c_void,
                                    bytes.as_ref().len() as i32,
                                    seed)
        }
    }
}

impl_hasher!(MurmurAligned2Hasher, MurmurAligned2);

/// MurmurHash2 64-bit hash functions for 64-bit processors
pub struct Murmur2_x64_64 {}

impl FastHash for Murmur2_x64_64 {
    type Value = u64;
    type Seed = u64;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u64) -> u64 {
        unsafe {
            ffi::MurmurHash64A(bytes.as_ref().as_ptr() as *const c_void,
                               bytes.as_ref().len() as i32,
                               seed)
        }
    }
}

impl_hasher!(Murmur2Hasher_x64_64, Murmur2_x64_64);

/// MurmurHash2 64-bit hash functions for 32-bit processors
pub struct Murmur2_x86_64 {}

impl FastHash for Murmur2_x86_64 {
    type Value = u64;
    type Seed = u64;

    #[inline]
    fn hash_with_seed<T: AsRef<[u8]>>(bytes: &T, seed: u64) -> u64 {
        unsafe {
            ffi::MurmurHash64B(bytes.as_ref().as_ptr() as *const c_void,
                               bytes.as_ref().len() as i32,
                               seed)
        }
    }
}

impl_hasher!(Murmur2Hasher_x86_64, Murmur2_x86_64);

/// MurmurHash2 32-bit hash functions for a byte array.
#[inline]
pub fn hash32<T: AsRef<[u8]>>(v: &T) -> u32 {
    Murmur2A::hash(v)
}

/// MurmurHash2 32-bit hash function for a byte array.
/// For convenience, a 32-bit seed is also hashed into the result.
#[inline]
pub fn hash32_with_seed<T: AsRef<[u8]>>(v: &T, seed: u32) -> u32 {
    Murmur2A::hash_with_seed(v, seed)
}

/// MurmurHash2 64-bit hash functions for a byte array.
#[inline]
pub fn hash64<T: AsRef<[u8]>>(v: &T) -> u64 {
    Murmur2_x64_64::hash(v)
}

/// MurmurHash2 64-bit hash function for a byte array.
/// For convenience, a 64-bit seed is also hashed into the result.
#[inline]
pub fn hash64_with_seed<T: AsRef<[u8]>>(v: &T, seed: u64) -> u64 {
    Murmur2_x64_64::hash_with_seed(v, seed)
}

#[cfg(test)]
mod tests {
    use std::hash::Hasher;

    use hasher::FastHash;
    use super::*;

    #[test]
    fn test_murmur2() {
        assert_eq!(Murmur2::hash(b"hello"), 3848350155);
        assert_eq!(Murmur2::hash_with_seed(b"hello", 123), 2385981934);
        assert_eq!(Murmur2::hash(b"helloworld"), 2155944146);

        let mut h = Murmur2Hasher::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 3848350155);

        h.write(b"world");
        assert_eq!(h.finish(), 2155944146);
    }

    #[test]
    fn test_murmur2a() {
        assert_eq!(Murmur2A::hash(b"hello"), 259931098);
        assert_eq!(Murmur2A::hash_with_seed(b"hello", 123), 509510832);
        assert_eq!(Murmur2A::hash(b"helloworld"), 403945221);

        let mut h = Murmur2AHasher::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 259931098);

        h.write(b"world");
        assert_eq!(h.finish(), 403945221);
    }

    #[test]
    fn test_murmur2_neutral() {
        assert_eq!(MurmurNeutral2::hash(b"hello"), 3848350155);
        assert_eq!(MurmurNeutral2::hash_with_seed(b"hello", 123), 2385981934);
        assert_eq!(MurmurNeutral2::hash(b"helloworld"), 2155944146);

        let mut h = MurmurNeutral2Hasher::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 3848350155);

        h.write(b"world");
        assert_eq!(h.finish(), 2155944146);
    }

    #[test]
    fn test_murmur2_aligned() {
        assert_eq!(MurmurAligned2::hash(b"hello"), 3848350155);
        assert_eq!(MurmurAligned2::hash_with_seed(b"hello", 123), 2385981934);
        assert_eq!(MurmurAligned2::hash(b"helloworld"), 2155944146);

        let mut h = MurmurAligned2Hasher::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 3848350155);

        h.write(b"world");
        assert_eq!(h.finish(), 2155944146);
    }

    #[test]
    fn test_murmur2_x64_64() {
        assert_eq!(Murmur2_x64_64::hash(b"hello"), 2191231550387646743);
        assert_eq!(Murmur2_x64_64::hash_with_seed(b"hello", 123),
                   2597646618390559622);
        assert_eq!(Murmur2_x64_64::hash(b"helloworld"), 2139823713852166039);

        let mut h = Murmur2Hasher_x64_64::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 2191231550387646743);

        h.write(b"world");
        assert_eq!(h.finish(), 2139823713852166039);
    }

    #[test]
    fn test_murmur2_x86_64() {
        assert_eq!(Murmur2_x86_64::hash(b"hello"), 17658855022785723775);
        assert_eq!(Murmur2_x86_64::hash_with_seed(b"hello", 123),
                   1883382312211796549);
        assert_eq!(Murmur2_x86_64::hash(b"helloworld"), 14017254558097603378);

        let mut h = Murmur2Hasher_x86_64::new();

        h.write(b"hello");
        assert_eq!(h.finish(), 17658855022785723775);

        h.write(b"world");
        assert_eq!(h.finish(), 14017254558097603378);
    }
}
<|endoftext|>


<commit_before>
use std::error::Error;
use std::fmt::{self,Display,Formatter};

use super::device::{DeviceFileDescriptor,BlockMode,ReadWriteMode,DeviceResult,DeviceError};

#[allow(dead_code,non_camel_case_types,non_snake_case)]
mod ffi;

pub mod caps;

#[allow(dead_code,non_camel_case_types,non_snake_case)]
pub mod properties {
    use super::ffi as ffi;

    include!(concat!(env!("OUT_DIR"), "/frontend-properties.rs"));
}

pub struct Frontend {
    device: DeviceFileDescriptor
}

impl Frontend {
    pub fn open(filename: &str, rw_mode: ReadWriteMode, block_mode: BlockMode) -> DeviceResult<Frontend> {
        let device = try!(DeviceFileDescriptor::open(filename, rw_mode, block_mode));
        Ok(Frontend { device: device })
    }

    pub fn get_info(&self) -> DeviceResult<FrontendInfo> {
        unimplemented!();
    }
    pub fn read_status(&self) -> DeviceResult<FrontendStatus> {
        unimplemented!();
    }
    pub fn set_properties(&self, properties: &[properties::SetPropertyValue]) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn get_properties(&self, properties: &[properties::GetProperty]) -> PropertyResult<Vec<properties::GetPropertyValue>> {
        unimplemented!();
    }
    pub fn diseqc_reset_overload(&self) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn diseqc_send_master_cmd(&self, command: DiseqcMasterCommand) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn diseqc_recv_slave_reply(&self) -> DeviceResult<DiseqcSlaveReply> {
        unimplemented!();
    }
    pub fn diseqc_send_burst(&self, command: SecMiniCmd) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn set_tone(&self, tone: SecToneMode) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn set_voltage(&self, voltage: properties::Voltage) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn enable_high_lnb_voltage(&self, high: u32) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn set_frontend_tune_mode(&self, tune_mode: TuneMode) -> DeviceResult<()> {
        unimplemented!();
    }
}

#[derive(Clone,Debug)]
pub struct FrontendInfo {
    pub name: String,
    pub frequency_min: u32,
    pub frequency_max: u32,
    pub frequency_stepsize: u32,
    pub frequency_tolerance: u32,
    pub symbol_rate_min: u32,
    pub symbol_rate_max: u32,
    pub symbol_rate_tolerance: u32,
    pub caps: caps::FrontendCaps,
}

pub struct FrontendStatus {
    pub has_signal: bool,
    pub has_carrier: bool,
    pub has_viterbi: bool,
    pub has_sync: bool,
    pub has_lock: bool,
    pub timedout: bool,
    pub reinit: bool
}

pub struct DiseqcSlaveReply {
    pub msg: [u8; 4],
    pub msg_len: u8,
    pub timeout: i32
}

pub struct DiseqcMasterCommand {
    pub msg: [u8; 6],
    pub msg_len: u8
}

pub enum SecMiniCmd {
    A,
    B
}

pub enum SecToneMode {
    On,
    Off
}

pub enum TuneMode {
    Normal,
    OneShot
}

pub type PropertyResult<T> = Result<T, PropertyError>;

#[derive(Clone,Debug)]
pub enum PropertyError {
    DeviceError(DeviceError),
    PropertyMappingError(properties::PropertyMappingError)
}

impl Error for PropertyError {
    fn description(&self) -> &str {
        match *self {
            PropertyError::DeviceError(ref err) => err.description(),
            PropertyError::PropertyMappingError(ref err) => err.description()
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            PropertyError::DeviceError(ref err) => Some(err),
            PropertyError::PropertyMappingError(ref err) => Some(err)
        }
    }
}

impl Display for PropertyError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "PropertyError: {}", self.description())
    }
}<commit_msg>Implement DiSEqC related frontend functions.<commit_after>
use std::error::Error;
use std::fmt::{self,Display,Formatter};
use std::default::Default;

use libc::{c_uint, c_int,c_ulong};

use super::device::{DeviceFileDescriptor,BlockMode,ReadWriteMode,DeviceResult,DeviceError};

#[allow(dead_code,non_camel_case_types,non_snake_case)]
mod ffi;

pub mod caps;

#[allow(dead_code,non_camel_case_types,non_snake_case)]
pub mod properties {
    use super::ffi as ffi;

    include!(concat!(env!("OUT_DIR"), "/frontend-properties.rs"));
}

pub struct Frontend {
    device: DeviceFileDescriptor
}

impl Frontend {
    pub fn open(filename: &str, rw_mode: ReadWriteMode, block_mode: BlockMode) -> DeviceResult<Frontend> {
        let device = try!(DeviceFileDescriptor::open(filename, rw_mode, block_mode));
        Ok(Frontend { device: device })
    }

    pub fn get_info(&self) -> DeviceResult<FrontendInfo> {
        unimplemented!();
    }
    pub fn read_status(&self) -> DeviceResult<FrontendStatus> {
        unimplemented!();
    }
    pub fn set_properties(&self, properties: &[properties::SetPropertyValue]) -> DeviceResult<()> {
        unimplemented!();
    }
    pub fn get_properties(&self, properties: &[properties::GetProperty]) -> PropertyResult<Vec<properties::GetPropertyValue>> {
        unimplemented!();
    }

    pub fn diseqc_reset_overload(&self) -> DeviceResult<()> {
        self.device.ioctl_argumentless(ffi::FE_DISEQC_RESET_OVERLOAD as c_ulong)
    }

    pub fn diseqc_send_master_cmd(&self, command: DiseqcMasterCommand) -> DeviceResult<()> {
        let mut ffi_cmd = ffi::Struct_dvb_diseqc_master_cmd {
            msg: command.msg,
            msg_len: command.msg_len
        };
        self.device.ioctl_pointer(ffi::FE_DISEQC_SEND_MASTER_CMD as c_ulong, &mut ffi_cmd)
    }

    /// The timeout parameter is not used by most drivers. (2015-06-17)
    pub fn diseqc_recv_slave_reply(&self, timeout: u32) -> DeviceResult<DiseqcSlaveReply> {
        let mut ffi_reply: ffi::Struct_dvb_diseqc_slave_reply = Default::default();
        ffi_reply.timeout = timeout as c_int;
        try!(self.device.ioctl_pointer(ffi::FE_DISEQC_RECV_SLAVE_REPLY as c_ulong, &mut ffi_reply));
        Ok(DiseqcSlaveReply {
            msg: ffi_reply.msg,
            msg_len: ffi_reply.msg_len
        })
    }

    pub fn diseqc_send_burst(&self, command: SecMiniCmd) -> DeviceResult<()> {
        let command = match command {
            SecMiniCmd::A => ffi::SEC_MINI_A,
            SecMiniCmd::B => ffi::SEC_MINI_B
        };
        let command_ptr: *const c_uint = &command;
        self.device.ioctl_value(ffi::FE_DISEQC_SEND_BURST as c_ulong, command_ptr)
    }

    pub fn set_tone(&self, tone: SecToneMode) -> DeviceResult<()> {
        let tone = match tone {
            SecToneMode::On => ffi::SEC_TONE_ON,
            SecToneMode::Off => ffi::SEC_TONE_OFF
        };
        let tone_ptr: *const c_uint = &tone;
        self.device.ioctl_value(ffi::FE_SET_TONE as c_ulong, tone_ptr)
    }

    pub fn set_voltage(&self, voltage: properties::Voltage) -> DeviceResult<()> {
        let voltage = match voltage {
            properties::Voltage::SecVoltage13 => ffi::SEC_VOLTAGE_13,
            properties::Voltage::SecVoltage18 => ffi::SEC_VOLTAGE_18,
            properties::Voltage::SecVoltageOff => ffi::SEC_VOLTAGE_OFF,
        };
        self.device.ioctl_value(ffi::FE_SET_VOLTAGE as c_ulong, voltage)
    }

    pub fn enable_high_lnb_voltage(&self, high: u32) -> DeviceResult<()> {
        self.device.ioctl_value(ffi::FE_ENABLE_HIGH_LNB_VOLTAGE as c_ulong, high)
    }

    pub fn set_frontend_tune_mode(&self, tune_mode: TuneMode) -> DeviceResult<()> {
        let value = match tune_mode {
            TuneMode::Normal => 0,
            TuneMode::OneShot => ffi::FE_TUNE_MODE_ONESHOT
        };
        self.device.ioctl_value(ffi::FE_SET_FRONTEND_TUNE_MODE as c_ulong, value)
    }
}

#[derive(Clone,Debug)]
pub struct FrontendInfo {
    pub name: String,
    pub frequency_min: u32,
    pub frequency_max: u32,
    pub frequency_stepsize: u32,
    pub frequency_tolerance: u32,
    pub symbol_rate_min: u32,
    pub symbol_rate_max: u32,
    pub symbol_rate_tolerance: u32,
    pub caps: caps::FrontendCaps,
}

pub struct FrontendStatus {
    pub has_signal: bool,
    pub has_carrier: bool,
    pub has_viterbi: bool,
    pub has_sync: bool,
    pub has_lock: bool,
    pub timedout: bool,
    pub reinit: bool
}

pub struct DiseqcSlaveReply {
    pub msg: [u8; 4],
    pub msg_len: u8
}

pub struct DiseqcMasterCommand {
    pub msg: [u8; 6],
    pub msg_len: u8
}

pub enum SecMiniCmd {
    A,
    B
}

pub enum SecToneMode {
    On,
    Off
}

pub enum TuneMode {
    Normal,
    OneShot
}

pub type PropertyResult<T> = Result<T, PropertyError>;

#[derive(Clone,Debug)]
pub enum PropertyError {
    DeviceError(DeviceError),
    PropertyMappingError(properties::PropertyMappingError)
}

impl Error for PropertyError {
    fn description(&self) -> &str {
        match *self {
            PropertyError::DeviceError(ref err) => err.description(),
            PropertyError::PropertyMappingError(ref err) => err.description()
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            PropertyError::DeviceError(ref err) => Some(err),
            PropertyError::PropertyMappingError(ref err) => Some(err)
        }
    }
}

impl Display for PropertyError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "PropertyError: {}", self.description())
    }
}<|endoftext|>


<commit_before>use std::mem;

fn eq_ref<T>(x: &T, y: &T) -> bool {
    x as *const _ == y as *const _
}

fn f() -> i32 { 42 }

fn main() {
    // int-ptr-int
    assert_eq!(1 as *const i32 as usize, 1);
    assert_eq!((1 as *const i32).wrapping_offset(4) as usize, 1 + 4*4);

    {   // ptr-int-ptr
        let x = 13;
        let mut y = &x as *const _ as usize;
        y += 13;
        y -= 13;
        let y = y as *const _;
        assert!(eq_ref(&x, unsafe { &*y }));
    }

    {   // fnptr-int-fnptr
        let x : fn() -> i32 = f;
        let y : *mut u8 = unsafe { mem::transmute(x) };
        let mut y = y as usize;
        y += 13;
        y -= 13;
        let x : fn() -> i32 = unsafe { mem::transmute(y as *mut u8) };
        assert_eq!(x(), 42);
    }
}
<commit_msg>make sure that 'identity casting' works<commit_after>use std::mem;

fn eq_ref<T>(x: &T, y: &T) -> bool {
    x as *const _ == y as *const _
}

fn f() -> i32 { 42 }

fn main() {
    // int-ptr-int
    assert_eq!(1 as *const i32 as usize, 1);
    assert_eq!((1 as *const i32).wrapping_offset(4) as usize, 1 + 4*4);

    {   // ptr-int-ptr
        let x = 13;
        let mut y = &x as &_ as *const _ as usize;
        y += 13;
        y -= 13;
        let y = y as *const _;
        assert!(eq_ref(&x, unsafe { &*y }));
    }

    {   // fnptr-int-fnptr
        let x : fn() -> i32 = f;
        let y : *mut u8 = unsafe { mem::transmute(x as fn() -> i32) };
        let mut y = y as usize;
        y += 13;
        y -= 13;
        let x : fn() -> i32 = unsafe { mem::transmute(y as *mut u8) };
        assert_eq!(x(), 42);
    }
}
<|endoftext|>


<commit_before>mod codegen {
    extern crate quasi_codegen;
    use std::path::Path;

    pub fn main() {
        let out_dir = Path::new(env!("OUT_DIR"));
        let src = Path::new("src/codegen/mod.rs");
        let dst = Path::new(&out_dir).join("codegen.rs");

        quasi_codegen::expand(&src, &dst).unwrap();
        println!("cargo:rerun-if-changed=src/codegen/mod.rs");
        println!("cargo:rerun-if-changed=src/codegen/helpers.rs");
    }
}

mod testgen {
    use std::char;
    use std::ffi::OsStr;
    use std::fs::{self, File};
    use std::io::Write;
    use std::path::Path;

    pub fn main() {
        let out_dir = Path::new(env!("OUT_DIR"));
        let mut dst = File::create(Path::new(&out_dir).join("tests.rs")).unwrap();

        println!("cargo:rerun-if-changed=tests/headers");
        let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
        let headers_dir = manifest_dir.join("tests").join("headers");

        let entries = fs::read_dir(headers_dir)
            .expect("Couldn't read headers dir")
            .map(|result| result.expect("Couldn't read header file"));

        for entry in entries {
            match entry.path().extension().and_then(OsStr::to_str) {
                Some("h") | Some("hpp") => {
                    let func = entry.file_name().to_str().unwrap()
                        .replace(|c| !char::is_alphanumeric(c), "_")
                        .replace("__", "_")
                        .to_lowercase();
                    writeln!(dst, "test_header!(header_{}, {:?});",
                             func, entry.path()).unwrap();
                }
                _ => {}
            }
        }

        dst.flush().unwrap();
    }
}

fn main() {
    codegen::main();
    testgen::main();
}
<commit_msg>Use std::env::var instead of env! in build srcipt<commit_after>mod codegen {
    extern crate quasi_codegen;
    use std::env;
    use std::path::{Path, PathBuf};

    pub fn main() {
        let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
        let src = Path::new("src/codegen/mod.rs");
        let dst = Path::new(&out_dir).join("codegen.rs");

        quasi_codegen::expand(&src, &dst).unwrap();
        println!("cargo:rerun-if-changed=src/codegen/mod.rs");
        println!("cargo:rerun-if-changed=src/codegen/helpers.rs");
    }
}

mod testgen {
    use std::char;
    use std::env;
    use std::ffi::OsStr;
    use std::fs::{self, File};
    use std::io::Write;
    use std::path::{Path, PathBuf};

    pub fn main() {
        let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
        let mut dst = File::create(Path::new(&out_dir).join("tests.rs")).unwrap();

        println!("cargo:rerun-if-changed=tests/headers");
        let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
        let headers_dir = manifest_dir.join("tests").join("headers");

        let entries = fs::read_dir(headers_dir)
            .expect("Couldn't read headers dir")
            .map(|result| result.expect("Couldn't read header file"));

        for entry in entries {
            match entry.path().extension().and_then(OsStr::to_str) {
                Some("h") | Some("hpp") => {
                    let func = entry.file_name().to_str().unwrap()
                        .replace(|c| !char::is_alphanumeric(c), "_")
                        .replace("__", "_")
                        .to_lowercase();
                    writeln!(dst, "test_header!(header_{}, {:?});",
                             func, entry.path()).unwrap();
                }
                _ => {}
            }
        }

        dst.flush().unwrap();
    }
}

fn main() {
    codegen::main();
    testgen::main();
}
<|endoftext|>


<commit_before>use common::{R};
use monomial::Monomial;
use polynomial::{PolyOwning};
use dense_matrix::DenseMatrix;
use mesh::{Mesh, OShape, SideFace};
use wg_basis::{WGBasis, FaceMonNum};
use weak_gradient::{WeakGrad, WeakGradOps};
use projection::Projector;
use variational_bilinear_form::VariationalBilinearForm;

use std::vec;
use std::cast;
use std::iter::{AdditiveIterator};

/*  Definition
 *  a_s(v, w) = sum_T{ (a wgrad_T v, wgrad_T w)_T } + sum_T{ (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T) }
 *    for piecewise functions v and w on the mesh, where v_T0 and w_T0 are the extensions of the interior
 *    polynomials v|T0 and w|T0 on T0 to the boundary of T, and Q_b is per-side projection onto the span
 *    of basis elements supported on the boundary of T.
 */

struct VBFLaplace<Mon,MeshT> {

  left_wgrad_multiplier: Option<DenseMatrix>, // post-multiplier matrix for left weak gradient in inner product

  // TODO: Seems we should be able borrow mons from the basis without having to copy them, without introducing a lifetime param on the struct.
  int_mon_side_projs: ~[~[~[PolyOwning<Mon>]]], // indexed by fe oshape, side face, int mon num

  weak_grad_ops: WeakGradOps<Mon>,

  basis: ~WGBasis<Mon,MeshT>,

}

impl<Mon:Monomial, MeshT:Mesh<Mon>> VBFLaplace<Mon,MeshT> {

  pub fn new(left_wgrad_multiplier: Option<DenseMatrix>, basis: ~WGBasis<Mon,MeshT>) -> VBFLaplace<Mon,MeshT> {

    let int_mon_side_projs = {
      let mut projector = Projector::new(&*basis);
      vec::from_fn(basis.mesh().num_oriented_element_shapes(), |os| {
        vec::from_fn(basis.mesh().num_side_faces_for_oshape(OShape(os)), |sf| {
          projector.projs_int_mons_to_side_supp_approx_space(basis.ref_int_mons(), OShape(os), SideFace(sf))
        })
      })
    };

    let wgrad_ops = basis.new_weak_grad_ops();

    VBFLaplace {
      left_wgrad_multiplier: left_wgrad_multiplier,
      basis: basis,
      int_mon_side_projs: int_mon_side_projs,
      weak_grad_ops: wgrad_ops
    }
  }

  #[inline]
  fn ip_wgrads_term(&self, wgrad_1: &WeakGrad, wgrad_2: &WeakGrad, oshape: OShape) -> R {
    let wgrads_prod = unsafe {
      match self.left_wgrad_multiplier {
        Some(ref m) => cast::transmute_mut(self).weak_grad_ops.mdot(m, wgrad_1, wgrad_2),
        None => cast::transmute_mut(self).weak_grad_ops.dot(wgrad_1, wgrad_2)
      }
    };
    self.basis.mesh().intg_facerel_poly_on_oshape_int(&wgrads_prod, oshape)
  }

  pub fn left_wgrad_multiplier<'a>(&'a self) -> &'a Option<DenseMatrix> {
    &self.left_wgrad_multiplier
  }
}

impl<Mon:Monomial, MeshT:Mesh<Mon>> VariationalBilinearForm<Mon,MeshT>
                                for VBFLaplace<Mon,MeshT> {

  #[inline]
  fn basis<'a>(&'a self) -> &'a WGBasis<Mon,MeshT> {
    &*self.basis
  }

  #[inline]
  fn is_symmetric(&self) -> bool {
    self.left_wgrad_multiplier.is_none()
  }

  #[inline]
  fn int_mon_vs_int_mon(&self,
                        oshape: OShape,
                        monn_1: FaceMonNum,
                        monn_2: FaceMonNum) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.int_mon_wgrad(monn_1, oshape),
                                             basis.int_mon_wgrad(monn_2, oshape),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // The values of v and w on the boundary are 0, leaving only
    // s(v,w) = (1/h_T) <Q_b v_T0, Q_b w_T0>_bnd(T)
    //        = (1/h_T) sum_{s in sides(T)} {<Q_b v_T0, Q_b w_T0>_s}
    let h_inv = mesh.shape_diameter_inv(oshape);
    let stab_term = h_inv * range(0, mesh.num_side_faces_for_oshape(oshape)).map(|sf| {
      let projs = &self.int_mon_side_projs[*oshape][sf];
      mesh.intg_facerel_poly_x_facerel_poly_on_oshape_side(&projs[*monn_1], &projs[*monn_2], oshape, SideFace(sf))
    }).sum();

    ip_wgrads_term + stab_term
  }

  #[inline]
  fn side_mon_vs_int_mon(&self,
                         oshape: OShape,
                         side_monn: FaceMonNum, side_face: SideFace,
                         int_monn: FaceMonNum) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.side_mon_wgrad(side_monn, oshape, side_face),
                                             basis.int_mon_wgrad(int_monn, oshape),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // With v being our side supported basis element and w the interior supported element,
    // s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    //        = (1/h_T) <-v, Q_b w_T0>_bnd(T)
    //        = (1/h_T) <-v, Q_b w_T0>_s where s is the supporting side face of v
    let stab_term = {
      let side_mon = basis.side_mons_for_oshape_side(oshape, side_face)[*side_monn].clone();
      let int_proj = &self.int_mon_side_projs[*oshape][*side_face][*int_monn];
      let ip = -mesh.intg_facerel_mon_x_facerel_poly_on_oshape_side(side_mon, int_proj, oshape, side_face);
      let h_inv = mesh.shape_diameter_inv(oshape);
      h_inv * ip
    };

    ip_wgrads_term + stab_term
  }

  #[inline]
  fn int_mon_vs_side_mon(&self,
                         oshape: OShape,
                         int_monn: FaceMonNum,
                         side_monn: FaceMonNum, side_face: SideFace) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.int_mon_wgrad(int_monn, oshape),
                                             basis.side_mon_wgrad(side_monn, oshape, side_face),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // With v being our interior supported basis element and w the side supported element,
    // s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    //        = (1/h_T) <Q_b v_T0, -w>_bnd(T)
    //        = (1/h_T) <Q_b v_T0, -w>_s where s is the supporting side face of w
    let stab_term = {
      let side_mon = basis.side_mons_for_oshape_side(oshape, side_face)[*side_monn].clone();
      let int_proj = &self.int_mon_side_projs[*oshape][*side_face][*int_monn];
      let ip = -mesh.intg_facerel_mon_x_facerel_poly_on_oshape_side(side_mon, int_proj, oshape, side_face);
      let h_inv = mesh.shape_diameter_inv(oshape);
      h_inv * ip
    };

    ip_wgrads_term + stab_term
  }

  #[inline]
  fn side_mon_vs_side_mon_fe_contr(&self,
                                   oshape: OShape,
                                   monn_1: FaceMonNum, side_face_1: SideFace,
                                   monn_2: FaceMonNum, side_face_2: SideFace) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.side_mon_wgrad(monn_1, oshape, side_face_1),
                                             basis.side_mon_wgrad(monn_2, oshape, side_face_2),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // With v and w being our side supported elements, the projections of the interior extensions are 0, so
    // s(v,w) = (1/h_T) <-v, -w>_bnd(T)
    //        = (1/h_T) sum_{s in sides(T)} <v, w>_s
    //        = | (1/h_T) <v, w>_s,  if v and w have a common support side face s
    //          | 0, otherwise
    let stab_term =
      if side_face_1 != side_face_2 { 0 as R }
      else {
        let common_supp_side = side_face_1;
        let side_mons = basis.side_mons_for_oshape_side(oshape, common_supp_side);
        let ip = mesh.intg_facerel_mon_on_oshape_side(side_mons[*monn_1] * side_mons[*monn_2], oshape, common_supp_side);
        mesh.shape_diameter_inv(oshape) * ip
      };

    ip_wgrads_term + stab_term
  }
}

<commit_msg>Make VBFLaplace struct public.<commit_after>use common::{R};
use monomial::Monomial;
use polynomial::{PolyOwning};
use dense_matrix::DenseMatrix;
use mesh::{Mesh, OShape, SideFace};
use wg_basis::{WGBasis, FaceMonNum};
use weak_gradient::{WeakGrad, WeakGradOps};
use projection::Projector;
use variational_bilinear_form::VariationalBilinearForm;

use std::vec;
use std::cast;
use std::iter::{AdditiveIterator};

/*  Definition
 *  a_s(v, w) = sum_T{ (a wgrad_T v, wgrad_T w)_T } + sum_T{ (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T) }
 *    for piecewise functions v and w on the mesh, where v_T0 and w_T0 are the extensions of the interior
 *    polynomials v|T0 and w|T0 on T0 to the boundary of T, and Q_b is per-side projection onto the span
 *    of basis elements supported on the boundary of T.
 */

pub struct VBFLaplace<Mon,MeshT> {

  left_wgrad_multiplier: Option<DenseMatrix>, // post-multiplier matrix for left weak gradient in inner product

  // TODO: Seems we should be able borrow mons from the basis without having to copy them, without introducing a lifetime param on the struct.
  int_mon_side_projs: ~[~[~[PolyOwning<Mon>]]], // indexed by fe oshape, side face, int mon num

  weak_grad_ops: WeakGradOps<Mon>,

  basis: ~WGBasis<Mon,MeshT>,

}

impl<Mon:Monomial, MeshT:Mesh<Mon>> VBFLaplace<Mon,MeshT> {

  pub fn new(left_wgrad_multiplier: Option<DenseMatrix>, basis: ~WGBasis<Mon,MeshT>) -> VBFLaplace<Mon,MeshT> {

    let int_mon_side_projs = {
      let mut projector = Projector::new(&*basis);
      vec::from_fn(basis.mesh().num_oriented_element_shapes(), |os| {
        vec::from_fn(basis.mesh().num_side_faces_for_oshape(OShape(os)), |sf| {
          projector.projs_int_mons_to_side_supp_approx_space(basis.ref_int_mons(), OShape(os), SideFace(sf))
        })
      })
    };

    let wgrad_ops = basis.new_weak_grad_ops();

    VBFLaplace {
      left_wgrad_multiplier: left_wgrad_multiplier,
      basis: basis,
      int_mon_side_projs: int_mon_side_projs,
      weak_grad_ops: wgrad_ops
    }
  }

  #[inline]
  fn ip_wgrads_term(&self, wgrad_1: &WeakGrad, wgrad_2: &WeakGrad, oshape: OShape) -> R {
    let wgrads_prod = unsafe {
      match self.left_wgrad_multiplier {
        Some(ref m) => cast::transmute_mut(self).weak_grad_ops.mdot(m, wgrad_1, wgrad_2),
        None => cast::transmute_mut(self).weak_grad_ops.dot(wgrad_1, wgrad_2)
      }
    };
    self.basis.mesh().intg_facerel_poly_on_oshape_int(&wgrads_prod, oshape)
  }

  pub fn left_wgrad_multiplier<'a>(&'a self) -> &'a Option<DenseMatrix> {
    &self.left_wgrad_multiplier
  }
}

impl<Mon:Monomial, MeshT:Mesh<Mon>> VariationalBilinearForm<Mon,MeshT>
                                for VBFLaplace<Mon,MeshT> {

  #[inline]
  fn basis<'a>(&'a self) -> &'a WGBasis<Mon,MeshT> {
    &*self.basis
  }

  #[inline]
  fn is_symmetric(&self) -> bool {
    self.left_wgrad_multiplier.is_none()
  }

  #[inline]
  fn int_mon_vs_int_mon(&self,
                        oshape: OShape,
                        monn_1: FaceMonNum,
                        monn_2: FaceMonNum) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.int_mon_wgrad(monn_1, oshape),
                                             basis.int_mon_wgrad(monn_2, oshape),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // The values of v and w on the boundary are 0, leaving only
    // s(v,w) = (1/h_T) <Q_b v_T0, Q_b w_T0>_bnd(T)
    //        = (1/h_T) sum_{s in sides(T)} {<Q_b v_T0, Q_b w_T0>_s}
    let h_inv = mesh.shape_diameter_inv(oshape);
    let stab_term = h_inv * range(0, mesh.num_side_faces_for_oshape(oshape)).map(|sf| {
      let projs = &self.int_mon_side_projs[*oshape][sf];
      mesh.intg_facerel_poly_x_facerel_poly_on_oshape_side(&projs[*monn_1], &projs[*monn_2], oshape, SideFace(sf))
    }).sum();

    ip_wgrads_term + stab_term
  }

  #[inline]
  fn side_mon_vs_int_mon(&self,
                         oshape: OShape,
                         side_monn: FaceMonNum, side_face: SideFace,
                         int_monn: FaceMonNum) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.side_mon_wgrad(side_monn, oshape, side_face),
                                             basis.int_mon_wgrad(int_monn, oshape),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // With v being our side supported basis element and w the interior supported element,
    // s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    //        = (1/h_T) <-v, Q_b w_T0>_bnd(T)
    //        = (1/h_T) <-v, Q_b w_T0>_s where s is the supporting side face of v
    let stab_term = {
      let side_mon = basis.side_mons_for_oshape_side(oshape, side_face)[*side_monn].clone();
      let int_proj = &self.int_mon_side_projs[*oshape][*side_face][*int_monn];
      let ip = -mesh.intg_facerel_mon_x_facerel_poly_on_oshape_side(side_mon, int_proj, oshape, side_face);
      let h_inv = mesh.shape_diameter_inv(oshape);
      h_inv * ip
    };

    ip_wgrads_term + stab_term
  }

  #[inline]
  fn int_mon_vs_side_mon(&self,
                         oshape: OShape,
                         int_monn: FaceMonNum,
                         side_monn: FaceMonNum, side_face: SideFace) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.int_mon_wgrad(int_monn, oshape),
                                             basis.side_mon_wgrad(side_monn, oshape, side_face),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // With v being our interior supported basis element and w the side supported element,
    // s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    //        = (1/h_T) <Q_b v_T0, -w>_bnd(T)
    //        = (1/h_T) <Q_b v_T0, -w>_s where s is the supporting side face of w
    let stab_term = {
      let side_mon = basis.side_mons_for_oshape_side(oshape, side_face)[*side_monn].clone();
      let int_proj = &self.int_mon_side_projs[*oshape][*side_face][*int_monn];
      let ip = -mesh.intg_facerel_mon_x_facerel_poly_on_oshape_side(side_mon, int_proj, oshape, side_face);
      let h_inv = mesh.shape_diameter_inv(oshape);
      h_inv * ip
    };

    ip_wgrads_term + stab_term
  }

  #[inline]
  fn side_mon_vs_side_mon_fe_contr(&self,
                                   oshape: OShape,
                                   monn_1: FaceMonNum, side_face_1: SideFace,
                                   monn_2: FaceMonNum, side_face_2: SideFace) -> R {
    let (basis, mesh) = (self.basis(), self.basis().mesh());

    let ip_wgrads_term = self.ip_wgrads_term(basis.side_mon_wgrad(monn_1, oshape, side_face_1),
                                             basis.side_mon_wgrad(monn_2, oshape, side_face_2),
                                             oshape);

    // stabilization term: s(v,w) = (1/h_T) <Q_b v_T0 - v, Q_b w_T0 - w>_bnd(T)
    // With v and w being our side supported elements, the projections of the interior extensions are 0, so
    // s(v,w) = (1/h_T) <-v, -w>_bnd(T)
    //        = (1/h_T) sum_{s in sides(T)} <v, w>_s
    //        = | (1/h_T) <v, w>_s,  if v and w have a common support side face s
    //          | 0, otherwise
    let stab_term =
      if side_face_1 != side_face_2 { 0 as R }
      else {
        let common_supp_side = side_face_1;
        let side_mons = basis.side_mons_for_oshape_side(oshape, common_supp_side);
        let ip = mesh.intg_facerel_mon_on_oshape_side(side_mons[*monn_1] * side_mons[*monn_2], oshape, common_supp_side);
        mesh.shape_diameter_inv(oshape) * ip
      };

    ip_wgrads_term + stab_term
  }
}

<|endoftext|>


<commit_before>extern crate schannel;

use std::io;
use std::fmt;
use std::error;
use std::error::Error;
use std::sync::Arc;
use self::schannel::cert_store::{PfxImportOptions, Memory, CertStore, CertAdd};
use self::schannel::cert_context::CertContext;
use self::schannel::schannel_cred::{Direction, SchannelCred, Protocol};
use self::schannel::tls_stream;

fn convert_protocols(protocols: &[::Protocol]) -> Vec<Protocol> {
    protocols
        .iter()
        .map(|p| match *p {
            ::Protocol::Sslv3 => Protocol::Ssl3,
            ::Protocol::Tlsv10 => Protocol::Tls10,
            ::Protocol::Tlsv11 => Protocol::Tls11,
            ::Protocol::Tlsv12 => Protocol::Tls12,
            ::Protocol::__NonExhaustive => unreachable!(),
        })
        .collect()
}

pub struct Error(io::Error);

impl error::Error for Error {
    fn description(&self) -> &str {
        error::Error::description(&self.0)
    }

    fn cause(&self) -> Option<&error::Error> {
        error::Error::cause(&self.0)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, fmt)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Error {
        Error(error)
    }
}

pub struct Pkcs12 {
    cert: CertContext,
}

impl Pkcs12 {
    pub fn from_der(buf: &[u8], pass: &str) -> Result<Pkcs12, Error> {
        let mut store = try!(PfxImportOptions::new().password(pass).import(buf));
        let mut identity = None;

        for cert in store.certs() {
            if cert.private_key()
                .silent(true)
                .compare_key(true)
                .acquire()
                .is_ok()
            {
                identity = Some(cert);
            }
        }

        let identity = match identity {
            Some(identity) => identity,
            None => {
                return Err(
                    io::Error::new(
                        io::ErrorKind::InvalidInput,
                        "No identity found in PKCS #12 archive",
                    ).into(),
                );
            }
        };

        Ok(Pkcs12 { cert: identity })
    }
}

pub struct Certificate(CertContext);

impl Certificate {
    pub fn from_der(buf: &[u8]) -> Result<Certificate, Error> {
        let cert = try!(CertContext::new(buf));
        Ok(Certificate(cert))
    }
    pub fn from_pem(buf: &[u8]) -> Result<Certificate, Error> {
        match ::std::str::from_utf8(buf) {
            Ok(s) => {
                let cert = try!(CertContext::from_pem(s));
                Ok(Certificate(cert))
            }
            Err(_) => {
                Err(
                    io::Error::new(
                        io::ErrorKind::InvalidInput,
                        "PEM representation contains non-UTF-8 bytes",
                    ).into(),
                )
            }
        }
    }
}

pub struct MidHandshakeTlsStream<S>(tls_stream::MidHandshakeTlsStream<S>);

impl<S> fmt::Debug for MidHandshakeTlsStream<S>
where
    S: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl<S> MidHandshakeTlsStream<S>
where
    S: io::Read + io::Write,
{
    pub fn get_ref(&self) -> &S {
        self.0.get_ref()
    }

    pub fn get_mut(&mut self) -> &mut S {
        self.0.get_mut()
    }

    pub fn handshake(self) -> Result<TlsStream<S>, HandshakeError<S>> {
        match self.0.handshake() {
            Ok(s) => Ok(TlsStream(s)),
            Err(e) => Err(e.into()),
        }
    }
}

pub enum HandshakeError<S> {
    Failure(Error),
    Interrupted(MidHandshakeTlsStream<S>),
}

impl<S> From<tls_stream::HandshakeError<S>> for HandshakeError<S> {
    fn from(e: tls_stream::HandshakeError<S>) -> HandshakeError<S> {
        match e {
            tls_stream::HandshakeError::Failure(e) => HandshakeError::Failure(e.into()),
            tls_stream::HandshakeError::Interrupted(s) => {
                HandshakeError::Interrupted(MidHandshakeTlsStream(s))
            }
        }
    }
}

impl<S> From<io::Error> for HandshakeError<S> {
    fn from(e: io::Error) -> HandshakeError<S> {
        HandshakeError::Failure(e.into())
    }
}

pub struct TlsConnectorBuilder(TlsConnector);

impl TlsConnectorBuilder {
    pub fn identity(&mut self, pkcs12: Pkcs12) -> Result<(), Error> {
        self.0.cert = Some(pkcs12.cert);
        Ok(())
    }

    pub fn add_root_certificate(&mut self, cert: Certificate) -> Result<(), Error> {
        try!(self.0.roots.add_cert(&cert.0, CertAdd::ReplaceExisting));
        Ok(())
    }

    pub fn supported_protocols(&mut self, protocols: &[::Protocol]) -> Result<(), Error> {
        self.0.protocols = convert_protocols(protocols);
        Ok(())
    }

    pub fn build(self) -> Result<TlsConnector, Error> {
        Ok(self.0)
    }
}

#[derive(Clone)]
pub struct TlsConnector {
    cert: Option<CertContext>,
    roots: CertStore,
    protocols: Vec<Protocol>,
    callback: Option<Arc<Fn(tls_stream::CertValidationResult) -> io::Result<()> + Sync + Send>>,
}

impl TlsConnector {
    pub fn builder() -> Result<TlsConnectorBuilder, Error> {
        Ok(TlsConnectorBuilder(TlsConnector {
            cert: None,
            roots: try!(Memory::new()).into_store(),
            protocols: vec![Protocol::Tls10, Protocol::Tls11, Protocol::Tls12],
            callback: None,
        }))
    }

    pub fn connect<S>(&self, domain: &str, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        self._connect(Some(domain), stream)
    }

    pub fn connect_no_domain<S>(&self, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        self._connect(None, stream)
    }

    fn _connect<S>(
        &self,
        domain: Option<&str>,
        stream: S,
    ) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        let mut builder = SchannelCred::builder();
        builder.enabled_protocols(&self.protocols);
        if let Some(cert) = self.cert.as_ref() {
            builder.cert(cert.clone());
        }
        let cred = try!(builder.acquire(Direction::Outbound));
        let mut builder = tls_stream::Builder::new();
        if let Some(domain) = domain {
            builder.domain(domain);
        }
        if let Some(ref callback) = self.callback {
            let callback = callback.clone();
            builder.verify_callback(move |r| callback(r));
        }
        builder.cert_store(self.roots.clone());
        match builder.connect(cred, stream) {
            Ok(s) => Ok(TlsStream(s)),
            Err(e) => Err(e.into()),
        }
    }
}

pub struct TlsAcceptorBuilder(TlsAcceptor);

impl TlsAcceptorBuilder {
    pub fn supported_protocols(&mut self, protocols: &[::Protocol]) -> Result<(), Error> {
        self.0.protocols = convert_protocols(protocols);
        Ok(())
    }

    pub fn build(self) -> Result<TlsAcceptor, Error> {
        Ok(self.0)
    }
}

#[derive(Clone)]
pub struct TlsAcceptor {
    cert: CertContext,
    protocols: Vec<Protocol>,
}

impl TlsAcceptor {
    pub fn builder(pkcs12: Pkcs12) -> Result<TlsAcceptorBuilder, Error> {
        Ok(TlsAcceptorBuilder(TlsAcceptor {
            cert: pkcs12.cert,
            protocols: vec![Protocol::Tls10, Protocol::Tls11, Protocol::Tls12],
        }))
    }

    pub fn accept<S>(&self, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        let mut builder = SchannelCred::builder();
        builder.enabled_protocols(&self.protocols);
        builder.cert(self.cert.clone());
        // FIXME we're probably missing the certificate chain?
        let cred = try!(builder.acquire(Direction::Inbound));
        match tls_stream::Builder::new().accept(cred, stream) {
            Ok(s) => Ok(TlsStream(s)),
            Err(e) => Err(e.into()),
        }
    }
}

pub struct TlsStream<S>(tls_stream::TlsStream<S>);

impl<S: fmt::Debug> fmt::Debug for TlsStream<S> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl<S: io::Read + io::Write> TlsStream<S> {
    pub fn buffered_read_size(&self) -> Result<usize, Error> {
        Ok(self.0.get_buf().len())
    }

    pub fn shutdown(&mut self) -> io::Result<()> {
        try!(self.0.shutdown());
        Ok(())
    }

    pub fn get_ref(&self) -> &S {
        self.0.get_ref()
    }

    pub fn get_mut(&mut self) -> &mut S {
        self.0.get_mut()
    }
}

impl<S: io::Read + io::Write> io::Read for TlsStream<S> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

/// SChannel-specific extensions to `TlsConnectorBuilder`.
pub trait TlsConnectorBuilderExt {
    /// Sets a callback function which decides if the server's certificate chain
    /// is to be trusted.
    fn verify_callback<F>(&mut self, callback: F)
    where
        F: Fn(tls_stream::CertValidationResult) -> io::Result<()> + 'static + Send + Sync;
}

impl TlsConnectorBuilderExt for ::TlsConnectorBuilder {
    fn verify_callback<F>(&mut self, callback: F)
    where
        F: Fn(tls_stream::CertValidationResult) -> io::Result<()> + 'static + Send + Sync,
    {
        (self.0).0.callback = Some(Arc::new(callback));
    }
}

/// SChannel-specific extensions to `TlsStream`.
pub trait TlsStreamExt<S> {
    /// Returns a shared reference to the SChannel `TlsStream`.
    fn raw_stream(&self) -> &tls_stream::TlsStream<S>;

    /// Returns a mutable reference to the SChannel `TlsStream`.
    fn raw_stream_mut(&mut self) -> &mut tls_stream::TlsStream<S>;
}

impl<S> TlsStreamExt<S> for ::TlsStream<S> {
    fn raw_stream(&self) -> &tls_stream::TlsStream<S> {
        &(self.0).0
    }

    fn raw_stream_mut(&mut self) -> &mut tls_stream::TlsStream<S> {
        &mut (self.0).0
    }
}

/// SChannel-specific extensions to `Error`
pub trait ErrorExt {
    /// Extract the underlying SChannel error for inspection.
    fn schannel_error(&self) -> &io::Error;
}

impl ErrorExt for ::Error {
    fn schannel_error(&self) -> &io::Error {
        &(self.0).0
    }
}

/// SChannel-specific extensions to `Certificate`.
pub trait CertificateExt {
    /// builds a native_Tls `Certificate` from an schannel `CertContext`
    fn from_cert_context(CertContext) -> ::Certificate;
}

impl CertificateExt for ::Certificate {
    fn from_cert_context(cert: CertContext) -> ::Certificate {
        ::Certificate(Certificate(cert))
    }
}
<commit_msg>Remove import<commit_after>extern crate schannel;

use std::io;
use std::fmt;
use std::error;
use std::sync::Arc;
use self::schannel::cert_store::{PfxImportOptions, Memory, CertStore, CertAdd};
use self::schannel::cert_context::CertContext;
use self::schannel::schannel_cred::{Direction, SchannelCred, Protocol};
use self::schannel::tls_stream;

fn convert_protocols(protocols: &[::Protocol]) -> Vec<Protocol> {
    protocols
        .iter()
        .map(|p| match *p {
            ::Protocol::Sslv3 => Protocol::Ssl3,
            ::Protocol::Tlsv10 => Protocol::Tls10,
            ::Protocol::Tlsv11 => Protocol::Tls11,
            ::Protocol::Tlsv12 => Protocol::Tls12,
            ::Protocol::__NonExhaustive => unreachable!(),
        })
        .collect()
}

pub struct Error(io::Error);

impl error::Error for Error {
    fn description(&self) -> &str {
        error::Error::description(&self.0)
    }

    fn cause(&self) -> Option<&error::Error> {
        error::Error::cause(&self.0)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, fmt)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Error {
        Error(error)
    }
}

pub struct Pkcs12 {
    cert: CertContext,
}

impl Pkcs12 {
    pub fn from_der(buf: &[u8], pass: &str) -> Result<Pkcs12, Error> {
        let mut store = try!(PfxImportOptions::new().password(pass).import(buf));
        let mut identity = None;

        for cert in store.certs() {
            if cert.private_key()
                .silent(true)
                .compare_key(true)
                .acquire()
                .is_ok()
            {
                identity = Some(cert);
            }
        }

        let identity = match identity {
            Some(identity) => identity,
            None => {
                return Err(
                    io::Error::new(
                        io::ErrorKind::InvalidInput,
                        "No identity found in PKCS #12 archive",
                    ).into(),
                );
            }
        };

        Ok(Pkcs12 { cert: identity })
    }
}

pub struct Certificate(CertContext);

impl Certificate {
    pub fn from_der(buf: &[u8]) -> Result<Certificate, Error> {
        let cert = try!(CertContext::new(buf));
        Ok(Certificate(cert))
    }
    pub fn from_pem(buf: &[u8]) -> Result<Certificate, Error> {
        match ::std::str::from_utf8(buf) {
            Ok(s) => {
                let cert = try!(CertContext::from_pem(s));
                Ok(Certificate(cert))
            }
            Err(_) => {
                Err(
                    io::Error::new(
                        io::ErrorKind::InvalidInput,
                        "PEM representation contains non-UTF-8 bytes",
                    ).into(),
                )
            }
        }
    }
}

pub struct MidHandshakeTlsStream<S>(tls_stream::MidHandshakeTlsStream<S>);

impl<S> fmt::Debug for MidHandshakeTlsStream<S>
where
    S: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl<S> MidHandshakeTlsStream<S>
where
    S: io::Read + io::Write,
{
    pub fn get_ref(&self) -> &S {
        self.0.get_ref()
    }

    pub fn get_mut(&mut self) -> &mut S {
        self.0.get_mut()
    }

    pub fn handshake(self) -> Result<TlsStream<S>, HandshakeError<S>> {
        match self.0.handshake() {
            Ok(s) => Ok(TlsStream(s)),
            Err(e) => Err(e.into()),
        }
    }
}

pub enum HandshakeError<S> {
    Failure(Error),
    Interrupted(MidHandshakeTlsStream<S>),
}

impl<S> From<tls_stream::HandshakeError<S>> for HandshakeError<S> {
    fn from(e: tls_stream::HandshakeError<S>) -> HandshakeError<S> {
        match e {
            tls_stream::HandshakeError::Failure(e) => HandshakeError::Failure(e.into()),
            tls_stream::HandshakeError::Interrupted(s) => {
                HandshakeError::Interrupted(MidHandshakeTlsStream(s))
            }
        }
    }
}

impl<S> From<io::Error> for HandshakeError<S> {
    fn from(e: io::Error) -> HandshakeError<S> {
        HandshakeError::Failure(e.into())
    }
}

pub struct TlsConnectorBuilder(TlsConnector);

impl TlsConnectorBuilder {
    pub fn identity(&mut self, pkcs12: Pkcs12) -> Result<(), Error> {
        self.0.cert = Some(pkcs12.cert);
        Ok(())
    }

    pub fn add_root_certificate(&mut self, cert: Certificate) -> Result<(), Error> {
        try!(self.0.roots.add_cert(&cert.0, CertAdd::ReplaceExisting));
        Ok(())
    }

    pub fn supported_protocols(&mut self, protocols: &[::Protocol]) -> Result<(), Error> {
        self.0.protocols = convert_protocols(protocols);
        Ok(())
    }

    pub fn build(self) -> Result<TlsConnector, Error> {
        Ok(self.0)
    }
}

#[derive(Clone)]
pub struct TlsConnector {
    cert: Option<CertContext>,
    roots: CertStore,
    protocols: Vec<Protocol>,
    callback: Option<Arc<Fn(tls_stream::CertValidationResult) -> io::Result<()> + Sync + Send>>,
}

impl TlsConnector {
    pub fn builder() -> Result<TlsConnectorBuilder, Error> {
        Ok(TlsConnectorBuilder(TlsConnector {
            cert: None,
            roots: try!(Memory::new()).into_store(),
            protocols: vec![Protocol::Tls10, Protocol::Tls11, Protocol::Tls12],
            callback: None,
        }))
    }

    pub fn connect<S>(&self, domain: &str, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        self._connect(Some(domain), stream)
    }

    pub fn connect_no_domain<S>(&self, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        self._connect(None, stream)
    }

    fn _connect<S>(
        &self,
        domain: Option<&str>,
        stream: S,
    ) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        let mut builder = SchannelCred::builder();
        builder.enabled_protocols(&self.protocols);
        if let Some(cert) = self.cert.as_ref() {
            builder.cert(cert.clone());
        }
        let cred = try!(builder.acquire(Direction::Outbound));
        let mut builder = tls_stream::Builder::new();
        if let Some(domain) = domain {
            builder.domain(domain);
        }
        if let Some(ref callback) = self.callback {
            let callback = callback.clone();
            builder.verify_callback(move |r| callback(r));
        }
        builder.cert_store(self.roots.clone());
        match builder.connect(cred, stream) {
            Ok(s) => Ok(TlsStream(s)),
            Err(e) => Err(e.into()),
        }
    }
}

pub struct TlsAcceptorBuilder(TlsAcceptor);

impl TlsAcceptorBuilder {
    pub fn supported_protocols(&mut self, protocols: &[::Protocol]) -> Result<(), Error> {
        self.0.protocols = convert_protocols(protocols);
        Ok(())
    }

    pub fn build(self) -> Result<TlsAcceptor, Error> {
        Ok(self.0)
    }
}

#[derive(Clone)]
pub struct TlsAcceptor {
    cert: CertContext,
    protocols: Vec<Protocol>,
}

impl TlsAcceptor {
    pub fn builder(pkcs12: Pkcs12) -> Result<TlsAcceptorBuilder, Error> {
        Ok(TlsAcceptorBuilder(TlsAcceptor {
            cert: pkcs12.cert,
            protocols: vec![Protocol::Tls10, Protocol::Tls11, Protocol::Tls12],
        }))
    }

    pub fn accept<S>(&self, stream: S) -> Result<TlsStream<S>, HandshakeError<S>>
    where
        S: io::Read + io::Write,
    {
        let mut builder = SchannelCred::builder();
        builder.enabled_protocols(&self.protocols);
        builder.cert(self.cert.clone());
        // FIXME we're probably missing the certificate chain?
        let cred = try!(builder.acquire(Direction::Inbound));
        match tls_stream::Builder::new().accept(cred, stream) {
            Ok(s) => Ok(TlsStream(s)),
            Err(e) => Err(e.into()),
        }
    }
}

pub struct TlsStream<S>(tls_stream::TlsStream<S>);

impl<S: fmt::Debug> fmt::Debug for TlsStream<S> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl<S: io::Read + io::Write> TlsStream<S> {
    pub fn buffered_read_size(&self) -> Result<usize, Error> {
        Ok(self.0.get_buf().len())
    }

    pub fn shutdown(&mut self) -> io::Result<()> {
        try!(self.0.shutdown());
        Ok(())
    }

    pub fn get_ref(&self) -> &S {
        self.0.get_ref()
    }

    pub fn get_mut(&mut self) -> &mut S {
        self.0.get_mut()
    }
}

impl<S: io::Read + io::Write> io::Read for TlsStream<S> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

/// SChannel-specific extensions to `TlsConnectorBuilder`.
pub trait TlsConnectorBuilderExt {
    /// Sets a callback function which decides if the server's certificate chain
    /// is to be trusted.
    fn verify_callback<F>(&mut self, callback: F)
    where
        F: Fn(tls_stream::CertValidationResult) -> io::Result<()> + 'static + Send + Sync;
}

impl TlsConnectorBuilderExt for ::TlsConnectorBuilder {
    fn verify_callback<F>(&mut self, callback: F)
    where
        F: Fn(tls_stream::CertValidationResult) -> io::Result<()> + 'static + Send + Sync,
    {
        (self.0).0.callback = Some(Arc::new(callback));
    }
}

/// SChannel-specific extensions to `TlsStream`.
pub trait TlsStreamExt<S> {
    /// Returns a shared reference to the SChannel `TlsStream`.
    fn raw_stream(&self) -> &tls_stream::TlsStream<S>;

    /// Returns a mutable reference to the SChannel `TlsStream`.
    fn raw_stream_mut(&mut self) -> &mut tls_stream::TlsStream<S>;
}

impl<S> TlsStreamExt<S> for ::TlsStream<S> {
    fn raw_stream(&self) -> &tls_stream::TlsStream<S> {
        &(self.0).0
    }

    fn raw_stream_mut(&mut self) -> &mut tls_stream::TlsStream<S> {
        &mut (self.0).0
    }
}

/// SChannel-specific extensions to `Error`
pub trait ErrorExt {
    /// Extract the underlying SChannel error for inspection.
    fn schannel_error(&self) -> &io::Error;
}

impl ErrorExt for ::Error {
    fn schannel_error(&self) -> &io::Error {
        &(self.0).0
    }
}

/// SChannel-specific extensions to `Certificate`.
pub trait CertificateExt {
    /// builds a native_Tls `Certificate` from an schannel `CertContext`
    fn from_cert_context(CertContext) -> ::Certificate;
}

impl CertificateExt for ::Certificate {
    fn from_cert_context(cert: CertContext) -> ::Certificate {
        ::Certificate(Certificate(cert))
    }
}
<|endoftext|>