<commit_before>syn_dev::r#mod! {
    // Write Rust code here and run `cargo check` to have Syn parse it.

//! Ergonomic, checked cast functions for primitive types
//!
//! This crate provides one checked cast function for each numeric primitive.
//! Use these functions to perform a cast from any other numeric primitive:
//!
//! ```
//! extern crate cast;
//!
//! use cast::{u8, u16, Error};
//!
//! # fn main() {
//! // Infallible operations, like integer promotion, are equivalent to a normal
//! // cast with `as`
//! assert_eq!(u16(0u8), 0u16);
//!
//! // Everything else will return a `Result` depending on the success of the
//! // operation
//! assert_eq!(u8(0u16), Ok(0u8));
//! assert_eq!(u8(256u16), Err(Error::Overflow));
//! assert_eq!(u8(-1i8), Err(Error::Underflow));
//! assert_eq!(u8(1. / 0.), Err(Error::Infinite));
//! assert_eq!(u8(0. / 0.), Err(Error::NaN));
//! # }
//! ```
//!
//! There are no namespace problems between these functions, the "primitive
//! modules" in `core`/`std` and the built-in primitive types, so all them can
//! be in the same scope:
//!
//! ```
//! extern crate cast;
//!
//! use std::u8;
//! use cast::{u8, u16};
//!
//! # fn main() {
//! // `u8` as a type
//! let x: u8 = 0;
//! // `u8` as a module
//! let y = u16(u8::MAX);
//! // `u8` as a function
//! let z = u8(y).unwrap();
//! # }
//! ```
//!
//! The checked cast functionality is also usable with type aliases via the
//! `cast` static method:
//!
//! ```
//! extern crate cast;
//!
//! use std::os::raw::c_ulonglong;
//! // NOTE avoid shadowing `std::convert::From` - cf. rust-lang/rfcs#1311
//! use cast::From as _0;
//!
//! # fn main() {
//! assert_eq!(c_ulonglong::cast(0u8), 0u64);
//! # }
//! ```
//!
//! This crate also provides a `From` trait that can be used, for example,
//! to create a generic function that accepts any type that can be infallibly
//! casted to `u32`.
//!
//! ```
//! extern crate cast;
//!
//! fn to_u32<T>(x: T) -> u32
//!     // reads as: "where u32 can be casted from T with output u32"
//!     where u32: cast::From<T, Output=u32>,
//! {
//!     cast::u32(x)
//! }
//!
//! # fn main() {
//! assert_eq!(to_u32(0u8), 0u32);
//! assert_eq!(to_u32(1u16), 1u32);
//! assert_eq!(to_u32(2u32), 2u32);
//!
//! // to_u32(-1i32);  // Compile error
//! # }
//! ```
//!
//! ## Minimal Supported Rust Version
//!
//! This crate is guaranteed to compile on stable Rust 1.13 and up. It *might* compile on older
//! versions but that may change in any new patch release.
//!
//! ## Building without `std`
//!
//! This crate can be used without Rust's `std` crate by declaring it as
//! follows in your `Cargo.toml`:
//!
//! ``` toml
//! cast = { version = "*", default-features = false }
//! ```

#![deny(missing_docs)]
#![deny(warnings)]
#![allow(const_err)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(all(feature = "x128", not(stable_i128)), feature(i128_type, i128))]

#[cfg(feature = "std")]
extern crate core;

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

use core::fmt;
#[cfg(feature = "std")]
use std::error;

#[cfg(test)]
mod test;

/// Cast errors
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error {
    /// Infinite value casted to a type that can only represent finite values
    Infinite,
    /// NaN value casted to a type that can't represent a NaN value
    NaN,
    /// Source value is greater than the maximum value that the destination type
    /// can hold
    Overflow,
    /// Source value is smaller than the minimum value that the destination type
    /// can hold
    Underflow,
}

impl Error {
    /// A private helper function that implements `description`, because
    /// `description` is only available when we have `std` enabled.
    fn description_helper(&self) -> &str {
        match *self {
            Error::Infinite => "Cannot store infinite value in finite type",
            Error::NaN => "Cannot store NaN in type which does not support it",
            Error::Overflow => "Overflow during numeric conversion",
            Error::Underflow => "Underflow during numeric conversion",
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description_helper())
    }
}

#[cfg(feature = "std")]
impl error::Error for Error {
    fn description(&self) -> &str {
        self.description_helper()
    }
}

/// The "cast from" operation
pub trait From<Src> {
    /// The result of the cast operation: either `Self` or `Result<Self, Error>`
    type Output;

    /// Checked cast from `Src` to `Self`
    fn cast(Src) -> Self::Output;
}

macro_rules! fns {
    ($($ty:ident),+) => {
        $(
            /// Checked cast function
            #[inline]
            pub fn $ty<T>(x: T) -> <$ty as From<T>>::Output
                where $ty: From<T>
            {
                <$ty as From<T>>::cast(x)
            }
         )+
    }
}

fns!(f32, f64, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);

#[cfg(feature = "x128")]
fns!(i128, u128);

/// `$dst` can hold any value of `$src`
macro_rules! promotion {
    ($($src:ty => $($dst: ty),+);+;) => {
        $(
            $(
                impl From<$src> for $dst {
                    type Output = $dst;

                    #[inline]
                    fn cast(src: $src) -> $dst {
                        src as $dst
                    }
                }
            )+
        )+
    }
}

/// `$dst` can hold any positive value of `$src`
macro_rules! half_promotion {
    ($($src:ty => $($dst:ty),+);+;) => {
        $(
            $(
                impl From<$src> for $dst {
                    type Output = Result<$dst, Error>;

                    #[inline]
                    fn cast(src: $src) -> Self::Output {
                        if src < 0 {
                            Err(Error::Underflow)
                        } else {
                            Ok(src as $dst)
                        }
                    }
                }
            )+
        )+
    }
}

/// From an unsigned `$src` to a smaller `$dst`
macro_rules! from_unsigned {
    ($($src:ident => $($dst:ident),+);+;) => {
        $(
            $(
                impl From<$src> for $dst {
                    type Output = Result<$dst, Error>;

                    #[inline]
                    fn cast(src: $src) -> Self::Output {
                        use core::$dst;

                        if src > $dst::MAX as $src {
                            Err(Error::Overflow)
                        } else {
                            Ok(src as $dst)
                        }
                    }
                }
            )+
        )+
    }
}

/// From a signed `$src` to a smaller `$dst`
macro_rules! from_signed {
    ($($src:ident => $($dst:ident),+);+;) => {
        $(
            $(
                impl From<$src> for $dst {
                    type Output = Result<$dst, Error>;

                    #[inline]
                    fn cast(src: $src) -> Self::Output {
                        use core::$dst;

                        Err(if src < $dst::MIN as $src {
                            Error::Underflow
                        } else if src > $dst::MAX as $src {
                            Error::Overflow
                        } else {
                            return Ok(src as $dst);
                        })
                    }
                }
            )+
        )+
    }
}

/// From a float `$src` to an integer `$dst`
macro_rules! from_float {
    ($($src:ident, $usrc:ident => $($dst:ident),+);+;) => {
        $(
            $(
                impl From<$src> for $dst {
                    type Output = Result<$dst, Error>;

                    #[inline]
                    fn cast(src: $src) -> Self::Output {
                        use core::{$dst, $src};

                        Err(if src != src {
                            Error::NaN
                        } else if src == $src::INFINITY ||
                            src == $src::NEG_INFINITY {
                            Error::Infinite
                        } else if {
                            // we subtract 1 ULP (unit of least precision) here because some
                            // lossy conversions like `u64::MAX as f64` round *up* and we want
                            // to avoid this evaluating to false in that case
                            use core::mem::transmute;
                            let max = unsafe {
                                transmute::<_, $src>(transmute::<_, $usrc>($dst::MAX as $src) - 1)
                            };
                            src > max
                        } {
                            Error::Overflow
                        } else if $dst::MIN == 0 {
                            // when casting to unsigned integer, negative values close to 0 but
                            // larger than 1.0 should be truncated to 0; this behavior matches
                            // casting from a float to a signed integer
                            if src <= -1.0 {
                                Error::Underflow
                            } else {
                                return Ok(src as $dst);
                            }
                        } else if src < $dst::MIN as $src {
                            Error::Underflow
                        } else  {
                            return Ok(src as $dst);
                        })
                    }
                }
            )+
        )+
    }
}

/// From a float `$src` to an integer `$dst`, where $dst is large enough to contain
/// all values of `$src`. We can't ever overflow here
#[cfg(feature = "x128")]
macro_rules! from_float_dst {
    ($($src:ident => $($dst:ident),+);+;) => {
        $(
            $(
                impl From<$src> for $dst {
                     type Output = Result<$dst, Error>;

                    #[inline]
                    #[allow(unused_comparisons)]
                    fn cast(src: $src) -> Self::Output {
                        use core::{$dst, $src};

                        Err(if src != src {
                            Error::NaN
                        } else if src == $src::INFINITY ||
                            src == $src::NEG_INFINITY {
                            Error::Infinite
                        } else if ($dst::MIN == 0) && src <= -1.0 {
                            Error::Underflow
                        } else {
                            return Ok(src as $dst);
                        })
                    }
                }
            )+
        )+
    }
}

// PLAY TETRIS! ;-)

#[cfg(target_pointer_width = "32")]
mod _32 {
    use {Error, From};

    // Signed
    promotion! {
        i8    => f32, f64, i8, i16, i32, isize, i64;
        i16   => f32, f64,     i16, i32, isize, i64;
        i32   => f32, f64,          i32, isize, i64;
        isize => f32, f64,          i32, isize, i64;
        i64   => f32, f64,                      i64;
    }

    half_promotion! {
        i8    =>                                     u8, u16, u32, usize, u64;
        i16   =>                                         u16, u32, usize, u64;
        i32   =>                                              u32, usize, u64;
        isize =>                                              u32, usize, u64;
        i64   =>                                                          u64;
    }

    from_signed! {

        i16   =>           i8,                       u8;
        i32   =>           i8, i16,                  u8, u16;
        isize =>           i8, i16,                  u8, u16;
        i64   =>           i8, i16, i32, isize,      u8, u16, u32, usize;
    }

    // Unsigned
    promotion! {
        u8    => f32, f64,     i16, i32, isize, i64, u8, u16, u32, usize, u64;
        u16   => f32, f64,          i32, isize, i64,     u16, u32, usize, u64;
        u32   => f32, f64,                      i64,          u32, usize, u64;
        usize => f32, f64,                      i64,          u32, usize, u64;
        u64   => f32, f64,                                                u64;
    }

    from_unsigned! {
        u8    =>           i8;
        u16   =>           i8, i16,                  u8;
        u32   =>           i8, i16, i32, isize,      u8, u16;
        usize =>           i8, i16, i32, isize,      u8, u16;
        u64   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize;
    }

    // Float
    promotion! {
        f32   => f32, f64;
        f64   =>      f64;
    }

    from_float! {
        f32, u32 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
        f64, u64 =>        i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
    }
}

#[cfg(target_pointer_width = "64")]
mod _64 {
    use {Error, From};

