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

//! Pin configuration for ST STM32L1.
//!
//! Some pins that could be configured here may be missing from actual MCU
//! depending on the package.

use super::peripheral_clock;
use core::intrinsics::abort;
use self::Port::*;

/// Available port names.
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum Port {
  PortA,
  PortB,
  PortC,
  PortD,
  PortE,
  PortF,
  PortG,
  PortH,
}

/// Pin output type.
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum OutputType {
  OutPushPull  = 0,
  OutOpenDrain = 1,
}

/// Pin pull resistors: up, down, or none.
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum PullType {
  PullNone = 0,
  PullUp   = 1,
  PullDown = 2,
}

/// Pin speed.
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum Speed {
  /// 400 KHz
  VeryLow = 0,
  /// 2 MHz
  Low     = 1,
  /// 10 MHz
  Medium  = 2,
  /// 40 MHz
  High    = 3,
}

/// Extended pin modes.
#[allow(missing_docs, non_camel_case_types)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum AltMode {
  AfRtc50Mhz_Mco_RtcAfl_Wakeup_SwJtag_Trace = 0,
  AfTim2 = 1,
  AfTim3_Tim4_Tim5 = 2,
  AfTim9_Tim10_Tim11 = 3,
  AfI2C1_I2C2 = 4,
  AfSpi1_Spi2 = 5,
  AfSpi3 = 6,
  AfUsart1_Usart2_Usart3 = 7,
  AfUart4_Uart5 = 8,
  AfUsb = 10,
  AfLcd = 11,
  AfFsmc_Sdio = 12,
  AfRe = 14,
  AfEventOut = 15,
}

/// Pin mode.
#[derive(Clone, Copy)]
pub enum Mode {
  /// GPIO Input Mode
  GpioIn,
  /// GPIO Output Mode
  GpioOut(OutputType, Speed),
  /// GPIO Alternate function Mode
  AltFunction(AltMode, OutputType, Speed),
  /// GPIO Analog Mode
  Analog,
}

/// Pin configuration.
#[derive(Clone, Copy)]
pub struct Pin {
  /// Pin index.
  pub index: u8,
  /// GPIO register
  reg: &'static reg::GPIO,
}

impl Pin {
  /// Setup the pin.
  #[inline(always)]
  pub fn new(port: Port, pin_index: u8, mode: Mode, pull_type: PullType) -> Pin {
    use hal::stm32l1::peripheral_clock::BusAhb as clock;
    use self::Mode::*;
    let (reg, clock) = match port {
      PortA => (&reg::GPIOA, clock::GpioA),
      PortB => (&reg::GPIOB, clock::GpioB),
      PortC => (&reg::GPIOC, clock::GpioC),
      PortD => (&reg::GPIOD, clock::GpioD),
      PortE => (&reg::GPIOE, clock::GpioE),
      PortF => (&reg::GPIOF, clock::GpioF),
      PortG => (&reg::GPIOG, clock::GpioG),
      PortH => (&reg::GPIOH, clock::GpioH),
    };
    // TODO(farcaller): should be done once per port
    peripheral_clock::PeripheralClock::Ahb(clock).enable();

    let offset1 = pin_index as usize;
    let mask1 = !(0b1u16 << offset1);
    let offset2 = pin_index as usize * 2;
    let mask2: u32 = !(0b11 << offset2);

    let fun: u32 = match mode {
      GpioIn  => 0b00,
      GpioOut(otype, speed) => {
        // set type and speed
        let tv: u16 = reg.otyper.otype() & mask1;
        reg.otyper.set_otype(tv | ((otype as u16) << offset1));
        let sv: u32 = reg.ospeedr.speed() & mask2;
        reg.ospeedr.set_speed(sv | ((speed as u32) << offset2));
        // done
        0b01
      },
      AltFunction(alt, otype, speed) => {
        // set type and speed
        let tv: u16 = reg.otyper.otype() & mask1;
        reg.otyper.set_otype(tv | ((otype as u16) << offset1));
        let sv: u32 = reg.ospeedr.speed() & mask2;
        reg.ospeedr.set_speed(sv | ((speed as u32) << offset2));
        // set alt mode
        let mut off = (pin_index as usize) << 2;
        if pin_index < 8 {
          let v = reg.afrl.alt_fun() & !(0xF << off);
          reg.afrl.set_alt_fun(v | ((alt as u32) << off));
        }else {
          off -= 32;
          let v = reg.afrh.alt_fun() & !(0xF << off);
          reg.afrh.set_alt_fun(v | ((alt as u32) << off));
        }
        // done
        0b10
      },
      Analog => {
        //unsafe { abort() } //TODO
        0b11
      },
    };

    let mode: u32 = reg.moder.mode() & mask2;
    reg.moder.set_mode(mode | (fun << offset2));

    let pull: u32 = reg.pupdr.mode() & mask2;
    let pull_val = (pull_type as u32) << offset2;
    reg.pupdr.set_mode(pull | pull_val);

    Pin {
      index: pin_index,
      reg: reg,
    }
  }
}

impl ::hal::pin::Gpio for Pin {
  fn set_high(&self) {
    let bit: u32 = 1 << self.index as usize;
    self.reg.bsrr.set_reset(bit);
  }

  fn set_low(&self) {
    let bit: u32 = 1 << (self.index as usize + 16);
    self.reg.bsrr.set_reset(bit);
  }

  fn level(&self) -> ::hal::pin::GpioLevel {
    let bit = 1u16 << (self.index as usize);

    match self.reg.idr.input() & bit {
      0 => ::hal::pin::Low,
      _ => ::hal::pin::High,
    }
  }

  fn set_direction(&self, _new_mode: ::hal::pin::GpioDirection) {
    //TODO(kvark)
    unsafe { abort() }
  }
}

mod reg {
  use volatile_cell::VolatileCell;
  use core::ops::Drop;

  ioregs!(GPIO = {
    0x00 => reg32 moder {   // port mode
      31..0 => mode : rw,
    },
    0x04 => reg16 otyper {  // port output type
      15..0 => otype : rw,
    },
    0x08 => reg32 ospeedr { // port output speed
      31..0 => speed : rw,
    },
    0x0C => reg32 pupdr {   // port pull-up/pull-down
      31..0 => mode : rw,
    },
    0x10 => reg16 idr {     // port input data
      15..0 => input : rw,
    },
    0x14 => reg16 odr {     // port output data
      15..0 => output : rw,
    },
    0x18 => reg32 bsrr {    // port bit set/reset
      31..0 => reset : rw,
    },
    0x1C => reg32 lckr {    // port configuration lock
      31..0 => config_lock : rw,
    },
    0x20 => reg32 afrl {    // alternate function low
      31..0 => alt_fun : rw,
    },
    0x24 => reg32 afrh {     // alternate function high
      31..0 => alt_fun : rw,
    },
    0x28 => reg16 brr {      // bit reset register
      15..0 => reset : rw,
    },
  });

  extern {
    #[link_name="stm32l1_iomem_GPIOA"] pub static GPIOA: GPIO;
    #[link_name="stm32l1_iomem_GPIOB"] pub static GPIOB: GPIO;
    #[link_name="stm32l1_iomem_GPIOC"] pub static GPIOC: GPIO;
    #[link_name="stm32l1_iomem_GPIOD"] pub static GPIOD: GPIO;
    #[link_name="stm32l1_iomem_GPIOE"] pub static GPIOE: GPIO;
    #[link_name="stm32l1_iomem_GPIOF"] pub static GPIOF: GPIO;
    #[link_name="stm32l1_iomem_GPIOG"] pub static GPIOG: GPIO;
    #[link_name="stm32l1_iomem_GPIOH"] pub static GPIOH: GPIO;
  }
}
<commit_msg>pin configuration<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Dzmitry "kvark" Malyshau <kvarkus@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Pin configuration for ST STM32L1.
//!
//! Some pins that could be configured here may be missing from actual MCU
//! depending on the package.

use super::peripheral_clock;
use core::intrinsics::abort;
use self::Port::*;

/// Available port names.
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum Port {
  PortA,
  PortB,
  PortC,
  PortD,
  PortE,
  PortF,
  PortG,
}

/// Pin output mode.
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum PinConf {
  /* Input mode */
  InAnalog,
  InFloating,
  InPullUpDown,
  /* Output mode, max speed 10 MHz */
  OutPushPull_10MHz,
  OutOpenDrain_10MHz,
  OutPushPullAlt_10MHz,
  OutOpenDrainAlt_10MHz,
  /* Output mode, max speed 2 MHz */
  OutPushPull_2MHz,
  OutOpenDrain_2MHz,
  OutPushPullAlt_2MHz,
  OutOpenDrainAlt_2MHz,
  /* Output mode, max speed 50 MHz */
  OutPushPull_50MHz,
  OutOpenDrain_50MHz,
  OutPushPullAlt_50MHz,
  OutOpenDrainAlt_50MHz,
}

