<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Nicholas Juszczak <juszczakn@gmail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) ugoa cmode

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, AppSettings, Arg, ArgMatches, OsValues};
use std::fs;
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
#[cfg(not(windows))]
use uucore::mode;
use uucore::InvalidEncodingHandling;

static DEFAULT_PERM: u32 = 0o755;

static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist";
mod options {
    pub const MODE: &str = "mode";
    pub const PARENTS: &str = "parents";
    pub const VERBOSE: &str = "verbose";
    pub const DIRS: &str = "dirs";
}

fn usage() -> String {
    format!("{0} [OPTION]... [USER]", uucore::execution_phrase())
}
fn get_long_usage() -> String {
    String::from("Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.")
}

#[cfg(windows)]
fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result<u32, String> {
    Ok(DEFAULT_PERM)
}

#[cfg(not(windows))]
fn get_mode(matches: &ArgMatches, mode_had_minus_prefix: bool) -> Result<u32, String> {
    let digits: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    // Translate a ~str in octal form to u16, default to 755
    // Not tested on Windows
    let mut new_mode = DEFAULT_PERM;
    match matches.value_of(options::MODE) {
        Some(m) => {
            for mode in m.split(',') {
                if mode.contains(digits) {
                    new_mode = mode::parse_numeric(new_mode, m, true)?;
                } else {
                    let cmode = if mode_had_minus_prefix {
                        // clap parsing is finished, now put prefix back
                        format!("-{}", mode)
                    } else {
                        mode.to_string()
                    };
                    new_mode = mode::parse_symbolic(new_mode, &cmode, mode::get_umask(), true)?;
                }
            }
            Ok(new_mode)
        }
        None => {
            // If no mode argument is specified return the mode from umask
            Ok(mode::get_umask())
        }
    }
}

#[cfg(windows)]
fn strip_minus_from_mode(_args: &mut Vec<String>) -> bool {
    false
}

#[cfg(not(windows))]
fn strip_minus_from_mode(args: &mut Vec<String>) -> bool {
    mode::strip_minus_from_mode(args)
}

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let mut args = args
        .collect_str(InvalidEncodingHandling::ConvertLossy)
        .accept_any();

    // Before we can parse 'args' with clap (and previously getopts),
    // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").
    let mode_had_minus_prefix = strip_minus_from_mode(&mut args);

    let usage = usage();
    let after_help = get_long_usage();

    // Linux-specific options, not implemented
    // opts.optflag("Z", "context", "set SELinux security context" +
    // " of each created directory to CTX"),
    let matches = uu_app()
        .override_usage(&usage[..])
        .after_help(&after_help[..])
        .get_matches_from(args);

    let dirs = matches.values_of_os(options::DIRS).unwrap_or_default();
    let verbose = matches.is_present(options::VERBOSE);
    let recursive = matches.is_present(options::PARENTS);

    match get_mode(&matches, mode_had_minus_prefix) {
        Ok(mode) => exec(dirs, recursive, mode, verbose),
        Err(f) => Err(USimpleError::new(1, f)),
    }
}

pub fn uu_app<'a>() -> App<'a> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .setting(AppSettings::InferLongArgs)
        .arg(
            Arg::new(options::MODE)
                .short('m')
                .long(options::MODE)
                .help("set file mode (not implemented on windows)")
                .takes_value(true),
        )
        .arg(
            Arg::new(options::PARENTS)
                .short('p')
                .long(options::PARENTS)
                .help("make parent directories as needed"),
        )
        .arg(
            Arg::new(options::VERBOSE)
                .short('v')
                .long(options::VERBOSE)
                .help("print a message for each printed directory"),
        )
        .arg(
            Arg::new(options::DIRS)
                .multiple_occurrences(true)
                .takes_value(true)
                .min_values(1)
                .allow_invalid_utf8(true),
        )
}

/**
 * Create the list of new directories
 */
fn exec(dirs: OsValues, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
    for dir in dirs {
        let path = Path::new(dir);
        show_if_err!(mkdir(path, recursive, mode, verbose));
    }
    Ok(())
}

fn mkdir(path: &Path, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
    let create_dir = if recursive {
        fs::create_dir_all
    } else {
        fs::create_dir
    };

    create_dir(path).map_err_context(|| format!("cannot create directory {}", path.quote()))?;

    if verbose {
        println!(
            "{}: created directory {}",
            uucore::util_name(),
            path.quote()
        );
    }

    chmod(path, mode)
}

#[cfg(any(unix, target_os = "redox"))]
fn chmod(path: &Path, mode: u32) -> UResult<()> {
    use std::fs::{set_permissions, Permissions};
    use std::os::unix::fs::PermissionsExt;

    let mode = Permissions::from_mode(mode);

    set_permissions(path, mode)
        .map_err_context(|| format!("cannot set permissions {}", path.quote()))
}

#[cfg(windows)]
fn chmod(_path: &Path, _mode: u32) -> UResult<()> {
    // chmod on Windows only sets the readonly flag, which isn't even honored on directories
    Ok(())
}
<commit_msg>mkdir: fixed permissions behavior with umask - umask application more closely resembles gnu<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Nicholas Juszczak <juszczakn@gmail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) ugoa cmode

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, AppSettings, Arg, ArgMatches, OsValues};
use std::fs;
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult, USimpleError};
#[cfg(not(windows))]
use uucore::mode;
use uucore::InvalidEncodingHandling;

static DEFAULT_PERM: u32 = 0o755;

static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist";
mod options {
    pub const MODE: &str = "mode";
    pub const PARENTS: &str = "parents";
    pub const VERBOSE: &str = "verbose";
    pub const DIRS: &str = "dirs";
}

fn usage() -> String {
    format!("{0} [OPTION]... [USER]", uucore::execution_phrase())
}
fn get_long_usage() -> String {
    String::from("Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.")
}

#[cfg(windows)]
fn get_mode(_matches: &ArgMatches, _mode_had_minus_prefix: bool) -> Result<u32, String> {
    Ok(DEFAULT_PERM)
}

#[cfg(not(windows))]
fn get_mode(matches: &ArgMatches, mode_had_minus_prefix: bool) -> Result<u32, String> {
    let digits: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    // Translate a ~str in octal form to u16, default to 755
    // Not tested on Windows
    let mut new_mode = DEFAULT_PERM;
    match matches.value_of(options::MODE) {
        Some(m) => {
            for mode in m.split(',') {
                if mode.contains(digits) {
                    new_mode = mode::parse_numeric(new_mode, m, true)?;
                } else {
                    let cmode = if mode_had_minus_prefix {
                        // clap parsing is finished, now put prefix back
                        format!("-{}", mode)
                    } else {
                        mode.to_string()
                    };
                    new_mode = mode::parse_symbolic(new_mode, &cmode, mode::get_umask(), true)?;
                }
            }
            Ok(new_mode)
        }
        None => {
            // If no mode argument is specified return the mode derived from umask
            Ok(!mode::get_umask() & 0o0777)
        }
    }
}

#[cfg(windows)]
fn strip_minus_from_mode(_args: &mut Vec<String>) -> bool {
    false
}

#[cfg(not(windows))]
fn strip_minus_from_mode(args: &mut Vec<String>) -> bool {
    mode::strip_minus_from_mode(args)
}

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let mut args = args
        .collect_str(InvalidEncodingHandling::ConvertLossy)
        .accept_any();

    // Before we can parse 'args' with clap (and previously getopts),
    // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").
    let mode_had_minus_prefix = strip_minus_from_mode(&mut args);

    let usage = usage();
    let after_help = get_long_usage();

    // Linux-specific options, not implemented
    // opts.optflag("Z", "context", "set SELinux security context" +
    // " of each created directory to CTX"),
    let matches = uu_app()
        .override_usage(&usage[..])
        .after_help(&after_help[..])
        .get_matches_from(args);

    let dirs = matches.values_of_os(options::DIRS).unwrap_or_default();
    let verbose = matches.is_present(options::VERBOSE);
    let recursive = matches.is_present(options::PARENTS);

    match get_mode(&matches, mode_had_minus_prefix) {
        Ok(mode) => exec(dirs, recursive, mode, verbose),
        Err(f) => Err(USimpleError::new(1, f)),
    }
}

pub fn uu_app<'a>() -> App<'a> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .setting(AppSettings::InferLongArgs)
        .arg(
            Arg::new(options::MODE)
                .short('m')
                .long(options::MODE)
                .help("set file mode (not implemented on windows)")
                .takes_value(true),
        )
        .arg(
            Arg::new(options::PARENTS)
                .short('p')
                .long(options::PARENTS)
                .help("make parent directories as needed"),
        )
        .arg(
            Arg::new(options::VERBOSE)
                .short('v')
                .long(options::VERBOSE)
                .help("print a message for each printed directory"),
        )
        .arg(
            Arg::new(options::DIRS)
                .multiple_occurrences(true)
                .takes_value(true)
                .min_values(1)
                .allow_invalid_utf8(true),
        )
}

/**
 * Create the list of new directories
 */
fn exec(dirs: OsValues, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
    for dir in dirs {
        let path = Path::new(dir);
        show_if_err!(mkdir(path, recursive, mode, verbose));
    }
    Ok(())
}

fn mkdir(path: &Path, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
    let create_dir = if recursive {
        fs::create_dir_all
    } else {
        fs::create_dir
    };

    create_dir(path).map_err_context(|| format!("cannot create directory {}", path.quote()))?;

    if verbose {
        println!(
            "{}: created directory {}",
            uucore::util_name(),
            path.quote()
        );
    }

    chmod(path, mode)
}

#[cfg(any(unix, target_os = "redox"))]
fn chmod(path: &Path, mode: u32) -> UResult<()> {
    use std::fs::{set_permissions, Permissions};
    use std::os::unix::fs::PermissionsExt;

    let mode = Permissions::from_mode(mode);

    set_permissions(path, mode)
        .map_err_context(|| format!("cannot set permissions {}", path.quote()))
}