    // Signed
    promotion! {
        i8    => f32, f64, i8, i16, i32, i64, isize;
        i16   => f32, f64,     i16, i32, i64, isize;
        i32   => f32, f64,          i32, i64, isize;
        i64   => f32, f64,               i64, isize;
        isize => f32, f64,               i64, isize;
    }

    half_promotion! {
        i8    =>                                     u8, u16, u32, u64, usize;
        i16   =>                                         u16, u32, u64, usize;
        i32   =>                                              u32, u64, usize;
        i64   =>                                                   u64, usize;
        isize =>                                                   u64, usize;
    }

    from_signed! {

        i16   =>           i8,                       u8;
        i32   =>           i8, i16,                  u8, u16;
        i64   =>           i8, i16, i32,             u8, u16, u32;
        isize =>           i8, i16, i32,             u8, u16, u32;
    }

    // Unsigned
    promotion! {
        u8    => f32, f64,     i16, i32, i64, isize, u8, u16, u32, u64, usize;
        u16   => f32, f64,          i32, i64, isize,     u16, u32, u64, usize;
        u32   => f32, f64,               i64, isize,          u32, u64, usize;
        u64   => f32, f64,                                         u64, usize;
        usize => f32, f64,                                         u64, usize;
    }

    from_unsigned! {
        u8    =>           i8;
        u16   =>           i8, i16,                  u8;
        u32   =>           i8, i16, i32,             u8, u16;
        u64   =>           i8, i16, i32, i64, isize, u8, u16, u32;
        usize =>           i8, i16, i32, i64, isize, u8, u16, u32;
    }

    // Float
    promotion! {
        f32  => f32, f64;
        f64  =>      f64;
    }

    from_float! {
        f32, u32  =>       i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
        f64, u64  =>       i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
    }
}

#[cfg(feature = "x128")]
mod _x128 {
    use {Error, From};

    // Signed
    promotion! {
        i8    =>                              i128;
        i16   =>                              i128;
        i32   =>                              i128;
        i64   =>                              i128;
        isize =>                              i128;
        i128  => f32, f64,                    i128;
    }

    half_promotion! {
        i8    =>                                                              u128;
        i16   =>                                                              u128;
        i32   =>                                                              u128;
        i64   =>                                                              u128;
        isize =>                                                              u128;
        i128  =>                                                              u128;
    }

    from_signed! {
        i128  =>           i8, i16, i32, i64,       isize, u8, u16, u32, u64,       usize;
    }

    // Unsigned
    promotion! {
        u8    =>                              i128,                           u128;
        u16   =>                              i128,                           u128;
        u32   =>                              i128,                           u128;
        u64   =>                              i128,                           u128;
        usize =>                              i128,                           u128;
        u128  =>      f64,                                                    u128;
    }

    from_unsigned! {
        u128 => f32,       i8, i16, i32, i64, i128, isize, u8, u16, u32, u64,       usize;
    }

    // Float
    from_float! {
        f32, u32  => i128;
        f64, u64  => i128, u128;
    }

    from_float_dst! {
        f32       =>       u128;
    }
}

// The missing piece
impl From<f64> for f32 {
    type Output = Result<f32, Error>;

    #[inline]
    fn cast(src: f64) -> Self::Output {
        use core::{f32, f64};

        if src != src || src == f64::INFINITY || src == f64::NEG_INFINITY {
            Ok(src as f32)
        } else if src < f32::MIN as f64 {
            Err(Error::Underflow)
        } else if src > f32::MAX as f64 {
            Err(Error::Overflow)
        } else {
            Ok(src as f32)
        }
    }
}
}
<commit_msg>Delete unintentional test code from dev/main.rs<commit_after>syn_dev::r#mod! {
    // Write Rust code here and run `cargo check` to have Syn parse it.

}
<|endoftext|>


<commit_before>//! Objective-C Runtime bindings and wrapper for Rust.

#![crate_name = "objc"]
#![crate_type = "lib"]

#![warn(missing_docs)]

extern crate libc;
extern crate malloc_buf;

#[cfg(test)]
extern crate objc_test_utils;

pub use id::{Id, Owned, Ownership, Shared, ShareId};
pub use encode::{Encode, Encoding};
pub use message::{Message, MessageArguments};
pub use weak::WeakId;

#[macro_use]
mod macros;

pub mod runtime;
mod id;
pub mod block;
pub mod declare;
mod encode;
mod message;
mod weak;

#[cfg(test)]
mod test_utils;
<commit_msg>Added some crate documentation with examples.<commit_after>/*!
Objective-C Runtime bindings and wrapper for Rust.

# Messaging objects

Objective-C objects can be messaged using the [`msg_send!`](macro.msg_send!.html) macro:

```
# #[macro_use] extern crate objc;
# use objc::runtime::{BOOL, Class, Object};
# fn main() {
# unsafe {
let cls = Class::get("NSObject").unwrap();
let obj: *mut Object = msg_send![cls, new];
let hash: usize = msg_send![obj, hash];
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
// Even void methods must have their return type annotated
let _: () = msg_send![obj, release];
# }
# }
```

# Reference counting

Objective-C objects are reference counted; to ensure that they are retained and
released at the proper times, we can use the [`Id`](struct.Id.html) struct.

To enforce aliasing rules, an `Id` can be either owned or shared; if it is
owned, meaning the `Id` is the only reference to the object, it can be mutably
dereferenced. An owned `Id` can be downgraded to a [`ShareId`](type.ShareId.html)
which can be cloned to allow multiple references.

Weak references may be created using the [`WeakId`](struct.WeakId.html) struct.

```
# #[macro_use] extern crate objc;
# use objc::runtime::{BOOL, Class, Object};
# use objc::{Id, WeakId};
# fn main() {
let cls = Class::get("NSObject").unwrap();
let obj: Id<Object> = unsafe {
    Id::from_retained_ptr(msg_send![cls, new])
};
// obj will be released when it goes out of scope

// share the object so we can clone it
let obj = obj.share();
let another_ref = obj.clone();
// dropping our other reference will decrement the retain count
drop(another_ref);

let weak = WeakId::new(&obj);
assert!(weak.load().is_some());
// After the object is deallocated, our weak pointer returns none
drop(obj);
assert!(weak.load().is_none());
# }
```

# Calling and creating Blocks

Objective-C blocks can be called and created using the functionality of the
[`block`](block/index.html) module.

# Declaring classes

Objective-C classes can even be declared from Rust using the functionality of
the [`declare`](declare/index.html) module.
*/

#![crate_name = "objc"]
#![crate_type = "lib"]

#![warn(missing_docs)]

extern crate libc;
extern crate malloc_buf;

#[cfg(test)]
extern crate objc_test_utils;

pub use id::{Id, Owned, Ownership, Shared, ShareId};
pub use encode::{Encode, Encoding};
pub use message::{Message, MessageArguments};
pub use weak::WeakId;

#[macro_use]
mod macros;

pub mod runtime;
mod id;
pub mod block;
pub mod declare;
mod encode;
mod message;
mod weak;

#[cfg(test)]
mod test_utils;
<|endoftext|>


<commit_before>// Internal Dependencies ------------------------------------------------------
use ::bot::BotConfig;
use ::core::member::Member;
use ::core::server::Server;
use ::core::message::MessageOrigin;
use ::command::{Command, CommandImplementation};
use ::actions::{ActionGroup, PlayEffects, SendMessage};

// Command Implementation -----------------------------------------------------
pub struct PlayEffectCommand {
    queued: bool
}

impl PlayEffectCommand {

    pub fn instant() -> PlayEffectCommand {
        PlayEffectCommand {
            queued: false
        }
    }

    pub fn queued() -> PlayEffectCommand {
        PlayEffectCommand {
            queued: true
        }
    }

}

impl CommandImplementation for PlayEffectCommand {

    fn run(
        &self,
        command: Command,
        server: &Server,
        member: &Member,
        config: &BotConfig

    ) -> ActionGroup {
        if command.message.origin == MessageOrigin::DirectMessage {
            self.requires_unique_server(command)

        } else if command.arguments.is_empty() {
            self.delete_and_send(command.message, SendMessage::public(
                &command.message,
                format!("Usage: `!{} <effect_name>`", if self.queued {
                    "q"

                } else {
                    "s"
                })
            ))

        } else {

            let effects = server.map_effects(
                &command.arguments[..],
                false,
                config
            );

            if effects.is_empty() {
                self.delete_and_send(command.message, SendMessage::public(
                    &command.message,
                    format!("No matching effect(s) found on {}.", server.name)
                ))

            } else if let Some(channel_id) = member.voice_channel_id {
                self.delete_and_send(command.message, PlayEffects::new(
                    command.message.server_id,
                    channel_id,
                    effects,
                    self.queued
                ))

            } else {
                self.delete_and_send(command.message, SendMessage::public(
                    &command.message,
                    format!(
                        "You must be in a voice channel on {} in order to play sound effects.",
                        server.name
                    )
                ))
            }

        }

    }

}

<commit_msg>Fix playback error messages being send to public channels.<commit_after>// Internal Dependencies ------------------------------------------------------
use ::bot::BotConfig;
use ::core::member::Member;
use ::core::server::Server;
use ::core::message::MessageOrigin;
use ::command::{Command, CommandImplementation};
use ::actions::{ActionGroup, PlayEffects, SendMessage};

// Command Implementation -----------------------------------------------------
pub struct PlayEffectCommand {
    queued: bool
}

impl PlayEffectCommand {

    pub fn instant() -> PlayEffectCommand {
        PlayEffectCommand {
            queued: false
        }
    }

    pub fn queued() -> PlayEffectCommand {
        PlayEffectCommand {
            queued: true
        }
    }

}

impl CommandImplementation for PlayEffectCommand {

    fn run(
        &self,
        command: Command,
        server: &Server,
        member: &Member,
        config: &BotConfig

    ) -> ActionGroup {
        if command.message.origin == MessageOrigin::DirectMessage {
            self.requires_unique_server(command)

        } else if command.arguments.is_empty() {
            self.delete_and_send(command.message, SendMessage::private(
                &command.message,
                format!("Usage: `!{} <effect_name>`", if self.queued {
                    "q"

                } else {
                    "s"
                })
            ))

        } else {

            let effects = server.map_effects(
                &command.arguments[..],
                false,
                config
            );

            if effects.is_empty() {
                // TODO provide a listing of similiar sounds
                self.delete_and_send(command.message, SendMessage::private(
                    &command.message,
                    format!(
                        "No effect(s) matching `{}` found on {}.",
                        command.arguments.join("`, `"),
                        server.name
                    )
                ))

            } else if let Some(channel_id) = member.voice_channel_id {
                self.delete_and_send(command.message, PlayEffects::new(
                    command.message.server_id,
                    channel_id,
                    effects,
                    self.queued
                ))

            } else {
                self.delete_and_send(command.message, SendMessage::private(
                    &command.message,
                    format!(
                        "You must be in a voice channel on {} in order to play sound effects.",
                        server.name
                    )
                ))
            }

        }

    }

}

<|endoftext|>


