<commit_before>#![deny(bare_trait_objects)]

mod compiler;
mod decls;
mod error;
mod function;
mod heap;
mod load;
mod module;
mod name;
mod output;
mod patch;
mod pointer;
mod runtime;
pub mod signature;
mod sparsedata;
mod stack_probe;
mod table;
mod traps;
mod types;

use crate::load::read_bytes;
pub use crate::{
    compiler::{Compiler, CompilerBuilder, CpuFeatures, OptLevel, SpecificFeature, TargetCpu},
    error::Error,
    heap::HeapSettings,
    load::read_module,
    patch::patch_module,
};
pub use lucet_module::bindings::Bindings;
pub use lucet_validate::Validator;
use signature::{PublicKey, SecretKey};
use std::env;
use std::path::{Path, PathBuf};
use target_lexicon::Triple;

enum LucetcInput {
    Bytes(Vec<u8>),
    Path(PathBuf),
}

pub struct Lucetc {
    input: LucetcInput,
    bindings: Vec<Bindings>,
    builtins_paths: Vec<PathBuf>,
    builder: CompilerBuilder,
    sk: Option<SecretKey>,
    pk: Option<PublicKey>,
    sign: bool,
    verify: bool,
}

pub trait AsLucetc {
    fn as_lucetc(&mut self) -> &mut Lucetc;
}

impl AsLucetc for Lucetc {
    fn as_lucetc(&mut self) -> &mut Lucetc {
        self
    }
}

pub trait LucetcOpts {
    fn bindings(&mut self, bindings: Bindings);
    fn with_bindings(self, bindings: Bindings) -> Self;

    fn target(&mut self, target: Triple);
    fn with_target(self, target: Triple) -> Self;

    fn opt_level(&mut self, opt_level: OptLevel);
    fn with_opt_level(self, opt_level: OptLevel) -> Self;

    fn cpu_features(&mut self, cpu_features: CpuFeatures);
    fn with_cpu_features(self, cpu_features: CpuFeatures) -> Self;

    fn builtins<P: AsRef<Path>>(&mut self, builtins_path: P);
    fn with_builtins<P: AsRef<Path>>(self, builtins_path: P) -> Self;

    fn validator(&mut self, validator: Validator);
    fn with_validator(self, validator: Validator) -> Self;

    fn min_reserved_size(&mut self, min_reserved_size: u64);
    fn with_min_reserved_size(self, min_reserved_size: u64) -> Self;

    fn max_reserved_size(&mut self, max_reserved_size: u64);
    fn with_max_reserved_size(self, max_reserved_size: u64) -> Self;

    /// Set the reserved size exactly.
    ///
    /// Equivalent to setting the minimum and maximum reserved sizes to the same value.
    fn reserved_size(&mut self, reserved_size: u64);
    /// Set the reserved size exactly.
    ///
    /// Equivalent to setting the minimum and maximum reserved sizes to the same value.
    fn with_reserved_size(self, reserved_size: u64) -> Self;

    fn guard_size(&mut self, guard_size: u64);
    fn with_guard_size(self, guard_size: u64) -> Self;

    fn pk(&mut self, pk: PublicKey);
    fn with_pk(self, pk: PublicKey) -> Self;
    fn sk(&mut self, sk: SecretKey);
    fn with_sk(self, sk: SecretKey) -> Self;
    fn verify(&mut self);
    fn with_verify(self) -> Self;
    fn sign(&mut self);
    fn with_sign(self) -> Self;
    fn count_instructions(&mut self, enable_count: bool);
    fn with_count_instructions(self, enable_count: bool) -> Self;
    fn canonicalize_nans(&mut self, enable_canonicalize_nans: bool);
    fn with_canonicalize_nans(self, enable_canonicalize_nans: bool) -> Self;
}

impl<T: AsLucetc> LucetcOpts for T {
    fn bindings(&mut self, bindings: Bindings) {
        self.as_lucetc().bindings.push(bindings);
    }

    fn with_bindings(mut self, bindings: Bindings) -> Self {
        self.bindings(bindings);
        self
    }

    fn target(&mut self, target: Triple) {
        self.as_lucetc().builder.target(target);
    }

    fn with_target(mut self, target: Triple) -> Self {
        self.target(target);
        self
    }

    fn opt_level(&mut self, opt_level: OptLevel) {
        self.as_lucetc().builder.opt_level(opt_level);
    }

    fn with_opt_level(mut self, opt_level: OptLevel) -> Self {
        self.opt_level(opt_level);
        self
    }

    fn cpu_features(&mut self, cpu_features: CpuFeatures) {
        self.as_lucetc().builder.cpu_features(cpu_features);
    }

    fn with_cpu_features(mut self, cpu_features: CpuFeatures) -> Self {
        self.cpu_features(cpu_features);
        self
    }

    fn builtins<P: AsRef<Path>>(&mut self, builtins_path: P) {
        self.as_lucetc()
            .builtins_paths
            .push(builtins_path.as_ref().to_owned());
    }

    fn with_builtins<P: AsRef<Path>>(mut self, builtins_path: P) -> Self {
        self.builtins(builtins_path);
        self
    }

    fn validator(&mut self, validator: Validator) {
        self.as_lucetc().builder.validator(Some(validator));
    }

    fn with_validator(mut self, validator: Validator) -> Self {
        self.validator(validator);
        self
    }

    fn min_reserved_size(&mut self, min_reserved_size: u64) {
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .min_reserved_size = min_reserved_size;
    }

    fn with_min_reserved_size(mut self, min_reserved_size: u64) -> Self {
        self.min_reserved_size(min_reserved_size);
        self
    }

    fn max_reserved_size(&mut self, max_reserved_size: u64) {
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .max_reserved_size = max_reserved_size;
    }

    fn with_max_reserved_size(mut self, max_reserved_size: u64) -> Self {
        self.max_reserved_size(max_reserved_size);
        self
    }

    fn reserved_size(&mut self, reserved_size: u64) {
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .min_reserved_size = reserved_size;
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .max_reserved_size = reserved_size;
    }

    fn with_reserved_size(mut self, reserved_size: u64) -> Self {
        self.reserved_size(reserved_size);
        self
    }

    fn guard_size(&mut self, guard_size: u64) {
        self.as_lucetc().builder.heap_settings_mut().guard_size = guard_size;
    }

    fn with_guard_size(mut self, guard_size: u64) -> Self {
        self.guard_size(guard_size);
        self
    }

    fn pk(&mut self, pk: PublicKey) {
        self.as_lucetc().pk = Some(pk);
    }

    fn with_pk(mut self, pk: PublicKey) -> Self {
        self.pk(pk);
        self
    }

    fn sk(&mut self, sk: SecretKey) {
        self.as_lucetc().sk = Some(sk);
    }

    fn with_sk(mut self, sk: SecretKey) -> Self {
        self.sk(sk);
        self
    }

    fn verify(&mut self) {
        self.as_lucetc().verify = true;
    }

    fn with_verify(mut self) -> Self {
        self.verify();
        self
    }

    fn sign(&mut self) {
        self.as_lucetc().sign = true;
    }

    fn with_sign(mut self) -> Self {
        self.sign();
        self
    }

    fn count_instructions(&mut self, count_instructions: bool) {
        self.as_lucetc()
            .builder
            .count_instructions(count_instructions);
    }

    fn with_count_instructions(mut self, count_instructions: bool) -> Self {
        self.count_instructions(count_instructions);
        self
    }

    fn canonicalize_nans(&mut self, enable_nans_canonicalization: bool) {
        self.as_lucetc()
            .builder
            .canonicalize_nans(enable_nans_canonicalization);
    }

    fn with_canonicalize_nans(mut self, enable_nans_canonicalization: bool) -> Self {
        self.canonicalize_nans(enable_nans_canonicalization);
        self
    }
}

impl Lucetc {
    pub fn new<P: AsRef<Path>>(input: P) -> Self {
        let input = input.as_ref();
        Self {
            input: LucetcInput::Path(input.to_owned()),
            bindings: vec![],
            builder: Compiler::builder(),
            builtins_paths: vec![],
            pk: None,
            sk: None,
            sign: false,
            verify: false,
        }
    }

    pub fn try_from_bytes<B: AsRef<[u8]>>(bytes: B) -> Result<Self, Error> {
        let input = read_bytes(bytes.as_ref().to_vec())?;
        Ok(Self {
            input: LucetcInput::Bytes(input),
            bindings: vec![],
            builder: Compiler::builder(),
            builtins_paths: vec![],
            pk: None,
            sk: None,
            sign: false,
            verify: false,
        })
    }

    fn build(&self) -> Result<(Vec<u8>, Bindings), Error> {
        use parity_wasm::elements::{deserialize_buffer, serialize};

        let mut builtins_bindings = vec![];
        let mut module_binary = match &self.input {
            LucetcInput::Bytes(bytes) => bytes.clone(),
            LucetcInput::Path(path) => read_module(&path, &self.pk, self.verify)?,
        };

        if !self.builtins_paths.is_empty() {
            let mut module = deserialize_buffer(&module_binary)?;
            for builtins in self.builtins_paths.iter() {
                let (newmodule, builtins_map) = patch_module(module, builtins)?;
                module = newmodule;
                builtins_bindings.push(Bindings::env(builtins_map));
            }
            module_binary = serialize(module)?;
        }

        let mut bindings = Bindings::empty();

        for binding in builtins_bindings.iter().chain(self.bindings.iter()) {
            bindings.extend(binding)?;
        }

        Ok((module_binary, bindings))
    }