#[cfg(windows)]
fn chmod(_path: &Path, _mode: u32) -> UResult<()> {
    // chmod on Windows only sets the readonly flag, which isn't even honored on directories
    Ok(())
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use std::cell::RefCell;
use glfw;
// use glfw::Context;
use cgmath::vector::Vector2;
use core::types::{Size2, MInt, Point2};
use core::conf::Config;
use visualizer::types::{MFloat, MatId, ColorId};
use visualizer::shader::Shader;
use visualizer::font_stash::FontStash;
use visualizer::mgl;

pub struct Context {
    pub win: glfw::Window,
    pub win_size: Size2<MInt>,
    pub mouse_pos: Point2<MFloat>, // TODO: Point2 -> ScreenPos
    pub config: Config,
    pub font_stash: RefCell<FontStash>,
    pub shader: Shader,
    pub mvp_mat_id: MatId,
    pub basic_color_id: ColorId,
}

impl Context {
    fn set_window_size(&mut self, win_size: Size2<MInt>) {
        self.win_size = win_size;
        mgl::set_viewport(win_size);
    }

    pub fn handle_event(&mut self, event: glfw::WindowEvent) {
        match event {
            glfw::CursorPosEvent(x, y) => {
                self.mouse_pos = Point2{v: Vector2 {
                    x: x as MFloat,
                    y: y as MFloat,
                }};
            },
            glfw::SizeEvent(w, h) => {
                self.set_window_size(Size2{w: w, h: h});
            },
            _ => {},
        }
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>visualizer/context.rs: Removed commented-out 'use glfw::Context'<commit_after>// See LICENSE file for copyright and license details.

use std::cell::RefCell;
use glfw;
use cgmath::vector::Vector2;
use core::types::{Size2, MInt, Point2};
use core::conf::Config;
use visualizer::types::{MFloat, MatId, ColorId};
use visualizer::shader::Shader;
use visualizer::font_stash::FontStash;
use visualizer::mgl;

pub struct Context {
    pub win: glfw::Window,
    pub win_size: Size2<MInt>,
    pub mouse_pos: Point2<MFloat>, // TODO: Point2 -> ScreenPos
    pub config: Config,
    pub font_stash: RefCell<FontStash>,
    pub shader: Shader,
    pub mvp_mat_id: MatId,
    pub basic_color_id: ColorId,
}

impl Context {
    fn set_window_size(&mut self, win_size: Size2<MInt>) {
        self.win_size = win_size;
        mgl::set_viewport(win_size);
    }

    pub fn handle_event(&mut self, event: glfw::WindowEvent) {
        match event {
            glfw::CursorPosEvent(x, y) => {
                self.mouse_pos = Point2{v: Vector2 {
                    x: x as MFloat,
                    y: y as MFloat,
                }};
            },
            glfw::SizeEvent(w, h) => {
                self.set_window_size(Size2{w: w, h: h});
            },
            _ => {},
        }
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>//! This module is an attempt to provide a friendly, rust-esque interface to Apple's Audio Unit API.
//!
//! Learn more about the Audio Unit API [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40003278-CH1-SW2)
//! and [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html).
//!
//! TODO: The following are `kAudioUnitSubType`s (along with their const u32) generated by
//! rust-bindgen that we could not find any documentation on:
//!
//! - MIDISynth            = 1836284270,
//! - RoundTripAAC         = 1918984547,
//! - SpatialMixer         = 862217581,
//! - SphericalHeadPanner  = 1936746610,
//! - VectorPanner         = 1986158963,
//! - SoundFieldPanner     = 1634558569,
//! - HRTFPanner           = 1752331366,
//! - NetReceive           = 1852990326,
//!
//! If you can find documentation on these, please feel free to submit an issue or PR with the
//! fixes!

use bindings::audio_unit as au;
use error::Error;
use libc;
use std::mem;
use std::ptr;

pub use self::audio_format::AudioFormat;
pub use self::stream_format::StreamFormat;
pub use self::types::{
    Type,
    EffectType,
    FormatConverterType,
    GeneratorType,
    IOType,
    MixerType,
    MusicDeviceType,
};

pub mod audio_format;
pub mod render_callback;
pub mod stream_format;
pub mod types;

/// The input and output **Scope**s.
///
/// More info [here](https://developer.apple.com/library/ios/documentation/AudioUnit/Reference/AudioUnitPropertiesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Scopes)
/// and [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html).
#[derive(Copy, Clone, Debug)]
pub enum Scope {
    Output = 0,
    Input  = 1,
}

/// Represents the **Input** and **Output** **Element**s.
///
/// These are used when specifying which **Element** we're setting the properties of.
#[derive(Copy, Clone, Debug)]
pub enum Element {
    Output = 0,
    Input  = 1,
}

/// A rust representation of the au::AudioUnit, including a pointer to the current rendering callback.
///
/// Find the original Audio Unit Programming Guide [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html).
pub struct AudioUnit {
    instance: au::AudioUnit,
    maybe_callback: Option<*mut render_callback::InputProcFnWrapper>
}

macro_rules! try_os_status {
    ($expr:expr) => (try!(Error::from_os_status($expr)))
}

impl AudioUnit {

    /// Construct a new AudioUnit with any type that may be automatically converted into
    /// [**Type**](./enum.Type).
    ///
    /// Here is a list of compatible types:
    ///
    /// - [**Type**](./types/enum.Type)
    /// - [**IOType**](./types/enum.IOType)
    /// - [**MusicDeviceType**](./types/enum.MusicDeviceType)
    /// - [**GeneratorType**](./types/enum.GeneratorType)
    /// - [**FormatConverterType**](./types/enum.FormatConverterType)
    /// - [**EffectType**](./types/enum.EffectType)
    /// - [**MixerType**](./types/enum.MixerType)
    ///
    /// To construct the **AudioUnit** with some component flags, see
    /// [**AudioUnit::new_with_flags**](./struct.AudioUnit#method.new_with_flags).
    ///
    /// Note: the `AudioUnit` is constructed with the `kAudioUnitManufacturer_Apple` Manufacturer
    /// Identifier, as this is the only Audio Unit Manufacturer Identifier documented by Apple in
    /// the AudioUnit reference (see [here](https://developer.apple.com/library/prerelease/mac/documentation/AudioUnit/Reference/AUComponentServicesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Manufacturer_Identifier)).
    pub fn new<T>(ty: T) -> Result<AudioUnit, Error>
        where T: Into<Type>,
    {
        AudioUnit::new_with_flags(ty, 0, 0)
    }

    /// The same as [**AudioUnit::new**](./struct.AudioUnit#method.new) but with the given
    /// component flags and mask.
    pub fn new_with_flags<T>(ty: T, flags: u32, mask: u32) -> Result<AudioUnit, Error>
        where T: Into<Type>,
    {
        const MANUFACTURER_IDENTIFIER: u32 = au::kAudioUnitManufacturer_Apple;
        let au_type: Type = ty.into();
        let sub_type_u32 = match au_type.to_subtype_u32() {
            Some(u) => u,
            None => return Err(Error::NoKnownSubtype),
        };

        // A description of the audio unit we desire.
        let desc = au::AudioComponentDescription {
            componentType: au_type.to_u32() as libc::c_uint,
            componentSubType: sub_type_u32 as libc::c_uint,
            componentManufacturer: MANUFACTURER_IDENTIFIER,
            componentFlags: flags,
            componentFlagsMask: mask,
        };

        unsafe {
            // Find the default audio unit for the description.
            //
            // From the "Audio Unit Hosting Guide for iOS":
            //
            // Passing NULL to the first parameter of AudioComponentFindNext tells this function to
            // find the first system audio unit matching the description, using a system-defined
            // ordering. If you instead pass a previously found audio unit reference in this
            // parameter, the function locates the next audio unit matching the description.
            let component = au::AudioComponentFindNext(ptr::null_mut(), &desc as *const _);
            if component.is_null() {
                return Err(Error::NoMatchingDefaultAudioUnitFound);
            }

            // Create an instance of the default audio unit using the component.
            let mut instance: au::AudioUnit = mem::uninitialized();
            try_os_status!(
                au::AudioComponentInstanceNew(component, &mut instance as *mut au::AudioUnit)
            );

            // Initialise the audio unit!
            try_os_status!(au::AudioUnitInitialize(instance));
            Ok(AudioUnit {
                instance: instance,
                maybe_callback: None
            })
        }
    }

    /// Sets the value for some property of the **AudioUnit**.
    ///
    /// To clear an audio unit property value, set the data paramater with `None::<()>`.
    ///
    /// Clearing properties only works for those properties that do not have a default value.
    ///
    /// For more on "properties" see [the reference](https://developer.apple.com/library/ios/documentation/AudioUnit/Reference/AudioUnitPropertiesReference/index.html#//apple_ref/doc/uid/TP40007288).
    ///
    /// **Available** in iOS 2.0 and later.
    ///
    /// Parameters
    /// ----------
    ///
    /// - **id**: The identifier of the property.
    /// - **scope**: The audio unit scope for the property.
    /// - **elem**: The audio unit element for the property.
    /// - **maybe_data**: The value that you want to apply to the property.
    pub fn set_property<T>(&mut self, id: u32, scope: Scope, elem: Element, maybe_data: Option<&T>)
        -> Result<(), Error>
    {
        let (data_ptr, size) = maybe_data.map(|data| {
            let ptr = data as *const _ as *const libc::c_void;
            let size = ::std::mem::size_of::<T>() as u32;
            (ptr, size)
        }).unwrap_or_else(|| (::std::ptr::null(), 0));
        let scope = scope as libc::c_uint;
        let elem = elem as libc::c_uint;
        unsafe {
            try_os_status!(au::AudioUnitSetProperty(self.instance, id, scope, elem, data_ptr, size))
        }
        Ok(())
    }

    /// Gets the value of an **AudioUnit** property.
    ///
    /// **Available** in iOS 2.0 and later.
    ///
    /// Parameters
    /// ----------
    ///
    /// - **id**: The identifier of the property.
    /// - **scope**: The audio unit scope for the property.
    /// - **elem**: The audio unit element for the property.
    pub fn get_property<T>(&self, id: u32, scope: Scope, elem: Element) -> Result<T, Error> {
        let scope = scope as libc::c_uint;
        let elem = elem as libc::c_uint;
        let mut size = ::std::mem::size_of::<T>() as u32;
        unsafe {
            let mut data: T = ::std::mem::uninitialized();
            let data_ptr = &mut data as *mut _ as *mut libc::c_void;
            let size_ptr = &mut size as *mut _;
            try_os_status!(
                au::AudioUnitGetProperty(self.instance, id, scope, elem, data_ptr, size_ptr)
            );
            Ok(data)
        }
    }

    /// Starts an I/O **AudioUnit**, which in turn starts the audio unit processing graph that it is
    /// connected to.
    ///
    /// **Available** in OS X v10.0 and later.
    pub fn start(&mut self) -> Result<(), Error> {
        unsafe { try_os_status!(au::AudioOutputUnitStart(self.instance)); }
        Ok(())
    }

    /// Stops an I/O **AudioUnit**, which in turn stops the audio unit processing graph that it is
    /// connected to.
    ///
    /// **Available** in OS X v10.0 and later.
    pub fn stop(&mut self) -> Result<(), Error> {
        unsafe { try_os_status!(au::AudioOutputUnitStop(self.instance)); }
        Ok(())
    }

    /// Set the **AudioUnit**'s sample rate.
    ///
    /// **Available** in iOS 2.0 and later.
    pub fn set_sample_rate(&mut self, sample_rate: f64) -> Result<(), Error> {
        let id = au::kAudioUnitProperty_SampleRate;
        self.set_property(id, Scope::Input, Element::Output, Some(&sample_rate))
    }

    /// Get the **AudioUnit**'s sample rate.
    pub fn sample_rate(&self) -> Result<f64, Error> {
        let id = au::kAudioUnitProperty_SampleRate;
        self.get_property(id, Scope::Input, Element::Output)
    }

    /// Sets the current **StreamFormat** for the AudioUnit.
    ///
    /// The default format stream is non-interleaved, 32-bit floating point, native-endian, linear
    /// PCM data.
    pub fn set_stream_format(&mut self, stream_format: StreamFormat) -> Result<(), Error> {
        let id = au::kAudioUnitProperty_StreamFormat;
        let asbd = stream_format.to_asbd();
        self.set_property(id, Scope::Input, Element::Output, Some(&asbd))
    }

    /// Return the current Stream Format for the AudioUnit.
    pub fn stream_format(&self) -> Result<StreamFormat, Error> {
        let id = au::kAudioUnitProperty_StreamFormat;
        let asbd = try!(self.get_property(id, Scope::Output, Element::Output));
        StreamFormat::from_asbd(asbd)
    }

}

impl Drop for AudioUnit {
    fn drop(&mut self) {
        unsafe {
            use error;
            use std::error::Error;

            // We don't want to panic in `drop`, so we'll ignore returned errors.
            //
            // A user should explicitly terminate the `AudioUnit` if they want to handle errors (we
            // still need to provide a way to actually do that).
            self.stop().ok();
            error::Error::from_os_status(au::AudioUnitUninitialize(self.instance)).ok();

            self.free_render_callback();
        }
    }
}
<commit_msg>Move Sample and SampleFormat into their own module<commit_after>//! This module is an attempt to provide a friendly, rust-esque interface to Apple's Audio Unit API.
//!
//! Learn more about the Audio Unit API [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40003278-CH1-SW2)
//! and [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html).
//!
//! TODO: The following are `kAudioUnitSubType`s (along with their const u32) generated by
//! rust-bindgen that we could not find any documentation on:
//!
//! - MIDISynth            = 1836284270,
//! - RoundTripAAC         = 1918984547,
//! - SpatialMixer         = 862217581,
//! - SphericalHeadPanner  = 1936746610,
//! - VectorPanner         = 1986158963,
//! - SoundFieldPanner     = 1634558569,
//! - HRTFPanner           = 1752331366,
//! - NetReceive           = 1852990326,
//!
//! If you can find documentation on these, please feel free to submit an issue or PR with the
//! fixes!

use bindings::audio_unit as au;
use error::Error;
use libc;
use std::mem;
use std::ptr;

pub use self::audio_format::AudioFormat;
pub use self::sample_format::{SampleFormat, Sample};
pub use self::stream_format::StreamFormat;
pub use self::types::{
    Type,
    EffectType,
    FormatConverterType,
    GeneratorType,
    IOType,
    MixerType,
    MusicDeviceType,
};

pub mod audio_format;
pub mod render_callback;
pub mod sample_format;
pub mod stream_format;
pub mod types;

/// The input and output **Scope**s.
///
/// More info [here](https://developer.apple.com/library/ios/documentation/AudioUnit/Reference/AudioUnitPropertiesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Scopes)
/// and [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html).
#[derive(Copy, Clone, Debug)]
pub enum Scope {
    Output = 0,
    Input  = 1,
}

/// Represents the **Input** and **Output** **Element**s.
///
/// These are used when specifying which **Element** we're setting the properties of.
#[derive(Copy, Clone, Debug)]
pub enum Element {
    Output = 0,
    Input  = 1,
}

/// A rust representation of the au::AudioUnit, including a pointer to the current rendering callback.
///
/// Find the original Audio Unit Programming Guide [here](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html).
pub struct AudioUnit {
    instance: au::AudioUnit,
    maybe_callback: Option<*mut render_callback::InputProcFnWrapper>
}

macro_rules! try_os_status {
    ($expr:expr) => (try!(Error::from_os_status($expr)))
}

impl AudioUnit {

    /// Construct a new AudioUnit with any type that may be automatically converted into
    /// [**Type**](./enum.Type).
    ///
    /// Here is a list of compatible types:
    ///
    /// - [**Type**](./types/enum.Type)
    /// - [**IOType**](./types/enum.IOType)
    /// - [**MusicDeviceType**](./types/enum.MusicDeviceType)
    /// - [**GeneratorType**](./types/enum.GeneratorType)
    /// - [**FormatConverterType**](./types/enum.FormatConverterType)
    /// - [**EffectType**](./types/enum.EffectType)
    /// - [**MixerType**](./types/enum.MixerType)
    ///
    /// To construct the **AudioUnit** with some component flags, see
    /// [**AudioUnit::new_with_flags**](./struct.AudioUnit#method.new_with_flags).
    ///
    /// Note: the `AudioUnit` is constructed with the `kAudioUnitManufacturer_Apple` Manufacturer
    /// Identifier, as this is the only Audio Unit Manufacturer Identifier documented by Apple in
    /// the AudioUnit reference (see [here](https://developer.apple.com/library/prerelease/mac/documentation/AudioUnit/Reference/AUComponentServicesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Manufacturer_Identifier)).
    pub fn new<T>(ty: T) -> Result<AudioUnit, Error>
        where T: Into<Type>,
    {
        AudioUnit::new_with_flags(ty, 0, 0)
    }

    /// The same as [**AudioUnit::new**](./struct.AudioUnit#method.new) but with the given
    /// component flags and mask.
    pub fn new_with_flags<T>(ty: T, flags: u32, mask: u32) -> Result<AudioUnit, Error>
        where T: Into<Type>,
    {
        const MANUFACTURER_IDENTIFIER: u32 = au::kAudioUnitManufacturer_Apple;
        let au_type: Type = ty.into();
        let sub_type_u32 = match au_type.to_subtype_u32() {
            Some(u) => u,
            None => return Err(Error::NoKnownSubtype),
        };

        // A description of the audio unit we desire.
        let desc = au::AudioComponentDescription {
            componentType: au_type.to_u32() as libc::c_uint,
            componentSubType: sub_type_u32 as libc::c_uint,
            componentManufacturer: MANUFACTURER_IDENTIFIER,
            componentFlags: flags,
            componentFlagsMask: mask,
        };

        unsafe {
            // Find the default audio unit for the description.
            //
            // From the "Audio Unit Hosting Guide for iOS":
            //
            // Passing NULL to the first parameter of AudioComponentFindNext tells this function to
            // find the first system audio unit matching the description, using a system-defined
            // ordering. If you instead pass a previously found audio unit reference in this
            // parameter, the function locates the next audio unit matching the description.
            let component = au::AudioComponentFindNext(ptr::null_mut(), &desc as *const _);
            if component.is_null() {
                return Err(Error::NoMatchingDefaultAudioUnitFound);
            }

            // Create an instance of the default audio unit using the component.
            let mut instance: au::AudioUnit = mem::uninitialized();
            try_os_status!(
                au::AudioComponentInstanceNew(component, &mut instance as *mut au::AudioUnit)
            );

            // Initialise the audio unit!
            try_os_status!(au::AudioUnitInitialize(instance));
            Ok(AudioUnit {
                instance: instance,
                maybe_callback: None
            })
        }
    }

    /// Sets the value for some property of the **AudioUnit**.
    ///
    /// To clear an audio unit property value, set the data paramater with `None::<()>`.
    ///
    /// Clearing properties only works for those properties that do not have a default value.
    ///
    /// For more on "properties" see [the reference](https://developer.apple.com/library/ios/documentation/AudioUnit/Reference/AudioUnitPropertiesReference/index.html#//apple_ref/doc/uid/TP40007288).
    ///
    /// **Available** in iOS 2.0 and later.
    ///
    /// Parameters
    /// ----------
    ///
    /// - **id**: The identifier of the property.
    /// - **scope**: The audio unit scope for the property.
    /// - **elem**: The audio unit element for the property.
    /// - **maybe_data**: The value that you want to apply to the property.
    pub fn set_property<T>(&mut self, id: u32, scope: Scope, elem: Element, maybe_data: Option<&T>)
        -> Result<(), Error>
    {
        let (data_ptr, size) = maybe_data.map(|data| {
            let ptr = data as *const _ as *const libc::c_void;
            let size = ::std::mem::size_of::<T>() as u32;
            (ptr, size)
        }).unwrap_or_else(|| (::std::ptr::null(), 0));
        let scope = scope as libc::c_uint;
        let elem = elem as libc::c_uint;
        unsafe {
            try_os_status!(au::AudioUnitSetProperty(self.instance, id, scope, elem, data_ptr, size))
        }
        Ok(())
    }

    /// Gets the value of an **AudioUnit** property.
    ///
    /// **Available** in iOS 2.0 and later.
    ///
    /// Parameters
    /// ----------
    ///
    /// - **id**: The identifier of the property.
    /// - **scope**: The audio unit scope for the property.
    /// - **elem**: The audio unit element for the property.
    pub fn get_property<T>(&self, id: u32, scope: Scope, elem: Element) -> Result<T, Error> {
        let scope = scope as libc::c_uint;
        let elem = elem as libc::c_uint;
        let mut size = ::std::mem::size_of::<T>() as u32;
        unsafe {
            let mut data: T = ::std::mem::uninitialized();
            let data_ptr = &mut data as *mut _ as *mut libc::c_void;
            let size_ptr = &mut size as *mut _;
            try_os_status!(
                au::AudioUnitGetProperty(self.instance, id, scope, elem, data_ptr, size_ptr)
            );
            Ok(data)
        }
    }

    /// Starts an I/O **AudioUnit**, which in turn starts the audio unit processing graph that it is
    /// connected to.
    ///
    /// **Available** in OS X v10.0 and later.
    pub fn start(&mut self) -> Result<(), Error> {
        unsafe { try_os_status!(au::AudioOutputUnitStart(self.instance)); }
        Ok(())
    }

    /// Stops an I/O **AudioUnit**, which in turn stops the audio unit processing graph that it is
    /// connected to.
    ///
    /// **Available** in OS X v10.0 and later.
    pub fn stop(&mut self) -> Result<(), Error> {
        unsafe { try_os_status!(au::AudioOutputUnitStop(self.instance)); }
        Ok(())
    }

    /// Set the **AudioUnit**'s sample rate.
    ///
    /// **Available** in iOS 2.0 and later.
    pub fn set_sample_rate(&mut self, sample_rate: f64) -> Result<(), Error> {
        let id = au::kAudioUnitProperty_SampleRate;
        self.set_property(id, Scope::Input, Element::Output, Some(&sample_rate))
    }

    /// Get the **AudioUnit**'s sample rate.
    pub fn sample_rate(&self) -> Result<f64, Error> {
        let id = au::kAudioUnitProperty_SampleRate;
        self.get_property(id, Scope::Input, Element::Output)
    }

    /// Sets the current **StreamFormat** for the AudioUnit.
    ///
    /// The default format stream is non-interleaved, 32-bit floating point, native-endian, linear
    /// PCM data.
    pub fn set_stream_format(&mut self, stream_format: StreamFormat) -> Result<(), Error> {
        let id = au::kAudioUnitProperty_StreamFormat;
        let asbd = stream_format.to_asbd();
        self.set_property(id, Scope::Input, Element::Output, Some(&asbd))
    }

    /// Return the current Stream Format for the AudioUnit.
    pub fn stream_format(&self) -> Result<StreamFormat, Error> {
        let id = au::kAudioUnitProperty_StreamFormat;
        let asbd = try!(self.get_property(id, Scope::Output, Element::Output));
        StreamFormat::from_asbd(asbd)
    }

}

impl Drop for AudioUnit {
    fn drop(&mut self) {
        unsafe {
            use error;
            use std::error::Error;

            // We don't want to panic in `drop`, so we'll ignore returned errors.
            //
            // A user should explicitly terminate the `AudioUnit` if they want to handle errors (we
            // still need to provide a way to actually do that).
            self.stop().ok();
            error::Error::from_os_status(au::AudioUnitUninitialize(self.instance)).ok();

            self.free_render_callback();
        }
    }
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::io::Read;
use std::fs::File;
use std::path::Path;
use crc::{crc32, Hasher32};

pub fn verify_file_crc32(file: &Path) -> Result<u32, String> {
    let file = get!(File::open(file), "An error occured while opening file. (verify_file)");
    let mut digest = crc32::Digest::new(crc32::IEEE);

    for line in file.bytes() {
        digest.write(&[line.unwrap()]);
    }

    Ok(digest.sum32())
}
<commit_msg>Documentation for verify.rs<commit_after>use std::error::Error;
use std::io::Read;
use std::fs::File;
use std::path::Path;
use crc::{crc32, Hasher32};

/// Verifies the file in `path`, and returns a
/// Result, which returns the CRC32 of the file if
/// the file verification succeeds, or a error message
/// if the file verification failed.
pub fn verify_file_crc32(path: &Path) -> Result<u32, String> {
    let file = get!(File::open(path), "An error occured while opening file. (verify_file)");
    let mut digest = crc32::Digest::new(crc32::IEEE);

    for line in file.bytes() {
        digest.write(&[line.unwrap()]);
    }

    Ok(digest.sum32())
}
<|endoftext|>


<commit_before>use base::{TreeBase, Node, lefti, righti};
use base::bulk_delete::DeleteRangeCache;
use std::fmt::{Debug, Formatter};
use std::fmt;
use std::mem;
use std::ptr;
use std::cmp::{max};
use std::ops::{Deref, DerefMut};
use std::marker::PhantomData;

pub trait TreeReprAccess<K: Ord, V>:    Deref<Target=TreeRepr<K, V, <Self as TreeReprAccess<K,V>>::N>> +
                                     DerefMut<Target=TreeRepr<K, V, <Self as TreeReprAccess<K,V>>::N>> {
    type N: Node<K, V>;
}

#[derive(Clone)]
pub struct TreeRepr<K: Ord, V, N: Node<K, V>> {
    pub data: Vec<N>,
    pub mask: Vec<bool>,
    pub size: usize,

    pub delete_range_cache: DeleteRangeCache,

    _ph: PhantomData<(K, V)>
}

#[derive(Clone)]
pub struct TreeWrapper<K: Ord, V, N: Node<K, V>> {
    repr: TreeRepr<K, V, N>
}

impl<K: Ord, V, N: Node<K, V>> TreeWrapper<K, V, N> {
    pub fn new(mut items: Vec<(K, V)>) -> TreeWrapper<K, V, N> {
        items.sort_by(|a, b| a.0.cmp(&b.0));
        Self::with_sorted(items)
    }

    /// Constructs a new TeardownTree<T>
    /// Note: the argument must be sorted!
    pub fn with_sorted(mut sorted: Vec<(K, V)>) -> TreeWrapper<K, V, N> {
        let size = sorted.len();

        let capacity = size;

        let mut data = Vec::with_capacity(capacity);
        unsafe { data.set_len(capacity); }

        let mask: Vec<bool> = vec![true; capacity];
        let height = Self::build(&mut sorted, 0, &mut data);
        unsafe { sorted.set_len(0); }
        let cache = DeleteRangeCache::new(height);
        TreeWrapper { repr: TreeRepr { data: data, mask: mask, size: size, delete_range_cache: cache, _ph: PhantomData }}
    }

    pub fn calc_height(nodes: &Vec<Option<N>>, idx: usize) -> usize {
        if idx < nodes.len() && nodes[idx].is_some() {
            1 + max(Self::calc_height(nodes, lefti(idx)),
                    Self::calc_height(nodes, righti(idx)))
        } else {
            0
        }
    }

    /// Finds the point to partition n keys for a nearly-complete binary tree
    /// http://stackoverflow.com/a/26896494/3646645
    pub fn build_select_root(n: usize) -> usize {
        // the highest power of two <= n
        let x = if n.is_power_of_two() { n }
            else { n.next_power_of_two() / 2 };

        if x/2 <= (n-x) + 1 {
            debug_assert!(x >= 1, "x={}, n={}", x, n);
            x - 1
        } else {
            n - x/2
        }
    }

    /// Returns the height of the tree.
    pub fn build(sorted: &mut [(K, V)], idx: usize, data: &mut [N]) -> usize {
        match sorted.len() {
            0 => 0,
            n => {
                let mid = Self::build_select_root(n);
                let (lefti, righti) = (lefti(idx), righti(idx));
                let lh = Self::build(&mut sorted[..mid], lefti, data);
                let rh = Self::build(&mut sorted[mid+1..], righti, data);

                unsafe {
                    let p = sorted.get_unchecked(mid);
                    let (k, v) = ptr::read(p);
                    ptr::write(data.get_unchecked_mut(idx), N::new(k, v));
                }

                debug_assert!(rh <= lh);
                1 + lh
            }
        }
    }

    /// Constructs a new TeardownTree<T> based on raw nodes vec.
    pub fn with_nodes(mut nodes: Vec<Option<N>>) -> TreeWrapper<K, V, N> {
        let size = nodes.iter().filter(|x| x.is_some()).count();
        let height = Self::calc_height(&nodes, 0);
        let capacity = nodes.len();

        let mut mask = vec![false; capacity];
        let mut data = Vec::with_capacity(capacity);
        unsafe {
            data.set_len(capacity);
        }

        for i in 0..capacity {
            if let Some(node) = nodes[i].take() {
                mask[i] = true;
                let garbage = mem::replace(&mut data[i], node );
                mem::forget(garbage);
            }
        }

        let cache = DeleteRangeCache::new(height);
        TreeWrapper { repr: TreeRepr { data: data, mask: mask, size: size, delete_range_cache: cache, _ph: PhantomData } }
    }

//    fn into_node_vec(self) -> Vec<Option<Node<T>>> {
//        self.data()
//            .into_iter()
//            .zip(self.mask().into_iter())
//            .map(|(node, flag)| if flag {
//                    Some(node)
//                } else {
//                    None
//                })
//            .collect::<Vec<Option<Node<T>>>>()
//    }
}

impl<K: Ord, V, N: Node<K, V>> Deref for TreeWrapper<K, V, N> {
    type Target = TreeRepr<K, V, N>;

    fn deref(&self) -> &Self::Target {
        &self.repr
    }
}

impl<K: Ord, V, N: Node<K, V>> DerefMut for TreeWrapper<K, V, N> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.repr
    }
}

impl<K: Ord, V, N: Node<K, V>> Drop for TreeWrapper<K, V, N> {
    fn drop(&mut self) {
        self.drop_items();
        unsafe {
            self.data.set_len(0)
        }
    }
}

impl<K: Ord+Debug, V, N: Node<K, V>> Debug for TreeWrapper<K, V, N> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        let mut nz: Vec<_> = self.mask.iter().enumerate()
            .rev()
            .skip_while(|&(_, flag)| !flag)
            .map(|(i, &flag)| match (self.node(i), flag) {
                (_, false) => String::from("0"),
                (ref node, true) => format!("{:?}", node.key)
            })
            .collect();
        nz.reverse();

        let _ = write!(fmt, "[size={}: ", self.size);
        let mut sep = "";
        for ref key in nz.iter() {
            let _ = write!(fmt, "{}", sep);
            sep = ", ";
            let _ = write!(fmt, "{}", key);
        }
        let _ = write!(fmt, "]");
        Ok(())
    }
}

impl<K: Ord+Debug, V, N: Node<K, V>> fmt::Display for TreeWrapper<K, V, N> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        writeln!(fmt, "")?;
        let mut ancestors = vec![];
        self.fmt_subtree(fmt, 0, &mut ancestors)
    }
}