<commit_before>extern crate env_logger;
extern crate fuse;
extern crate libc;
extern crate time;

use std::env;
use std::ffi::OsStr;
use libc::ENOENT;
use time::Timespec;
use fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyDirectory};

const TTL: Timespec = Timespec { sec: 1, nsec: 0 };                     // 1 second

const CREATE_TIME: Timespec = Timespec { sec: 1381237736, nsec: 0 };    // 2013-10-08 08:56

const HELLO_DIR_ATTR: FileAttr = FileAttr {
    ino: 1,
    size: 0,
    blocks: 0,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::Directory,
    perm: 0o755,
    nlink: 2,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

const HELLO_TXT_CONTENT: &'static str = "Hello World!\n";

const HELLO_TXT_ATTR: FileAttr = FileAttr {
    ino: 2,
    size: 13,
    blocks: 1,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::RegularFile,
    perm: 0o644,
    nlink: 1,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

struct HelloFS;

impl Filesystem for HelloFS {
    fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
        if parent == 1 && name.to_str() == Some("hello.txt") {
            reply.entry(&TTL, &HELLO_TXT_ATTR, 0);
        } else {
            reply.error(ENOENT);
        }
    }

    fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
        match ino {
            1 => reply.attr(&TTL, &HELLO_DIR_ATTR),
            2 => reply.attr(&TTL, &HELLO_TXT_ATTR),
            _ => reply.error(ENOENT),
        }
    }

    fn read(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, _size: u32, reply: ReplyData) {
        if ino == 2 {
            reply.data(&HELLO_TXT_CONTENT.as_bytes()[offset as usize..]);
        } else {
            reply.error(ENOENT);
        }
    }

    fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, mut reply: ReplyDirectory) {
        if ino == 1 {
            if offset == 0 {
                reply.add(1, 0, FileType::Directory, ".");
                reply.add(1, 1, FileType::Directory, "..");
                reply.add(2, 2, FileType::RegularFile, "hello.txt");
            }
            reply.ok();
        } else {
            reply.error(ENOENT);
        }
    }
}

fn main() {
    env_logger::init();
    let mountpoint = env::args_os().nth(1).unwrap();
    let options = ["-o", "ro", "-o", "fsname=hello"]
        .iter()
        .map(|o| o.as_ref())
        .collect::<Vec<&OsStr>>();
    fuse::mount(HelloFS, &mountpoint, &options).unwrap();
}
<commit_msg>Support non-zero offsets in Hello World example<commit_after>extern crate env_logger;
extern crate fuse;
extern crate libc;
extern crate time;

use std::env;
use std::ffi::OsStr;
use libc::ENOENT;
use time::Timespec;
use fuse::{FileType, FileAttr, Filesystem, Request, ReplyData, ReplyEntry, ReplyAttr, ReplyDirectory};

const TTL: Timespec = Timespec { sec: 1, nsec: 0 };                     // 1 second

const CREATE_TIME: Timespec = Timespec { sec: 1381237736, nsec: 0 };    // 2013-10-08 08:56

const HELLO_DIR_ATTR: FileAttr = FileAttr {
    ino: 1,
    size: 0,
    blocks: 0,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::Directory,
    perm: 0o755,
    nlink: 2,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

const HELLO_TXT_CONTENT: &'static str = "Hello World!\n";

const HELLO_TXT_ATTR: FileAttr = FileAttr {
    ino: 2,
    size: 13,
    blocks: 1,
    atime: CREATE_TIME,
    mtime: CREATE_TIME,
    ctime: CREATE_TIME,
    crtime: CREATE_TIME,
    kind: FileType::RegularFile,
    perm: 0o644,
    nlink: 1,
    uid: 501,
    gid: 20,
    rdev: 0,
    flags: 0,
};

struct HelloFS;

impl Filesystem for HelloFS {
    fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
        if parent == 1 && name.to_str() == Some("hello.txt") {
            reply.entry(&TTL, &HELLO_TXT_ATTR, 0);
        } else {
            reply.error(ENOENT);
        }
    }

    fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
        match ino {
            1 => reply.attr(&TTL, &HELLO_DIR_ATTR),
            2 => reply.attr(&TTL, &HELLO_TXT_ATTR),
            _ => reply.error(ENOENT),
        }
    }

    fn read(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, _size: u32, reply: ReplyData) {
        if ino == 2 {
            reply.data(&HELLO_TXT_CONTENT.as_bytes()[offset as usize..]);
        } else {
            reply.error(ENOENT);
        }
    }

    fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, mut reply: ReplyDirectory) {
        if ino != 1 {
            reply.error(ENOENT);
            return;
        }

        let entries = vec![
            (1, FileType::Directory, "."),
            (1, FileType::Directory, ".."),
            (2, FileType::RegularFile, "hello.txt"),
        ];

        // Offset of 0 means no offset.
        // Non-zero offset means the passed offset has already been seen, and we should start after
        // it.
        let to_skip = if offset == 0 { offset } else { offset + 1 } as usize;
        for (i, entry) in entries.into_iter().enumerate().skip(to_skip) {
            reply.add(entry.0, i as i64, entry.1, entry.2);
        }
        reply.ok();
    }
}

fn main() {
    env_logger::init();
    let mountpoint = env::args_os().nth(1).unwrap();
    let options = ["-o", "ro", "-o", "fsname=hello"]
        .iter()
        .map(|o| o.as_ref())
        .collect::<Vec<&OsStr>>();
    fuse::mount(HelloFS, &mountpoint, &options).unwrap();
}
<|endoftext|>


<commit_before>// This requires running with:
//
// ```bash
// cargo run --example https --features native-tls-example
// ```
//
// Generate an identity like so:
//
// ```bash
// openssl req -x509 -newkey rsa:4096 -nodes -keyout localhost.key -out localhost.crt -days 3650
// openssl pkcs12 -export -out identity.p12 -inkey localhost.key -in localhost.crt -password mypass
//
// ```

extern crate iron;
#[cfg(feature = "native-tls-example")]
extern crate hyper_native_tls;

#[cfg(feature = "native-tls-example")]
fn main() {
    // Avoid unused errors due to conditional compilation ('native-tls-example' feature is not default)
    use hyper_native_tls::NativeTlsServer;
    use iron::{Iron, Request, Response};
    use iron::status;
    use std::result::Result;

    let ssl = NativeTlsServer::new("identity.p12", "mypass").unwrap();

    match Iron::new(|_: &mut Request| {
        Ok(Response::with((status::Ok, "Hello world!")))
    }).https("127.0.0.1:3000", ssl) {
        Result::Ok(listening) => println!("{:?}", listening),
        Result::Err(err) => panic!("{:?}", err),
    }
    // curl -vvvv https://127.0.0.1:3000/ -k
}