    pub fn object_file<P: AsRef<Path>>(&self, output: P) -> Result<(), Error> {
        let (module_contents, bindings) = self.build()?;
        let compiler = self.builder.create(&module_contents, &bindings)?;
        let obj = compiler.object_file()?;
        obj.write(output.as_ref())?;

        Ok(())
    }

    pub fn clif_ir<P: AsRef<Path>>(&self, output: P) -> Result<(), Error> {
        let (module_contents, bindings) = self.build()?;

        let compiler = self.builder.create(&module_contents, &bindings)?;

        compiler.cranelift_funcs()?.write(&output)?;

        Ok(())
    }

    pub fn shared_object_file<P: AsRef<Path>>(&self, output: P) -> Result<(), Error> {
        let dir = tempfile::Builder::new().prefix("lucetc").tempdir()?;
        let objpath = dir.path().join("tmp.o");
        self.object_file(objpath.clone())?;
        link_so(objpath, self.builder.target_ref(), &output)?;
        if self.sign {
            let sk = self.sk.as_ref().ok_or(Error::Signature(
                "signing requires a secret key".to_string(),
            ))?;
            signature::sign_module(&output, sk)?;
        }
        Ok(())
    }
}

const LD_DEFAULT: &str = "ld";

fn link_so<P, Q>(objpath: P, target: &Triple, sopath: Q) -> Result<(), Error>
where
    P: AsRef<Path>,
    Q: AsRef<Path>,
{
    use std::process::Command;

    // Let `LD` be something like "clang --target=... ..." for convenience.
    let env_ld = env::var("LD").unwrap_or(LD_DEFAULT.into());
    let mut ld_iter = env_ld.split_whitespace();
    let ld_prog = ld_iter.next().expect("LD must not be empty");
    let mut cmd_ld = Command::new(ld_prog);
    for flag in ld_iter {
        cmd_ld.arg(flag);
    }

    cmd_ld.arg(objpath.as_ref());
    let env_ldflags = env::var("LDFLAGS").unwrap_or_else(|_| ldflags_default(target));
    for flag in env_ldflags.split_whitespace() {
        cmd_ld.arg(flag);
    }
    cmd_ld.arg("-o");
    cmd_ld.arg(sopath.as_ref());

    let run_ld = cmd_ld.output()?;

    if !run_ld.status.success() {
        let message = format!(
            "ld of {} failed: {}",
            objpath.as_ref().to_str().unwrap(),
            String::from_utf8_lossy(&run_ld.stderr)
        );
        return Err(Error::LdError(message));
    }
    Ok(())
}

fn ldflags_default(target: &Triple) -> String {
    use target_lexicon::OperatingSystem;

    match target.operating_system {
        OperatingSystem::Linux => "-shared",
        OperatingSystem::Darwin | OperatingSystem::MacOSX { .. } => {
            "-dylib -dead_strip -export_dynamic -undefined dynamic_lookup"
        }
        _ => panic!(
            "Cannot determine default flags for {}.

Please define the LDFLAGS environment variable with the necessary command-line
flags for generating shared libraries.",
            Triple::host()
        ),
    }
    .into()
}
<commit_msg>fix linker output argument for windows<commit_after>#![deny(bare_trait_objects)]

mod compiler;
mod decls;
mod error;
mod function;
mod heap;
mod load;
mod module;
mod name;
mod output;
mod patch;
mod pointer;
mod runtime;
pub mod signature;
mod sparsedata;
mod stack_probe;
mod table;
mod traps;
mod types;

use crate::load::read_bytes;
pub use crate::{
    compiler::{Compiler, CompilerBuilder, CpuFeatures, OptLevel, SpecificFeature, TargetCpu},
    error::Error,
    heap::HeapSettings,
    load::read_module,
    patch::patch_module,
};
pub use lucet_module::bindings::Bindings;
pub use lucet_validate::Validator;
use signature::{PublicKey, SecretKey};
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
use target_lexicon::Triple;

enum LucetcInput {
    Bytes(Vec<u8>),
    Path(PathBuf),
}

pub struct Lucetc {
    input: LucetcInput,
    bindings: Vec<Bindings>,
    builtins_paths: Vec<PathBuf>,
    builder: CompilerBuilder,
    sk: Option<SecretKey>,
    pk: Option<PublicKey>,
    sign: bool,
    verify: bool,
}

pub trait AsLucetc {
    fn as_lucetc(&mut self) -> &mut Lucetc;
}

impl AsLucetc for Lucetc {
    fn as_lucetc(&mut self) -> &mut Lucetc {
        self
    }
}

pub trait LucetcOpts {
    fn bindings(&mut self, bindings: Bindings);
    fn with_bindings(self, bindings: Bindings) -> Self;

    fn target(&mut self, target: Triple);
    fn with_target(self, target: Triple) -> Self;

    fn opt_level(&mut self, opt_level: OptLevel);
    fn with_opt_level(self, opt_level: OptLevel) -> Self;

    fn cpu_features(&mut self, cpu_features: CpuFeatures);
    fn with_cpu_features(self, cpu_features: CpuFeatures) -> Self;

    fn builtins<P: AsRef<Path>>(&mut self, builtins_path: P);
    fn with_builtins<P: AsRef<Path>>(self, builtins_path: P) -> Self;

    fn validator(&mut self, validator: Validator);
    fn with_validator(self, validator: Validator) -> Self;

    fn min_reserved_size(&mut self, min_reserved_size: u64);
    fn with_min_reserved_size(self, min_reserved_size: u64) -> Self;

    fn max_reserved_size(&mut self, max_reserved_size: u64);
    fn with_max_reserved_size(self, max_reserved_size: u64) -> Self;

    /// Set the reserved size exactly.
    ///
    /// Equivalent to setting the minimum and maximum reserved sizes to the same value.
    fn reserved_size(&mut self, reserved_size: u64);
    /// Set the reserved size exactly.
    ///
    /// Equivalent to setting the minimum and maximum reserved sizes to the same value.
    fn with_reserved_size(self, reserved_size: u64) -> Self;

    fn guard_size(&mut self, guard_size: u64);
    fn with_guard_size(self, guard_size: u64) -> Self;

    fn pk(&mut self, pk: PublicKey);
    fn with_pk(self, pk: PublicKey) -> Self;
    fn sk(&mut self, sk: SecretKey);
    fn with_sk(self, sk: SecretKey) -> Self;
    fn verify(&mut self);
    fn with_verify(self) -> Self;
    fn sign(&mut self);
    fn with_sign(self) -> Self;
    fn count_instructions(&mut self, enable_count: bool);
    fn with_count_instructions(self, enable_count: bool) -> Self;
    fn canonicalize_nans(&mut self, enable_canonicalize_nans: bool);
    fn with_canonicalize_nans(self, enable_canonicalize_nans: bool) -> Self;
}

impl<T: AsLucetc> LucetcOpts for T {
    fn bindings(&mut self, bindings: Bindings) {
        self.as_lucetc().bindings.push(bindings);
    }

    fn with_bindings(mut self, bindings: Bindings) -> Self {
        self.bindings(bindings);
        self
    }

    fn target(&mut self, target: Triple) {
        self.as_lucetc().builder.target(target);
    }

    fn with_target(mut self, target: Triple) -> Self {
        self.target(target);
        self
    }

    fn opt_level(&mut self, opt_level: OptLevel) {
        self.as_lucetc().builder.opt_level(opt_level);
    }

    fn with_opt_level(mut self, opt_level: OptLevel) -> Self {
        self.opt_level(opt_level);
        self
    }

    fn cpu_features(&mut self, cpu_features: CpuFeatures) {
        self.as_lucetc().builder.cpu_features(cpu_features);
    }

    fn with_cpu_features(mut self, cpu_features: CpuFeatures) -> Self {
        self.cpu_features(cpu_features);
        self
    }

    fn builtins<P: AsRef<Path>>(&mut self, builtins_path: P) {
        self.as_lucetc()
            .builtins_paths
            .push(builtins_path.as_ref().to_owned());
    }

    fn with_builtins<P: AsRef<Path>>(mut self, builtins_path: P) -> Self {
        self.builtins(builtins_path);
        self
    }

    fn validator(&mut self, validator: Validator) {
        self.as_lucetc().builder.validator(Some(validator));
    }

    fn with_validator(mut self, validator: Validator) -> Self {
        self.validator(validator);
        self
    }

    fn min_reserved_size(&mut self, min_reserved_size: u64) {
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .min_reserved_size = min_reserved_size;
    }

    fn with_min_reserved_size(mut self, min_reserved_size: u64) -> Self {
        self.min_reserved_size(min_reserved_size);
        self
    }

    fn max_reserved_size(&mut self, max_reserved_size: u64) {
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .max_reserved_size = max_reserved_size;
    }

    fn with_max_reserved_size(mut self, max_reserved_size: u64) -> Self {
        self.max_reserved_size(max_reserved_size);
        self
    }

    fn reserved_size(&mut self, reserved_size: u64) {
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .min_reserved_size = reserved_size;
        self.as_lucetc()
            .builder
            .heap_settings_mut()
            .max_reserved_size = reserved_size;
    }

    fn with_reserved_size(mut self, reserved_size: u64) -> Self {
        self.reserved_size(reserved_size);
        self
    }

    fn guard_size(&mut self, guard_size: u64) {
        self.as_lucetc().builder.heap_settings_mut().guard_size = guard_size;
    }