impl<K: Ord+Debug, V, N: Node<K, V>> TreeWrapper<K, V, N> {
    fn fmt_branch(&self, fmt: &mut Formatter, ancestors: &Vec<bool>) -> fmt::Result {
        for (i, c) in ancestors.iter().enumerate() {
            if i == ancestors.len() - 1 {
                write!(fmt, "|--")?;
            } else {
                if *c {
                    write!(fmt, "|")?;
                } else {
                    write!(fmt, " ")?;
                }
                write!(fmt, "  ")?;
            }
        }

        Ok(())
    }

    fn fmt_subtree(&self, fmt: &mut Formatter, idx: usize, ancestors: &mut Vec<bool>) -> fmt::Result {
        self.fmt_branch(fmt, ancestors)?;

        if !self.is_nil(idx) {
            writeln!(fmt, "{:?}", self.key(idx))?;

            if idx%2 == 0 && !ancestors.is_empty() {
                *ancestors.last_mut().unwrap() = false;
            }

            if self.has_left(idx) || self.has_right(idx) {
                ancestors.push(true);
                self.fmt_subtree(fmt, lefti(idx), ancestors)?;
                self.fmt_subtree(fmt, righti(idx), ancestors)?;
                ancestors.pop();
            }
        } else {
            writeln!(fmt, "X")?;
        }

        Ok(())
    }
}
<commit_msg>minor<commit_after>use base::{TreeBase, Node, lefti, righti};
use base::bulk_delete::DeleteRangeCache;
use std::fmt::{Debug, Formatter};
use std::fmt;
use std::mem;
use std::ptr;
use std::cmp::{max};
use std::ops::{Deref, DerefMut};
use std::marker::PhantomData;