#[cfg(not(feature = "native-tls-example"))]
fn main() {
    // We need to do this to make sure `cargo test` passes.
}
<commit_msg>(doc) fix SSL cert generating command error (#561)<commit_after>// This requires running with:
//
// ```bash
// cargo run --example https --features native-tls-example
// ```
//
// Generate an identity like so:
//
// ```bash
// openssl req -x509 -newkey rsa:4096 -nodes -keyout localhost.key -out localhost.crt -days 3650
// openssl pkcs12 -export -out identity.p12 -inkey localhost.key -in localhost.crt -password pass:mypass
//
// ```

extern crate iron;
#[cfg(feature = "native-tls-example")]
extern crate hyper_native_tls;

#[cfg(feature = "native-tls-example")]
fn main() {
    // Avoid unused errors due to conditional compilation ('native-tls-example' feature is not default)
    use hyper_native_tls::NativeTlsServer;
    use iron::{Iron, Request, Response};
    use iron::status;
    use std::result::Result;

    let ssl = NativeTlsServer::new("identity.p12", "mypass").unwrap();

    match Iron::new(|_: &mut Request| {
        Ok(Response::with((status::Ok, "Hello world!")))
    }).https("127.0.0.1:3000", ssl) {
        Result::Ok(listening) => println!("{:?}", listening),
        Result::Err(err) => panic!("{:?}", err),
    }
    // curl -vvvv https://127.0.0.1:3000/ -k
}

#[cfg(not(feature = "native-tls-example"))]
fn main() {
    // We need to do this to make sure `cargo test` passes.
}
<|endoftext|>


<commit_before>//! Decode pixel data using GDCM when the default features are enabled.

use crate::*;
use dicom_encoding::transfer_syntax::TransferSyntaxIndex;
use dicom_transfer_syntax_registry::TransferSyntaxRegistry;
use gdcm_rs::{decode_single_frame_compressed, GDCMPhotometricInterpretation, GDCMTransferSyntax};
use std::str::FromStr;

impl<D> PixelDecoder for FileDicomObject<InMemDicomObject<D>>
where
    D: DataDictionary + Clone,
{
    fn decode_pixel_data(&self) -> Result<DecodedPixelData> {
        let pixel_data = self
            .element(dicom_dictionary_std::tags::PIXEL_DATA)
            .context(MissingRequiredField)?;
        let cols = cols(self)?;
        let rows = rows(self)?;

        let photometric_interpretation = photometric_interpretation(self)?;
        let pi_type = GDCMPhotometricInterpretation::from_str(&photometric_interpretation)
            .map_err(|_| Error::UnsupportedPhotometricInterpretation {
                pi: photometric_interpretation.clone(),
            })?;

        let transfer_syntax = &self.meta().transfer_syntax;
        let registry =
            TransferSyntaxRegistry
                .get(&&transfer_syntax)
                .context(UnsupportedTransferSyntax {
                    ts: transfer_syntax,
                })?;
        let ts_type = GDCMTransferSyntax::from_str(&registry.uid()).map_err(|_| {
            Error::UnsupportedTransferSyntax {
                ts: transfer_syntax.clone(),
            }
        })?;

        let samples_per_pixel = samples_per_pixel(self)?;
        let bits_allocated = bits_allocated(self)?;
        let bits_stored = bits_stored(self)?;
        let high_bit = high_bit(self)?;
        let pixel_representation = pixel_representation(self)?;
        let rescale_intercept = rescale_intercept(self);
        let rescale_slope = rescale_slope(self);
        let number_of_frames = number_of_frames(self);

        let decoded_pixel_data = match pixel_data.value() {
            Value::PixelSequence {
                fragments,
                offset_table: _,
            } => {
                if fragments.len() > 1 {
                    // Bundle fragments and decode multi-frame dicoms
                    UnsupportedMultiFrame.fail()?
                }
                let decoded_frame = decode_single_frame_compressed(
                    &fragments[0],
                    cols.into(),
                    rows.into(),
                    pi_type,
                    ts_type,
                    samples_per_pixel,
                    bits_allocated,
                    bits_stored,
                    high_bit,
                    pixel_representation,
                )
                .map_err(|source| Error::ImplementerError {
                    source: Box::new(source),
                })?;
                decoded_frame.to_vec()
            }
            Value::Primitive(p) => {
                // Non-encoded, just return the pixel data of the first frame
                let total_bytes = rows as usize
                    * cols as usize
                    * samples_per_pixel as usize
                    * (bits_allocated as usize / 8);
                p.to_bytes()[0..total_bytes].to_vec()
            }
            Value::Sequence { items: _, size: _ } => InvalidPixelData.fail()?,
        };

        Ok(DecodedPixelData {
            data: Cow::from(decoded_pixel_data),
            cols: cols.into(),
            rows: rows.into(),
            number_of_frames,
            photometric_interpretation,
            samples_per_pixel,
            bits_allocated,
            bits_stored,
            high_bit,
            pixel_representation,
            rescale_intercept,
            rescale_slope,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use dicom_object::open_file;
    use dicom_test_files;
    use rstest::rstest;
    use std::path::Path;

    #[rstest(value => [
        "pydicom/693_J2KI.dcm",
        "pydicom/693_J2KR.dcm",
        "pydicom/693_UNCI.dcm",
        "pydicom/693_UNCR.dcm",
        "pydicom/CT_small.dcm",
        "pydicom/JPEG-lossy.dcm",
        "pydicom/JPEG2000.dcm",
        "pydicom/JPEG2000_UNC.dcm",
        "pydicom/JPGLosslessP14SV1_1s_1f_8b.dcm",
        "pydicom/MR_small.dcm",
        "pydicom/MR_small_RLE.dcm",
        "pydicom/MR_small_implicit.dcm",
        "pydicom/MR_small_jp2klossless.dcm",
        "pydicom/MR_small_jpeg_ls_lossless.dcm",
        "pydicom/explicit_VR-UN.dcm",
        "pydicom/MR_small_bigendian.dcm",
        "pydicom/MR_small_expb.dcm",
        "pydicom/SC_rgb.dcm",
        "pydicom/SC_rgb_16bit.dcm",
        "pydicom/SC_rgb_dcmtk_+eb+cr.dcm",
        "pydicom/SC_rgb_expb.dcm",
        "pydicom/SC_rgb_expb_16bit.dcm",
        "pydicom/SC_rgb_gdcm2k_uncompressed.dcm",
        "pydicom/SC_rgb_gdcm_KY.dcm",
        "pydicom/SC_rgb_jpeg_gdcm.dcm",
        "pydicom/SC_rgb_jpeg_lossy_gdcm.dcm",
        "pydicom/SC_rgb_rle.dcm",
        "pydicom/SC_rgb_rle_16bit.dcm",
        "pydicom/color-pl.dcm",
        "pydicom/color-px.dcm",
        "pydicom/SC_ybr_full_uncompressed.dcm",

    // "pydicom/RG1_J2KI.dcm",
    // "pydicom/RG1_J2KR.dcm",
    // "pydicom/RG1_UNCI.dcm",
    // "pydicom/RG1_UNCR.dcm",
    // "pydicom/RG3_J2KI.dcm",
    // "pydicom/RG3_J2KR.dcm",
    // "pydicom/RG3_UNCI.dcm",
    // "pydicom/RG3_UNCR.dcm",
    // "pydicom/ExplVR_BigEnd.dcm",
    // "pydicom/ExplVR_BigEndNoMeta.dcm",
    // "pydicom/ExplVR_LitEndNoMeta.dcm",
    // "pydicom/JPEG-LL.dcm",                       // More than 1 fragment
    // "pydicom/MR-SIEMENS-DICOM-WithOverlays.dcm", // Overlays not supported
    // "pydicom/MR2_J2KI.dcm",  // Multi-frame
    // "pydicom/MR2_J2KR.dcm",
    // "pydicom/MR2_UNCI.dcm",
    // "pydicom/MR2_UNCR.dcm",
    // "pydicom/MR_small_padded.dcm",
    // "pydicom/MR_truncated.dcm",
    // "pydicom/OBXXXX1A.dcm",
    // "pydicom/OBXXXX1A_2frame.dcm",
    // "pydicom/OBXXXX1A_expb.dcm",
    // "pydicom/OBXXXX1A_expb_2frame.dcm",
    // "pydicom/OBXXXX1A_rle.dcm",
    // "pydicom/OBXXXX1A_rle_2frame.dcm",
    // "pydicom/OT-PAL-8-face.dcm",
    // "pydicom/SC_rgb_16bit_2frame.dcm",
    // "pydicom/SC_rgb_2frame.dcm",
    // "pydicom/SC_rgb_32bit.dcm",
    // "pydicom/SC_rgb_32bit_2frame.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+n1.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+n2.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+np.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+s2.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+s4.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcr_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcyn1_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcyn2_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcynp_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcys2_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcys4_dcmd.dcm",
    // "pydicom/SC_rgb_expb_16bit_2frame.dcm",
    // "pydicom/SC_rgb_expb_2frame.dcm",
    // "pydicom/SC_rgb_expb_32bit.dcm",
    // "pydicom/SC_rgb_expb_32bit_2frame.dcm",
    // "pydicom/SC_rgb_rle_16bit_2frame.dcm",
    // "pydicom/SC_rgb_rle_2frame.dcm",
    // "pydicom/SC_rgb_rle_32bit.dcm",
    // "pydicom/SC_rgb_rle_32bit_2frame.dcm",
    // "pydicom/SC_rgb_small_odd.dcm",
    // "pydicom/SC_rgb_small_odd_jpeg.dcm",
    // "pydicom/SC_rgb_jpeg_dcmtk.dcm",
    // "pydicom/SC_ybr_full_422_uncompressed.dcm",
    // "pydicom/US1_J2KI.dcm",
    // "pydicom/US1_J2KR.dcm",
    // "pydicom/US1_UNCI.dcm",
    // "pydicom/US1_UNCR.dcm",
    // "pydicom/badVR.dcm",
    // "pydicom/bad_sequence.dcm",
    // "pydicom/color3d_jpeg_baseline.dcm",
    // "pydicom/eCT_Supplemental.dcm",
    // "pydicom/empty_charset_LEI.dcm",
    // "pydicom/emri_small.dcm",
    // "pydicom/emri_small_RLE.dcm",
    // "pydicom/emri_small_big_endian.dcm",
    // "pydicom/emri_small_jpeg_2k_lossless.dcm",
    // "pydicom/emri_small_jpeg_2k_lossless_too_short.dcm",
    // "pydicom/emri_small_jpeg_ls_lossless.dcm",
    // "pydicom/gdcm-US-ALOKA-16.dcm",
    // "pydicom/gdcm-US-ALOKA-16_big.dcm",
    // "pydicom/image_dfl.dcm",
    // "pydicom/liver.dcm",
    // "pydicom/liver_1frame.dcm",
    // "pydicom/liver_expb.dcm",
    // "pydicom/liver_expb_1frame.dcm",
    // "pydicom/meta_missing_tsyntax.dcm",
    // "pydicom/mlut_18.dcm",
    // "pydicom/nested_priv_SQ.dcm",
    // "pydicom/no_meta.dcm",
    // "pydicom/no_meta_group_length.dcm",
    // "pydicom/priv_SQ.dcm",
    // "pydicom/reportsi.dcm",
    // "pydicom/reportsi_with_empty_number_tags.dcm",
    // "pydicom/rtdose.dcm",
    // "pydicom/rtdose_1frame.dcm",
    // "pydicom/rtdose_expb.dcm",
    // "pydicom/rtdose_expb_1frame.dcm",
    // "pydicom/rtdose_rle.dcm",
    // "pydicom/rtdose_rle_1frame.dcm",
    // "pydicom/rtplan.dcm",
    // "pydicom/rtplan_truncated.dcm",
    // "pydicom/rtstruct.dcm",
    // "pydicom/test-SR.dcm",
    // "pydicom/vlut_04.dcm",
])]
    fn test_parse_dicom_pixel_data(value: &str) {
        let test_file = dicom_test_files::path(value).unwrap();
        println!("Parsing pixel data for {}", test_file.display());
        let obj = open_file(test_file).unwrap();
        let image = obj
            .decode_pixel_data()
            .unwrap()
            .to_dynamic_image(0)
            .unwrap();
        image
            .save(format!(
                "../target/dicom_test_files/pydicom/{}.png",
                Path::new(value).file_stem().unwrap().to_str().unwrap()
            ))
            .unwrap();
    }

    #[test]
    fn test_to_ndarray_signed_word() {
        let test_file = dicom_test_files::path("pydicom/JPEG2000.dcm").unwrap();
        let obj = open_file(test_file).unwrap();
        let ndarray = obj
            .decode_pixel_data()
            .unwrap()
            .to_ndarray::<i16>()
            .unwrap();
        assert_eq!(ndarray.shape(), &[1, 1024, 256, 1]);
        assert_eq!(ndarray.len(), 262144);
        assert_eq!(ndarray[[0, 260, 0, 0]], -3);
    }
}
<commit_msg>[pixeldata] migrate gdcm module to snafu 0.7<commit_after>//! Decode pixel data using GDCM when the default features are enabled.

use crate::*;
use dicom_encoding::transfer_syntax::TransferSyntaxIndex;
use dicom_transfer_syntax_registry::TransferSyntaxRegistry;
use gdcm_rs::{decode_single_frame_compressed, GDCMPhotometricInterpretation, GDCMTransferSyntax};
use std::str::FromStr;

impl<D> PixelDecoder for FileDicomObject<InMemDicomObject<D>>
where
    D: DataDictionary + Clone,
{
    fn decode_pixel_data(&self) -> Result<DecodedPixelData> {
        let pixel_data = self
            .element(dicom_dictionary_std::tags::PIXEL_DATA)
            .context(MissingRequiredFieldSnafu)?;
        let cols = cols(self)?;
        let rows = rows(self)?;

        let photometric_interpretation = photometric_interpretation(self)?;
        let pi_type = GDCMPhotometricInterpretation::from_str(&photometric_interpretation)
            .map_err(|_| Error::UnsupportedPhotometricInterpretation {
                pi: photometric_interpretation.clone(),
            })?;

        let transfer_syntax = &self.meta().transfer_syntax;
        let registry =
            TransferSyntaxRegistry
                .get(&&transfer_syntax)
                .context(UnsupportedTransferSyntaxSnafu {
                    ts: transfer_syntax,
                })?;
        let ts_type = GDCMTransferSyntax::from_str(&registry.uid()).map_err(|_| {
            Error::UnsupportedTransferSyntax {
                ts: transfer_syntax.clone(),
            }
        })?;

        let samples_per_pixel = samples_per_pixel(self)?;
        let bits_allocated = bits_allocated(self)?;
        let bits_stored = bits_stored(self)?;
        let high_bit = high_bit(self)?;
        let pixel_representation = pixel_representation(self)?;
        let rescale_intercept = rescale_intercept(self);
        let rescale_slope = rescale_slope(self);
        let number_of_frames = number_of_frames(self);

        let decoded_pixel_data = match pixel_data.value() {
            Value::PixelSequence {
                fragments,
                offset_table: _,
            } => {
                if fragments.len() > 1 {
                    // Bundle fragments and decode multi-frame dicoms
                    UnsupportedMultiFrameSnafu.fail()?
                }
                let decoded_frame = decode_single_frame_compressed(
                    &fragments[0],
                    cols.into(),
                    rows.into(),
                    pi_type,
                    ts_type,
                    samples_per_pixel,
                    bits_allocated,
                    bits_stored,
                    high_bit,
                    pixel_representation,
                )
                .map_err(|source| Error::ImplementerError {
                    source: Box::new(source),
                })?;
                decoded_frame.to_vec()
            }
            Value::Primitive(p) => {
                // Non-encoded, just return the pixel data of the first frame
                let total_bytes = rows as usize
                    * cols as usize
                    * samples_per_pixel as usize
                    * (bits_allocated as usize / 8);
                p.to_bytes()[0..total_bytes].to_vec()
            }
            Value::Sequence { items: _, size: _ } => InvalidPixelDataSnafu.fail()?,
        };

        Ok(DecodedPixelData {
            data: Cow::from(decoded_pixel_data),
            cols: cols.into(),
            rows: rows.into(),
            number_of_frames,
            photometric_interpretation,
            samples_per_pixel,
            bits_allocated,
            bits_stored,
            high_bit,
            pixel_representation,
            rescale_intercept,
            rescale_slope,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use dicom_object::open_file;
    use dicom_test_files;
    use rstest::rstest;
    use std::path::Path;

    #[rstest(value => [
        "pydicom/693_J2KI.dcm",
        "pydicom/693_J2KR.dcm",
        "pydicom/693_UNCI.dcm",
        "pydicom/693_UNCR.dcm",
        "pydicom/CT_small.dcm",
        "pydicom/JPEG-lossy.dcm",
        "pydicom/JPEG2000.dcm",
        "pydicom/JPEG2000_UNC.dcm",
        "pydicom/JPGLosslessP14SV1_1s_1f_8b.dcm",
        "pydicom/MR_small.dcm",
        "pydicom/MR_small_RLE.dcm",
        "pydicom/MR_small_implicit.dcm",
        "pydicom/MR_small_jp2klossless.dcm",
        "pydicom/MR_small_jpeg_ls_lossless.dcm",
        "pydicom/explicit_VR-UN.dcm",
        "pydicom/MR_small_bigendian.dcm",
        "pydicom/MR_small_expb.dcm",
        "pydicom/SC_rgb.dcm",
        "pydicom/SC_rgb_16bit.dcm",
        "pydicom/SC_rgb_dcmtk_+eb+cr.dcm",
        "pydicom/SC_rgb_expb.dcm",
        "pydicom/SC_rgb_expb_16bit.dcm",
        "pydicom/SC_rgb_gdcm2k_uncompressed.dcm",
        "pydicom/SC_rgb_gdcm_KY.dcm",
        "pydicom/SC_rgb_jpeg_gdcm.dcm",
        "pydicom/SC_rgb_jpeg_lossy_gdcm.dcm",
        "pydicom/SC_rgb_rle.dcm",
        "pydicom/SC_rgb_rle_16bit.dcm",
        "pydicom/color-pl.dcm",
        "pydicom/color-px.dcm",
        "pydicom/SC_ybr_full_uncompressed.dcm",

    // "pydicom/RG1_J2KI.dcm",
    // "pydicom/RG1_J2KR.dcm",
    // "pydicom/RG1_UNCI.dcm",
    // "pydicom/RG1_UNCR.dcm",
    // "pydicom/RG3_J2KI.dcm",
    // "pydicom/RG3_J2KR.dcm",
    // "pydicom/RG3_UNCI.dcm",
    // "pydicom/RG3_UNCR.dcm",
    // "pydicom/ExplVR_BigEnd.dcm",
    // "pydicom/ExplVR_BigEndNoMeta.dcm",
    // "pydicom/ExplVR_LitEndNoMeta.dcm",
    // "pydicom/JPEG-LL.dcm",                       // More than 1 fragment
    // "pydicom/MR-SIEMENS-DICOM-WithOverlays.dcm", // Overlays not supported
    // "pydicom/MR2_J2KI.dcm",  // Multi-frame
    // "pydicom/MR2_J2KR.dcm",
    // "pydicom/MR2_UNCI.dcm",
    // "pydicom/MR2_UNCR.dcm",
    // "pydicom/MR_small_padded.dcm",
    // "pydicom/MR_truncated.dcm",
    // "pydicom/OBXXXX1A.dcm",
    // "pydicom/OBXXXX1A_2frame.dcm",
    // "pydicom/OBXXXX1A_expb.dcm",
    // "pydicom/OBXXXX1A_expb_2frame.dcm",
    // "pydicom/OBXXXX1A_rle.dcm",
    // "pydicom/OBXXXX1A_rle_2frame.dcm",
    // "pydicom/OT-PAL-8-face.dcm",
    // "pydicom/SC_rgb_16bit_2frame.dcm",
    // "pydicom/SC_rgb_2frame.dcm",
    // "pydicom/SC_rgb_32bit.dcm",
    // "pydicom/SC_rgb_32bit_2frame.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+n1.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+n2.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+np.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+s2.dcm",
    // "pydicom/SC_rgb_dcmtk_+eb+cy+s4.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcr_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcyn1_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcyn2_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcynp_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcys2_dcmd.dcm",
    // "pydicom/SC_rgb_dcmtk_ebcys4_dcmd.dcm",
    // "pydicom/SC_rgb_expb_16bit_2frame.dcm",
    // "pydicom/SC_rgb_expb_2frame.dcm",
    // "pydicom/SC_rgb_expb_32bit.dcm",
    // "pydicom/SC_rgb_expb_32bit_2frame.dcm",
    // "pydicom/SC_rgb_rle_16bit_2frame.dcm",
    // "pydicom/SC_rgb_rle_2frame.dcm",
    // "pydicom/SC_rgb_rle_32bit.dcm",
    // "pydicom/SC_rgb_rle_32bit_2frame.dcm",
    // "pydicom/SC_rgb_small_odd.dcm",
    // "pydicom/SC_rgb_small_odd_jpeg.dcm",
    // "pydicom/SC_rgb_jpeg_dcmtk.dcm",
    // "pydicom/SC_ybr_full_422_uncompressed.dcm",
    // "pydicom/US1_J2KI.dcm",
    // "pydicom/US1_J2KR.dcm",
    // "pydicom/US1_UNCI.dcm",
    // "pydicom/US1_UNCR.dcm",
    // "pydicom/badVR.dcm",
    // "pydicom/bad_sequence.dcm",
    // "pydicom/color3d_jpeg_baseline.dcm",
    // "pydicom/eCT_Supplemental.dcm",
    // "pydicom/empty_charset_LEI.dcm",
    // "pydicom/emri_small.dcm",
    // "pydicom/emri_small_RLE.dcm",
    // "pydicom/emri_small_big_endian.dcm",
    // "pydicom/emri_small_jpeg_2k_lossless.dcm",
    // "pydicom/emri_small_jpeg_2k_lossless_too_short.dcm",
    // "pydicom/emri_small_jpeg_ls_lossless.dcm",
    // "pydicom/gdcm-US-ALOKA-16.dcm",
    // "pydicom/gdcm-US-ALOKA-16_big.dcm",
    // "pydicom/image_dfl.dcm",
    // "pydicom/liver.dcm",
    // "pydicom/liver_1frame.dcm",
    // "pydicom/liver_expb.dcm",
    // "pydicom/liver_expb_1frame.dcm",
    // "pydicom/meta_missing_tsyntax.dcm",
    // "pydicom/mlut_18.dcm",
    // "pydicom/nested_priv_SQ.dcm",
    // "pydicom/no_meta.dcm",
    // "pydicom/no_meta_group_length.dcm",
    // "pydicom/priv_SQ.dcm",
    // "pydicom/reportsi.dcm",
    // "pydicom/reportsi_with_empty_number_tags.dcm",
    // "pydicom/rtdose.dcm",
    // "pydicom/rtdose_1frame.dcm",
    // "pydicom/rtdose_expb.dcm",
    // "pydicom/rtdose_expb_1frame.dcm",
    // "pydicom/rtdose_rle.dcm",
    // "pydicom/rtdose_rle_1frame.dcm",
    // "pydicom/rtplan.dcm",
    // "pydicom/rtplan_truncated.dcm",
    // "pydicom/rtstruct.dcm",
    // "pydicom/test-SR.dcm",
    // "pydicom/vlut_04.dcm",
])]
    fn test_parse_dicom_pixel_data(value: &str) {
        let test_file = dicom_test_files::path(value).unwrap();
        println!("Parsing pixel data for {}", test_file.display());
        let obj = open_file(test_file).unwrap();
        let image = obj
            .decode_pixel_data()
            .unwrap()
            .to_dynamic_image(0)
            .unwrap();
        image
            .save(format!(
                "../target/dicom_test_files/pydicom/{}.png",
                Path::new(value).file_stem().unwrap().to_str().unwrap()
            ))
            .unwrap();
    }

    #[test]
    fn test_to_ndarray_signed_word() {
        let test_file = dicom_test_files::path("pydicom/JPEG2000.dcm").unwrap();
        let obj = open_file(test_file).unwrap();
        let ndarray = obj
            .decode_pixel_data()
            .unwrap()
            .to_ndarray::<i16>()
            .unwrap();
        assert_eq!(ndarray.shape(), &[1, 1024, 256, 1]);
        assert_eq!(ndarray.len(), 262144);
        assert_eq!(ndarray[[0, 260, 0, 0]], -3);
    }
}
<|endoftext|>


<commit_before>/// A module exposing utilities for encoding and decoding Huffman-coded octet
/// strings, under the Huffman code defined by HPACK.
/// (HPACK-draft-10, Appendix B)

use std::collections::HashMap;

/// Represents a symbol that can be inserted into a Huffman-encoded octet
/// string.
enum HuffmanCodeSymbol {
    /// Any octet is a valid symbol
    Symbol(u8),
    /// A special symbol represents the end of the string
    EndOfString,
}

impl HuffmanCodeSymbol {
    pub fn new(symbol: usize) -> HuffmanCodeSymbol {
        if symbol == 256 {
            HuffmanCodeSymbol::EndOfString
        } else {
            // It is safe to downcast since now we know that the value
            // is in the half-open interval [0, 256)
            HuffmanCodeSymbol::Symbol(symbol as u8)
        }
    }
}

/// A helper struct that represents an iterator over individual bits of all
/// bytes found in a wrapped Iterator over bytes.
/// Bits are represented as `bool`s, where `true` corresponds to a set bit and
/// `false` to a 0 bit.
///
/// Bits are yielded in order of significance, starting from the
/// most-significant bit.
struct BitIterator<'a, I: Iterator> {
    buffer_iterator: I,
    current_byte: Option<&'a u8>,
    /// The bit-position within the current byte
    pos: u8,
}