    fn with_guard_size(mut self, guard_size: u64) -> Self {
        self.guard_size(guard_size);
        self
    }

    fn pk(&mut self, pk: PublicKey) {
        self.as_lucetc().pk = Some(pk);
    }

    fn with_pk(mut self, pk: PublicKey) -> Self {
        self.pk(pk);
        self
    }

    fn sk(&mut self, sk: SecretKey) {
        self.as_lucetc().sk = Some(sk);
    }

    fn with_sk(mut self, sk: SecretKey) -> Self {
        self.sk(sk);
        self
    }

    fn verify(&mut self) {
        self.as_lucetc().verify = true;
    }

    fn with_verify(mut self) -> Self {
        self.verify();
        self
    }

    fn sign(&mut self) {
        self.as_lucetc().sign = true;
    }

    fn with_sign(mut self) -> Self {
        self.sign();
        self
    }

    fn count_instructions(&mut self, count_instructions: bool) {
        self.as_lucetc()
            .builder
            .count_instructions(count_instructions);
    }

    fn with_count_instructions(mut self, count_instructions: bool) -> Self {
        self.count_instructions(count_instructions);
        self
    }

    fn canonicalize_nans(&mut self, enable_nans_canonicalization: bool) {
        self.as_lucetc()
            .builder
            .canonicalize_nans(enable_nans_canonicalization);
    }

    fn with_canonicalize_nans(mut self, enable_nans_canonicalization: bool) -> Self {
        self.canonicalize_nans(enable_nans_canonicalization);
        self
    }
}

impl Lucetc {
    pub fn new<P: AsRef<Path>>(input: P) -> Self {
        let input = input.as_ref();
        Self {
            input: LucetcInput::Path(input.to_owned()),
            bindings: vec![],
            builder: Compiler::builder(),
            builtins_paths: vec![],
            pk: None,
            sk: None,
            sign: false,
            verify: false,
        }
    }

    pub fn try_from_bytes<B: AsRef<[u8]>>(bytes: B) -> Result<Self, Error> {
        let input = read_bytes(bytes.as_ref().to_vec())?;
        Ok(Self {
            input: LucetcInput::Bytes(input),
            bindings: vec![],
            builder: Compiler::builder(),
            builtins_paths: vec![],
            pk: None,
            sk: None,
            sign: false,
            verify: false,
        })
    }

    fn build(&self) -> Result<(Vec<u8>, Bindings), Error> {
        use parity_wasm::elements::{deserialize_buffer, serialize};

        let mut builtins_bindings = vec![];
        let mut module_binary = match &self.input {
            LucetcInput::Bytes(bytes) => bytes.clone(),
            LucetcInput::Path(path) => read_module(&path, &self.pk, self.verify)?,
        };

        if !self.builtins_paths.is_empty() {
            let mut module = deserialize_buffer(&module_binary)?;
            for builtins in self.builtins_paths.iter() {
                let (newmodule, builtins_map) = patch_module(module, builtins)?;
                module = newmodule;
                builtins_bindings.push(Bindings::env(builtins_map));
            }
            module_binary = serialize(module)?;
        }

        let mut bindings = Bindings::empty();

        for binding in builtins_bindings.iter().chain(self.bindings.iter()) {
            bindings.extend(binding)?;
        }

        Ok((module_binary, bindings))
    }

    pub fn object_file<P: AsRef<Path>>(&self, output: P) -> Result<(), Error> {
        let (module_contents, bindings) = self.build()?;
        let compiler = self.builder.create(&module_contents, &bindings)?;
        let obj = compiler.object_file()?;
        obj.write(output.as_ref())?;

        Ok(())
    }

    pub fn clif_ir<P: AsRef<Path>>(&self, output: P) -> Result<(), Error> {
        let (module_contents, bindings) = self.build()?;

        let compiler = self.builder.create(&module_contents, &bindings)?;

        compiler.cranelift_funcs()?.write(&output)?;

        Ok(())
    }

    pub fn shared_object_file<P: AsRef<Path>>(&self, output: P) -> Result<(), Error> {
        let dir = tempfile::Builder::new().prefix("lucetc").tempdir()?;
        let objpath = dir.path().join("tmp.o");
        self.object_file(objpath.clone())?;
        link_so(objpath, self.builder.target_ref(), &output)?;
        if self.sign {
            let sk = self.sk.as_ref().ok_or(Error::Signature(
                "signing requires a secret key".to_string(),
            ))?;
            signature::sign_module(&output, sk)?;
        }
        Ok(())
    }
}

const LD_DEFAULT: &str = "ld";

fn link_so<P, Q>(objpath: P, target: &Triple, sopath: Q) -> Result<(), Error>
where
    P: AsRef<Path>,
    Q: AsRef<Path>,
{
    // Let `LD` be something like "clang --target=... ..." for convenience.
    let env_ld = env::var("LD").unwrap_or(LD_DEFAULT.into());
    let mut ld_iter = env_ld.split_whitespace();
    let ld_prog = ld_iter.next().expect("LD must not be empty");
    let mut cmd_ld = Command::new(ld_prog);
    for flag in ld_iter {
        cmd_ld.arg(flag);
    }

    cmd_ld.arg(objpath.as_ref());
    let env_ldflags = env::var("LDFLAGS").unwrap_or_else(|_| ldflags_default(target));
    for flag in env_ldflags.split_whitespace() {
        cmd_ld.arg(flag);
    }

    output_arg_for(&mut cmd_ld, target, sopath);

    let run_ld = cmd_ld.output()?;

    if !run_ld.status.success() {
        let message = format!(
            "ld of {} failed: {}",
            objpath.as_ref().to_str().unwrap(),
            String::from_utf8_lossy(&run_ld.stderr)
        );
        return Err(Error::LdError(message));
    }
    Ok(())
}

fn output_arg_for<P>(cmd_ld: &mut Command, target: &Triple, sopath: P)
where
    P: AsRef<Path>,
{
    use target_lexicon::{Environment, OperatingSystem};

    if target.operating_system != OperatingSystem::Windows || target.environment == Environment::Gnu
    {
        cmd_ld.arg("-o");
        cmd_ld.arg(sopath.as_ref());
        return;
    }

    assert!(target.environment == Environment::Msvc);

    cmd_ld.arg(format!("/out:{:?}", sopath.as_ref()));
}

fn ldflags_default(target: &Triple) -> String {
    use target_lexicon::OperatingSystem;

    match target.operating_system {
        OperatingSystem::Linux => "-shared",
        OperatingSystem::Darwin | OperatingSystem::MacOSX { .. } => {
            "-dylib -dead_strip -export_dynamic -undefined dynamic_lookup"
        }
        _ => panic!(
            "Cannot determine default flags for {}.

Please define the LDFLAGS environment variable with the necessary command-line
flags for generating shared libraries.",
            Triple::host()
        ),
    }
    .into()
}
<|endoftext|>


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

#![unstable(feature = "collections_range", reason = "was just added",
            issue = "27711")]

//! Range syntax.

use core::option::Option::{self, None, Some};
use core::ops::{RangeFull, Range, RangeTo, RangeFrom};

/// **RangeArgument** is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
pub trait RangeArgument<T> {
    /// Start index (inclusive)
    ///
    /// Return start value if present, else `None`.
    fn start(&self) -> Option<&T> {
        None
    }

    /// End index (exclusive)
    ///
    /// Return end value if present, else `None`.
    fn end(&self) -> Option<&T> {
        None
    }
}

impl<T> RangeArgument<T> for RangeFull {}

impl<T> RangeArgument<T> for RangeFrom<T> {
    fn start(&self) -> Option<&T> {
        Some(&self.start)
    }
}

impl<T> RangeArgument<T> for RangeTo<T> {
    fn end(&self) -> Option<&T> {
        Some(&self.end)
    }
}

impl<T> RangeArgument<T> for Range<T> {
    fn start(&self) -> Option<&T> {
        Some(&self.start)
    }
    fn end(&self) -> Option<&T> {
        Some(&self.end)
    }
}
<commit_msg>Rollup merge of #30879 - durka:collections-range-tracking-issue, r=nagisa<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![unstable(feature = "collections_range",
            reason = "waiting for dust to settle on inclusive ranges",
            issue = "30877")]

//! Range syntax.

use core::option::Option::{self, None, Some};
use core::ops::{RangeFull, Range, RangeTo, RangeFrom};

/// **RangeArgument** is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
pub trait RangeArgument<T> {
    /// Start index (inclusive)
    ///
    /// Return start value if present, else `None`.
    fn start(&self) -> Option<&T> {
        None
    }

    /// End index (exclusive)
    ///
    /// Return end value if present, else `None`.
    fn end(&self) -> Option<&T> {
        None
    }
}

impl<T> RangeArgument<T> for RangeFull {}

impl<T> RangeArgument<T> for RangeFrom<T> {
    fn start(&self) -> Option<&T> {
        Some(&self.start)
    }
}

impl<T> RangeArgument<T> for RangeTo<T> {
    fn end(&self) -> Option<&T> {
        Some(&self.end)
    }
}

impl<T> RangeArgument<T> for Range<T> {
    fn start(&self) -> Option<&T> {
        Some(&self.start)
    }
    fn end(&self) -> Option<&T> {
        Some(&self.end)
    }
}
<|endoftext|>


<commit_before>use crate::ffi::CStr;
use crate::io;
use crate::ffi::OsString;
use crate::marker::PhantomData;
use crate::os::wasi::ffi::OsStringExt;
use crate::vec;

pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
}

pub unsafe fn cleanup() {
}