pub trait TreeReprAccess<K: Ord, V>: Deref<Target=TreeRepr<K, V, <Self as TreeReprAccess<K,V>>::N>> +
                                     DerefMut
{
    type N: Node<K, V>;
}

#[derive(Clone)]
pub struct TreeRepr<K: Ord, V, N: Node<K, V>> {
    pub data: Vec<N>,
    pub mask: Vec<bool>,
    pub size: usize,

    pub delete_range_cache: DeleteRangeCache,

    _ph: PhantomData<(K, V)>
}

#[derive(Clone)]
pub struct TreeWrapper<K: Ord, V, N: Node<K, V>> {
    repr: TreeRepr<K, V, N>
}

impl<K: Ord, V, N: Node<K, V>> TreeWrapper<K, V, N> {
    pub fn new(mut items: Vec<(K, V)>) -> TreeWrapper<K, V, N> {
        items.sort_by(|a, b| a.0.cmp(&b.0));
        Self::with_sorted(items)
    }

    /// Constructs a new TeardownTree<T>
    /// Note: the argument must be sorted!
    pub fn with_sorted(mut sorted: Vec<(K, V)>) -> TreeWrapper<K, V, N> {
        let size = sorted.len();

        let capacity = size;

        let mut data = Vec::with_capacity(capacity);
        unsafe { data.set_len(capacity); }

        let mask: Vec<bool> = vec![true; capacity];
        let height = Self::build(&mut sorted, 0, &mut data);
        unsafe { sorted.set_len(0); }
        let cache = DeleteRangeCache::new(height);
        TreeWrapper { repr: TreeRepr { data: data, mask: mask, size: size, delete_range_cache: cache, _ph: PhantomData }}
    }

    pub fn calc_height(nodes: &Vec<Option<N>>, idx: usize) -> usize {
        if idx < nodes.len() && nodes[idx].is_some() {
            1 + max(Self::calc_height(nodes, lefti(idx)),
                    Self::calc_height(nodes, righti(idx)))
        } else {
            0
        }
    }

    /// Finds the point to partition n keys for a nearly-complete binary tree
    /// http://stackoverflow.com/a/26896494/3646645
    pub fn build_select_root(n: usize) -> usize {
        // the highest power of two <= n
        let x = if n.is_power_of_two() { n }
            else { n.next_power_of_two() / 2 };

        if x/2 <= (n-x) + 1 {
            debug_assert!(x >= 1, "x={}, n={}", x, n);
            x - 1
        } else {
            n - x/2
        }
    }

    /// Returns the height of the tree.
    pub fn build(sorted: &mut [(K, V)], idx: usize, data: &mut [N]) -> usize {
        match sorted.len() {
            0 => 0,
            n => {
                let mid = Self::build_select_root(n);
                let (lefti, righti) = (lefti(idx), righti(idx));
                let lh = Self::build(&mut sorted[..mid], lefti, data);
                let rh = Self::build(&mut sorted[mid+1..], righti, data);

                unsafe {
                    let p = sorted.get_unchecked(mid);
                    let (k, v) = ptr::read(p);
                    ptr::write(data.get_unchecked_mut(idx), N::new(k, v));
                }

                debug_assert!(rh <= lh);
                1 + lh
            }
        }
    }

    /// Constructs a new TeardownTree<T> based on raw nodes vec.
    pub fn with_nodes(mut nodes: Vec<Option<N>>) -> TreeWrapper<K, V, N> {
        let size = nodes.iter().filter(|x| x.is_some()).count();
        let height = Self::calc_height(&nodes, 0);
        let capacity = nodes.len();

        let mut mask = vec![false; capacity];
        let mut data = Vec::with_capacity(capacity);
        unsafe {
            data.set_len(capacity);
        }

        for i in 0..capacity {
            if let Some(node) = nodes[i].take() {
                mask[i] = true;
                let garbage = mem::replace(&mut data[i], node );
                mem::forget(garbage);
            }
        }

        let cache = DeleteRangeCache::new(height);
        TreeWrapper { repr: TreeRepr { data: data, mask: mask, size: size, delete_range_cache: cache, _ph: PhantomData } }
    }

//    fn into_node_vec(self) -> Vec<Option<Node<T>>> {
//        self.data()
//            .into_iter()
//            .zip(self.mask().into_iter())
//            .map(|(node, flag)| if flag {
//                    Some(node)
//                } else {
//                    None
//                })
//            .collect::<Vec<Option<Node<T>>>>()
//    }
}

impl<K: Ord, V, N: Node<K, V>> Deref for TreeWrapper<K, V, N> {
    type Target = TreeRepr<K, V, N>;

    fn deref(&self) -> &Self::Target {
        &self.repr
    }
}

impl<K: Ord, V, N: Node<K, V>> DerefMut for TreeWrapper<K, V, N> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.repr
    }
}

impl<K: Ord, V, N: Node<K, V>> Drop for TreeWrapper<K, V, N> {
    fn drop(&mut self) {
        self.drop_items();
        unsafe {
            self.data.set_len(0)
        }
    }
}

impl<K: Ord+Debug, V, N: Node<K, V>> Debug for TreeWrapper<K, V, N> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        let mut nz: Vec<_> = self.mask.iter().enumerate()
            .rev()
            .skip_while(|&(_, flag)| !flag)
            .map(|(i, &flag)| match (self.node(i), flag) {
                (_, false) => String::from("0"),
                (ref node, true) => format!("{:?}", node.key)
            })
            .collect();
        nz.reverse();

        let _ = write!(fmt, "[size={}: ", self.size);
        let mut sep = "";
        for ref key in nz.iter() {
            let _ = write!(fmt, "{}", sep);
            sep = ", ";
            let _ = write!(fmt, "{}", key);
        }
        let _ = write!(fmt, "]");
        Ok(())
    }
}

impl<K: Ord+Debug, V, N: Node<K, V>> fmt::Display for TreeWrapper<K, V, N> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        writeln!(fmt, "")?;
        let mut ancestors = vec![];
        self.fmt_subtree(fmt, 0, &mut ancestors)
    }
}