impl<'a, I: Iterator> BitIterator<'a, I>
        where I: Iterator<Item=&'a u8> {
    pub fn new(iterator: I) -> BitIterator<'a, I> {
        BitIterator::<'a, I> {
            buffer_iterator: iterator,
            current_byte: None,
            pos: 7,
        }
    }
}

impl<'a, I> Iterator for BitIterator<'a, I>
        where I: Iterator<Item=&'a u8> {
    type Item = bool;

    fn next(&mut self) -> Option<bool> {
        if self.current_byte.is_none() {
            self.current_byte = self.buffer_iterator.next();
            self.pos = 7;
        }

        // If we still have `None`, it means the buffer has been exhausted
        if self.current_byte.is_none() {
            return None;
        }

        let b = *self.current_byte.unwrap();

        let is_set = (b & (1 << self.pos)) == (1 << self.pos);
        if self.pos == 0 {
            // We have exhausted all bits from the current byte -- try to get
            // a new one on the next pass.
            self.current_byte = None;
        } else {
            // Still more bits left here...
            self.pos -= 1;
        }

        Some(is_set)
    }
}

mod tests {
    use super::BitIterator;

    /// A helper function that converts the given slice containing values `1`
    /// and `0` to a `Vec` of `bool`s, according to the number.
    fn to_expected_bit_result(numbers: &[u8]) -> Vec<bool> {
        numbers.iter().map(|b| -> bool {
            *b == 1
        }).collect()
    }