/// Pin configuration.
#[derive(Clone, Copy)]
pub struct Pin {
  /// Pin index.
  pub index: u8,
  /// GPIO register
  reg: &'static reg::GPIO,
}

impl Pin {
  /// Setup the pin.
  #[inline(always)]
  pub fn new(port: Port, pin_index: u8, mode: PinConf) -> Pin {
    use hal::stm32l1::peripheral_clock::BusAhb as clock;
    use self::PinConf::*;
    let (reg, clock) = match port {
      PortA => (&reg::GPIOA, clock::GpioA),
      PortB => (&reg::GPIOB, clock::GpioB),
      PortC => (&reg::GPIOC, clock::GpioC),
      PortD => (&reg::GPIOD, clock::GpioD),
      PortE => (&reg::GPIOE, clock::GpioE),
      PortF => (&reg::GPIOF, clock::GpioF),
      PortG => (&reg::GPIOG, clock::GpioG),
    };
    // TODO(farcaller): should be done once per port
    peripheral_clock::PeripheralClock::Apb2(clock).enable();

    let conf: u32 = match mode {
      /* Input mode */
      InAnalog              => 0b00_00,
      InFloating            => 0b01_00,
      InPullUpDown          => 0b10_00,
      /* Output mode, max speed 10 MHz */
      OutPushPull_10MHz     => 0b00_01,
      OutOpenDrain_10MHz    => 0b01_01,
      OutPushPullAlt_10MHz  => 0b10_01,
      OutOpenDrainAlt_10MHz => 0b11_01,
      /* Output mode, max speed 2 MHz */
      OutPushPull_2MHz      => 0b00_10,
      OutOpenDrain_2MHz     => 0b01_10,
      OutPushPullAlt_2MHz   => 0b10_10,
      OutOpenDrainAlt_2MHz  => 0b11_10,
      /* Output mode, max speed 50 MHz */
      OutPushPull_50MHz     => 0b00_11,
      OutOpenDrain_50MHz    => 0b01_11,
      OutPushPullAlt_50MHz  => 0b10_11,
      OutOpenDrainAlt_50MHz => 0b11_11,
    };

    let offset = (pin_index % 8) as usize * 4;
    let mask = !(0xFu32 << offset);

    if pin_index < 8 {
        let mode: u32 = reg.crlr.mode() & mask;
        reg.moder.set_crlr(conf << offset);
    } else {
        let mode: u32 = reg.crhr.mode() & mask;
        reg.moder.set_crhr(conf << offset);
    }

    Pin {
      index: pin_index,
      reg: reg,
    }
  }
}

impl ::hal::pin::Gpio for Pin {
  fn set_high(&self) {
    let bit: u32 = 1 << self.index as usize;
    self.reg.bsrr.set_reset(bit);
  }

  fn set_low(&self) {
    let bit: u32 = 1 << (self.index as usize + 16);
    self.reg.bsrr.set_reset(bit);
  }

  fn level(&self) -> ::hal::pin::GpioLevel {
    let bit = 1u16 << (self.index as usize);

    match self.reg.idr.input() & bit {
      0 => ::hal::pin::Low,
      _ => ::hal::pin::High,
    }
  }
}

mod reg {
  use volatile_cell::VolatileCell;
  use core::ops::Drop;

  ioregs!(GPIO = {
    0x00 => reg32 crlr {   // port mode
      31..0 => crl : rw,
    },
    0x04 => reg32 crhr {  // port output type
      31..0 => crh : rw,
    },
    0x08 => reg16 idr {     // port input data
      15..0 => input : rw,
    },
    0x0c => reg16 odr {     // port output data
      15..0 => output : rw,
    },
    0x10 => reg32 bsrr {    // port bit set/reset
      31..0 => reset : rw,
    },
    // 0x14 => reg16 brr {      // bit reset register
    //   15..0 => reset : rw,
    // },
    0x18 => reg32 lckr {    // port configuration lock
      31..0 => config_lock : rw,
    },
  });

  extern {
    #[link_name="stm32l1_iomem_GPIOA"] pub static GPIOA: GPIO;
    #[link_name="stm32l1_iomem_GPIOB"] pub static GPIOB: GPIO;
    #[link_name="stm32l1_iomem_GPIOC"] pub static GPIOC: GPIO;
    #[link_name="stm32l1_iomem_GPIOD"] pub static GPIOD: GPIO;
    #[link_name="stm32l1_iomem_GPIOE"] pub static GPIOE: GPIO;
    #[link_name="stm32l1_iomem_GPIOF"] pub static GPIOF: GPIO;
    #[link_name="stm32l1_iomem_GPIOG"] pub static GPIOG: GPIO;
  }
}
<|endoftext|>


<commit_before>use cargo::ops::{self, CompileFilter};

use crate::command_prelude::*;

pub fn cli() -> App {
    subcommand("test")
        // Subcommand aliases are handled in `aliased_command()`.
        // .alias("t")
        .setting(AppSettings::TrailingVarArg)
        .about("Execute all unit and integration tests and build examples of a local package")
        .arg(
            Arg::with_name("TESTNAME")
                .help("If specified, only run tests containing this string in their names"),
        )
        .arg(
            Arg::with_name("args")
                .help("Arguments for the test binary")
                .multiple(true)
                .last(true),
        )
        .arg_targets_all(
            "Test only this package's library unit tests",
            "Test only the specified binary",
            "Test all binaries",
            "Test only the specified example",
            "Test all examples",
            "Test only the specified test target",
            "Test all tests",
            "Test only the specified bench target",
            "Test all benches",
            "Test all targets",
        )
        .arg(opt("doc", "Test only this library's documentation"))
        .arg(opt("no-run", "Compile, but don't run tests"))
        .arg(opt("no-fail-fast", "Run all tests regardless of failure"))
        .arg_package_spec(
            "Package to run tests for",
            "Test all packages in the workspace",
            "Exclude packages from the test",
        )
        .arg_jobs()
        .arg_release("Build artifacts in release mode, with optimizations")
        .arg_features()
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg_manifest_path()
        .arg_message_format()
        .after_help(
            "\
The test filtering argument TESTNAME and all the arguments following the
two dashes (`--`) are passed to the test binaries and thus to libtest
(rustc's built in unit-test and micro-benchmarking framework). If you're
passing arguments to both Cargo and the binary, the ones after `--` go to the
binary, the ones before go to Cargo. For details about libtest's arguments see
the output of `cargo test -- --help`. As an example, this will run all
tests with `foo` in their name on 3 threads in parallel:

    cargo test foo -- --test-threads 3

If the `--package` argument is given, then SPEC is a package ID specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.

All packages in the workspace are tested if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.

The `--jobs` argument affects the building of the test executable but does
not affect how many jobs are used when running the tests. The default value
for the `--jobs` argument is the number of CPUs. If you want to control the
number of simultaneous running test cases, pass the `--test-threads` option
to the test binaries:

    cargo test -- --test-threads=1

Compilation can be configured via the `test` profile in the manifest.

By default the rust test harness hides output from test execution to
keep results readable. Test output can be recovered (e.g., for debugging)
by passing `--nocapture` to the test binaries:

    cargo test -- --nocapture

To get the list of all options available for the test binaries use this:

    cargo test -- --help
",
        )
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    let ws = args.workspace(config)?;

    let mut compile_opts = args.compile_options(config, CompileMode::Test, Some(&ws))?;

    let no_run = args.is_present("no-run");
    let doc = args.is_present("doc");
    if doc {
        if let CompileFilter::Only { .. } = compile_opts.filter {
            return Err(CliError::new(
                failure::format_err!("Can't mix --doc with other target selecting options"),
                101,
            ));
        }
        if no_run {
            return Err(CliError::new(
                failure::format_err!("Can't skip running doc tests with --no-run"),
                101,
            ));
        }
        compile_opts.build_config.mode = CompileMode::Doctest;
        compile_opts.filter = ops::CompileFilter::new(
            true,
            Vec::new(),
            false,
            Vec::new(),
            false,
            Vec::new(),
            false,
            Vec::new(),
            false,
            false,
        );
    }

    let ops = ops::TestOptions {
        no_run,
        no_fail_fast: args.is_present("no-fail-fast"),
        compile_opts,
    };

    // `TESTNAME` is actually an argument of the test binary, but it's
    // important, so we explicitly mention it and reconfigure.
    let mut test_args = vec![];
    test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string()));
    test_args.extend(
        args.values_of("args")
            .unwrap_or_default()
            .map(|s| s.to_string()),
    );

    let err = ops::run_tests(&ws, &ops, &test_args)?;
    match err {
        None => Ok(()),
        Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
            Some(i) => CliError::new(failure::format_err!("{}", err.hint(&ws)), i),
            None => CliError::new(err.into(), 101),
        }),
    }
}
<commit_msg>pass -q flag to test harness<commit_after>use cargo::ops::{self, CompileFilter};