impl<K: Ord+Debug, V, N: Node<K, V>> TreeWrapper<K, V, N> {
    fn fmt_branch(&self, fmt: &mut Formatter, ancestors: &Vec<bool>) -> fmt::Result {
        for (i, c) in ancestors.iter().enumerate() {
            if i == ancestors.len() - 1 {
                write!(fmt, "|--")?;
            } else {
                if *c {
                    write!(fmt, "|")?;
                } else {
                    write!(fmt, " ")?;
                }
                write!(fmt, "  ")?;
            }
        }

        Ok(())
    }

    fn fmt_subtree(&self, fmt: &mut Formatter, idx: usize, ancestors: &mut Vec<bool>) -> fmt::Result {
        self.fmt_branch(fmt, ancestors)?;

        if !self.is_nil(idx) {
            writeln!(fmt, "{:?}", self.key(idx))?;

            if idx%2 == 0 && !ancestors.is_empty() {
                *ancestors.last_mut().unwrap() = false;
            }

            if self.has_left(idx) || self.has_right(idx) {
                ancestors.push(true);
                self.fmt_subtree(fmt, lefti(idx), ancestors)?;
                self.fmt_subtree(fmt, righti(idx), ancestors)?;
                ancestors.pop();
            }
        } else {
            writeln!(fmt, "X")?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use element_state::ElementState;
use selector_impl::{PseudoElementCascadeType, SelectorImplExt};
use selectors::parser::{ParserContext, SelectorImpl};
use string_cache::Atom;
use stylesheets::Stylesheet;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GeckoSelectorImpl;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum PseudoElement {
    Before,
    After,

    Backdrop,
    FirstLetter,
    FirstLine,
    MozSelection,
    MozFocusInner,
    MozFocusOuter,
    MozListBullet,
    MozListNumber,
    MozMathAnonymous,
    MozNumberWrapper,
    MozNumberText,
    MozNumberSpinBox,
    MozNumberSpinUp,
    MozNumberSpinDown,
    MozProgressBar,
    MozRangeTrack,
    MozRangeProgress,
    MozRangeThumb,
    MozMeterBar,
    MozPlaceholder,
    MozColorSwatch,

    AnonBox(AnonBoxPseudoElement),
}

// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum AnonBoxPseudoElement {
    MozNonElement,
    MozAnonymousBlock,
    MozAnonymousPositionedBlock,
    MozMathMLAnonymousBlock,
    MozXULAnonymousBlock,

    MozHorizontalFramesetBorder,
    MozVerticalFramesetBorder,
    MozLineFrame,
    MozButtonContent,
    MozButtonLabel,
    MozCellContent,
    MozDropdownList,
    MozFieldsetContent,
    MozFramesetBlank,
    MozDisplayComboboxControlFrame,

    MozHTMLCanvasContent,
    MozInlineTable,
    MozTable,
    MozTableCell,
    MozTableColumnGroup,
    MozTableColumn,
    MozTableOuter,
    MozTableRowGroup,
    MozTableRow,

    MozCanvas,
    MozPageBreak,
    MozPage,
    MozPageContent,
    MozPageSequence,
    MozScrolledContent,
    MozScrolledCanvas,
    MozScrolledPageSequence,
    MozColumnContent,
    MozViewport,
    MozViewportScroll,
    MozAnonymousFlexItem,
    MozAnonymousGridItem,

    MozRuby,
    MozRubyBase,
    MozRubyBaseContainer,
    MozRubyText,
    MozRubyTextContainer,

    MozTreeColumn,
    MozTreeRow,
    MozTreeSeparator,
    MozTreeCell,
    MozTreeIndentation,
    MozTreeLine,
    MozTreeTwisty,
    MozTreeImage,
    MozTreeCellText,
    MozTreeCheckbox,
    MozTreeProgressMeter,
    MozTreeDropFeedback,

    MozSVGMarkerAnonChild,
    MozSVGOuterSVGAnonChild,
    MozSVGForeignContent,
    MozSVGText,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum NonTSPseudoClass {
    AnyLink,
    Link,
    Visited,
    Active,
    Focus,
    Hover,
    Enabled,
    Disabled,
    Checked,
    Indeterminate,
    ReadWrite,
    ReadOnly,
}

impl NonTSPseudoClass {
    pub fn state_flag(&self) -> ElementState {
        use element_state::*;
        use self::NonTSPseudoClass::*;
        match *self {
            Active => IN_ACTIVE_STATE,
            Focus => IN_FOCUS_STATE,
            Hover => IN_HOVER_STATE,
            Enabled => IN_ENABLED_STATE,
            Disabled => IN_DISABLED_STATE,
            Checked => IN_CHECKED_STATE,
            Indeterminate => IN_INDETERMINATE_STATE,
            ReadOnly | ReadWrite => IN_READ_WRITE_STATE,

            AnyLink |
            Link |
            Visited => ElementState::empty(),
        }
    }
}

impl SelectorImpl for GeckoSelectorImpl {
    type AttrString = Atom;
    type PseudoElement = PseudoElement;
    type NonTSPseudoClass = NonTSPseudoClass;
    fn parse_non_ts_pseudo_class(_context: &ParserContext,
                                 name: &str) -> Result<NonTSPseudoClass, ()> {
        use self::NonTSPseudoClass::*;
        let pseudo_class = match_ignore_ascii_case! { name,
            "any-link" => AnyLink,
            "link" => Link,
            "visited" => Visited,
            "active" => Active,
            "focus" => Focus,
            "hover" => Hover,
            "enabled" => Enabled,
            "disabled" => Disabled,
            "checked" => Checked,
            "indeterminate" => Indeterminate,
            "read-write" => ReadWrite,
            "read-only" => ReadOnly,
            _ => return Err(())
        };

        Ok(pseudo_class)
    }

    fn parse_pseudo_element(context: &ParserContext,
                            name: &str) -> Result<PseudoElement, ()> {
        use self::AnonBoxPseudoElement::*;
        use self::PseudoElement::*;

        // The braces here are unfortunate, but they're needed for
        // match_ignore_ascii_case! to work as expected.
        match_ignore_ascii_case! { name,
            "before" => { return Ok(Before) },
            "after" => { return Ok(After) },
            "first-line" => { return Ok(FirstLine) },
            "backdrop" => { return Ok(Backdrop) },
            "first-letter" => { return Ok(FirstLetter) },
            "first-line" => { return Ok(FirstLine) },
            "-moz-selection" => { return Ok(MozSelection) },
            "-moz-focus-inner" => { return Ok(MozFocusInner) },
            "-moz-focus-outer" => { return Ok(MozFocusOuter) },
            "-moz-list-bullet" => { return Ok(MozListBullet) },
            "-moz-list-number" => { return Ok(MozListNumber) },
            "-moz-math-anonymous" => { return Ok(MozMathAnonymous) },
            "-moz-number-wrapper" => { return Ok(MozNumberWrapper) },
            "-moz-number-text" => { return Ok(MozNumberText) },
            "-moz-number-spin-box" => { return Ok(MozNumberSpinBox) },
            "-moz-number-spin-up" => { return Ok(MozNumberSpinUp) },
            "-moz-number-spin-down" => { return Ok(MozNumberSpinDown) },
            "-moz-progress-bar" => { return Ok(MozProgressBar) },
            "-moz-range-track" => { return Ok(MozRangeTrack) },
            "-moz-range-progress" => { return Ok(MozRangeProgress) },
            "-moz-range-thumb" => { return Ok(MozRangeThumb) },
            "-moz-metter-bar" => { return Ok(MozMeterBar) },
            "-moz-placeholder" => { return Ok(MozPlaceholder) },
            "-moz-color-swatch" => { return Ok(MozColorSwatch) },

            _ => {}
        }

        if !context.in_user_agent_stylesheet {
            return Err(())
        }

        Ok(AnonBox(match_ignore_ascii_case! { name,
            "-moz-non-element" => MozNonElement,

            "-moz-anonymous-block" => MozAnonymousBlock,
            "-moz-anonymous-positioned-block" => MozAnonymousPositionedBlock,
            "-moz-mathml-anonymous-block" => MozMathMLAnonymousBlock,
            "-moz-xul-anonymous-block" => MozXULAnonymousBlock,

            "-moz-hframeset-border" => MozHorizontalFramesetBorder,
            "-moz-vframeset-border" => MozVerticalFramesetBorder,

            "-moz-line-frame" => MozLineFrame,

            "-moz-button-content" => MozButtonContent,
            "-moz-buttonlabel" => MozButtonLabel,
            "-moz-cell-content" => MozCellContent,
            "-moz-dropdown-list" => MozDropdownList,
            "-moz-fieldset-content" => MozFieldsetContent,
            "-moz-frameset-blank" => MozFramesetBlank,
            "-moz-display-comboboxcontrol-frame" => MozDisplayComboboxControlFrame,
            "-moz-html-canvas-content" => MozHTMLCanvasContent,

            "-moz-inline-table" => MozInlineTable,
            "-moz-table" => MozTable,
            "-moz-table-cell" => MozTableCell,
            "-moz-table-column-group" => MozTableColumnGroup,
            "-moz-table-column" => MozTableColumn,
            "-moz-table-outer" => MozTableOuter,
            "-moz-table-row-group" => MozTableRowGroup,
            "-moz-table-row" => MozTableRow,

            "-moz-canvas" => MozCanvas,
            "-moz-pagebreak" => MozPageBreak,
            "-moz-page" => MozPage,
            "-moz-pagecontent" => MozPageContent,
            "-moz-page-sequence" => MozPageSequence,
            "-moz-scrolled-content" => MozScrolledContent,
            "-moz-scrolled-canvas" => MozScrolledCanvas,
            "-moz-scrolled-page-sequence" => MozScrolledPageSequence,
            "-moz-column-content" => MozColumnContent,
            "-moz-viewport" => MozViewport,
            "-moz-viewport-scroll" => MozViewportScroll,
            "-moz-anonymous-flex-item" => MozAnonymousFlexItem,
            "-moz-anonymous-grid-item" => MozAnonymousGridItem,
            "-moz-ruby" => MozRuby,
            "-moz-ruby-base" => MozRubyBase,
            "-moz-ruby-base-container" => MozRubyBaseContainer,
            "-moz-ruby-text" => MozRubyText,
            "-moz-ruby-text-container" => MozRubyTextContainer,
            "-moz-tree-column" => MozTreeColumn,
            "-moz-tree-row" => MozTreeRow,
            "-moz-tree-separator" => MozTreeSeparator,
            "-moz-tree-cell" => MozTreeCell,
            "-moz-tree-indentation" => MozTreeIndentation,
            "-moz-tree-line" => MozTreeLine,
            "-moz-tree-twisty" => MozTreeTwisty,
            "-moz-tree-image" => MozTreeImage,
            "-moz-tree-cell-text" => MozTreeCellText,
            "-moz-tree-checkbox" => MozTreeCheckbox,
            "-moz-tree-progressmeter" => MozTreeProgressMeter,
            "-moz-tree-drop-feedback" => MozTreeDropFeedback,
            "-moz-svg-marker-anon-child" => MozSVGMarkerAnonChild,
            "-moz-svg-outer-svg-anon-child" => MozSVGOuterSVGAnonChild,
            "-moz-svg-foreign-content" => MozSVGForeignContent,
            "-moz-svg-text" => MozSVGText,

            _ => return Err(())
        }))
    }
}

impl SelectorImplExt for GeckoSelectorImpl {
    #[inline]
    fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
        match *pseudo {
            PseudoElement::Before |
            PseudoElement::After => PseudoElementCascadeType::Eager,
            PseudoElement::AnonBox(_) => PseudoElementCascadeType::Precomputed,
            _ => PseudoElementCascadeType::Lazy,
        }
    }

    #[inline]
    fn each_pseudo_element<F>(mut fun: F)
        where F: FnMut(PseudoElement) {
        use self::AnonBoxPseudoElement::*;
        use self::PseudoElement::*;

        fun(Before);
        fun(After);
        fun(FirstLine);

        fun(AnonBox(MozNonElement));
        fun(AnonBox(MozAnonymousBlock));
        fun(AnonBox(MozAnonymousPositionedBlock));
        fun(AnonBox(MozMathMLAnonymousBlock));
        fun(AnonBox(MozXULAnonymousBlock));

        fun(AnonBox(MozHorizontalFramesetBorder));
        fun(AnonBox(MozVerticalFramesetBorder));
        fun(AnonBox(MozLineFrame));
        fun(AnonBox(MozButtonContent));
        fun(AnonBox(MozButtonLabel));
        fun(AnonBox(MozCellContent));
        fun(AnonBox(MozDropdownList));
        fun(AnonBox(MozFieldsetContent));
        fun(AnonBox(MozFramesetBlank));
        fun(AnonBox(MozDisplayComboboxControlFrame));

        fun(AnonBox(MozHTMLCanvasContent));
        fun(AnonBox(MozInlineTable));
        fun(AnonBox(MozTable));
        fun(AnonBox(MozTableCell));
        fun(AnonBox(MozTableColumnGroup));
        fun(AnonBox(MozTableColumn));
        fun(AnonBox(MozTableOuter));
        fun(AnonBox(MozTableRowGroup));
        fun(AnonBox(MozTableRow));

        fun(AnonBox(MozCanvas));
        fun(AnonBox(MozPageBreak));
        fun(AnonBox(MozPage));
        fun(AnonBox(MozPageContent));
        fun(AnonBox(MozPageSequence));
        fun(AnonBox(MozScrolledContent));
        fun(AnonBox(MozScrolledCanvas));
        fun(AnonBox(MozScrolledPageSequence));
        fun(AnonBox(MozColumnContent));
        fun(AnonBox(MozViewport));
        fun(AnonBox(MozViewportScroll));
        fun(AnonBox(MozAnonymousFlexItem));
        fun(AnonBox(MozAnonymousGridItem));

        fun(AnonBox(MozRuby));
        fun(AnonBox(MozRubyBase));
        fun(AnonBox(MozRubyBaseContainer));
        fun(AnonBox(MozRubyText));
        fun(AnonBox(MozRubyTextContainer));

        fun(AnonBox(MozTreeColumn));
        fun(AnonBox(MozTreeRow));
        fun(AnonBox(MozTreeSeparator));
        fun(AnonBox(MozTreeCell));
        fun(AnonBox(MozTreeIndentation));
        fun(AnonBox(MozTreeLine));
        fun(AnonBox(MozTreeTwisty));
        fun(AnonBox(MozTreeImage));
        fun(AnonBox(MozTreeCellText));
        fun(AnonBox(MozTreeCheckbox));
        fun(AnonBox(MozTreeProgressMeter));
        fun(AnonBox(MozTreeDropFeedback));

        fun(AnonBox(MozSVGMarkerAnonChild));
        fun(AnonBox(MozSVGOuterSVGAnonChild));
        fun(AnonBox(MozSVGForeignContent));
        fun(AnonBox(MozSVGText));
    }

    #[inline]
    fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
        match *pseudo {
            PseudoElement::Before |
            PseudoElement::After => true,
            _ => false,
        }
    }

    #[inline]
    fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
        pc.state_flag()
    }