    #[test]
    fn test_bit_iterator_single_byte() {
        let expected_result = to_expected_bit_result(
            &[0, 0, 0, 0, 1, 0, 1, 0]);

        let mut res: Vec<bool> = Vec::new();
        for b in BitIterator::new(vec![10u8].iter()) {
            res.push(b);
        }

        assert_eq!(res, expected_result);
    }

    #[test]
    fn test_bit_iterator_multiple_bytes() {
        let expected_result = to_expected_bit_result(
            &[0, 0, 0, 0, 1, 0, 1, 0,
              1, 1, 1, 1, 1, 1, 1, 1,
              1, 0, 0, 0, 0, 0, 0, 0,
              0, 0, 0, 0, 0, 0, 0, 1,
              0, 0, 0, 0, 0, 0, 0, 0,
              1, 0, 1, 0, 1, 0, 1, 0]);

        let mut res: Vec<bool> = Vec::new();
        for b in BitIterator::new(vec![10u8, 255, 128, 1, 0, 170].iter()) {
            res.push(b);
        }

        assert_eq!(res, expected_result);
    }
}
<commit_msg>Add the table of Huffman codes defined by IETF<commit_after>/// A module exposing utilities for encoding and decoding Huffman-coded octet
/// strings, under the Huffman code defined by HPACK.
/// (HPACK-draft-10, Appendix B)

use std::collections::HashMap;

/// Represents a symbol that can be inserted into a Huffman-encoded octet
/// string.
enum HuffmanCodeSymbol {
    /// Any octet is a valid symbol
    Symbol(u8),
    /// A special symbol represents the end of the string
    EndOfString,
}

impl HuffmanCodeSymbol {
    pub fn new(symbol: usize) -> HuffmanCodeSymbol {
        if symbol == 256 {
            HuffmanCodeSymbol::EndOfString
        } else {
            // It is safe to downcast since now we know that the value
            // is in the half-open interval [0, 256)
            HuffmanCodeSymbol::Symbol(symbol as u8)
        }
    }
}

/// A helper struct that represents an iterator over individual bits of all
/// bytes found in a wrapped Iterator over bytes.
/// Bits are represented as `bool`s, where `true` corresponds to a set bit and
/// `false` to a 0 bit.
///
/// Bits are yielded in order of significance, starting from the
/// most-significant bit.
struct BitIterator<'a, I: Iterator> {
    buffer_iterator: I,
    current_byte: Option<&'a u8>,
    /// The bit-position within the current byte
    pos: u8,
}

impl<'a, I: Iterator> BitIterator<'a, I>
        where I: Iterator<Item=&'a u8> {
    pub fn new(iterator: I) -> BitIterator<'a, I> {
        BitIterator::<'a, I> {
            buffer_iterator: iterator,
            current_byte: None,
            pos: 7,
        }
    }
}

impl<'a, I> Iterator for BitIterator<'a, I>
        where I: Iterator<Item=&'a u8> {
    type Item = bool;

    fn next(&mut self) -> Option<bool> {
        if self.current_byte.is_none() {
            self.current_byte = self.buffer_iterator.next();
            self.pos = 7;
        }

        // If we still have `None`, it means the buffer has been exhausted
        if self.current_byte.is_none() {
            return None;
        }

        let b = *self.current_byte.unwrap();

        let is_set = (b & (1 << self.pos)) == (1 << self.pos);
        if self.pos == 0 {
            // We have exhausted all bits from the current byte -- try to get
            // a new one on the next pass.
            self.current_byte = None;
        } else {
            // Still more bits left here...
            self.pos -= 1;
        }

        Some(is_set)
    }
}

static HUFFMAN_CODE_TABLE: &'static [(u32, u8)] = &[
    (0x1ff8, 13),
    (0x7fffd8, 23),
    (0xfffffe2, 28),
    (0xfffffe3, 28),
    (0xfffffe4, 28),
    (0xfffffe5, 28),
    (0xfffffe6, 28),
    (0xfffffe7, 28),
    (0xfffffe8, 28),
    (0xffffea, 24),
    (0x3ffffffc, 30),
    (0xfffffe9, 28),
    (0xfffffea, 28),
    (0x3ffffffd, 30),
    (0xfffffeb, 28),
    (0xfffffec, 28),
    (0xfffffed, 28),
    (0xfffffee, 28),
    (0xfffffef, 28),
    (0xffffff0, 28),
    (0xffffff1, 28),
    (0xffffff2, 28),
    (0x3ffffffe, 30),
    (0xffffff3, 28),
    (0xffffff4, 28),
    (0xffffff5, 28),
    (0xffffff6, 28),
    (0xffffff7, 28),
    (0xffffff8, 28),
    (0xffffff9, 28),
    (0xffffffa, 28),
    (0xffffffb, 28),
    (0x14, 6),
    (0x3f8, 10),
    (0x3f9, 10),
    (0xffa, 12),
    (0x1ff9, 13),
    (0x15, 6),
    (0xf8, 8),
    (0x7fa, 11),
    (0x3fa, 10),
    (0x3fb, 10),
    (0xf9, 8),
    (0x7fb, 11),
    (0xfa, 8),
    (0x16, 6),
    (0x17, 6),
    (0x18, 6),
    (0x0, 5),
    (0x1, 5),
    (0x2, 5),
    (0x19, 6),
    (0x1a, 6),
    (0x1b, 6),
    (0x1c, 6),
    (0x1d, 6),
    (0x1e, 6),
    (0x1f, 6),
    (0x5c, 7),
    (0xfb, 8),
    (0x7ffc, 15),
    (0x20, 6),
    (0xffb, 12),
    (0x3fc, 10),
    (0x1ffa, 13),
    (0x21, 6),
    (0x5d, 7),
    (0x5e, 7),
    (0x5f, 7),
    (0x60, 7),
    (0x61, 7),
    (0x62, 7),
    (0x63, 7),
    (0x64, 7),
    (0x65, 7),
    (0x66, 7),
    (0x67, 7),
    (0x68, 7),
    (0x69, 7),
    (0x6a, 7),
    (0x6b, 7),
    (0x6c, 7),
    (0x6d, 7),
    (0x6e, 7),
    (0x6f, 7),
    (0x70, 7),
    (0x71, 7),
    (0x72, 7),
    (0xfc, 8),
    (0x73, 7),
    (0xfd, 8),
    (0x1ffb, 13),
    (0x7fff0, 19),
    (0x1ffc, 13),
    (0x3ffc, 14),
    (0x22, 6),
    (0x7ffd, 15),
    (0x3, 5),
    (0x23, 6),
    (0x4, 5),
    (0x24, 6),
    (0x5, 5),
    (0x25, 6),
    (0x26, 6),
    (0x27, 6),
    (0x6, 5),
    (0x74, 7),
    (0x75, 7),
    (0x28, 6),
    (0x29, 6),
    (0x2a, 6),
    (0x7, 5),
    (0x2b, 6),
    (0x76, 7),
    (0x2c, 6),
    (0x8, 5),
    (0x9, 5),
    (0x2d, 6),
    (0x77, 7),
    (0x78, 7),
    (0x79, 7),
    (0x7a, 7),
    (0x7b, 7),
    (0x7ffe, 15),
    (0x7fc, 11),
    (0x3ffd, 14),
    (0x1ffd, 13),
    (0xffffffc, 28),
    (0xfffe6, 20),
    (0x3fffd2, 22),
    (0xfffe7, 20),
    (0xfffe8, 20),
    (0x3fffd3, 22),
    (0x3fffd4, 22),
    (0x3fffd5, 22),
    (0x7fffd9, 23),
    (0x3fffd6, 22),
    (0x7fffda, 23),
    (0x7fffdb, 23),
    (0x7fffdc, 23),
    (0x7fffdd, 23),
    (0x7fffde, 23),
    (0xffffeb, 24),
    (0x7fffdf, 23),
    (0xffffec, 24),
    (0xffffed, 24),
    (0x3fffd7, 22),
    (0x7fffe0, 23),
    (0xffffee, 24),
    (0x7fffe1, 23),
    (0x7fffe2, 23),
    (0x7fffe3, 23),
    (0x7fffe4, 23),
    (0x1fffdc, 21),
    (0x3fffd8, 22),
    (0x7fffe5, 23),
    (0x3fffd9, 22),
    (0x7fffe6, 23),
    (0x7fffe7, 23),
    (0xffffef, 24),
    (0x3fffda, 22),
    (0x1fffdd, 21),
    (0xfffe9, 20),
    (0x3fffdb, 22),
    (0x3fffdc, 22),
    (0x7fffe8, 23),
    (0x7fffe9, 23),
    (0x1fffde, 21),
    (0x7fffea, 23),
    (0x3fffdd, 22),
    (0x3fffde, 22),
    (0xfffff0, 24),
    (0x1fffdf, 21),
    (0x3fffdf, 22),
    (0x7fffeb, 23),
    (0x7fffec, 23),
    (0x1fffe0, 21),
    (0x1fffe1, 21),
    (0x3fffe0, 22),
    (0x1fffe2, 21),
    (0x7fffed, 23),
    (0x3fffe1, 22),
    (0x7fffee, 23),
    (0x7fffef, 23),
    (0xfffea, 20),
    (0x3fffe2, 22),
    (0x3fffe3, 22),
    (0x3fffe4, 22),
    (0x7ffff0, 23),
    (0x3fffe5, 22),
    (0x3fffe6, 22),
    (0x7ffff1, 23),
    (0x3ffffe0, 26),
    (0x3ffffe1, 26),
    (0xfffeb, 20),
    (0x7fff1, 19),
    (0x3fffe7, 22),
    (0x7ffff2, 23),
    (0x3fffe8, 22),
    (0x1ffffec, 25),
    (0x3ffffe2, 26),
    (0x3ffffe3, 26),
    (0x3ffffe4, 26),
    (0x7ffffde, 27),
    (0x7ffffdf, 27),
    (0x3ffffe5, 26),
    (0xfffff1, 24),
    (0x1ffffed, 25),
    (0x7fff2, 19),
    (0x1fffe3, 21),
    (0x3ffffe6, 26),
    (0x7ffffe0, 27),
    (0x7ffffe1, 27),
    (0x3ffffe7, 26),
    (0x7ffffe2, 27),
    (0xfffff2, 24),
    (0x1fffe4, 21),
    (0x1fffe5, 21),
    (0x3ffffe8, 26),
    (0x3ffffe9, 26),
    (0xffffffd, 28),
    (0x7ffffe3, 27),
    (0x7ffffe4, 27),
    (0x7ffffe5, 27),
    (0xfffec, 20),
    (0xfffff3, 24),
    (0xfffed, 20),
    (0x1fffe6, 21),
    (0x3fffe9, 22),
    (0x1fffe7, 21),
    (0x1fffe8, 21),
    (0x7ffff3, 23),
    (0x3fffea, 22),
    (0x3fffeb, 22),
    (0x1ffffee, 25),
    (0x1ffffef, 25),
    (0xfffff4, 24),
    (0xfffff5, 24),
    (0x3ffffea, 26),
    (0x7ffff4, 23),
    (0x3ffffeb, 26),
    (0x7ffffe6, 27),
    (0x3ffffec, 26),
    (0x3ffffed, 26),
    (0x7ffffe7, 27),
    (0x7ffffe8, 27),
    (0x7ffffe9, 27),
    (0x7ffffea, 27),
    (0x7ffffeb, 27),
    (0xffffffe, 28),
    (0x7ffffec, 27),
    (0x7ffffed, 27),
    (0x7ffffee, 27),
    (0x7ffffef, 27),
    (0x7fffff0, 27),
    (0x3ffffee, 26),
    (0x3fffffff, 30),
];