pub struct Args {
    iter: vec::IntoIter<OsString>,
    _dont_send_or_sync_me: PhantomData<*mut ()>,
}

/// Returns the command line arguments
pub fn args() -> Args {
    let mut buf = Vec::new();
    let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec())));
    Args {
        iter: buf.into_iter(),
        _dont_send_or_sync_me: PhantomData
    }
}

impl Args {
    pub fn inner_debug(&self) -> &[OsString] {
        self.iter.as_slice()
    }
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> {
        self.iter.next()
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize {
        self.iter.len()
    }
}

impl DoubleEndedIterator for Args {
    fn next_back(&mut self) -> Option<OsString> {
        self.iter.next_back()
    }
}
<commit_msg>update args<commit_after>use crate::ffi::CStr;
use crate::io;
use crate::ffi::OsString;
use crate::marker::PhantomData;
use crate::os::wasi::ffi::OsStringExt;
use crate::vec;

pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
}

pub unsafe fn cleanup() {
}

pub struct Args {
    iter: vec::IntoIter<OsString>,
    _dont_send_or_sync_me: PhantomData<*mut ()>,
}

/// Returns the command line arguments
pub fn args() -> Args {
    let buf = wasi::args_sizes_get().and_then(|args_sizes| {
        let mut buf = Vec::with_capacity(args_sizes.get_count());
        wasi::get_args(args_sizes, |arg| {
            let arg = OsString::from_vec(arg.to_vec());
            buf.push(arg);
        })?;
        Ok(buf)
    }).unwrap_or(vec![]);
    Args {
        iter: buf.into_iter(),
        _dont_send_or_sync_me: PhantomData
    }
}

impl Args {
    pub fn inner_debug(&self) -> &[OsString] {
        self.iter.as_slice()
    }
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> {
        self.iter.next()
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize {
        self.iter.len()
    }
}

impl DoubleEndedIterator for Args {
    fn next_back(&mut self) -> Option<OsString> {
        self.iter.next_back()
    }
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 native Rust implementation of [Apache Arrow](https://arrow.apache.org), a cross-language
//! development platform for in-memory data.
//!
//! ### DataType
//!
//! Every [`Array`](array::Array) in this crate has an associated [`DataType`](datatypes::DataType),
//! that specifies how its data is layed in memory and represented.
//! Thus, a central enum of this crate is [`DataType`](datatypes::DataType), that contains the set of valid
//! DataTypes in the specification. For example, [`DataType::Utf8`](datatypes::DataType::Utf8).
//!
//! ## Array
//!
//! The central trait of this package is the dynamically-typed [`Array`](array::Array) that
//! represents a fixed-sized, immutable, Send + Sync Array of nullable elements. An example of such an array is [`UInt32Array`](array::UInt32Array).
//! One way to think about an arrow [`Array`](array::Array) is a `Arc<[Option<T>; len]>` where T can be anything ranging from an integer to a string, or even
//! another [`Array`](array::Array).
//!
//! [`Arrays`](array::Array) have [`len()`](array::Array::len), [`data_type()`](array::Array::data_type), and the nullability of each of its elements,
//! can be obtained via [`is_null(index)`](array::Array::is_null). To downcast an [`Array`](array::Array) to a specific implementation, you can use
//!
//! ```rust
//! use arrow::array::{Array, UInt32Array};
//! let array = UInt32Array::from(vec![Some(1), None, Some(3)]);
//! assert_eq!(array.len(), 3);
//! assert_eq!(array.value(0), 1);
//! assert_eq!(array.is_null(1), true);
//! ```
//!
//! To make the array dynamically typed, we wrap it in an [`Arc`](std::sync::Arc):
//!
//! ```rust
//! # use std::sync::Arc;
//! use arrow::datatypes::DataType;
//! use arrow::array::{UInt32Array, ArrayRef};
//! # let array = UInt32Array::from(vec![Some(1), None, Some(3)]);
//! let array: ArrayRef = Arc::new(array);
//! assert_eq!(array.len(), 3);
//! // array.value() is not available in the dynamically-typed version
//! assert_eq!(array.is_null(1), true);
//! assert_eq!(array.data_type(), &DataType::UInt32);
//! ```
//!
//! to downcast, use `as_any()`:
//!
//! ```rust
//! # use std::sync::Arc;
//! # use arrow::array::{UInt32Array, ArrayRef};
//! # let array = UInt32Array::from(vec![Some(1), None, Some(3)]);
//! # let array: ArrayRef = Arc::new(array);
//! let array = array.as_any().downcast_ref::<UInt32Array>().unwrap();
//! assert_eq!(array.value(0), 1);
//! ```
//!
//! ## Memory and Buffers
//!
//! Data in [`Array`](array::Array) is stored in [`ArrayData`](array::ArrayData), that in turn
//! is a collection of other [`ArrayData`](array::ArrayData) and [`Buffers`](buffer::Buffer).
//! [`Buffers`](buffer::Buffer) is the central struct that array implementations use keep allocated memory and pointers.
//! The [`MutableBuffer`](buffer::MutableBuffer) is the mutable counter-part of[`Buffer`](buffer::Buffer).
//! These are the lowest abstractions of this crate, and are used throughout the crate to
//! efficiently allocate, write, read and deallocate memory.
//!
//! ## Field, Schema and RecordBatch
//!
//! [`Field`](datatypes::Field) is a struct that contains an array's metadata (datatype and whether its values
//! can be null), and a name. [`Schema`](datatypes::Schema) is a vector of fields with optional metadata.
//! Together, they form the basis of a schematic representation of a group of [`Arrays`](array::Array).
//!
//! In fact, [`RecordBatch`](record_batch::RecordBatch) is a struct with a [`Schema`](datatypes::Schema) and a vector of
//! [`Array`](array::Array)s, all with the same `len`. A record batch is the highest order struct that this crate currently offers
//! and is broadly used to represent a table where each column in an `Array`.
//!
//! ## Compute
//!
//! This crate offers many operations (called kernels) to operate on `Array`s, that you can find at [compute::kernels].
//! It has both vertical and horizontal operations, and some of them have an SIMD implementation.
//!
//! ## Status
//!
//! This crate has most of the implementation of the arrow specification. Specifically, it supports the following types:
//!
//! * All arrow primitive types, such as [`Int32Array`](array::UInt8Array), [`BooleanArray`](array::BooleanArray) and [`Float64Array`](array::Float64Array).
//! * All arrow variable length types, such as [`StringArray`](array::StringArray) and [`BinaryArray`](array::BinaryArray)
//! * All composite types such as [`StructArray`](array::StructArray) and [`ListArray`](array::ListArray)
//! * Dictionary types  [`DictionaryArray`](array::DictionaryArray)

//!
//! This crate also implements many common vertical operations:
//! * all mathematical binary operators, such as [`subtract`](compute::kernels::arithmetic::subtract)
//! * all boolean binary operators such as [`equality`](compute::kernels::comparison::eq)
//! * [`cast`](compute::kernels::cast::cast)
//! * [`filter`](compute::kernels::filter::filter)
//! * [`take`](compute::kernels::take::take) and [`limit`](compute::kernels::limit::limit)
//! * [`sort`](compute::kernels::sort::sort)
//! * some string operators such as [`substring`](compute::kernels::substring::substring) and [`length`](compute::kernels::length::length)
//!
//! as well as some horizontal operations, such as
//!
//! * [`min`](compute::kernels::aggregate::min) and [`max`](compute::kernels::aggregate::max)
//! * [`sum`](compute::kernels::aggregate::sum)
//!
//! Finally, this crate implements some readers and writers to different formats:
//!
//! * json: [reader](json::reader::Reader)
//! * csv: [reader](csv::reader::Reader) and [writer](csv::writer::Writer)
//! * ipc: [reader](ipc::reader::StreamReader) and [writer](ipc::writer::FileWriter)
//!
//! The parquet implementation is on a [separate crate](https://crates.io/crates/parquet)

#![cfg_attr(feature = "avx512", feature(stdsimd))]
#![cfg_attr(feature = "avx512", feature(repr_simd))]
#![cfg_attr(feature = "avx512", feature(avx512_target_feature))]
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(bare_trait_objects)]
#![warn(missing_debug_implementations)]
#![deny(clippy::redundant_clone)]
// introduced to ignore lint errors when upgrading from 2020-04-22 to 2020-11-14
#![allow(clippy::float_equality_without_abs, clippy::type_complexity)]

mod arch;
pub mod array;
pub mod bitmap;
pub mod buffer;
mod bytes;
pub mod compute;
pub mod csv;
pub mod datatypes;
pub mod error;
pub mod ffi;
pub mod ipc;
pub mod json;
mod memory;
pub mod record_batch;
pub mod tensor;
pub mod util;
mod zz_memory_check;
<commit_msg>ARROW-11322: [Rust] Re-opening `memory` module as public<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 native Rust implementation of [Apache Arrow](https://arrow.apache.org), a cross-language
//! development platform for in-memory data.
//!
//! ### DataType
//!
//! Every [`Array`](array::Array) in this crate has an associated [`DataType`](datatypes::DataType),
//! that specifies how its data is layed in memory and represented.
//! Thus, a central enum of this crate is [`DataType`](datatypes::DataType), that contains the set of valid
//! DataTypes in the specification. For example, [`DataType::Utf8`](datatypes::DataType::Utf8).
//!
//! ## Array
//!
//! The central trait of this package is the dynamically-typed [`Array`](array::Array) that
//! represents a fixed-sized, immutable, Send + Sync Array of nullable elements. An example of such an array is [`UInt32Array`](array::UInt32Array).
//! One way to think about an arrow [`Array`](array::Array) is a `Arc<[Option<T>; len]>` where T can be anything ranging from an integer to a string, or even
//! another [`Array`](array::Array).
//!
//! [`Arrays`](array::Array) have [`len()`](array::Array::len), [`data_type()`](array::Array::data_type), and the nullability of each of its elements,
//! can be obtained via [`is_null(index)`](array::Array::is_null). To downcast an [`Array`](array::Array) to a specific implementation, you can use
//!
//! ```rust
//! use arrow::array::{Array, UInt32Array};
//! let array = UInt32Array::from(vec![Some(1), None, Some(3)]);
//! assert_eq!(array.len(), 3);
//! assert_eq!(array.value(0), 1);
//! assert_eq!(array.is_null(1), true);
//! ```
//!
//! To make the array dynamically typed, we wrap it in an [`Arc`](std::sync::Arc):
//!
//! ```rust
//! # use std::sync::Arc;
//! use arrow::datatypes::DataType;
//! use arrow::array::{UInt32Array, ArrayRef};
//! # let array = UInt32Array::from(vec![Some(1), None, Some(3)]);
//! let array: ArrayRef = Arc::new(array);
//! assert_eq!(array.len(), 3);
//! // array.value() is not available in the dynamically-typed version
//! assert_eq!(array.is_null(1), true);
//! assert_eq!(array.data_type(), &DataType::UInt32);
//! ```
//!
//! to downcast, use `as_any()`:
//!
//! ```rust
//! # use std::sync::Arc;
//! # use arrow::array::{UInt32Array, ArrayRef};
//! # let array = UInt32Array::from(vec![Some(1), None, Some(3)]);
//! # let array: ArrayRef = Arc::new(array);
//! let array = array.as_any().downcast_ref::<UInt32Array>().unwrap();
//! assert_eq!(array.value(0), 1);
//! ```
//!
//! ## Memory and Buffers
//!
//! Data in [`Array`](array::Array) is stored in [`ArrayData`](array::ArrayData), that in turn
//! is a collection of other [`ArrayData`](array::ArrayData) and [`Buffers`](buffer::Buffer).
//! [`Buffers`](buffer::Buffer) is the central struct that array implementations use keep allocated memory and pointers.
//! The [`MutableBuffer`](buffer::MutableBuffer) is the mutable counter-part of[`Buffer`](buffer::Buffer).
//! These are the lowest abstractions of this crate, and are used throughout the crate to
//! efficiently allocate, write, read and deallocate memory.
//!
//! ## Field, Schema and RecordBatch
//!
//! [`Field`](datatypes::Field) is a struct that contains an array's metadata (datatype and whether its values
//! can be null), and a name. [`Schema`](datatypes::Schema) is a vector of fields with optional metadata.
//! Together, they form the basis of a schematic representation of a group of [`Arrays`](array::Array).
//!
//! In fact, [`RecordBatch`](record_batch::RecordBatch) is a struct with a [`Schema`](datatypes::Schema) and a vector of
//! [`Array`](array::Array)s, all with the same `len`. A record batch is the highest order struct that this crate currently offers
//! and is broadly used to represent a table where each column in an `Array`.
//!
//! ## Compute
//!
//! This crate offers many operations (called kernels) to operate on `Array`s, that you can find at [compute::kernels].
//! It has both vertical and horizontal operations, and some of them have an SIMD implementation.
//!
//! ## Status
//!
//! This crate has most of the implementation of the arrow specification. Specifically, it supports the following types:
//!
//! * All arrow primitive types, such as [`Int32Array`](array::UInt8Array), [`BooleanArray`](array::BooleanArray) and [`Float64Array`](array::Float64Array).
//! * All arrow variable length types, such as [`StringArray`](array::StringArray) and [`BinaryArray`](array::BinaryArray)
//! * All composite types such as [`StructArray`](array::StructArray) and [`ListArray`](array::ListArray)
//! * Dictionary types  [`DictionaryArray`](array::DictionaryArray)

//!
//! This crate also implements many common vertical operations:
//! * all mathematical binary operators, such as [`subtract`](compute::kernels::arithmetic::subtract)
//! * all boolean binary operators such as [`equality`](compute::kernels::comparison::eq)
//! * [`cast`](compute::kernels::cast::cast)
//! * [`filter`](compute::kernels::filter::filter)
//! * [`take`](compute::kernels::take::take) and [`limit`](compute::kernels::limit::limit)
//! * [`sort`](compute::kernels::sort::sort)
//! * some string operators such as [`substring`](compute::kernels::substring::substring) and [`length`](compute::kernels::length::length)
//!
//! as well as some horizontal operations, such as
//!
//! * [`min`](compute::kernels::aggregate::min) and [`max`](compute::kernels::aggregate::max)
//! * [`sum`](compute::kernels::aggregate::sum)
//!
//! Finally, this crate implements some readers and writers to different formats:
//!
//! * json: [reader](json::reader::Reader)
//! * csv: [reader](csv::reader::Reader) and [writer](csv::writer::Writer)
//! * ipc: [reader](ipc::reader::StreamReader) and [writer](ipc::writer::FileWriter)
//!
//! The parquet implementation is on a [separate crate](https://crates.io/crates/parquet)

#![cfg_attr(feature = "avx512", feature(stdsimd))]
#![cfg_attr(feature = "avx512", feature(repr_simd))]
#![cfg_attr(feature = "avx512", feature(avx512_target_feature))]
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(bare_trait_objects)]
#![warn(missing_debug_implementations)]
#![deny(clippy::redundant_clone)]
// introduced to ignore lint errors when upgrading from 2020-04-22 to 2020-11-14
#![allow(clippy::float_equality_without_abs, clippy::type_complexity)]

mod arch;
pub mod array;
pub mod bitmap;
pub mod buffer;
mod bytes;
pub mod compute;
pub mod csv;
pub mod datatypes;
pub mod error;
pub mod ffi;
pub mod ipc;
pub mod json;
pub mod memory;
pub mod record_batch;
pub mod tensor;
pub mod util;
mod zz_memory_check;
<|endoftext|>


<commit_before>// Copyright 2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::mem;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;

use futures_core;
use futures_core::executor::{Executor, SpawnError};
use futures_core::task::{LocalMap, UnsafeWake, Waker};
use futures_core::{Async, Future, Never};
use futures_executor;
use futures_util::future::FutureExt;

use MainContext;
use MainLoop;
use Source;
use Priority;

use ::translate::{from_glib_none, from_glib_full, mut_override, ToGlib};
use ffi as glib_ffi;

// We can't use an enum here because we want to store this in an atomic variable
const INIT: usize = 0;
const NOT_READY: usize = 1;
const READY: usize = 2;
const DONE: usize = 3;

#[repr(C)]
struct TaskSource {
    source: glib_ffi::GSource,
    future: Option<(Box<Future<Item = (), Error = Never>>, Box<LocalMap>)>,
    thread: Option<thread::ThreadId>,
    state: AtomicUsize,
}

unsafe impl UnsafeWake for TaskSource {
    unsafe fn clone_raw(&self) -> Waker {
        Waker::new(glib_ffi::g_source_ref(mut_override(&self.source)) as *const TaskSource)
    }