use crate::command_prelude::*;

pub fn cli() -> App {
    subcommand("test")
        // Subcommand aliases are handled in `aliased_command()`.
        // .alias("t")
        .setting(AppSettings::TrailingVarArg)
        .about("Execute all unit and integration tests and build examples of a local package")
        .arg(
            Arg::with_name("TESTNAME")
                .help("If specified, only run tests containing this string in their names"),
        )
        .arg(
            Arg::with_name("args")
                .help("Arguments for the test binary")
                .multiple(true)
                .last(true),
        )
        .arg_targets_all(
            "Test only this package's library unit tests",
            "Test only the specified binary",
            "Test all binaries",
            "Test only the specified example",
            "Test all examples",
            "Test only the specified test target",
            "Test all tests",
            "Test only the specified bench target",
            "Test all benches",
            "Test all targets",
        )
        .arg(opt("doc", "Test only this library's documentation"))
        .arg(opt("no-run", "Compile, but don't run tests"))
        .arg(opt("no-fail-fast", "Run all tests regardless of failure"))
        .arg_package_spec(
            "Package to run tests for",
            "Test all packages in the workspace",
            "Exclude packages from the test",
        )
        .arg_jobs()
        .arg_release("Build artifacts in release mode, with optimizations")
        .arg_features()
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg_manifest_path()
        .arg_message_format()
        .after_help(
            "\
The test filtering argument TESTNAME and all the arguments following the
two dashes (`--`) are passed to the test binaries and thus to libtest
(rustc's built in unit-test and micro-benchmarking framework). If you're
passing arguments to both Cargo and the binary, the ones after `--` go to the
binary, the ones before go to Cargo. For details about libtest's arguments see
the output of `cargo test -- --help`. As an example, this will run all
tests with `foo` in their name on 3 threads in parallel:

    cargo test foo -- --test-threads 3

If the `--package` argument is given, then SPEC is a package ID specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.

All packages in the workspace are tested if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.

The `--jobs` argument affects the building of the test executable but does
not affect how many jobs are used when running the tests. The default value
for the `--jobs` argument is the number of CPUs. If you want to control the
number of simultaneous running test cases, pass the `--test-threads` option
to the test binaries:

    cargo test -- --test-threads=1

Compilation can be configured via the `test` profile in the manifest.

By default the rust test harness hides output from test execution to
keep results readable. Test output can be recovered (e.g., for debugging)
by passing `--nocapture` to the test binaries:

    cargo test -- --nocapture

To get the list of all options available for the test binaries use this:

    cargo test -- --help
",
        )
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    let ws = args.workspace(config)?;

    let mut compile_opts = args.compile_options(config, CompileMode::Test, Some(&ws))?;

    let no_run = args.is_present("no-run");
    let doc = args.is_present("doc");
    if doc {
        if let CompileFilter::Only { .. } = compile_opts.filter {
            return Err(CliError::new(
                failure::format_err!("Can't mix --doc with other target selecting options"),
                101,
            ));
        }
        if no_run {
            return Err(CliError::new(
                failure::format_err!("Can't skip running doc tests with --no-run"),
                101,
            ));
        }
        compile_opts.build_config.mode = CompileMode::Doctest;
        compile_opts.filter = ops::CompileFilter::new(
            true,
            Vec::new(),
            false,
            Vec::new(),
            false,
            Vec::new(),
            false,
            Vec::new(),
            false,
            false,
        );
    }

    let ops = ops::TestOptions {
        no_run,
        no_fail_fast: args.is_present("no-fail-fast"),
        compile_opts,
    };

    // `TESTNAME` is actually an argument of the test binary, but it's
    // important, so we explicitly mention it and reconfigure.
    let mut test_args = vec![];
    test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string()));
    test_args.extend(
        args.values_of("args")
            .unwrap_or_default()
            .map(|s| s.to_string()),
    );

    if args.is_present("quiet") {
        test_args.push("-q".to_string())
    }

    let err = ops::run_tests(&ws, &ops, &test_args)?;
    match err {
        None => Ok(()),
        Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
            Some(i) => CliError::new(failure::format_err!("{}", err.hint(&ws)), i),
            None => CliError::new(err.into(), 101),
        }),
    }
}
<|endoftext|>


<commit_before>extern crate hyper;

use std::io::copy;
use std::sync::Mutex;

use self::hyper::net::Fresh;
use self::hyper::client::Client;
use self::hyper::header::Connection;
use self::hyper::header::Host;
use self::hyper::server::Handler;
use self::hyper::server::Request;
use self::hyper::server::Response;
use self::hyper::uri::RequestUri::AbsolutePath;

use http::app_manager::AppManager;

pub struct Dispatcher {
    pub app_manager: Mutex<AppManager>,
}

impl Dispatcher {
    pub fn new(app_manager: AppManager) -> Dispatcher {
        Dispatcher {
            app_manager: Mutex::new(app_manager),
        }
    }

    fn extract_app_name<'a>(&'a self, request: &'a Request) -> &str {
        let host = &request.headers.get::<Host>().unwrap().hostname;
        let host_parts = host.split(".").collect::<Vec<_>>();

        host_parts.first().unwrap()
    }

    fn ensure_app_running(&self, app_name: &str) -> u16 {
        let mut app_manager = self.app_manager.lock().unwrap();

        app_manager.ensure_app_running(&app_name)
    }

    fn forward_uri<'a>(&'a self, request: &'a Request) -> &str {
        match request.uri {
            AbsolutePath(ref value) => value,
            _ => panic!(),
        }
    }
}

impl Handler for Dispatcher {
    fn handle(&self, mut request: Request, response: Response<Fresh>) {
        let app_name = self.extract_app_name(&request).to_string();
        let port = self.ensure_app_running(&app_name);

        let uri = self.forward_uri(&request).to_string();

        let app_url = format!("http://localhost:{}{}", port, uri);

        let client = Client::new();

        let mut app_response = client.request(request.method.clone(), &app_url)
            .header(Connection::close())
            .body(&mut request)
            .send().unwrap();

        let mut stream = response.start().unwrap();
        copy(&mut app_response, &mut stream).unwrap();
        stream.end().unwrap();
    }
}
<commit_msg>feature: Handle proxying of headers<commit_after>extern crate hyper;

use std::io::copy;
use std::sync::Mutex;

use self::hyper::net::Fresh;
use self::hyper::client::Client;
use self::hyper::header::Connection;
use self::hyper::header::Host;
use self::hyper::server::Handler;
use self::hyper::server::Request;
use self::hyper::server::Response;
use self::hyper::uri::RequestUri::AbsolutePath;

use http::app_manager::AppManager;

pub struct Dispatcher {
    pub app_manager: Mutex<AppManager>,
}

impl Dispatcher {
    pub fn new(app_manager: AppManager) -> Dispatcher {
        Dispatcher {
            app_manager: Mutex::new(app_manager),
        }
    }

    fn extract_app_name<'a>(&'a self, request: &'a Request) -> &str {
        let host = &request.headers.get::<Host>().unwrap().hostname;
        let host_parts = host.split(".").collect::<Vec<_>>();

        host_parts.first().unwrap()
    }

    fn ensure_app_running(&self, app_name: &str) -> u16 {
        let mut app_manager = self.app_manager.lock().unwrap();

        app_manager.ensure_app_running(&app_name)
    }

    fn forward_uri<'a>(&'a self, request: &'a Request) -> &str {
        match request.uri {
            AbsolutePath(ref value) => value,
            _ => panic!(),
        }
    }
}

impl Handler for Dispatcher {
    fn handle(&self, mut request: Request, mut response: Response<Fresh>) {
        let app_name = self.extract_app_name(&request).to_string();
        let port = self.ensure_app_running(&app_name);

        let uri = self.forward_uri(&request).to_string();

        let app_url = format!("http://localhost:{}{}", port, uri);

        let connection_header = match request.headers.get::<Connection>() {
            Some(value) => value.clone(),
            None => Connection::close(),
        };

        let client = Client::new();

        let mut app_response = client.request(request.method.clone(), &app_url)
            .headers(request.headers.clone())
            .header(Connection::close())
            .body(&mut request)
            .send().unwrap();

        response.headers_mut().clear();
        response.headers_mut().extend(app_response.headers.iter());
        response.headers_mut().set(connection_header);

        let mut stream = response.start().unwrap();
        copy(&mut app_response, &mut stream).unwrap();
        stream.end().unwrap();
    }
}
<|endoftext|>