mod tests {
    use super::BitIterator;

    /// A helper function that converts the given slice containing values `1`
    /// and `0` to a `Vec` of `bool`s, according to the number.
    fn to_expected_bit_result(numbers: &[u8]) -> Vec<bool> {
        numbers.iter().map(|b| -> bool {
            *b == 1
        }).collect()
    }

    #[test]
    fn test_bit_iterator_single_byte() {
        let expected_result = to_expected_bit_result(
            &[0, 0, 0, 0, 1, 0, 1, 0]);

        let mut res: Vec<bool> = Vec::new();
        for b in BitIterator::new(vec![10u8].iter()) {
            res.push(b);
        }

        assert_eq!(res, expected_result);
    }

    #[test]
    fn test_bit_iterator_multiple_bytes() {
        let expected_result = to_expected_bit_result(
            &[0, 0, 0, 0, 1, 0, 1, 0,
              1, 1, 1, 1, 1, 1, 1, 1,
              1, 0, 0, 0, 0, 0, 0, 0,
              0, 0, 0, 0, 0, 0, 0, 1,
              0, 0, 0, 0, 0, 0, 0, 0,
              1, 0, 1, 0, 1, 0, 1, 0]);

        let mut res: Vec<bool> = Vec::new();
        for b in BitIterator::new(vec![10u8, 255, 128, 1, 0, 170].iter()) {
            res.push(b);
        }

        assert_eq!(res, expected_result);
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2017 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 borrow_check::place_ext::PlaceExt;
use dataflow::indexes::BorrowIndex;
use rustc::mir::traversal;
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{self, Location, Mir, Place};
use rustc::ty::{Region, TyCtxt};
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_vec::IndexVec;
use std::fmt;
use std::hash::Hash;
use std::ops::Index;

crate struct BorrowSet<'tcx> {
    /// The fundamental map relating bitvector indexes to the borrows
    /// in the MIR.
    crate borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,

    /// Each borrow is also uniquely identified in the MIR by the
    /// `Location` of the assignment statement in which it appears on
    /// the right hand side; we map each such location to the
    /// corresponding `BorrowIndex`.
    crate location_map: FxHashMap<Location, BorrowIndex>,

    /// Locations which activate borrows.
    /// NOTE: A given location may activate more than one borrow in the future
    /// when more general two-phase borrow support is introduced, but for now we
    /// only need to store one borrow index
    crate activation_map: FxHashMap<Location, Vec<BorrowIndex>>,

    /// Every borrow has a region; this maps each such regions back to
    /// its borrow-indexes.
    crate region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,

    /// Map from local to all the borrows on that local
    crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
}

impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
    type Output = BorrowData<'tcx>;

    fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> {
        &self.borrows[index]
    }
}

/// Location where a two phase borrow is activated, if a borrow
/// is in fact a two phase borrow.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
crate enum TwoPhaseActivation {
    NotTwoPhase,
    NotActivated,
    ActivatedAt(Location),
}

#[derive(Debug)]
crate struct BorrowData<'tcx> {
    /// Location where the borrow reservation starts.
    /// In many cases, this will be equal to the activation location but not always.
    crate reserve_location: Location,
    /// Location where the borrow is activated.
    crate activation_location: TwoPhaseActivation,
    /// What kind of borrow this is
    crate kind: mir::BorrowKind,
    /// The region for which this borrow is live
    crate region: Region<'tcx>,
    /// Place from which we are borrowing
    crate borrowed_place: mir::Place<'tcx>,
    /// Place to which the borrow was stored
    crate assigned_place: mir::Place<'tcx>,
}

impl<'tcx> fmt::Display for BorrowData<'tcx> {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        let kind = match self.kind {
            mir::BorrowKind::Shared => "",
            mir::BorrowKind::Unique => "uniq ",
            mir::BorrowKind::Mut { .. } => "mut ",
        };
        let region = format!("{}", self.region);
        let region = if region.len() > 0 {
            format!("{} ", region)
        } else {
            region
        };
        write!(w, "&{}{}{:?}", region, kind, self.borrowed_place)
    }
}

impl<'tcx> BorrowSet<'tcx> {
    pub fn build(tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) -> Self {
        let mut visitor = GatherBorrows {
            tcx,
            mir,
            idx_vec: IndexVec::new(),
            location_map: FxHashMap(),
            activation_map: FxHashMap(),
            region_map: FxHashMap(),
            local_map: FxHashMap(),
            pending_activations: FxHashMap(),
        };

        for (block, block_data) in traversal::preorder(mir) {
            visitor.visit_basic_block_data(block, block_data);
        }

        BorrowSet {
            borrows: visitor.idx_vec,
            location_map: visitor.location_map,
            activation_map: visitor.activation_map,
            region_map: visitor.region_map,
            local_map: visitor.local_map,
        }
    }

    crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
        self.activation_map
            .get(&location)
            .map(|activations| &activations[..])
            .unwrap_or(&[])
    }
}

struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'gcx, 'tcx>,
    mir: &'a Mir<'tcx>,
    idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
    location_map: FxHashMap<Location, BorrowIndex>,
    activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
    region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
    local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,

    /// When we encounter a 2-phase borrow statement, it will always
    /// be assigning into a temporary TEMP:
    ///
    ///    TEMP = &foo
    ///
    /// We add TEMP into this map with `b`, where `b` is the index of
    /// the borrow. When we find a later use of this activation, we
    /// remove from the map (and add to the "tombstone" set below).
    pending_activations: FxHashMap<mir::Local, BorrowIndex>,
}

impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
    fn visit_assign(
        &mut self,
        block: mir::BasicBlock,
        assigned_place: &mir::Place<'tcx>,
        rvalue: &mir::Rvalue<'tcx>,
        location: mir::Location,
    ) {
        if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
            if borrowed_place.is_unsafe_place(self.tcx, self.mir) {
                return;
            }

            let borrow = BorrowData {
                kind,
                region,
                reserve_location: location,
                activation_location: TwoPhaseActivation::NotTwoPhase,
                borrowed_place: borrowed_place.clone(),
                assigned_place: assigned_place.clone(),
            };
            let idx = self.idx_vec.push(borrow);
            self.location_map.insert(location, idx);

            self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);

            insert(&mut self.region_map, &region, idx);
            if let Some(local) = borrowed_place.root_local() {
                insert(&mut self.local_map, &local, idx);
            }
        }

        return self.super_assign(block, assigned_place, rvalue, location);

        fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>, k: &K, v: V)
        where
            K: Clone + Eq + Hash,
            V: Eq + Hash,
        {
            map.entry(k.clone()).or_insert(FxHashSet()).insert(v);
        }
    }

    fn visit_place(
        &mut self,
        place: &mir::Place<'tcx>,
        context: PlaceContext<'tcx>,
        location: Location,
    ) {
        self.super_place(place, context, location);

        // We found a use of some temporary TEMP...
        if let Place::Local(temp) = place {
            // ... check whether we (earlier) saw a 2-phase borrow like
            //
            //     TMP = &mut place
            match self.pending_activations.get(temp) {
                Some(&borrow_index) => {
                    let borrow_data = &mut self.idx_vec[borrow_index];

                    // Watch out: the use of TMP in the borrow itself
                    // doesn't count as an activation. =)
                    if borrow_data.reserve_location == location && context == PlaceContext::Store {
                        return;
                    }

                    if let TwoPhaseActivation::ActivatedAt(other_location) =
                            borrow_data.activation_location {
                        span_bug!(
                            self.mir.source_info(location).span,
                            "found two uses for 2-phase borrow temporary {:?}: \
                             {:?} and {:?}",
                            temp,
                            location,
                            other_location,
                        );
                    }

                    // Otherwise, this is the unique later use
                    // that we expect.
                    borrow_data.activation_location = match context {
                        // The use of TMP in a shared borrow does not
                        // count as an actual activation.
                        PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } => {
                            TwoPhaseActivation::NotActivated
                        }
                        _ => {
                            // Double check: This borrow is indeed a two-phase borrow (that is,
                            // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
                            // we've not found any other activations (checked above).
                            assert_eq!(
                                borrow_data.activation_location,
                                TwoPhaseActivation::NotActivated,
                                "never found an activation for this borrow!",
                            );

                            self.activation_map
                                .entry(location)
                                .or_insert(Vec::new())
                                .push(borrow_index);
                            TwoPhaseActivation::ActivatedAt(location)
                        }
                    };
                }

                None => {}
            }
        }
    }

    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) {
        if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue {
            // double-check that we already registered a BorrowData for this

            let borrow_index = self.location_map[&location];
            let borrow_data = &self.idx_vec[borrow_index];
            assert_eq!(borrow_data.reserve_location, location);
            assert_eq!(borrow_data.kind, kind);
            assert_eq!(borrow_data.region, region);
            assert_eq!(borrow_data.borrowed_place, *place);
        }

        return self.super_rvalue(rvalue, location);
    }

    fn visit_statement(
        &mut self,
        block: mir::BasicBlock,
        statement: &mir::Statement<'tcx>,
        location: Location,
    ) {
        return self.super_statement(block, statement, location);
    }
}

impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
    /// Returns true if the borrow represented by `kind` is
    /// allowed to be split into separate Reservation and
    /// Activation phases.
    fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool {
        self.tcx.two_phase_borrows()
            && (kind.allows_two_phase_borrow()
                || self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref)
    }

    /// If this is a two-phase borrow, then we will record it
    /// as "pending" until we find the activating use.
    fn insert_as_pending_if_two_phase(
        &mut self,
        start_location: Location,
        assigned_place: &mir::Place<'tcx>,
        region: Region<'tcx>,
        kind: mir::BorrowKind,
        borrow_index: BorrowIndex,
    ) {
        debug!(
            "Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?}, {:?})",
            start_location, assigned_place, region, borrow_index,
        );

        if !self.allow_two_phase_borrow(kind) {
            debug!("  -> {:?}", start_location);
            return;
        }

        // When we encounter a 2-phase borrow statement, it will always
        // be assigning into a temporary TEMP:
        //
        //    TEMP = &foo
        //
        // so extract `temp`.
        let temp = if let &mir::Place::Local(temp) = assigned_place {
            temp
        } else {
            span_bug!(
                self.mir.source_info(start_location).span,
                "expected 2-phase borrow to assign to a local, not `{:?}`",
                assigned_place,
            );
        };

        // Consider the borrow not activated to start. When we find an activation, we'll update
        // this field.
        let borrow_data = &mut self.idx_vec[borrow_index];
        borrow_data.activation_location = TwoPhaseActivation::NotActivated;

        // Insert `temp` into the list of pending activations. From
        // now on, we'll be on the lookout for a use of it. Note that
        // we are guaranteed that this use will come after the
        // assignment.
        let old_value = self.pending_activations.insert(temp, borrow_index);
        assert!(old_value.is_none());
    }
}
<commit_msg>Improve the information provided when this assertion fails.<commit_after>// Copyright 2012-2017 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 borrow_check::place_ext::PlaceExt;
use dataflow::indexes::BorrowIndex;
use rustc::mir::traversal;
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{self, Location, Mir, Place};
use rustc::ty::{Region, TyCtxt};
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_vec::IndexVec;
use std::fmt;
use std::hash::Hash;
use std::ops::Index;

crate struct BorrowSet<'tcx> {
    /// The fundamental map relating bitvector indexes to the borrows
    /// in the MIR.
    crate borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,

    /// Each borrow is also uniquely identified in the MIR by the
    /// `Location` of the assignment statement in which it appears on
    /// the right hand side; we map each such location to the
    /// corresponding `BorrowIndex`.
    crate location_map: FxHashMap<Location, BorrowIndex>,

    /// Locations which activate borrows.
    /// NOTE: A given location may activate more than one borrow in the future
    /// when more general two-phase borrow support is introduced, but for now we
    /// only need to store one borrow index
    crate activation_map: FxHashMap<Location, Vec<BorrowIndex>>,

    /// Every borrow has a region; this maps each such regions back to
    /// its borrow-indexes.
    crate region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,

    /// Map from local to all the borrows on that local
    crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
}

impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
    type Output = BorrowData<'tcx>;

    fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> {
        &self.borrows[index]
    }
}

/// Location where a two phase borrow is activated, if a borrow
/// is in fact a two phase borrow.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
crate enum TwoPhaseActivation {
    NotTwoPhase,
    NotActivated,
    ActivatedAt(Location),
}

#[derive(Debug)]
crate struct BorrowData<'tcx> {
    /// Location where the borrow reservation starts.
    /// In many cases, this will be equal to the activation location but not always.
    crate reserve_location: Location,
    /// Location where the borrow is activated.
    crate activation_location: TwoPhaseActivation,
    /// What kind of borrow this is
    crate kind: mir::BorrowKind,
    /// The region for which this borrow is live
    crate region: Region<'tcx>,
    /// Place from which we are borrowing
    crate borrowed_place: mir::Place<'tcx>,
    /// Place to which the borrow was stored
    crate assigned_place: mir::Place<'tcx>,
}

impl<'tcx> fmt::Display for BorrowData<'tcx> {
    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
        let kind = match self.kind {
            mir::BorrowKind::Shared => "",
            mir::BorrowKind::Unique => "uniq ",
            mir::BorrowKind::Mut { .. } => "mut ",
        };
        let region = format!("{}", self.region);
        let region = if region.len() > 0 {
            format!("{} ", region)
        } else {
            region
        };
        write!(w, "&{}{}{:?}", region, kind, self.borrowed_place)
    }
}

impl<'tcx> BorrowSet<'tcx> {
    pub fn build(tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) -> Self {
        let mut visitor = GatherBorrows {
            tcx,
            mir,
            idx_vec: IndexVec::new(),
            location_map: FxHashMap(),
            activation_map: FxHashMap(),
            region_map: FxHashMap(),
            local_map: FxHashMap(),
            pending_activations: FxHashMap(),
        };

        for (block, block_data) in traversal::preorder(mir) {
            visitor.visit_basic_block_data(block, block_data);
        }

        BorrowSet {
            borrows: visitor.idx_vec,
            location_map: visitor.location_map,
            activation_map: visitor.activation_map,
            region_map: visitor.region_map,
            local_map: visitor.local_map,
        }
    }

    crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
        self.activation_map
            .get(&location)
            .map(|activations| &activations[..])
            .unwrap_or(&[])
    }
}

struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'gcx, 'tcx>,
    mir: &'a Mir<'tcx>,
    idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
    location_map: FxHashMap<Location, BorrowIndex>,
    activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
    region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
    local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,

    /// When we encounter a 2-phase borrow statement, it will always
    /// be assigning into a temporary TEMP:
    ///
    ///    TEMP = &foo
    ///
    /// We add TEMP into this map with `b`, where `b` is the index of
    /// the borrow. When we find a later use of this activation, we
    /// remove from the map (and add to the "tombstone" set below).
    pending_activations: FxHashMap<mir::Local, BorrowIndex>,
}

impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
    fn visit_assign(
        &mut self,
        block: mir::BasicBlock,
        assigned_place: &mir::Place<'tcx>,
        rvalue: &mir::Rvalue<'tcx>,
        location: mir::Location,
    ) {
        if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
            if borrowed_place.is_unsafe_place(self.tcx, self.mir) {
                return;
            }

            let borrow = BorrowData {
                kind,
                region,
                reserve_location: location,
                activation_location: TwoPhaseActivation::NotTwoPhase,
                borrowed_place: borrowed_place.clone(),
                assigned_place: assigned_place.clone(),
            };
            let idx = self.idx_vec.push(borrow);
            self.location_map.insert(location, idx);

            self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);

            insert(&mut self.region_map, &region, idx);
            if let Some(local) = borrowed_place.root_local() {
                insert(&mut self.local_map, &local, idx);
            }
        }

        return self.super_assign(block, assigned_place, rvalue, location);

        fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>, k: &K, v: V)
        where
            K: Clone + Eq + Hash,
            V: Eq + Hash,
        {
            map.entry(k.clone()).or_insert(FxHashSet()).insert(v);
        }
    }

    fn visit_place(
        &mut self,
        place: &mir::Place<'tcx>,
        context: PlaceContext<'tcx>,
        location: Location,
    ) {
        self.super_place(place, context, location);

        // We found a use of some temporary TEMP...
        if let Place::Local(temp) = place {
            // ... check whether we (earlier) saw a 2-phase borrow like
            //
            //     TMP = &mut place
            match self.pending_activations.get(temp) {
                Some(&borrow_index) => {
                    let borrow_data = &mut self.idx_vec[borrow_index];

                    // Watch out: the use of TMP in the borrow itself
                    // doesn't count as an activation. =)
                    if borrow_data.reserve_location == location && context == PlaceContext::Store {
                        return;
                    }

                    if let TwoPhaseActivation::ActivatedAt(other_location) =
                            borrow_data.activation_location {
                        span_bug!(
                            self.mir.source_info(location).span,
                            "found two uses for 2-phase borrow temporary {:?}: \
                             {:?} and {:?}",
                            temp,
                            location,
                            other_location,
                        );
                    }

                    // Otherwise, this is the unique later use
                    // that we expect.
                    borrow_data.activation_location = match context {
                        // The use of TMP in a shared borrow does not
                        // count as an actual activation.
                        PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } => {
                            TwoPhaseActivation::NotActivated
                        }
                        _ => {
                            // Double check: This borrow is indeed a two-phase borrow (that is,
                            // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
                            // we've not found any other activations (checked above).
                            assert_eq!(
                                borrow_data.activation_location,
                                TwoPhaseActivation::NotActivated,
                                "never found an activation for this borrow!",
                            );

                            self.activation_map
                                .entry(location)
                                .or_insert(Vec::new())
                                .push(borrow_index);
                            TwoPhaseActivation::ActivatedAt(location)
                        }
                    };
                }

                None => {}
            }
        }
    }

    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) {
        if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue {
            // double-check that we already registered a BorrowData for this

            let borrow_index = self.location_map[&location];
            let borrow_data = &self.idx_vec[borrow_index];
            assert_eq!(borrow_data.reserve_location, location);
            assert_eq!(borrow_data.kind, kind);
            assert_eq!(borrow_data.region, region);
            assert_eq!(borrow_data.borrowed_place, *place);
        }

        return self.super_rvalue(rvalue, location);
    }

    fn visit_statement(
        &mut self,
        block: mir::BasicBlock,
        statement: &mir::Statement<'tcx>,
        location: Location,
    ) {
        return self.super_statement(block, statement, location);
    }
}

impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
    /// Returns true if the borrow represented by `kind` is
    /// allowed to be split into separate Reservation and
    /// Activation phases.
    fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool {
        self.tcx.two_phase_borrows()
            && (kind.allows_two_phase_borrow()
                || self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref)
    }

    /// If this is a two-phase borrow, then we will record it
    /// as "pending" until we find the activating use.
    fn insert_as_pending_if_two_phase(
        &mut self,
        start_location: Location,
        assigned_place: &mir::Place<'tcx>,
        region: Region<'tcx>,
        kind: mir::BorrowKind,
        borrow_index: BorrowIndex,
    ) {
        debug!(
            "Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?}, {:?})",
            start_location, assigned_place, region, borrow_index,
        );

        if !self.allow_two_phase_borrow(kind) {
            debug!("  -> {:?}", start_location);
            return;
        }

        // When we encounter a 2-phase borrow statement, it will always
        // be assigning into a temporary TEMP:
        //
        //    TEMP = &foo
        //
        // so extract `temp`.
        let temp = if let &mir::Place::Local(temp) = assigned_place {
            temp
        } else {
            span_bug!(
                self.mir.source_info(start_location).span,
                "expected 2-phase borrow to assign to a local, not `{:?}`",
                assigned_place,
            );
        };

        // Consider the borrow not activated to start. When we find an activation, we'll update
        // this field.
        {
            let borrow_data = &mut self.idx_vec[borrow_index];
            borrow_data.activation_location = TwoPhaseActivation::NotActivated;
        }

        // Insert `temp` into the list of pending activations. From
        // now on, we'll be on the lookout for a use of it. Note that
        // we are guaranteed that this use will come after the
        // assignment.
        let old_value = self.pending_activations.insert(temp, borrow_index);
        if let Some(old_index) = old_value {
            span_bug!(self.mir.source_info(start_location).span,
                      "found already pending activation for temp: {:?} \
                       at borrow_index: {:?} with associated data {:?}",
                      temp, old_index, self.idx_vec[old_index]);
        }
    }
}
<|endoftext|>