    unsafe fn drop_raw(&self) {
        glib_ffi::g_source_unref(mut_override(&self.source));
    }

    unsafe fn wake(&self) {
        if self.state
            .compare_and_swap(NOT_READY, READY, Ordering::SeqCst) == READY
        {
            glib_ffi::g_source_set_ready_time(mut_override(&self.source), 0);
        }
    }
}

unsafe extern "C" fn prepare(
    source: *mut glib_ffi::GSource,
    timeout: *mut i32,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    *timeout = -1;

    let mut cur = source
        .state
        .compare_and_swap(INIT, NOT_READY, Ordering::SeqCst);
    if cur == INIT {
        // XXX: This is not actually correct, we should not dispatch the
        // GSource here already but we need to know its current status so
        // that if it is not ready yet something can register to the waker
        if let Async::Ready(_) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn check(source: *mut glib_ffi::GSource) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    let cur = source.state.load(Ordering::SeqCst);
    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn dispatch(
    source: *mut glib_ffi::GSource,
    callback: glib_ffi::GSourceFunc,
    _user_data: glib_ffi::gpointer,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);
    assert!(callback.is_none());

    glib_ffi::g_source_set_ready_time(mut_override(&source.source), -1);
    let mut cur = source
        .state
        .compare_and_swap(READY, NOT_READY, Ordering::SeqCst);
    if cur == READY {
        if let Async::Ready(_) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == DONE {
        glib_ffi::G_SOURCE_REMOVE
    } else {
        glib_ffi::G_SOURCE_CONTINUE
    }
}

unsafe extern "C" fn finalize(source: *mut glib_ffi::GSource) {
    let source = source as *mut TaskSource;
    let _ = (*source).future.take();
}

static SOURCE_FUNCS: glib_ffi::GSourceFuncs = glib_ffi::GSourceFuncs {
    check: Some(check),
    prepare: Some(prepare),
    dispatch: Some(dispatch),
    finalize: Some(finalize),
    closure_callback: None,
    closure_marshal: None,
};

impl TaskSource {
    fn new(
        priority: Priority,
        future: Box<Future<Item = (), Error = Never> + 'static + Send>,
    ) -> Source {
        unsafe { Self::new_unsafe(priority, None, future) }
    }

    // NOTE: This does not have the Send bound and requires to be called from the same
    // thread where the main context is running
    unsafe fn new_unsafe(
        priority: Priority,
        thread: Option<thread::ThreadId>,
        future: Box<Future<Item = (), Error = Never> + 'static>,
    ) -> Source {
        let source = glib_ffi::g_source_new(
            mut_override(&SOURCE_FUNCS),
            mem::size_of::<TaskSource>() as u32,
        );
        {
            let source = &mut *(source as *mut TaskSource);
            source.future = Some((future, Box::new(LocalMap::new())));
            source.thread = thread;
            source.state = AtomicUsize::new(INIT);
        }

        glib_ffi::g_source_set_priority(source, priority.to_glib());

        from_glib_full(source)
    }

    fn poll(&mut self) -> Async<()> {
        // Make sure that the first time we're polled that the current thread is remembered
        // and from there one we ensure that we're always polled from exactly the same thread.
        //
        // In theory a GMainContext can be first run from one thread and later from another
        // thread, but we allow spawning non-Send futures and must not ever use them from
        // any other thread.
        match &mut self.thread {
            thread @ &mut None => {
                *thread = Some(thread::current().id());
            }
            &mut Some(thread_id) => {
                assert_eq!(thread::current().id(), thread_id);
            }
        }

        let waker = unsafe { self.clone_raw() };
        let source = &self.source as *const _;
        if let Some(ref mut future) = self.future {
            let (ref mut future, ref mut local_map) = *future;

            let mut executor: MainContext = unsafe {
                from_glib_none(glib_ffi::g_source_get_context(mut_override(source)))
            };

            // Clone that we store in the task local data so that
            // it can be retrieved as needed
            executor.push_thread_default();

            let res = {
                let enter = futures_executor::enter().unwrap();
                let mut context =
                    futures_core::task::Context::new(local_map, &waker, &mut executor);

                let res = future.poll(&mut context).unwrap_or(Async::Ready(()));

                drop(enter);

                res
            };

            executor.pop_thread_default();
            res
        } else {
            Async::Ready(())
        }
    }
}

impl MainContext {
    pub fn spawn<F: Future<Item = (), Error = Never> + Send + 'static>(&mut self, f: F) {
        self.spawn_with_priority(::PRIORITY_DEFAULT, f);
    }

    pub fn spawn_local<F: Future<Item = (), Error = Never> + 'static>(&mut self, f: F) {
        self.spawn_local_with_priority(::PRIORITY_DEFAULT, f);
    }

    pub fn spawn_with_priority<F: Future<Item = (), Error = Never> + Send + 'static>(&mut self, priority: Priority, f: F) {
        let source = TaskSource::new(priority, Box::new(f));
        source.attach(Some(&*self));
    }