    #[inline]
    fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] {
        &[]
    }

    #[inline]
    fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet> {
        None
    }
}
<commit_msg>Sync anonymous box list.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use element_state::ElementState;
use selector_impl::{PseudoElementCascadeType, SelectorImplExt};
use selectors::parser::{ParserContext, SelectorImpl};
use string_cache::Atom;
use stylesheets::Stylesheet;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GeckoSelectorImpl;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum PseudoElement {
    Before,
    After,

    Backdrop,
    FirstLetter,
    FirstLine,
    MozSelection,
    MozFocusInner,
    MozFocusOuter,
    MozListBullet,
    MozListNumber,
    MozMathAnonymous,
    MozNumberWrapper,
    MozNumberText,
    MozNumberSpinBox,
    MozNumberSpinUp,
    MozNumberSpinDown,
    MozProgressBar,
    MozRangeTrack,
    MozRangeProgress,
    MozRangeThumb,
    MozMeterBar,
    MozPlaceholder,
    MozColorSwatch,

    AnonBox(AnonBoxPseudoElement),
}

// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum AnonBoxPseudoElement {
    MozText,
    MozOtherNonElement,
    MozAnonymousBlock,
    MozAnonymousPositionedBlock,
    MozMathMLAnonymousBlock,
    MozXULAnonymousBlock,

    MozHorizontalFramesetBorder,
    MozVerticalFramesetBorder,
    MozLineFrame,
    MozButtonContent,
    MozButtonLabel,
    MozCellContent,
    MozDropdownList,
    MozFieldsetContent,
    MozFramesetBlank,
    MozDisplayComboboxControlFrame,

    MozHTMLCanvasContent,
    MozInlineTable,
    MozTable,
    MozTableCell,
    MozTableColumnGroup,
    MozTableColumn,
    MozTableWrapper,
    MozTableRowGroup,
    MozTableRow,

    MozCanvas,
    MozPageBreak,
    MozPage,
    MozPageContent,
    MozPageSequence,
    MozScrolledContent,
    MozScrolledCanvas,
    MozScrolledPageSequence,
    MozColumnContent,
    MozViewport,
    MozViewportScroll,
    MozAnonymousFlexItem,
    MozAnonymousGridItem,

    MozRuby,
    MozRubyBase,
    MozRubyBaseContainer,
    MozRubyText,
    MozRubyTextContainer,

    MozTreeColumn,
    MozTreeRow,
    MozTreeSeparator,
    MozTreeCell,
    MozTreeIndentation,
    MozTreeLine,
    MozTreeTwisty,
    MozTreeImage,
    MozTreeCellText,
    MozTreeCheckbox,
    MozTreeProgressMeter,
    MozTreeDropFeedback,

    MozSVGMarkerAnonChild,
    MozSVGOuterSVGAnonChild,
    MozSVGForeignContent,
    MozSVGText,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum NonTSPseudoClass {
    AnyLink,
    Link,
    Visited,
    Active,
    Focus,
    Hover,
    Enabled,
    Disabled,
    Checked,
    Indeterminate,
    ReadWrite,
    ReadOnly,
}

impl NonTSPseudoClass {
    pub fn state_flag(&self) -> ElementState {
        use element_state::*;
        use self::NonTSPseudoClass::*;
        match *self {
            Active => IN_ACTIVE_STATE,
            Focus => IN_FOCUS_STATE,
            Hover => IN_HOVER_STATE,
            Enabled => IN_ENABLED_STATE,
            Disabled => IN_DISABLED_STATE,
            Checked => IN_CHECKED_STATE,
            Indeterminate => IN_INDETERMINATE_STATE,
            ReadOnly | ReadWrite => IN_READ_WRITE_STATE,

            AnyLink |
            Link |
            Visited => ElementState::empty(),
        }
    }
}

impl SelectorImpl for GeckoSelectorImpl {
    type AttrString = Atom;
    type PseudoElement = PseudoElement;
    type NonTSPseudoClass = NonTSPseudoClass;
    fn parse_non_ts_pseudo_class(_context: &ParserContext,
                                 name: &str) -> Result<NonTSPseudoClass, ()> {
        use self::NonTSPseudoClass::*;
        let pseudo_class = match_ignore_ascii_case! { name,
            "any-link" => AnyLink,
            "link" => Link,
            "visited" => Visited,
            "active" => Active,
            "focus" => Focus,
            "hover" => Hover,
            "enabled" => Enabled,
            "disabled" => Disabled,
            "checked" => Checked,
            "indeterminate" => Indeterminate,
            "read-write" => ReadWrite,
            "read-only" => ReadOnly,
            _ => return Err(())
        };

        Ok(pseudo_class)
    }

    fn parse_pseudo_element(context: &ParserContext,
                            name: &str) -> Result<PseudoElement, ()> {
        use self::AnonBoxPseudoElement::*;
        use self::PseudoElement::*;

        // The braces here are unfortunate, but they're needed for
        // match_ignore_ascii_case! to work as expected.
        match_ignore_ascii_case! { name,
            "before" => { return Ok(Before) },
            "after" => { return Ok(After) },
            "first-line" => { return Ok(FirstLine) },
            "backdrop" => { return Ok(Backdrop) },
            "first-letter" => { return Ok(FirstLetter) },
            "first-line" => { return Ok(FirstLine) },
            "-moz-selection" => { return Ok(MozSelection) },
            "-moz-focus-inner" => { return Ok(MozFocusInner) },
            "-moz-focus-outer" => { return Ok(MozFocusOuter) },
            "-moz-list-bullet" => { return Ok(MozListBullet) },
            "-moz-list-number" => { return Ok(MozListNumber) },
            "-moz-math-anonymous" => { return Ok(MozMathAnonymous) },
            "-moz-number-wrapper" => { return Ok(MozNumberWrapper) },
            "-moz-number-text" => { return Ok(MozNumberText) },
            "-moz-number-spin-box" => { return Ok(MozNumberSpinBox) },
            "-moz-number-spin-up" => { return Ok(MozNumberSpinUp) },
            "-moz-number-spin-down" => { return Ok(MozNumberSpinDown) },
            "-moz-progress-bar" => { return Ok(MozProgressBar) },
            "-moz-range-track" => { return Ok(MozRangeTrack) },
            "-moz-range-progress" => { return Ok(MozRangeProgress) },
            "-moz-range-thumb" => { return Ok(MozRangeThumb) },
            "-moz-metter-bar" => { return Ok(MozMeterBar) },
            "-moz-placeholder" => { return Ok(MozPlaceholder) },
            "-moz-color-swatch" => { return Ok(MozColorSwatch) },

            _ => {}
        }

        if !context.in_user_agent_stylesheet {
            return Err(())
        }

        Ok(AnonBox(match_ignore_ascii_case! { name,
            "-moz-text" => MozText,
            "-moz-other-non-element" => MozOtherNonElement,

            "-moz-anonymous-block" => MozAnonymousBlock,
            "-moz-anonymous-positioned-block" => MozAnonymousPositionedBlock,
            "-moz-mathml-anonymous-block" => MozMathMLAnonymousBlock,
            "-moz-xul-anonymous-block" => MozXULAnonymousBlock,

            "-moz-hframeset-border" => MozHorizontalFramesetBorder,
            "-moz-vframeset-border" => MozVerticalFramesetBorder,

            "-moz-line-frame" => MozLineFrame,

            "-moz-button-content" => MozButtonContent,
            "-moz-buttonlabel" => MozButtonLabel,
            "-moz-cell-content" => MozCellContent,
            "-moz-dropdown-list" => MozDropdownList,
            "-moz-fieldset-content" => MozFieldsetContent,
            "-moz-frameset-blank" => MozFramesetBlank,
            "-moz-display-comboboxcontrol-frame" => MozDisplayComboboxControlFrame,
            "-moz-html-canvas-content" => MozHTMLCanvasContent,

            "-moz-inline-table" => MozInlineTable,
            "-moz-table" => MozTable,
            "-moz-table-cell" => MozTableCell,
            "-moz-table-column-group" => MozTableColumnGroup,
            "-moz-table-column" => MozTableColumn,
            "-moz-table-wrapper" => MozTableWrapper,
            "-moz-table-row-group" => MozTableRowGroup,
            "-moz-table-row" => MozTableRow,

            "-moz-canvas" => MozCanvas,
            "-moz-pagebreak" => MozPageBreak,
            "-moz-page" => MozPage,
            "-moz-pagecontent" => MozPageContent,
            "-moz-page-sequence" => MozPageSequence,
            "-moz-scrolled-content" => MozScrolledContent,
            "-moz-scrolled-canvas" => MozScrolledCanvas,
            "-moz-scrolled-page-sequence" => MozScrolledPageSequence,
            "-moz-column-content" => MozColumnContent,
            "-moz-viewport" => MozViewport,
            "-moz-viewport-scroll" => MozViewportScroll,
            "-moz-anonymous-flex-item" => MozAnonymousFlexItem,
            "-moz-anonymous-grid-item" => MozAnonymousGridItem,
            "-moz-ruby" => MozRuby,
            "-moz-ruby-base" => MozRubyBase,
            "-moz-ruby-base-container" => MozRubyBaseContainer,
            "-moz-ruby-text" => MozRubyText,
            "-moz-ruby-text-container" => MozRubyTextContainer,
            "-moz-tree-column" => MozTreeColumn,
            "-moz-tree-row" => MozTreeRow,
            "-moz-tree-separator" => MozTreeSeparator,
            "-moz-tree-cell" => MozTreeCell,
            "-moz-tree-indentation" => MozTreeIndentation,
            "-moz-tree-line" => MozTreeLine,
            "-moz-tree-twisty" => MozTreeTwisty,
            "-moz-tree-image" => MozTreeImage,
            "-moz-tree-cell-text" => MozTreeCellText,
            "-moz-tree-checkbox" => MozTreeCheckbox,
            "-moz-tree-progressmeter" => MozTreeProgressMeter,
            "-moz-tree-drop-feedback" => MozTreeDropFeedback,
            "-moz-svg-marker-anon-child" => MozSVGMarkerAnonChild,
            "-moz-svg-outer-svg-anon-child" => MozSVGOuterSVGAnonChild,
            "-moz-svg-foreign-content" => MozSVGForeignContent,
            "-moz-svg-text" => MozSVGText,

            _ => return Err(())
        }))
    }
}