<commit_before>/* Rustymine - Barebones Minecraft server in Rust
 *
 * Copyright (c) 2014 Ryan Mendivil <ryan@nullreff.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Rustymine nor the names of its contributors may be
 *     used to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

use std::io::{Listener, Acceptor, IoResult, IoError, InvalidInput};
use std::io::net::tcp::{TcpListener, TcpStream};
use varint::{ReadVarint, ToVarint};
mod varint;

// Most of this was put together using http://wiki.vg/Protocoland Wireshark captures.
struct Packet {
    cmd: u8,
    value: PacketValue
}

enum PacketValue {
    Command,
    Data(Vec<u8>),
    Message(String)
}

trait PacketStream {
    fn read_packet_command(&mut self) -> IoResult<Packet>;
    fn read_packet_data(&mut self) -> IoResult<Packet>;
    fn read_packet_string(&mut self) -> IoResult<Packet>;
    fn write_packet(&mut self, packet: Packet) -> IoResult<()>;
}

impl Packet {
    fn len(& self) -> uint {
        match self.value {
            Command => 1,
            Data(ref data) => 1 + data.len(),
            Message(ref string) => {
                let len = string.len();
                1 + len + len.to_varint().len()
            }
        }
    }

    fn as_bytes(&self) -> Vec<u8> {
        let mut response = Vec::new();
        response.push_all(self.len().to_varint().as_slice());
        response.push(self.cmd);
        match self.value {
            Command => {},
            Data(ref data) => {
                response.push_all(data.as_slice());
            },
            Message(ref string) => {
                response.push_all(string.len().to_varint().as_slice());
                response.push_all(string.as_bytes());
            }
        }
        response
    }
}

impl PacketStream for TcpStream {
    fn read_packet_command(&mut self) -> IoResult<Packet> {
        let size = try!(self.read_varint());
        if size == 1 {
            let command = try!(self.read_byte());
            Ok(Packet {cmd: command, value: Command})
        } else {
            Err(IoError {
                kind: InvalidInput,
                desc: "Command packet with a size greater than one",
                detail: None
            })
        }
    }

    fn read_packet_data(&mut self) -> IoResult<Packet> {
        let size = try!(self.read_varint());
        if size == 0 {
            return Err(IoError {
                kind: InvalidInput,
                desc: "Data packet with size zero",
                detail: None
            });
        }
        let command = try!(self.read_byte());
        let data = try!(self.read_exact(size - 1));
        Ok(Packet {cmd: command, value: Data(data)})
    }

    fn read_packet_string(&mut self) -> IoResult<Packet> {
        try!(self.read_varint());
        let command = try!(self.read_byte());
        let string_size = try!(self.read_varint());
        let data = try!(self.read_exact(string_size));
        match std::str::from_utf8(data.as_slice()) {
            Some(string) => Ok(Packet {
                cmd: command,
                value: Message(string.to_string())
            }),
            None => Err(IoError {
                kind: InvalidInput,
                desc: "Command packet with a size greater than one",
                detail: None
            })
        }
    }

    fn write_packet(&mut self, packet: Packet) -> IoResult<()> {
        self.write(packet.as_bytes().as_slice())
    }
}

fn process_stream(mut stream: TcpStream) -> IoResult<()> {
    let message = "{\"description\":\"Rustymine Server\",\"players\":{\"max\":0,\"online\":0},\"version\":{\"name\":\"1.8\",\"protocol\":47}}";

    let ip = try!(stream.peer_name()).ip;
    let packet = try!(stream.read_packet_data());
    match packet {
        Packet { cmd: 0, value: Data(data) } => {
            match data[13] {
                // Query
                1 => {
                    println!("Query from {}", ip);

                    // We don't need anything from the second packet sent
                    try!(stream.read_packet_command());

                    // Send back the server status as JSON
                    try!(stream.write_packet(Packet {cmd: 0, value: Message(message.to_string())}));

                    // Then receive and respond to the ping packet
                    let ping = try!(stream.read_packet_data());
                    try!(stream.write_packet(ping));

                },
                // Login
                2 => {
                    match stream.read_packet_string() {
                        Ok(Packet {cmd: _, value: Message(name)}) => {
                            println!("Connection from {} ({})", name, ip);
                        },
                        _ => println!("Invalid login packet")
                    }

                },
                _ => println!("Invalid query packet")
            }
        },

        // Everything else
        _ => println!("Unknown packet")
    }
    Ok(())
}

fn main() {
    let address = "0.0.0.0";
    let port = 25565;
    let mut acceptor = TcpListener::bind(address, port).listen().unwrap();
    println!("Rustymine is listening on {}:{}", address, port);
    for opt_stream in acceptor.incoming() {
        spawn(proc() process_stream(opt_stream.unwrap()).unwrap())
    }
}
<commit_msg>Fix comment format<commit_after>/* Rustymine - Barebones Minecraft server in Rust
 *
 * Copyright (c) 2014 Ryan Mendivil <ryan@nullreff.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Rustymine nor the names of its contributors may be
 *     used to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

use std::io::{Listener, Acceptor, IoResult, IoError, InvalidInput};
use std::io::net::tcp::{TcpListener, TcpStream};
use varint::{ReadVarint, ToVarint};
mod varint;

// Most of this was put together using http://wiki.vg/Protocol
// and Wireshark captures.
struct Packet {
    cmd: u8,
    value: PacketValue
}

enum PacketValue {
    Command,
    Data(Vec<u8>),
    Message(String)
}

trait PacketStream {
    fn read_packet_command(&mut self) -> IoResult<Packet>;
    fn read_packet_data(&mut self) -> IoResult<Packet>;
    fn read_packet_string(&mut self) -> IoResult<Packet>;
    fn write_packet(&mut self, packet: Packet) -> IoResult<()>;
}

impl Packet {
    fn len(& self) -> uint {
        match self.value {
            Command => 1,
            Data(ref data) => 1 + data.len(),
            Message(ref string) => {
                let len = string.len();
                1 + len + len.to_varint().len()
            }
        }
    }

    fn as_bytes(&self) -> Vec<u8> {
        let mut response = Vec::new();
        response.push_all(self.len().to_varint().as_slice());
        response.push(self.cmd);
        match self.value {
            Command => {},
            Data(ref data) => {
                response.push_all(data.as_slice());
            },
            Message(ref string) => {
                response.push_all(string.len().to_varint().as_slice());
                response.push_all(string.as_bytes());
            }
        }
        response
    }
}

impl PacketStream for TcpStream {
    fn read_packet_command(&mut self) -> IoResult<Packet> {
        let size = try!(self.read_varint());
        if size == 1 {
            let command = try!(self.read_byte());
            Ok(Packet {cmd: command, value: Command})
        } else {
            Err(IoError {
                kind: InvalidInput,
                desc: "Command packet with a size greater than one",
                detail: None
            })
        }
    }

    fn read_packet_data(&mut self) -> IoResult<Packet> {
        let size = try!(self.read_varint());
        if size == 0 {
            return Err(IoError {
                kind: InvalidInput,
                desc: "Data packet with size zero",
                detail: None
            });
        }
        let command = try!(self.read_byte());
        let data = try!(self.read_exact(size - 1));
        Ok(Packet {cmd: command, value: Data(data)})
    }

    fn read_packet_string(&mut self) -> IoResult<Packet> {
        try!(self.read_varint());
        let command = try!(self.read_byte());
        let string_size = try!(self.read_varint());
        let data = try!(self.read_exact(string_size));
        match std::str::from_utf8(data.as_slice()) {
            Some(string) => Ok(Packet {
                cmd: command,
                value: Message(string.to_string())
            }),
            None => Err(IoError {
                kind: InvalidInput,
                desc: "Command packet with a size greater than one",
                detail: None
            })
        }
    }

    fn write_packet(&mut self, packet: Packet) -> IoResult<()> {
        self.write(packet.as_bytes().as_slice())
    }
}

fn process_stream(mut stream: TcpStream) -> IoResult<()> {
    let message = "{\"description\":\"Rustymine Server\",\"players\":{\"max\":0,\"online\":0},\"version\":{\"name\":\"1.8\",\"protocol\":47}}";

    let ip = try!(stream.peer_name()).ip;
    let packet = try!(stream.read_packet_data());
    match packet {
        Packet { cmd: 0, value: Data(data) } => {
            match data[13] {
                // Query
                1 => {
                    println!("Query from {}", ip);

                    // We don't need anything from the second packet sent
                    try!(stream.read_packet_command());

                    // Send back the server status as JSON
                    try!(stream.write_packet(Packet {cmd: 0, value: Message(message.to_string())}));

                    // Then receive and respond to the ping packet
                    let ping = try!(stream.read_packet_data());
                    try!(stream.write_packet(ping));

                },
                // Login
                2 => {
                    match stream.read_packet_string() {
                        Ok(Packet {cmd: _, value: Message(name)}) => {
                            println!("Connection from {} ({})", name, ip);
                        },
                        _ => println!("Invalid login packet")
                    }

                },
                _ => println!("Invalid query packet")
            }
        },

        // Everything else
        _ => println!("Unknown packet")
    }
    Ok(())
}

fn main() {
    let address = "0.0.0.0";
    let port = 25565;
    let mut acceptor = TcpListener::bind(address, port).listen().unwrap();
    println!("Rustymine is listening on {}:{}", address, port);
    for opt_stream in acceptor.incoming() {
        spawn(proc() process_stream(opt_stream.unwrap()).unwrap())
    }
}
<|endoftext|>


<commit_before>use x86::__m128i;
use v128::*;

#[cfg(test)]
use stdsimd_test::assert_instr;

/// Alternatively add and subtract packed single-precision (32-bit)
/// floating-point elements in `a` to/from packed elements in `b`.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(addsub))]
pub unsafe fn _mm_addsub_ps(a: f32x4, b: f32x4) -> f32x4 {
    addsubps(a, b)
}

/// Alternatively add and subtract packed double-precision (64-bit)
/// floating-point elements in `a` to/from packed elements in `b`.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(addsub))]
pub unsafe fn _mm_addsub_pd(a: f64x2, b: f64x2) -> f64x2 {
    addsubpd(a, b)
}

/// Horizontally add adjacent pairs of double-precision (64-bit)
/// floating-point elements in `a` and `b`, and pack the results.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(hadd))]
pub unsafe fn _mm_hadd_pd(a: f64x2, b: f64x2) -> f64x2 {
    haddpd(a, b)
}

/// Load 128-bits of integer data from unaligned memory.
/// This intrinsic may perform better than `_mm_loadu_si128`
/// when the data crosses a cache line boundary.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(lddqu))]
pub unsafe fn _mm_lddqu_si128(mem_addr: *const __m128i) -> __m128i {
    lddqu(mem_addr as *const _)
}

#[allow(improper_ctypes)]
extern {
    #[link_name = "llvm.x86.sse3.addsub.ps"]
    fn addsubps(a: f32x4, b: f32x4) -> f32x4;
    #[link_name = "llvm.x86.sse3.addsub.pd"]
    fn addsubpd(a: f64x2, b: f64x2) -> f64x2;
    #[link_name = "llvm.x86.sse3.hadd.pd"]
    fn haddpd(a: f64x2, b: f64x2) -> f64x2;
    #[link_name = "llvm.x86.sse3.ldu.dq"]
    fn lddqu(mem_addr: *const i8) -> __m128i;
}

#[cfg(test)]
mod tests {
    use stdsimd_test::simd_test;

    use v128::*;
    use x86::sse3 as sse3;

    #[simd_test = "sse3"]
    unsafe fn _mm_addsub_ps() {
        let a = f32x4::new(-1.0, 5.0, 0.0, -10.0);
        let b = f32x4::new(-100.0, 20.0, 0.0, -5.0);
        let r = sse3::_mm_addsub_ps(a, b);
        assert_eq!(r, f32x4::new(99.0, 25.0, 0.0, -15.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_addsub_pd() {
        let a = f64x2::new(-1.0, 5.0);
        let b = f64x2::new(-100.0, 20.0);
        let r = sse3::_mm_addsub_pd(a, b);
        assert_eq!(r, f64x2::new(99.0, 25.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_hadd_pd() {
        let a = f64x2::new(-1.0, 5.0);
        let b = f64x2::new(-100.0, 20.0);
        let r = sse3::_mm_hadd_pd(a, b);
        assert_eq!(r, f64x2::new(4.0, -80.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_lddqu_si128() {
        let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
        let r = sse3::_mm_lddqu_si128(&a);
        assert_eq!(a, r);
    }
}<commit_msg>sse3: _mm_hadd_ps<commit_after>use x86::__m128i;
use v128::*;

#[cfg(test)]
use stdsimd_test::assert_instr;

/// Alternatively add and subtract packed single-precision (32-bit)
/// floating-point elements in `a` to/from packed elements in `b`.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(addsub))]
pub unsafe fn _mm_addsub_ps(a: f32x4, b: f32x4) -> f32x4 {
    addsubps(a, b)
}

/// Alternatively add and subtract packed double-precision (64-bit)
/// floating-point elements in `a` to/from packed elements in `b`.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(addsub))]
pub unsafe fn _mm_addsub_pd(a: f64x2, b: f64x2) -> f64x2 {
    addsubpd(a, b)
}

/// Horizontally add adjacent pairs of double-precision (64-bit)
/// floating-point elements in `a` and `b`, and pack the results.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(hadd))]
pub unsafe fn _mm_hadd_pd(a: f64x2, b: f64x2) -> f64x2 {
    haddpd(a, b)
}

/// Horizontally add adjacent pairs of single-precision (32-bit)
/// floating-point elements in `a` and `b`, and pack the results.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(hadd))]
pub unsafe fn _mm_hadd_ps(a: f32x4, b: f32x4) -> f32x4 {
    haddps(a, b)
}

/// Load 128-bits of integer data from unaligned memory.
/// This intrinsic may perform better than `_mm_loadu_si128`
/// when the data crosses a cache line boundary.
#[inline(always)]
#[target_feature = "+sse3"]
#[cfg_attr(test, assert_instr(lddqu))]
pub unsafe fn _mm_lddqu_si128(mem_addr: *const __m128i) -> __m128i {
    lddqu(mem_addr as *const _)
}

#[allow(improper_ctypes)]
extern {
    #[link_name = "llvm.x86.sse3.addsub.ps"]
    fn addsubps(a: f32x4, b: f32x4) -> f32x4;
    #[link_name = "llvm.x86.sse3.addsub.pd"]
    fn addsubpd(a: f64x2, b: f64x2) -> f64x2;
    #[link_name = "llvm.x86.sse3.hadd.pd"]
    fn haddpd(a: f64x2, b: f64x2) -> f64x2;
    #[link_name = "llvm.x86.sse3.hadd.ps"]
    fn haddps(a: f32x4, b: f32x4) -> f32x4;
    #[link_name = "llvm.x86.sse3.ldu.dq"]
    fn lddqu(mem_addr: *const i8) -> __m128i;
}

#[cfg(test)]
mod tests {
    use stdsimd_test::simd_test;

    use v128::*;
    use x86::sse3 as sse3;

    #[simd_test = "sse3"]
    unsafe fn _mm_addsub_ps() {
        let a = f32x4::new(-1.0, 5.0, 0.0, -10.0);
        let b = f32x4::new(-100.0, 20.0, 0.0, -5.0);
        let r = sse3::_mm_addsub_ps(a, b);
        assert_eq!(r, f32x4::new(99.0, 25.0, 0.0, -15.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_addsub_pd() {
        let a = f64x2::new(-1.0, 5.0);
        let b = f64x2::new(-100.0, 20.0);
        let r = sse3::_mm_addsub_pd(a, b);
        assert_eq!(r, f64x2::new(99.0, 25.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_hadd_pd() {
        let a = f64x2::new(-1.0, 5.0);
        let b = f64x2::new(-100.0, 20.0);
        let r = sse3::_mm_hadd_pd(a, b);
        assert_eq!(r, f64x2::new(4.0, -80.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_hadd_ps() {
        let a = f32x4::new(-1.0, 5.0, 0.0, -10.0);
        let b = f32x4::new(-100.0, 20.0, 0.0, -5.0);
        let r = sse3::_mm_hadd_ps(a, b);
        assert_eq!(r, f32x4::new(4.0, -10.0, -80.0, -5.0));
    }

    #[simd_test = "sse3"]
    unsafe fn _mm_lddqu_si128() {
        let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
        let r = sse3::_mm_lddqu_si128(&a);
        assert_eq!(a, r);
    }
}<|endoftext|>


<commit_before>use component::Component;
use tokio_core::reactor::Handle;
use error::{Error, Result, ErrorKind};
use xcb::{self, Connection};
use xcb_event_stream;
use futures::stream::Stream;

const ATOM_FOCUS_CHANGE: xcb::AtomEnum = 334;

/// This struct is used for creation and storing the refresh rate.
pub struct WindowTitle;

// Get the title of the window that currently is focused
fn get_window_title() -> Result<String> {
    // Connect to Xorg
    let (conn, _) = Connection::connect(None)
        .map_err(|e| ErrorKind::XcbConnection(e))?;

    // Get the window that is currently in focus
    let input_focus_cookie = xcb::get_input_focus(&conn);
    let window = input_focus_cookie.get_reply()?.focus();

    // Use ewmh to poll for the _NET_WM_NAME of the focused window
    let atom = xcb::intern_atom(&conn, true, "_NET_WM_NAME")
        .get_reply()?
        .atom();

    let property_reply = xcb::get_property(&conn, false, window, atom, xcb::ATOM_ANY, 0, 32)
        .get_reply();
    let reply = match property_reply {
        Ok(reply) => reply,
        _ => {
            xcb::get_property(
                &conn,
                false,
                window,
                xcb::ATOM_WM_NAME,
                xcb::ATOM_STRING,
                0,
                32,
            ).get_reply()?
        }
    };

    let name = String::from_utf8_lossy(reply.value());
    Ok(name.into())
}

// Poll the window title on a timer
impl Component for WindowTitle {
    type Error = Error;
    type Stream = Box<Stream<Item = String, Error = Error>>;

    fn stream(self, _: Handle) -> Self::Stream {
        let (conn, screen_num) = Connection::connect(None).unwrap();

        {
            let setup = conn.get_setup();
            let screen = setup.roots().nth(screen_num as usize).unwrap();

            xcb::change_window_attributes(
                &conn,
                screen.root(),
                &[(xcb::CW_EVENT_MASK, xcb::EVENT_MASK_PROPERTY_CHANGE)],
            );
        }

        conn.flush();
        let stream = xcb_event_stream::XcbEventStream::new(conn)
            .filter(|event| unsafe {
                let property_event: &xcb::PropertyNotifyEvent = xcb::cast_event(&event);
                let property_atom = property_event.atom();
                property_atom == ATOM_FOCUS_CHANGE
            })
            .and_then(move |_| get_window_title());

        Box::new(stream)
    }
}
<commit_msg>Change to support all EWMH WMs<commit_after>use component::Component;
use tokio_core::reactor::Handle;
use error::{Error, Result, ErrorKind};
use xcb::{self, Connection};
use xcb_event_stream;
use futures::stream::Stream;

/// This struct is used for creation and storing the refresh rate.
pub struct WindowTitle {
    active_window: xcb::AtomEnum,
    wm_name: xcb::AtomEnum,
}

impl WindowTitle {
    pub fn new() -> Result<WindowTitle> {
        let (conn, _) = Connection::connect(None)
            .map_err(|e| ErrorKind::XcbConnection(e))?;

        let active_window = xcb::intern_atom(&conn, true, "_NET_ACTIVE_WINDOW")
            .get_reply()?
            .atom();
        let wm_name = xcb::intern_atom(&conn, true, "_NET_WM_NAME")
            .get_reply()?
            .atom();

        Ok(WindowTitle {
            active_window,
            wm_name,
        })
    }
}

// Get the title of the window that currently is focused
fn get_window_title(window_title: &WindowTitle) -> Result<String> {
    // Connect to Xorg
    let (conn, screen_num) = Connection::connect(None)
        .map_err(|e| ErrorKind::XcbConnection(e))?;

    // Get the screen for accessing the root window later
    let setup = conn.get_setup();
    let screen = setup
        .roots()
        .nth(screen_num as usize)
        .ok_or("Unable to acquire screen.")?;

    // Get the currently active window
    let property_reply = xcb::get_property(
        &conn,
        false,
        screen.root(),
        window_title.active_window,
        xcb::ATOM_WINDOW,
        0,
        32,
    ).get_reply()?;

    // Get the window from the reply
    // Returns with error if no window has been found
    let active_window_value: &[u32] = property_reply.value();
    if active_window_value.is_empty() {
        return Err("Could not get active window.".into());
    }
    let window = active_window_value[0];

    // Get the title of the active window
    let property_reply = xcb::get_property(
        &conn,
        false,
        window,
        window_title.wm_name,
        xcb::ATOM_ANY,
        0,
        32,
    ).get_reply()?;

    // Convert active window reply to string and return it
    let name = String::from_utf8_lossy(property_reply.value());
    Ok(name.into())
}

// Poll the window title on a timer
impl Component for WindowTitle {
    type Error = Error;
    type Stream = Box<Stream<Item = String, Error = Error>>;

    fn stream(self, _: Handle) -> Self::Stream {
        let (conn, screen_num) = Connection::connect(None).unwrap();

        // Setup the event for the root screen
        {
            let setup = conn.get_setup();
            let screen = setup.roots().nth(screen_num as usize).unwrap();

            xcb::change_window_attributes(
                &conn,
                screen.root(),
                &[(xcb::CW_EVENT_MASK, xcb::EVENT_MASK_PROPERTY_CHANGE)],
            );
        }

        // Start event receiver future
        // Executes `get_window_title` every time window title event is received
        conn.flush();
        let active_window = self.active_window;
        let stream = xcb_event_stream::XcbEventStream::new(conn)
            .filter(move |event| unsafe {
                let property_event: &xcb::PropertyNotifyEvent = xcb::cast_event(&event);
                let property_atom = property_event.atom();
                property_atom == active_window
            })
            .and_then(move |_| get_window_title(&self));

        Box::new(stream)
    }
}
<|endoftext|>


<commit_before>//! WebAssembly interpreter module.

/// Custom user error.
pub trait UserError: 'static + ::std::fmt::Display + ::std::fmt::Debug + Clone + PartialEq {
}

/// Internal interpreter error.
#[derive(Debug, Clone, PartialEq)]
pub enum Error<E> where E: UserError {
	/// Program-level error.
	Program(String),
	/// Validation error.
	Validation(String),
	/// Initialization error.
	Initialization(String),
	/// Function-level error.
	Function(String),
	/// Table-level error.
	Table(String),
	/// Memory-level error.
	Memory(String),
	/// Variable-level error.
	Variable(String),
	/// Global-level error.
	Global(String),
	/// Local-level error.
	Local(String),
	/// Stack-level error.
	Stack(String),
	/// Value-level error.
	Value(String),
	/// Interpreter (code) error.
	Interpreter(String),
	/// Env module error.
	Env(String),
	/// Native module error.
	Native(String),
	/// Trap.
	Trap(String),
	/// Custom user error.
	User(E),
}

impl<E> Into<String> for Error<E> where E: UserError {
	fn into(self) -> String {
		match self {
			Error::Program(s) => s,
			Error::Validation(s) => s,
			Error::Initialization(s) => s,
			Error::Function(s) => s,
			Error::Table(s) => s,
			Error::Memory(s) => s,
			Error::Variable(s) => s,
			Error::Global(s) => s,
			Error::Local(s) => s,
			Error::Stack(s) => s,
			Error::Interpreter(s) => s,
			Error::Value(s) => s,
			Error::Env(s) => s,
			Error::Native(s) => s,
			Error::Trap(s) => format!("trap: {}", s),
			Error::User(e) => format!("user: {}", e),
		}
	}
}

/// Dummy user error.
#[derive(Debug, Clone, PartialEq)]
pub struct DummyUserError;

impl UserError for DummyUserError {}

impl ::std::fmt::Display for DummyUserError {
	fn fmt(&self, _f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { Ok(()) }
}

impl<U> From<U> for Error<U> where U: UserError + Sized {
	fn from(e: U) -> Self {
		Error::User(e)
	}
}

mod env;
mod env_native;
mod imports;
mod memory;
mod module;
mod program;
mod runner;
mod stack;
mod table;
mod validator;
mod value;
mod variable;

#[cfg(test)]
mod tests;

pub use self::memory::MemoryInstance;
pub use self::module::{ModuleInstance, ModuleInstanceInterface,
	ItemIndex, ExportEntryType, CallerContext, ExecutionParams, FunctionSignature};
pub use self::table::TableInstance;
pub use self::program::ProgramInstance;
pub use self::value::RuntimeValue;
pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue};
pub use self::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
pub use self::env::EnvParams;

/// Default type of Error if you do not need any custom user errors.
pub type DummyError = Error<DummyUserError>;

/// Default type of ProgramInstance if you do not need any custom user errors.
/// To work with custom user errors or interpreter internals, use CustomProgramInstance.
pub type DefaultProgramInstance = self::program::ProgramInstance<DummyUserError>;

/// Default type of ModuleInstance if you do not need any custom user errors.
/// To work with custom user errors or interpreter internals, use CustomModuleInstance.
pub type DefaultModuleInstance = self::module::ModuleInstance<DummyUserError>;

/// Default type of ModuleInstanceInterface if you do not need any custom user errors.
/// To work with custom user errors or interpreter internals, use CustomModuleInstanceInterface.
pub type DefaultModuleInstanceInterface = self::module::ModuleInstanceInterface<DummyUserError>;
<commit_msg>add display for errors<commit_after>//! WebAssembly interpreter module.

/// Custom user error.
pub trait UserError: 'static + ::std::fmt::Display + ::std::fmt::Debug + Clone + PartialEq {
}

/// Internal interpreter error.
#[derive(Debug, Clone, PartialEq)]
pub enum Error<E> where E: UserError {
	/// Program-level error.
	Program(String),
	/// Validation error.
	Validation(String),
	/// Initialization error.
	Initialization(String),
	/// Function-level error.
	Function(String),
	/// Table-level error.
	Table(String),
	/// Memory-level error.
	Memory(String),
	/// Variable-level error.
	Variable(String),
	/// Global-level error.
	Global(String),
	/// Local-level error.
	Local(String),
	/// Stack-level error.
	Stack(String),
	/// Value-level error.
	Value(String),
	/// Interpreter (code) error.
	Interpreter(String),
	/// Env module error.
	Env(String),
	/// Native module error.
	Native(String),
	/// Trap.
	Trap(String),
	/// Custom user error.
	User(E),
}

impl<E> Into<String> for Error<E> where E: UserError {
	fn into(self) -> String {
		match self {
			Error::Program(s) => s,
			Error::Validation(s) => s,
			Error::Initialization(s) => s,
			Error::Function(s) => s,
			Error::Table(s) => s,
			Error::Memory(s) => s,
			Error::Variable(s) => s,
			Error::Global(s) => s,
			Error::Local(s) => s,
			Error::Stack(s) => s,
			Error::Interpreter(s) => s,
			Error::Value(s) => s,
			Error::Env(s) => s,
			Error::Native(s) => s,
			Error::Trap(s) => format!("trap: {}", s),
			Error::User(e) => format!("user: {}", e),
		}
	}
}

impl<E> ::std::fmt::Display for Error<E> where E: UserError {
	fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
		match *self {
			Error::Program(ref s) => write!(f, "Program: {}", s),
			Error::Validation(ref s) => write!(f, "Validation: {}", s),
			Error::Initialization(ref s) => write!(f, "Initialization: {}", s),
			Error::Function(ref s) => write!(f, "Function: {}", s),
			Error::Table(ref s) => write!(f, "Table: {}", s),
			Error::Memory(ref s) => write!(f, "Memory: {}", s),
			Error::Variable(ref s) => write!(f, "Variable: {}", s),
			Error::Global(ref s) => write!(f, "Global: {}", s),
			Error::Local(ref s) => write!(f, "Local: {}", s),
			Error::Stack(ref s) => write!(f, "Stack: {}", s),
			Error::Interpreter(ref s) => write!(f, "Interpreter: {}", s),
			Error::Value(ref s) => write!(f, "Value: {}", s),
			Error::Env(ref s) => write!(f, "Env: {}", s),
			Error::Native(ref s) => write!(f, "Native: {}", s),
			Error::Trap(ref s) => write!(f, "Trap: {}", s),
			Error::User(ref e) => write!(f, "User: {}", e),
		}
	}
}

/// Dummy user error.
#[derive(Debug, Clone, PartialEq)]
pub struct DummyUserError;

impl UserError for DummyUserError {}

impl ::std::fmt::Display for DummyUserError {
	fn fmt(&self, _f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { Ok(()) }
}

impl<U> From<U> for Error<U> where U: UserError + Sized {
	fn from(e: U) -> Self {
		Error::User(e)
	}
}

mod env;
mod env_native;
mod imports;
mod memory;
mod module;
mod program;
mod runner;
mod stack;
mod table;
mod validator;
mod value;
mod variable;

#[cfg(test)]
mod tests;

pub use self::memory::MemoryInstance;
pub use self::module::{ModuleInstance, ModuleInstanceInterface,
	ItemIndex, ExportEntryType, CallerContext, ExecutionParams, FunctionSignature};
pub use self::table::TableInstance;
pub use self::program::ProgramInstance;
pub use self::value::RuntimeValue;
pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue};
pub use self::env_native::{env_native_module, UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor};
pub use self::env::EnvParams;

/// Default type of Error if you do not need any custom user errors.
pub type DummyError = Error<DummyUserError>;

/// Default type of ProgramInstance if you do not need any custom user errors.
/// To work with custom user errors or interpreter internals, use CustomProgramInstance.
pub type DefaultProgramInstance = self::program::ProgramInstance<DummyUserError>;

/// Default type of ModuleInstance if you do not need any custom user errors.
/// To work with custom user errors or interpreter internals, use CustomModuleInstance.
pub type DefaultModuleInstance = self::module::ModuleInstance<DummyUserError>;

/// Default type of ModuleInstanceInterface if you do not need any custom user errors.
/// To work with custom user errors or interpreter internals, use CustomModuleInstanceInterface.
pub type DefaultModuleInstanceInterface = self::module::ModuleInstanceInterface<DummyUserError>;
<|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.

use core::ptr::*;

#[test]
fn test() {
    unsafe {
        struct Pair {
            fst: isize,
            snd: isize
        };
        let mut p = Pair {fst: 10, snd: 20};
        let pptr: *mut Pair = &mut p;
        let iptr: *mut isize = pptr as *mut isize;
        assert_eq!(*iptr, 10);
        *iptr = 30;
        assert_eq!(*iptr, 30);
        assert_eq!(p.fst, 30);

        *pptr = Pair {fst: 50, snd: 60};
        assert_eq!(*iptr, 50);
        assert_eq!(p.fst, 50);
        assert_eq!(p.snd, 60);

        let v0 = vec![32000u16, 32001u16, 32002u16];
        let mut v1 = vec![0u16, 0u16, 0u16];

        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
        assert!((v1[0] == 0u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 32000u16));
    }
}

#[test]
fn test_is_null() {
    let p: *const isize = null();
    assert!(p.is_null());

    let q = unsafe { p.offset(1) };
    assert!(!q.is_null());

    let mp: *mut isize = null_mut();
    assert!(mp.is_null());

    let mq = unsafe { mp.offset(1) };
    assert!(!mq.is_null());
}

#[test]
fn test_as_ref() {
    unsafe {
        let p: *const isize = null();
        assert_eq!(p.as_ref(), None);

        let q: *const isize = &2;
        assert_eq!(q.as_ref().unwrap(), &2);

        let p: *mut isize = null_mut();
        assert_eq!(p.as_ref(), None);

        let q: *mut isize = &mut 2;
        assert_eq!(q.as_ref().unwrap(), &2);

        // Lifetime inference
        let u = 2isize;
        {
            let p = &u as *const isize;
            assert_eq!(p.as_ref().unwrap(), &2);
        }
    }
}

#[test]
fn test_as_mut() {
    unsafe {
        let p: *mut isize = null_mut();
        assert!(p.as_mut() == None);

        let q: *mut isize = &mut 2;
        assert!(q.as_mut().unwrap() == &mut 2);

        // Lifetime inference
        let mut u = 2isize;
        {
            let p = &mut u as *mut isize;
            assert!(p.as_mut().unwrap() == &mut 2);
        }
    }
}

#[test]
fn test_ptr_addition() {
    unsafe {
        let xs = vec![5; 16];
        let mut ptr = xs.as_ptr();
        let end = ptr.offset(16);

        while ptr < end {
            assert_eq!(*ptr, 5);
            ptr = ptr.offset(1);
        }

        let mut xs_mut = xs;
        let mut m_ptr = xs_mut.as_mut_ptr();
        let m_end = m_ptr.offset(16);

        while m_ptr < m_end {
            *m_ptr += 5;
            m_ptr = m_ptr.offset(1);
        }

        assert!(xs_mut == vec![10; 16]);
    }
}

#[test]
fn test_ptr_subtraction() {
    unsafe {
        let xs = vec![0,1,2,3,4,5,6,7,8,9];
        let mut idx = 9;
        let ptr = xs.as_ptr();

        while idx >= 0 {
            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
            idx = idx - 1;
        }

        let mut xs_mut = xs;
        let m_start = xs_mut.as_mut_ptr();
        let mut m_ptr = m_start.offset(9);

        while m_ptr >= m_start {
            *m_ptr += *m_ptr;
            m_ptr = m_ptr.offset(-1);
        }

        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
    }
}

#[test]
fn test_set_memory() {
    let mut xs = [0u8; 20];
    let ptr = xs.as_mut_ptr();
    unsafe { write_bytes(ptr, 5u8, xs.len()); }
    assert!(xs == [5u8; 20]);
}

#[test]
fn test_unsized_unique() {
    let xs: &mut [i32] = &mut [1, 2, 3];
    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
    let ys = unsafe { &mut **ptr };
    let zs: &mut [i32] = &mut [1, 2, 3];
    assert!(ys == zs);
}

#[test]
fn test_variadic_fnptr() {
    use core::hash::{Hash, SipHasher};
    extern "C" {
        fn printf(_: *const u8, ...);
    }
    let p: unsafe extern "C" fn(*const u8, ...) = printf;
    let q = p.clone();
    assert_eq!(p, q);
    assert!(!(p < q));
    let mut s = SipHasher::new();
    assert_eq!(p.hash(&mut s), q.hash(&mut s));
}
<commit_msg>Fix the test_variadic_ptr fn on printf-less sys<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.

use core::ptr::*;

#[test]
fn test() {
    unsafe {
        struct Pair {
            fst: isize,
            snd: isize
        };
        let mut p = Pair {fst: 10, snd: 20};
        let pptr: *mut Pair = &mut p;
        let iptr: *mut isize = pptr as *mut isize;
        assert_eq!(*iptr, 10);
        *iptr = 30;
        assert_eq!(*iptr, 30);
        assert_eq!(p.fst, 30);

        *pptr = Pair {fst: 50, snd: 60};
        assert_eq!(*iptr, 50);
        assert_eq!(p.fst, 50);
        assert_eq!(p.snd, 60);

        let v0 = vec![32000u16, 32001u16, 32002u16];
        let mut v1 = vec![0u16, 0u16, 0u16];

        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
        assert!((v1[0] == 0u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 32000u16));
    }
}

#[test]
fn test_is_null() {
    let p: *const isize = null();
    assert!(p.is_null());

    let q = unsafe { p.offset(1) };
    assert!(!q.is_null());

    let mp: *mut isize = null_mut();
    assert!(mp.is_null());

    let mq = unsafe { mp.offset(1) };
    assert!(!mq.is_null());
}

#[test]
fn test_as_ref() {
    unsafe {
        let p: *const isize = null();
        assert_eq!(p.as_ref(), None);

        let q: *const isize = &2;
        assert_eq!(q.as_ref().unwrap(), &2);

        let p: *mut isize = null_mut();
        assert_eq!(p.as_ref(), None);

        let q: *mut isize = &mut 2;
        assert_eq!(q.as_ref().unwrap(), &2);

        // Lifetime inference
        let u = 2isize;
        {
            let p = &u as *const isize;
            assert_eq!(p.as_ref().unwrap(), &2);
        }
    }
}

#[test]
fn test_as_mut() {
    unsafe {
        let p: *mut isize = null_mut();
        assert!(p.as_mut() == None);

        let q: *mut isize = &mut 2;
        assert!(q.as_mut().unwrap() == &mut 2);

        // Lifetime inference
        let mut u = 2isize;
        {
            let p = &mut u as *mut isize;
            assert!(p.as_mut().unwrap() == &mut 2);
        }
    }
}

#[test]
fn test_ptr_addition() {
    unsafe {
        let xs = vec![5; 16];
        let mut ptr = xs.as_ptr();
        let end = ptr.offset(16);

        while ptr < end {
            assert_eq!(*ptr, 5);
            ptr = ptr.offset(1);
        }

        let mut xs_mut = xs;
        let mut m_ptr = xs_mut.as_mut_ptr();
        let m_end = m_ptr.offset(16);

        while m_ptr < m_end {
            *m_ptr += 5;
            m_ptr = m_ptr.offset(1);
        }

        assert!(xs_mut == vec![10; 16]);
    }
}

#[test]
fn test_ptr_subtraction() {
    unsafe {
        let xs = vec![0,1,2,3,4,5,6,7,8,9];
        let mut idx = 9;
        let ptr = xs.as_ptr();

        while idx >= 0 {
            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
            idx = idx - 1;
        }

        let mut xs_mut = xs;
        let m_start = xs_mut.as_mut_ptr();
        let mut m_ptr = m_start.offset(9);

        while m_ptr >= m_start {
            *m_ptr += *m_ptr;
            m_ptr = m_ptr.offset(-1);
        }

        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
    }
}

#[test]
fn test_set_memory() {
    let mut xs = [0u8; 20];
    let ptr = xs.as_mut_ptr();
    unsafe { write_bytes(ptr, 5u8, xs.len()); }
    assert!(xs == [5u8; 20]);
}

#[test]
fn test_unsized_unique() {
    let xs: &mut [i32] = &mut [1, 2, 3];
    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
    let ys = unsafe { &mut **ptr };
    let zs: &mut [i32] = &mut [1, 2, 3];
    assert!(ys == zs);
}

#[test]
#[allow(warnings)]
// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
// ABI, or even point to an actual executable code, because the function itself is never invoked.
#[no_mangle]
pub fn test_variadic_fnptr() {
    use core::hash::{Hash, SipHasher};
    extern {
        fn test_variadic_fnptr(_: u64, ...) -> f64;
    }
    let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
    let q = p.clone();
    assert_eq!(p, q);
    assert!(!(p < q));
    let mut s = SipHasher::new();
    assert_eq!(p.hash(&mut s), q.hash(&mut s));
}
<|endoftext|>


<commit_before>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  /// Data containing one of the four different types of subframes.
  pub data: Data,
  /// Number of wasted bits within each sample.
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  /// A single value that represents a constant subframe.
  Constant(i32),
  /// An uncompressed subframe.
  Verbatim(Vec<i32>),
  /// Fixed linear prediction subframe.
  Fixed(Fixed),
  /// FIR linear prediction subframe.
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// Polynomial order.
  pub order: u8,
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i32; MAX_FIXED_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// FIR order.
  pub order: u8,
  /// Quantized FIR filter coefficient precision in bits.
  pub qlp_coeff_precision: u8,
  /// Quantized linear predictor coefficient shift needed in bits.
  pub quantization_level: i8,
  /// FIR filter coefficients.
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i32; MAX_LPC_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i32>,
}

/// Header for the entropy coding method.
#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  /// The type of coding method being used.
  pub method_type: CodingMethod,
  /// Data for each entropy coding method partition.
  pub data: PartitionedRice,
}

/// The available entropy coding methods.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
}

impl PartitionedRiceContents {
  pub fn new(capacity: usize) -> PartitionedRiceContents {
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
    }
  }
}
<commit_msg>Add variant documentation for `CodingMethod`<commit_after>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  /// Data containing one of the four different types of subframes.
  pub data: Data,
  /// Number of wasted bits within each sample.
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  /// A single value that represents a constant subframe.
  Constant(i32),
  /// An uncompressed subframe.
  Verbatim(Vec<i32>),
  /// Fixed linear prediction subframe.
  Fixed(Fixed),
  /// FIR linear prediction subframe.
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// Polynomial order.
  pub order: u8,
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i32; MAX_FIXED_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  /// Residual coding method.
  pub entropy_coding_method: EntropyCodingMethod,
  /// FIR order.
  pub order: u8,
  /// Quantized FIR filter coefficient precision in bits.
  pub qlp_coeff_precision: u8,
  /// Quantized linear predictor coefficient shift needed in bits.
  pub quantization_level: i8,
  /// FIR filter coefficients.
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  /// Samples used to warm up, or prime, the predictor.
  pub warmup: [i32; MAX_LPC_ORDER],
  /// Remaining samples after the warm up samples.
  pub residual: Vec<i32>,
}

/// Header for the entropy coding method.
#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  /// The type of coding method being used.
  pub method_type: CodingMethod,
  /// Data for each entropy coding method partition.
  pub data: PartitionedRice,
}

/// The available entropy coding methods.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  /// Coding partition with a 4-bit Rice parameter.
  PartitionedRice,
  /// Coding partition with a 5-bit Rice parameter.
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
}

impl PartitionedRiceContents {
  pub fn new(capacity: usize) -> PartitionedRiceContents {
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
    }
  }
}
<|endoftext|>


<commit_before>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  /// Data containing one of the four different types of subframes.
  pub data: Data,
  /// Number of wasted bits within each sample.
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

/// Header for the entropy coding method.
#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

/// The available entropy coding methods.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<commit_msg>Add variant documentation `subframe::Data` enum<commit_after>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  /// Data containing one of the four different types of subframes.
  pub data: Data,
  /// Number of wasted bits within each sample.
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  /// A single value that represents a constant subframe.
  Constant(i32),
  /// An uncompressed suframe.
  Verbatim(Vec<i32>),
  /// Fixed linear prediction subframe.
  Fixed(Fixed),
  /// FIR linear prediction subframe.
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

/// Header for the entropy coding method.
#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

/// The available entropy coding methods.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<|endoftext|>