    pub fn spawn_local_with_priority<F: Future<Item = (), Error = Never> + 'static>(&mut self, priority: Priority, f: F) {
        assert!(self.is_owner());
        unsafe {
            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            let source = TaskSource::new_unsafe(priority, Some(thread::current().id()), Box::new(f));
            source.attach(Some(&*self));
        }
    }

    pub fn block_on<F: Future>(&mut self, f: F) -> Result<F::Item, F::Error> {
        let mut res = None;
        let l = MainLoop::new(Some(&*self), false);
        let l_clone = l.clone();

        let source = unsafe {
            let future = f.then(|r| {
                res = Some(r);
                l_clone.quit();
                Ok::<(), Never>(())
            });

            let future: *mut Future<Item = (), Error = Never> = Box::into_raw(Box::new(future));
            // XXX: Transmute to get a 'static lifetime here, super unsafe
            let future: *mut (Future<Item = (), Error = Never> + 'static) = mem::transmute(future);
            let future: Box<Future<Item = (), Error = Never> + 'static> = Box::from_raw(future);

            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            TaskSource::new_unsafe(::PRIORITY_DEFAULT, Some(thread::current().id()), future)
        };

        source.attach(Some(&*self));

        l.run();

        res.unwrap()
    }
}

impl Executor for MainContext {
    fn spawn(&mut self, f: Box<Future<Item = (), Error = Never> + Send>) -> Result<(), SpawnError> {
        let source = TaskSource::new(::PRIORITY_DEFAULT, f);
        source.attach(Some(&*self));
        Ok(())
    }
}

<commit_msg>Add various tests for the MainContext futures executor<commit_after>// Copyright 2018, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::mem;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;

use futures_core;
use futures_core::executor::{Executor, SpawnError};
use futures_core::task::{LocalMap, UnsafeWake, Waker};
use futures_core::{Async, Future, Never};
use futures_executor;
use futures_util::future::FutureExt;

use MainContext;
use MainLoop;
use Source;
use Priority;

use ::translate::{from_glib_none, from_glib_full, mut_override, ToGlib};
use ffi as glib_ffi;

// We can't use an enum here because we want to store this in an atomic variable
const INIT: usize = 0;
const NOT_READY: usize = 1;
const READY: usize = 2;
const DONE: usize = 3;

#[repr(C)]
struct TaskSource {
    source: glib_ffi::GSource,
    future: Option<(Box<Future<Item = (), Error = Never>>, Box<LocalMap>)>,
    thread: Option<thread::ThreadId>,
    state: AtomicUsize,
}

unsafe impl UnsafeWake for TaskSource {
    unsafe fn clone_raw(&self) -> Waker {
        Waker::new(glib_ffi::g_source_ref(mut_override(&self.source)) as *const TaskSource)
    }

    unsafe fn drop_raw(&self) {
        glib_ffi::g_source_unref(mut_override(&self.source));
    }

    unsafe fn wake(&self) {
        if self.state
            .compare_and_swap(NOT_READY, READY, Ordering::SeqCst) == READY
        {
            glib_ffi::g_source_set_ready_time(mut_override(&self.source), 0);
        }
    }
}

unsafe extern "C" fn prepare(
    source: *mut glib_ffi::GSource,
    timeout: *mut i32,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    *timeout = -1;

    let mut cur = source
        .state
        .compare_and_swap(INIT, NOT_READY, Ordering::SeqCst);
    if cur == INIT {
        // XXX: This is not actually correct, we should not dispatch the
        // GSource here already but we need to know its current status so
        // that if it is not ready yet something can register to the waker
        if let Async::Ready(_) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn check(source: *mut glib_ffi::GSource) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);

    let cur = source.state.load(Ordering::SeqCst);
    if cur == READY || cur == DONE {
        glib_ffi::GTRUE
    } else {
        glib_ffi::GFALSE
    }
}

unsafe extern "C" fn dispatch(
    source: *mut glib_ffi::GSource,
    callback: glib_ffi::GSourceFunc,
    _user_data: glib_ffi::gpointer,
) -> glib_ffi::gboolean {
    let source = &mut *(source as *mut TaskSource);
    assert!(callback.is_none());

    glib_ffi::g_source_set_ready_time(mut_override(&source.source), -1);
    let mut cur = source
        .state
        .compare_and_swap(READY, NOT_READY, Ordering::SeqCst);
    if cur == READY {
        if let Async::Ready(_) = source.poll() {
            source.state.store(DONE, Ordering::SeqCst);
            cur = DONE;
        } else {
            cur = NOT_READY;
        }
    }

    if cur == DONE {
        glib_ffi::G_SOURCE_REMOVE
    } else {
        glib_ffi::G_SOURCE_CONTINUE
    }
}

unsafe extern "C" fn finalize(source: *mut glib_ffi::GSource) {
    let source = source as *mut TaskSource;
    let _ = (*source).future.take();
}

static SOURCE_FUNCS: glib_ffi::GSourceFuncs = glib_ffi::GSourceFuncs {
    check: Some(check),
    prepare: Some(prepare),
    dispatch: Some(dispatch),
    finalize: Some(finalize),
    closure_callback: None,
    closure_marshal: None,
};

impl TaskSource {
    fn new(
        priority: Priority,
        future: Box<Future<Item = (), Error = Never> + 'static + Send>,
    ) -> Source {
        unsafe { Self::new_unsafe(priority, None, future) }
    }

    // NOTE: This does not have the Send bound and requires to be called from the same
    // thread where the main context is running
    unsafe fn new_unsafe(
        priority: Priority,
        thread: Option<thread::ThreadId>,
        future: Box<Future<Item = (), Error = Never> + 'static>,
    ) -> Source {
        let source = glib_ffi::g_source_new(
            mut_override(&SOURCE_FUNCS),
            mem::size_of::<TaskSource>() as u32,
        );
        {
            let source = &mut *(source as *mut TaskSource);
            source.future = Some((future, Box::new(LocalMap::new())));
            source.thread = thread;
            source.state = AtomicUsize::new(INIT);
        }

        glib_ffi::g_source_set_priority(source, priority.to_glib());

        from_glib_full(source)
    }