impl SelectorImplExt for GeckoSelectorImpl {
    #[inline]
    fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
        match *pseudo {
            PseudoElement::Before |
            PseudoElement::After => PseudoElementCascadeType::Eager,
            PseudoElement::AnonBox(_) => PseudoElementCascadeType::Precomputed,
            _ => PseudoElementCascadeType::Lazy,
        }
    }

    #[inline]
    fn each_pseudo_element<F>(mut fun: F)
        where F: FnMut(PseudoElement) {
        use self::AnonBoxPseudoElement::*;
        use self::PseudoElement::*;

        fun(Before);
        fun(After);
        fun(FirstLine);

        fun(AnonBox(MozText));
        fun(AnonBox(MozOtherNonElement));
        fun(AnonBox(MozAnonymousBlock));
        fun(AnonBox(MozAnonymousPositionedBlock));
        fun(AnonBox(MozMathMLAnonymousBlock));
        fun(AnonBox(MozXULAnonymousBlock));

        fun(AnonBox(MozHorizontalFramesetBorder));
        fun(AnonBox(MozVerticalFramesetBorder));
        fun(AnonBox(MozLineFrame));
        fun(AnonBox(MozButtonContent));
        fun(AnonBox(MozButtonLabel));
        fun(AnonBox(MozCellContent));
        fun(AnonBox(MozDropdownList));
        fun(AnonBox(MozFieldsetContent));
        fun(AnonBox(MozFramesetBlank));
        fun(AnonBox(MozDisplayComboboxControlFrame));

        fun(AnonBox(MozHTMLCanvasContent));
        fun(AnonBox(MozInlineTable));
        fun(AnonBox(MozTable));
        fun(AnonBox(MozTableCell));
        fun(AnonBox(MozTableColumnGroup));
        fun(AnonBox(MozTableColumn));
        fun(AnonBox(MozTableWrapper));
        fun(AnonBox(MozTableRowGroup));
        fun(AnonBox(MozTableRow));

        fun(AnonBox(MozCanvas));
        fun(AnonBox(MozPageBreak));
        fun(AnonBox(MozPage));
        fun(AnonBox(MozPageContent));
        fun(AnonBox(MozPageSequence));
        fun(AnonBox(MozScrolledContent));
        fun(AnonBox(MozScrolledCanvas));
        fun(AnonBox(MozScrolledPageSequence));
        fun(AnonBox(MozColumnContent));
        fun(AnonBox(MozViewport));
        fun(AnonBox(MozViewportScroll));
        fun(AnonBox(MozAnonymousFlexItem));
        fun(AnonBox(MozAnonymousGridItem));

        fun(AnonBox(MozRuby));
        fun(AnonBox(MozRubyBase));
        fun(AnonBox(MozRubyBaseContainer));
        fun(AnonBox(MozRubyText));
        fun(AnonBox(MozRubyTextContainer));

        fun(AnonBox(MozTreeColumn));
        fun(AnonBox(MozTreeRow));
        fun(AnonBox(MozTreeSeparator));
        fun(AnonBox(MozTreeCell));
        fun(AnonBox(MozTreeIndentation));
        fun(AnonBox(MozTreeLine));
        fun(AnonBox(MozTreeTwisty));
        fun(AnonBox(MozTreeImage));
        fun(AnonBox(MozTreeCellText));
        fun(AnonBox(MozTreeCheckbox));
        fun(AnonBox(MozTreeProgressMeter));
        fun(AnonBox(MozTreeDropFeedback));

        fun(AnonBox(MozSVGMarkerAnonChild));
        fun(AnonBox(MozSVGOuterSVGAnonChild));
        fun(AnonBox(MozSVGForeignContent));
        fun(AnonBox(MozSVGText));
    }

    #[inline]
    fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
        match *pseudo {
            PseudoElement::Before |
            PseudoElement::After => true,
            _ => false,
        }
    }

    #[inline]
    fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
        pc.state_flag()
    }

    #[inline]
    fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] {
        &[]
    }

    #[inline]
    fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet> {
        None
    }
}
<|endoftext|>


<commit_before>extern crate uosql;
extern crate bincode;

use uosql::storage::*;
use bincode::rustc_serialize::{encode_into};
use bincode::SizeLimit;
use uosql::parse::ast::SqlType;

fn main() {

    let ty = SqlType::Int;
    let mut v = Vec::new();
    encode_into(&ty, &mut v, SizeLimit::Infinite);
    println!("{:?}", v);

    //let db = Database::create("storage_team").unwrap();
    let db = Database::load("storage_team").unwrap();

    let mut cols = Vec::new();
    cols.push(Column { name: "Heiner".into(), sql_type: SqlType::Int });
    cols.push(Column { name: "Mathias".into(), sql_type: SqlType::Bool });
    cols.push(Column { name: "Dennis".into(), sql_type: SqlType::Char(6) });
    cols.push(Column { name: "Jana".into(), sql_type: SqlType::VarChar(178) });

    let _storage_team = db.create_table("storage_team", cols, 1).unwrap();

    let t = db.load_table("storage_team").unwrap();

    let mut engine = t.create_engine();
    let _e  = engine.create_table();
    // println!("{:?}", t.name);
    let f = engine.table();
    println!("{:?}", f.name);
    println!("{:?}", f);
}
<commit_msg>Adds finished verision of delet and example in table_test.rs<commit_after>extern crate uosql;
extern crate bincode;
extern crate log;
use uosql::storage::*;
use bincode::rustc_serialize::{encode_into};
use bincode::SizeLimit;
use uosql::parse::ast::SqlType;
use uosql::logger;

fn main() {

    logger::with_loglevel(::log::LogLevelFilter::Trace)
        .with_logfile(std::path::Path::new("log.txt"))
        .enable().unwrap();

    let ty = SqlType::Int;
    let mut v = Vec::new();
    encode_into(&ty, &mut v, SizeLimit::Infinite);
    println!("{:?}", v);

    //let db = Database::create("storage_team").unwrap();
    let db = Database::load("storage_team").unwrap();

    let mut cols = Vec::new();
    cols.push(Column { name: "Heiner".into(), sql_type: SqlType::Int });
    cols.push(Column { name: "Mathias".into(), sql_type: SqlType::Bool });
    cols.push(Column { name: "Dennis".into(), sql_type: SqlType::Char(6) });
    cols.push(Column { name: "Jana".into(), sql_type: SqlType::VarChar(178) });

    let _storage_team = db.create_table("storage_team", cols, 1).unwrap();

    let mut t = db.load_table("storage_team").unwrap();

    let mut engine = t.create_engine();

    let _e  = engine.create_table();
    let t = engine.table();

    t.delete().unwrap();
}
<|endoftext|>


<commit_before>use name::*;
use art::*;
use std::hash;
use std::hash::Hash;
use std::result::Result;

//
// Cmd C ::= Skip
//        | C ; C
//        | While E C
//        | x := E
//
//     C ::= .. | Amb C C
//
// Exp E ::=
//        | x
//        | N
//        | E + E
//

/// Nominal, artful commands for the while language
#[derive(Show,Hash,PartialEq,Eq)]
pub enum Cmd<'x> {
    Skip,
    Seq(CmdB<'x>, CmdB<'x>),
    While(ExpB<'x>, CmdB<'x>),
    Assign(Var<'x>, ExpB<'x>),
    // ----
    Name(Name, CmdB<'x>),
    Art(Art<'x,CmdB<'x>>),
}
pub type CmdB<'x> = Box<Cmd<'x>>;

/// Expressions for the while language
#[derive(Show,Hash,PartialEq,Eq)]
pub enum Exp<'x> {
    Var(Var<'x>),
    Plus(ExpB<'x>,ExpB<'x>),
    Num(int),
}
pub type ExpB<'x> = Box<Exp<'x>>;

/// Variables for the while language
pub type Var<'x> = String;

pub trait Heap<L:Hash+Eq, V> {
    fn empty () -> Box<Self> ;
    fn update (Box<Self>, L, V) -> Box<Self> ;
    fn select (Box<Self>, L) -> (Box<Self>, Option<V>) ;
}

pub enum Error {
    VarNotDef(String),
}

pub fn eval_exp<'x>
    (heap:Box<Heap<String, int>>, exp:Exp<'x>)
     -> (Box<Heap<String, int>>, Result<int, Error>)
{
    match exp {
        Exp::Num(n) => (heap, Ok(n)),
        Exp::Var(v) => {
            let (heap,q) = Heap::select(heap, v.clone()) ;
            match q {
                None => (heap, Err(Error::VarNotDef(v))),
                Some(val) => (heap, Ok(val))
            }},

        Exp::Plus(l, r) => {
            let (heap, l) = eval_exp(heap, *l) ;
            let (heap, r) = eval_exp(heap, *r) ;
            match (l,r) {
                (Ok(l), Ok(r)) => (heap, Ok(l+r)),
                (Err(l), _) => (heap, Err(l)),
                (_, Err(r)) => (heap, Err(r))
            }},
    }
}

#[test]
pub fn doit () {
    println!("while lang!");
}
<commit_msg>still learning how to do hashtables in Rust<commit_after>use name::*;
use art::*;
use std::hash;
use std::hash::Hash;
use std::result::Result;
use std::collections::HashMap;

//
// Cmd C ::= Skip
//        | C ; C
//        | While E C
//        | x := E
//
//     C ::= .. | Amb C C
//
// Exp E ::=
//        | x
//        | N
//        | E + E
//

/// Nominal, artful commands for the while language
#[derive(Show,Hash,PartialEq,Eq)]
pub enum Cmd<'x> {
    Skip,
    Seq(CmdB<'x>, CmdB<'x>),
    While(ExpB<'x>, CmdB<'x>),
    Assign(Var<'x>, ExpB<'x>),
    // ----
    Name(Name, CmdB<'x>),
    Art(Art<'x,CmdB<'x>>),
}
pub type CmdB<'x> = Box<Cmd<'x>>;

/// Expressions for the while language
#[derive(Show,Hash,PartialEq,Eq)]
pub enum Exp<'x> {
    Var(Var<'x>),
    Plus(ExpB<'x>,ExpB<'x>),
    Num(int),
}
pub type ExpB<'x> = Box<Exp<'x>>;

/// Variables for the while language
pub type Var<'x> = String;

pub trait Heap<L:Hash+Eq, V> : Sized {
    fn empty () -> Self ;
    fn update (Self, L, V) -> Self ;
    fn select (Self, L) -> (Self, Option<V>) ;
}

pub struct HashMapHeap { hm : HashMap<String, int> }

impl Heap<String, int> for HashMapHeap {
    fn empty () -> Self {
        HashMapHeap { hm : HashMap::new() }
    }
    fn update (hm:Self, l:String, v:int) -> Self {
        panic!("")
    }
    fn select (hm:Self, l:String) -> (Self, Option<int>) {
        panic!("")
    }
}

pub enum Error {
    VarNotDef(String),
}

pub fn eval_exp<'x>
    (heap:HashMapHeap, exp:Exp<'x>)
     -> (HashMapHeap, Result<int, Error>)
{
    match exp {
        Exp::Num(n) => (heap, Ok(n)),
        Exp::Var(v) => {
            let (heap,q) = Heap::select(heap, v.clone()) ;
            match q {
                None => (heap, Err(Error::VarNotDef(v))),
                Some(val) => (heap, Ok(val))
            }},

        Exp::Plus(l, r) => {
            let (heap, l) = eval_exp(heap, *l) ;
            let (heap, r) = eval_exp(heap, *r) ;
            match (l,r) {
                (Ok(l), Ok(r)) => (heap, Ok(l+r)),
                (Err(l), _) => (heap, Err(l)),
                (_, Err(r)) => (heap, Err(r))
            }},
    }
}

#[test]
pub fn doit () {
    println!("while lang!");
}
<|endoftext|>


<commit_before>//! Buffering and session mechanisms to provide the appearance of record-at-a-time sending,
//! with the performance of batched sends.

use dataflow::channels::{Bundle, Message};
use progress::Timestamp;
use dataflow::operators::Capability;
use timely_communication::Push;

/// Buffers data sent at the same time, for efficient communication.
///
/// The `Buffer` type should be used by calling `session` with a time, which checks whether
/// data must be flushed and creates a `Session` object which allows sending at the given time.
pub struct Buffer<T, D, P: Push<Bundle<T, D>>> {
    time: Option<T>,  // the currently open time, if it is open
    buffer: Vec<D>,   // a buffer for records, to send at self.time
    pusher: P,
}

impl<T, D, P: Push<Bundle<T, D>>> Buffer<T, D, P> where T: Eq+Clone {

    /// Creates a new `Buffer`.
    pub fn new(pusher: P) -> Buffer<T, D, P> {
        Buffer {
            time: None,
            buffer: Vec::with_capacity(Message::<T, D>::default_length()),
            pusher,
        }
    }

    /// Returns a `Session`, which accepts data to send at the associated time
    pub fn session(&mut self, time: &T) -> Session<T, D, P> {
        if let Some(true) = self.time.as_ref().map(|x| x != time) { self.flush(); }
        self.time = Some(time.clone());
        Session { buffer: self }
    }
    /// Allocates a new `AutoflushSession` which flushes itself on drop.
    pub fn autoflush_session(&mut self, cap: Capability<T>) -> AutoflushSession<T, D, P> where T: Timestamp {
        if let Some(true) = self.time.as_ref().map(|x| x != cap.time()) { self.flush(); }
        self.time = Some(cap.time().clone());
        AutoflushSession {
            buffer: self,
            _capability: cap,
        }
    }

    /// Returns a reference to the inner `P: Push` type.
    ///
    /// This is currently used internally, and should not be used without some care.
    pub fn inner(&mut self) -> &mut P { &mut self.pusher }

    /// Flushes all data and pushes a `None` to `self.pusher`, indicating a flush.
    pub fn cease(&mut self) {
        self.flush();
        self.pusher.push(&mut None);
    }

    /// moves the contents of
    fn flush(&mut self) {
        if !self.buffer.is_empty() {
            let time = self.time.as_ref().unwrap().clone();
            Message::push_at(&mut self.buffer, time, &mut self.pusher);
        }
    }

    // internal method for use by `Session`.
    fn give(&mut self, data: D) {
        self.buffer.push(data);
        // assert!(self.buffer.capacity() == Message::<O::Data>::default_length());
        if self.buffer.len() == self.buffer.capacity() {
            self.flush();
        }
    }

    // Gives an entire message at a specific time.
    fn give_vec(&mut self, vector: &mut Vec<D>) {
        // flush to ensure fifo-ness
        if !self.buffer.is_empty() {
            self.flush();
        }

        let time = self.time.as_ref().expect("Buffer::give_vec(): time is None.").clone();
        let data = ::std::mem::replace(vector, Vec::new());

        let mut bundle = Some(Bundle::from_typed(Message::new(time, data, 0, 0)));

        self.pusher.push(&mut bundle);
        if let Some(message) = bundle {
            if let Some(message) = message.if_typed() {
                *vector = message.data;
            }
        }
    }
}

/// An output session for sending records at a specified time.
///
/// The `Session` struct provides the user-facing interface to an operator output, namely
/// the `Buffer` type. A `Session` wraps a session of output at a specified time, and
/// avoids what would otherwise be a constant cost of checking timestamp equality.
pub struct Session<'a, T, D, P: Push<Bundle<T, D>>+'a> where T: Eq+Clone+'a, D: 'a {
    buffer: &'a mut Buffer<T, D, P>,
}

impl<'a, T, D, P: Push<Bundle<T, D>>+'a> Session<'a, T, D, P>  where T: Eq+Clone+'a, D: 'a {
    /// Provides one record at the time specified by the `Session`.
    #[inline(always)]
    pub fn give(&mut self, data: D) {
        self.buffer.give(data);
    }
    /// Provides an iterator of records at the time specified by the `Session`.
    #[inline(always)]
    pub fn give_iterator<I: Iterator<Item=D>>(&mut self, iter: I) {
        for item in iter {
            self.give(item);
        }
    }
    /// Provides a fully formed `Content<D>` message for senders which can use this type.
    ///
    /// The `Content` type is the backing memory for communication in timely, and it can
    /// often be more efficient to re-use this memory rather than have timely allocate
    /// new backing memory.
    #[inline(always)]
    pub fn give_vec(&mut self, message: &mut Vec<D>) {
        if message.len() > 0 {
            self.buffer.give_vec(message);
        }
    }
}

/// A session which will flush itself when dropped.
pub struct AutoflushSession<'a, T: Timestamp, D, P: Push<Bundle<T, D>>+'a> where
    T: Eq+Clone+'a, D: 'a {
    /// A reference to the underlying buffer.
    buffer: &'a mut Buffer<T, D, P>,
    /// The capability being used to send the data.
    _capability: Capability<T>,
}

impl<'a, T: Timestamp, D, P: Push<Bundle<T, D>>+'a> AutoflushSession<'a, T, D, P> where T: Eq+Clone+'a, D: 'a {
    /// Transmits a single record.
    #[inline(always)]
    pub fn give(&mut self, data: D) {
        self.buffer.give(data);
    }
    /// Transmits records produced by an iterator.
    #[inline(always)]
    pub fn give_iterator<I: Iterator<Item=D>>(&mut self, iter: I) {
        for item in iter {
            self.give(item);
        }
    }
    /// Transmits a pre-packed batch of data.
    #[inline(always)]
    pub fn give_content(&mut self, message: &mut Vec<D>) {
        if message.len() > 0 {
            self.buffer.give_vec(message);
        }
    }
}

impl<'a, T: Timestamp, D, P: Push<Bundle<T, D>>+'a> Drop for AutoflushSession<'a, T, D, P> where T: Eq+Clone+'a, D: 'a {
    fn drop(&mut self) {
        self.buffer.cease();
    }
}
<commit_msg>use Message::push_at<commit_after>//! Buffering and session mechanisms to provide the appearance of record-at-a-time sending,
//! with the performance of batched sends.

use dataflow::channels::{Bundle, Message};
use progress::Timestamp;
use dataflow::operators::Capability;
use timely_communication::Push;

/// Buffers data sent at the same time, for efficient communication.
///
/// The `Buffer` type should be used by calling `session` with a time, which checks whether
/// data must be flushed and creates a `Session` object which allows sending at the given time.
pub struct Buffer<T, D, P: Push<Bundle<T, D>>> {
    time: Option<T>,  // the currently open time, if it is open
    buffer: Vec<D>,   // a buffer for records, to send at self.time
    pusher: P,
}

impl<T, D, P: Push<Bundle<T, D>>> Buffer<T, D, P> where T: Eq+Clone {

    /// Creates a new `Buffer`.
    pub fn new(pusher: P) -> Buffer<T, D, P> {
        Buffer {
            time: None,
            buffer: Vec::with_capacity(Message::<T, D>::default_length()),
            pusher,
        }
    }

    /// Returns a `Session`, which accepts data to send at the associated time
    pub fn session(&mut self, time: &T) -> Session<T, D, P> {
        if let Some(true) = self.time.as_ref().map(|x| x != time) { self.flush(); }
        self.time = Some(time.clone());
        Session { buffer: self }
    }
    /// Allocates a new `AutoflushSession` which flushes itself on drop.
    pub fn autoflush_session(&mut self, cap: Capability<T>) -> AutoflushSession<T, D, P> where T: Timestamp {
        if let Some(true) = self.time.as_ref().map(|x| x != cap.time()) { self.flush(); }
        self.time = Some(cap.time().clone());
        AutoflushSession {
            buffer: self,
            _capability: cap,
        }
    }

    /// Returns a reference to the inner `P: Push` type.
    ///
    /// This is currently used internally, and should not be used without some care.
    pub fn inner(&mut self) -> &mut P { &mut self.pusher }

    /// Flushes all data and pushes a `None` to `self.pusher`, indicating a flush.
    pub fn cease(&mut self) {
        self.flush();
        self.pusher.push(&mut None);
    }

    /// moves the contents of
    fn flush(&mut self) {
        if !self.buffer.is_empty() {
            let time = self.time.as_ref().unwrap().clone();
            Message::push_at(&mut self.buffer, time, &mut self.pusher);
        }
    }

    // internal method for use by `Session`.
    fn give(&mut self, data: D) {
        self.buffer.push(data);
        // assert!(self.buffer.capacity() == Message::<O::Data>::default_length());
        if self.buffer.len() == self.buffer.capacity() {
            self.flush();
        }
    }

    // Gives an entire message at a specific time.
    fn give_vec(&mut self, vector: &mut Vec<D>) {
        // flush to ensure fifo-ness
        if !self.buffer.is_empty() {
            self.flush();
        }

        let time = self.time.as_ref().expect("Buffer::give_vec(): time is None.").clone();
        Message::push_at(vector, time, &mut self.pusher);
    }
}

/// An output session for sending records at a specified time.
///
/// The `Session` struct provides the user-facing interface to an operator output, namely
/// the `Buffer` type. A `Session` wraps a session of output at a specified time, and
/// avoids what would otherwise be a constant cost of checking timestamp equality.
pub struct Session<'a, T, D, P: Push<Bundle<T, D>>+'a> where T: Eq+Clone+'a, D: 'a {
    buffer: &'a mut Buffer<T, D, P>,
}

impl<'a, T, D, P: Push<Bundle<T, D>>+'a> Session<'a, T, D, P>  where T: Eq+Clone+'a, D: 'a {
    /// Provides one record at the time specified by the `Session`.
    #[inline(always)]
    pub fn give(&mut self, data: D) {
        self.buffer.give(data);
    }
    /// Provides an iterator of records at the time specified by the `Session`.
    #[inline(always)]
    pub fn give_iterator<I: Iterator<Item=D>>(&mut self, iter: I) {
        for item in iter {
            self.give(item);
        }
    }
    /// Provides a fully formed `Content<D>` message for senders which can use this type.
    ///
    /// The `Content` type is the backing memory for communication in timely, and it can
    /// often be more efficient to re-use this memory rather than have timely allocate
    /// new backing memory.
    #[inline(always)]
    pub fn give_vec(&mut self, message: &mut Vec<D>) {
        if message.len() > 0 {
            self.buffer.give_vec(message);
        }
    }
}

/// A session which will flush itself when dropped.
pub struct AutoflushSession<'a, T: Timestamp, D, P: Push<Bundle<T, D>>+'a> where
    T: Eq+Clone+'a, D: 'a {
    /// A reference to the underlying buffer.
    buffer: &'a mut Buffer<T, D, P>,
    /// The capability being used to send the data.
    _capability: Capability<T>,
}

impl<'a, T: Timestamp, D, P: Push<Bundle<T, D>>+'a> AutoflushSession<'a, T, D, P> where T: Eq+Clone+'a, D: 'a {
    /// Transmits a single record.
    #[inline(always)]
    pub fn give(&mut self, data: D) {
        self.buffer.give(data);
    }
    /// Transmits records produced by an iterator.
    #[inline(always)]
    pub fn give_iterator<I: Iterator<Item=D>>(&mut self, iter: I) {
        for item in iter {
            self.give(item);
        }
    }
    /// Transmits a pre-packed batch of data.
    #[inline(always)]
    pub fn give_content(&mut self, message: &mut Vec<D>) {
        if message.len() > 0 {
            self.buffer.give_vec(message);
        }
    }
}

impl<'a, T: Timestamp, D, P: Push<Bundle<T, D>>+'a> Drop for AutoflushSession<'a, T, D, P> where T: Eq+Clone+'a, D: 'a {
    fn drop(&mut self) {
        self.buffer.cease();
    }
}
<|endoftext|>