    fn poll(&mut self) -> Async<()> {
        // Make sure that the first time we're polled that the current thread is remembered
        // and from there one we ensure that we're always polled from exactly the same thread.
        //
        // In theory a GMainContext can be first run from one thread and later from another
        // thread, but we allow spawning non-Send futures and must not ever use them from
        // any other thread.
        match &mut self.thread {
            thread @ &mut None => {
                *thread = Some(thread::current().id());
            }
            &mut Some(thread_id) => {
                assert_eq!(thread::current().id(), thread_id);
            }
        }

        let waker = unsafe { self.clone_raw() };
        let source = &self.source as *const _;
        if let Some(ref mut future) = self.future {
            let (ref mut future, ref mut local_map) = *future;

            let mut executor: MainContext = unsafe {
                from_glib_none(glib_ffi::g_source_get_context(mut_override(source)))
            };

            // Clone that we store in the task local data so that
            // it can be retrieved as needed
            executor.push_thread_default();

            let res = {
                let enter = futures_executor::enter().unwrap();
                let mut context =
                    futures_core::task::Context::new(local_map, &waker, &mut executor);

                let res = future.poll(&mut context).unwrap_or(Async::Ready(()));

                drop(enter);

                res
            };

            executor.pop_thread_default();
            res
        } else {
            Async::Ready(())
        }
    }
}

impl MainContext {
    pub fn spawn<F: Future<Item = (), Error = Never> + Send + 'static>(&mut self, f: F) {
        self.spawn_with_priority(::PRIORITY_DEFAULT, f);
    }

    pub fn spawn_local<F: Future<Item = (), Error = Never> + 'static>(&mut self, f: F) {
        self.spawn_local_with_priority(::PRIORITY_DEFAULT, f);
    }

    pub fn spawn_with_priority<F: Future<Item = (), Error = Never> + Send + 'static>(&mut self, priority: Priority, f: F) {
        let source = TaskSource::new(priority, Box::new(f));
        source.attach(Some(&*self));
    }

    pub fn spawn_local_with_priority<F: Future<Item = (), Error = Never> + 'static>(&mut self, priority: Priority, f: F) {
        assert!(self.is_owner());
        unsafe {
            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            let source = TaskSource::new_unsafe(priority, Some(thread::current().id()), Box::new(f));
            source.attach(Some(&*self));
        }
    }

    pub fn block_on<F: Future>(&mut self, f: F) -> Result<F::Item, F::Error> {
        let mut res = None;
        let l = MainLoop::new(Some(&*self), false);
        let l_clone = l.clone();

        let source = unsafe {
            let future = f.then(|r| {
                res = Some(r);
                l_clone.quit();
                Ok::<(), Never>(())
            });

            let future: *mut Future<Item = (), Error = Never> = Box::into_raw(Box::new(future));
            // XXX: Transmute to get a 'static lifetime here, super unsafe
            let future: *mut (Future<Item = (), Error = Never> + 'static) = mem::transmute(future);
            let future: Box<Future<Item = (), Error = Never> + 'static> = Box::from_raw(future);

            // Ensure that this task is never polled on another thread
            // than this one where it was spawned now.
            TaskSource::new_unsafe(::PRIORITY_DEFAULT, Some(thread::current().id()), future)
        };

        source.attach(Some(&*self));

        l.run();

        res.unwrap()
    }
}

impl Executor for MainContext {
    fn spawn(&mut self, f: Box<Future<Item = (), Error = Never> + Send>) -> Result<(), SpawnError> {
        let source = TaskSource::new(::PRIORITY_DEFAULT, f);
        source.attach(Some(&*self));
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::sync::mpsc;
    use futures_channel::oneshot;
    use futures_util::future;

    #[test]
    fn test_spawn() {
        let mut c = MainContext::new();
        let l = ::MainLoop::new(Some(&c), false);

        let (sender, receiver) = mpsc::channel();
        let (o_sender, o_receiver) = oneshot::channel();

        let l_clone = l.clone();
        c.spawn(o_receiver
                .map_err(|_| unimplemented!())
                .and_then(move |()| {
                    sender.send(()).unwrap();
                    l_clone.quit();

                    Ok(())
                })
        );

        thread::spawn(move || {
            l.run();
        });

        o_sender.send(()).unwrap();

        let _ = receiver.recv().unwrap();
    }

    #[test]
    fn test_spawn_local() {
        let mut c = MainContext::new();
        let l = ::MainLoop::new(Some(&c), false);

        c.push_thread_default();
        let l_clone = l.clone();
        c.spawn_local(future::lazy(move |_ctx| {
            l_clone.quit();

            Ok(())
        }));

        l.run();

        c.pop_thread_default();
    }

    #[test]
    fn test_block_on() {
        let mut c = MainContext::new();

        let mut v = None;
        {
            let v = &mut v;

            let future = future::lazy(|_ctx| {
                *v = Some(123);
                Ok::<i32, ()>(123)
            });

            let res = c.block_on(future);
            assert_eq!(res, Ok(123));
        }

        assert_eq!(v, Some(123));
    }
}
<|endoftext|>


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

#![allow(missing_copy_implementations)]

use prelude::v1::*;

use io::{self, Read, Write, ErrorKind, BufRead};

/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `reader` and then
/// write it into `writer` in a streaming fashion until `reader`
/// returns EOF.
///
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
///
/// # Examples
///
/// ```
/// use std::io;
///
/// # fn foo() -> io::Result<()> {
/// let mut reader: &[u8] = b"hello";
/// let mut writer: Vec<u8> = vec![];
///
/// try!(io::copy(&mut reader, &mut writer));
///
/// assert_eq!(reader, &writer[..]);
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
    let mut buf = [0; super::DEFAULT_BUF_SIZE];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        try!(writer.write_all(&buf[..len]));
        written += len as u64;
    }
}

/// A reader which is always at EOF.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// use std::io;
/// use std::io::Read;
///
/// # fn foo() -> io::Result<String> {
/// let mut buffer = String::new();
/// try!(io::empty().read_to_string(&mut buffer));
/// # Ok(buffer)
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
    fn consume(&mut self, _n: usize) {}
}

/// A reader which infinitely yields one byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }

/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        for slot in &mut *buf {
            *slot = self.byte;
        }
        Ok(buf.len())
    }
}

/// A writer which will move data into the void.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }

/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;

    use io::prelude::*;
    use io::{sink, empty, repeat};

    #[test]
    fn sink_sinks() {
        let mut s = sink();
        assert_eq!(s.write(&[]).unwrap(), 0);
        assert_eq!(s.write(&[0]).unwrap(), 1);
        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
    }

    #[test]
    fn empty_reads() {
        let mut e = empty();
        assert_eq!(e.read(&mut []).unwrap(), 0);
        assert_eq!(e.read(&mut [0]).unwrap(), 0);
        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
    }

    #[test]
    fn repeat_repeats() {
        let mut r = repeat(4);
        let mut b = [0; 1024];
        assert_eq!(r.read(&mut b).unwrap(), 1024);
        assert!(b.iter().all(|b| *b == 4));
    }

    #[test]
    fn take_some_bytes() {
        assert_eq!(repeat(4).take(100).bytes().count(), 100);
        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
    }

    #[test]
    fn tee() {
        let mut buf = [0; 10];
        {
            let mut ptr: &mut [u8] = &mut buf;
            assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
        }
        assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn broadcast() {
        let mut buf1 = [0; 10];
        let mut buf2 = [0; 10];
        {
            let mut ptr1: &mut [u8] = &mut buf1;
            let mut ptr2: &mut [u8] = &mut buf2;

            assert_eq!((&mut ptr1).broadcast(&mut ptr2)
                                  .write(&[1, 2, 3]).unwrap(), 3);
        }
        assert_eq!(buf1, buf2);
        assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
    }
}
<commit_msg>Document structures in std::io::utils<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(missing_copy_implementations)]

use prelude::v1::*;

use io::{self, Read, Write, ErrorKind, BufRead};

/// Copies the entire contents of a reader into a writer.
///
/// This function will continuously read data from `reader` and then
/// write it into `writer` in a streaming fashion until `reader`
/// returns EOF.
///
/// On success, the total number of bytes that were copied from
/// `reader` to `writer` is returned.
///
/// # Errors
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
///
/// # Examples
///
/// ```
/// use std::io;
///
/// # fn foo() -> io::Result<()> {
/// let mut reader: &[u8] = b"hello";
/// let mut writer: Vec<u8> = vec![];
///
/// try!(io::copy(&mut reader, &mut writer));
///
/// assert_eq!(reader, &writer[..]);
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
    let mut buf = [0; super::DEFAULT_BUF_SIZE];
    let mut written = 0;
    loop {
        let len = match reader.read(&mut buf) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        try!(writer.write_all(&buf[..len]));
        written += len as u64;
    }
}

/// A reader which is always at EOF.
///
/// This struct is generally created by calling [`empty()`][empty]. Please see
/// the documentation of `empty()` for more details.
///
/// [empty]: fn.empty.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }

/// Constructs a new handle to an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
///
/// # Examples
///
/// A slightly sad example of not reading anything into a buffer:
///
/// ```
/// use std::io;
/// use std::io::Read;
///
/// # fn foo() -> io::Result<String> {
/// let mut buffer = String::new();
/// try!(io::empty().read_to_string(&mut buffer));
/// # Ok(buffer)
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for Empty {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
    fn consume(&mut self, _n: usize) {}
}

/// A reader which yields one byte over and over and over and over and over and...
///
/// This struct is generally created by calling [`repeat()`][repeat]. Please
/// see the documentation of `repeat()` for more details.
///
/// [empty]: fn.repeat.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }

/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        for slot in &mut *buf {
            *slot = self.byte;
        }
        Ok(buf.len())
    }
}

/// A writer which will move data into the void.
///
/// This struct is generally created by calling [`sink()`][sink]. Please
/// see the documentation of `sink()` for more details.
///
/// [empty]: fn.sink.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }

/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

#[cfg(test)]
mod tests {
    use prelude::v1::*;

    use io::prelude::*;
    use io::{sink, empty, repeat};

    #[test]
    fn sink_sinks() {
        let mut s = sink();
        assert_eq!(s.write(&[]).unwrap(), 0);
        assert_eq!(s.write(&[0]).unwrap(), 1);
        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
    }

    #[test]
    fn empty_reads() {
        let mut e = empty();
        assert_eq!(e.read(&mut []).unwrap(), 0);
        assert_eq!(e.read(&mut [0]).unwrap(), 0);
        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
    }

    #[test]
    fn repeat_repeats() {
        let mut r = repeat(4);
        let mut b = [0; 1024];
        assert_eq!(r.read(&mut b).unwrap(), 1024);
        assert!(b.iter().all(|b| *b == 4));
    }

    #[test]
    fn take_some_bytes() {
        assert_eq!(repeat(4).take(100).bytes().count(), 100);
        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
        assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
    }

    #[test]
    fn tee() {
        let mut buf = [0; 10];
        {
            let mut ptr: &mut [u8] = &mut buf;
            assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
        }
        assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn broadcast() {
        let mut buf1 = [0; 10];
        let mut buf2 = [0; 10];
        {
            let mut ptr1: &mut [u8] = &mut buf1;
            let mut ptr2: &mut [u8] = &mut buf2;

            assert_eq!((&mut ptr1).broadcast(&mut ptr2)
                                  .write(&[1, 2, 3]).unwrap(), 3);
        }
        assert_eq!(buf1, buf2);
        assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
    }
}
<|endoftext|>


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

//! Networking primitives for TCP/UDP communication.

#![stable(feature = "rust1", since = "1.0.0")]

use prelude::v1::*;

use io::{self, Error, ErrorKind};
use sys_common::net as net_imp;

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::tcp::{TcpStream, TcpListener, Incoming};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::udp::UdpSocket;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::parser::AddrParseError;

mod ip;
mod addr;
mod tcp;
mod udp;
mod parser;
#[cfg(test)] mod test;

/// Possible values which can be passed to the `shutdown` method of `TcpStream`.
#[derive(Copy, Clone, PartialEq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Shutdown {
    /// Indicates that the reading portion of this stream/socket should be shut
    /// down. All currently blocked and future reads will return `Ok(0)`.
    #[stable(feature = "rust1", since = "1.0.0")]
    Read,
    /// Indicates that the writing portion of this stream/socket should be shut
    /// down. All currently blocked and future writes will return an error.
    #[stable(feature = "rust1", since = "1.0.0")]
    Write,
    /// Shut down both the reading and writing portions of this stream.
    ///
    /// See `Shutdown::Read` and `Shutdown::Write` for more information.
    #[stable(feature = "rust1", since = "1.0.0")]
    Both,
}

#[doc(hidden)]
trait NetInt {
    fn from_be(i: Self) -> Self;
    fn to_be(&self) -> Self;
}
macro_rules! doit {
    ($($t:ident)*) => ($(impl NetInt for $t {
        fn from_be(i: Self) -> Self { <$t>::from_be(i) }
        fn to_be(&self) -> Self { <$t>::to_be(*self) }
    })*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

fn hton<I: NetInt>(i: I) -> I { i.to_be() }
fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }

fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
    where F: FnMut(&SocketAddr) -> io::Result<T>
{
    let mut last_err = None;
    for addr in try!(addr.to_socket_addrs()) {
        match f(&addr) {
            Ok(l) => return Ok(l),
            Err(e) => last_err = Some(e),
        }
    }
    Err(last_err.unwrap_or_else(|| {
        Error::new(ErrorKind::InvalidInput,
                   "could not resolve to any addresses")
    }))
}

/// An iterator over `SocketAddr` values returned from a host lookup operation.
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
                                              iterator and returning socket \
                                              addresses",
           issue = "27705")]
pub struct LookupHost(net_imp::LookupHost);

#[unstable(feature = "lookup_host", reason = "unsure about the returned \
                                              iterator and returning socket \
                                              addresses",
           issue = "27705")]
impl Iterator for LookupHost {
    type Item = io::Result<SocketAddr>;
    fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
}

/// Resolve the host specified by `host` as a number of `SocketAddr` instances.
///
/// This method may perform a DNS query to resolve `host` and may also inspect
/// system configuration to resolve the specified hostname.
///
/// # Examples
///
/// ```no_run
/// #![feature(lookup_host)]
///
/// use std::net;
///
/// # fn foo() -> std::io::Result<()> {
/// for host in try!(net::lookup_host("rust-lang.org")) {
///     println!("found address: {}", try!(host));
/// }
/// # Ok(())
/// # }
/// ```
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
                                              iterator and returning socket \
                                              addresses",
           issue = "27705")]
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
    net_imp::lookup_host(host).map(LookupHost)
}

/// Resolve the given address to a hostname.
///
/// This function may perform a DNS query to resolve `addr` and may also inspect
/// system configuration to resolve the specified address. If the address
/// cannot be resolved, it is returned in string format.
#[unstable(feature = "lookup_addr", reason = "recent addition",
           issue = "27705")]
#[rustc_deprecated(reason = "ipaddr type is being deprecated",
                   since = "1.6.0")]
#[allow(deprecated)]
pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
    net_imp::lookup_addr(addr)
}
<commit_msg>Auto merge of #30188 - tshepang:lookup_addr-example, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Networking primitives for TCP/UDP communication.

#![stable(feature = "rust1", since = "1.0.0")]

use prelude::v1::*;

use io::{self, Error, ErrorKind};
use sys_common::net as net_imp;

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::tcp::{TcpStream, TcpListener, Incoming};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::udp::UdpSocket;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::parser::AddrParseError;

mod ip;
mod addr;
mod tcp;
mod udp;
mod parser;
#[cfg(test)] mod test;

/// Possible values which can be passed to the `shutdown` method of `TcpStream`.
#[derive(Copy, Clone, PartialEq, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Shutdown {
    /// Indicates that the reading portion of this stream/socket should be shut
    /// down. All currently blocked and future reads will return `Ok(0)`.
    #[stable(feature = "rust1", since = "1.0.0")]
    Read,
    /// Indicates that the writing portion of this stream/socket should be shut
    /// down. All currently blocked and future writes will return an error.
    #[stable(feature = "rust1", since = "1.0.0")]
    Write,
    /// Shut down both the reading and writing portions of this stream.
    ///
    /// See `Shutdown::Read` and `Shutdown::Write` for more information.
    #[stable(feature = "rust1", since = "1.0.0")]
    Both,
}

#[doc(hidden)]
trait NetInt {
    fn from_be(i: Self) -> Self;
    fn to_be(&self) -> Self;
}
macro_rules! doit {
    ($($t:ident)*) => ($(impl NetInt for $t {
        fn from_be(i: Self) -> Self { <$t>::from_be(i) }
        fn to_be(&self) -> Self { <$t>::to_be(*self) }
    })*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

fn hton<I: NetInt>(i: I) -> I { i.to_be() }
fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }

fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
    where F: FnMut(&SocketAddr) -> io::Result<T>
{
    let mut last_err = None;
    for addr in try!(addr.to_socket_addrs()) {
        match f(&addr) {
            Ok(l) => return Ok(l),
            Err(e) => last_err = Some(e),
        }
    }
    Err(last_err.unwrap_or_else(|| {
        Error::new(ErrorKind::InvalidInput,
                   "could not resolve to any addresses")
    }))
}

/// An iterator over `SocketAddr` values returned from a host lookup operation.
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
                                              iterator and returning socket \
                                              addresses",
           issue = "27705")]
pub struct LookupHost(net_imp::LookupHost);

#[unstable(feature = "lookup_host", reason = "unsure about the returned \
                                              iterator and returning socket \
                                              addresses",
           issue = "27705")]
impl Iterator for LookupHost {
    type Item = io::Result<SocketAddr>;
    fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
}

/// Resolve the host specified by `host` as a number of `SocketAddr` instances.
///
/// This method may perform a DNS query to resolve `host` and may also inspect
/// system configuration to resolve the specified hostname.
///
/// # Examples
///
/// ```no_run
/// #![feature(lookup_host)]
///
/// use std::net;
///
/// # fn foo() -> std::io::Result<()> {
/// for host in try!(net::lookup_host("rust-lang.org")) {
///     println!("found address: {}", try!(host));
/// }
/// # Ok(())
/// # }
/// ```
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
                                              iterator and returning socket \
                                              addresses",
           issue = "27705")]
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
    net_imp::lookup_host(host).map(LookupHost)
}

/// Resolve the given address to a hostname.
///
/// This function may perform a DNS query to resolve `addr` and may also inspect
/// system configuration to resolve the specified address. If the address
/// cannot be resolved, it is returned in string format.
///
/// # Examples
///
/// ```no_run
/// #![feature(lookup_addr)]
/// #![feature(ip_addr)]
///
/// use std::net::{self, Ipv4Addr, IpAddr};
///
/// let ip_addr = "8.8.8.8";
/// let addr: Ipv4Addr = ip_addr.parse().unwrap();
/// let hostname = net::lookup_addr(&IpAddr::V4(addr)).unwrap();
///
/// println!("{} --> {}", ip_addr, hostname);
/// // Output: 8.8.8.8 --> google-public-dns-a.google.com
/// ```
#[unstable(feature = "lookup_addr", reason = "recent addition",
           issue = "27705")]
#[rustc_deprecated(reason = "ipaddr type is being deprecated",
                   since = "1.6.0")]
#[allow(deprecated)]
pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
    net_imp::lookup_addr(addr)
}
<|endoftext|>