<commit_before>use byteorder::{ReadBytesExt, LittleEndian};
use lnkpkg::errors::{LnkError};
use lnkpkg::utils;
use rwinstructs::guid::{Guid};
use std::io::SeekFrom;
use std::io::Read;
use std::io::Seek;

#[derive(Debug)]
pub struct SpecialFolder {
    special_folder_id: u32,
    first_child_segment_offset: u32
}
impl SpecialFolder {
    pub fn new<R: Read>(mut reader: R) -> Result<SpecialFolder,LnkError> {
        let special_folder_id = reader.read_u32::<LittleEndian>()?;
        let first_child_segment_offset = reader.read_u32::<LittleEndian>()?;

        Ok (
            SpecialFolder {
                special_folder_id: special_folder_id,
                first_child_segment_offset: first_child_segment_offset
            }
        )
    }
}

#[derive(Debug)]
pub struct Codepage {
    codepage: u32
}
impl Codepage {
    pub fn new<R: Read>(mut reader: R) -> Result<Codepage,LnkError> {
        let codepage = reader.read_u32::<LittleEndian>()?;

        Ok (
            Codepage {
                codepage: codepage
            }
        )
    }
}

#[derive(Debug)]
pub struct DistributedTracker {
    size: u32,
    version: u32,
    machine_id: String, // 16 bytes (ascii)
    droid_volume: Guid,
    droid_file: Guid,
    birth_droid_volume: Guid,
    birth_droid_file: Guid
}
impl DistributedTracker {
    pub fn new<R: Read>(mut reader: R) -> Result<DistributedTracker,LnkError> {
        let size = reader.read_u32::<LittleEndian>()?;
        let version = reader.read_u32::<LittleEndian>()?;

        let mut buff_machine_id = vec![0; 16];
        reader.read_exact(buff_machine_id.as_mut_slice())?;
        let machine_id = utils::read_string_u8_till_null(
            buff_machine_id.as_slice()
        )?;

        let droid_volume = Guid::new(&mut reader)?;
        let droid_file = Guid::new(&mut reader)?;
        let birth_droid_volume = Guid::new(&mut reader)?;
        let birth_droid_file = Guid::new(&mut reader)?;

        Ok (
            DistributedTracker {
                size: size,
                version: version,
                machine_id: machine_id,
                droid_volume: droid_volume,
                droid_file: droid_file,
                birth_droid_volume: birth_droid_volume,
                birth_droid_file: birth_droid_file
            }
        )
    }
}

#[derive(Debug)]
pub struct EnvironmentVars {
    location: String, //size is 260 bytes (Unicode string terminated by an end-of-string character)
    location_unicode: String //size is 520 bytes (Unicode string terminated by an end-of-string character)
}
impl EnvironmentVars {
    pub fn new<R: Read>(mut reader: R) -> Result<EnvironmentVars,LnkError> {
        let mut buff_location = vec![0; 260];
        reader.read_exact(buff_location.as_mut_slice())?;
        let location = utils::read_string_u8_till_null(
            buff_location.as_slice()
        )?;

        let mut buff_location_unicode = vec![0; 520];
        reader.read_exact(buff_location_unicode.as_mut_slice())?;
        let location_unicode = utils::read_string_u16_till_null(
            buff_location_unicode.as_slice()
        )?;

        Ok(
            EnvironmentVars {
                location: location,
                location_unicode: location_unicode
            }
        )
    }
}

#[derive(Debug)]
pub struct ConsoleProperties {
    color_flags: u16,
    popup_attribs: u16,
    screen_width_buff_size: u16,
    screen_height_buff_size: u16,
    window_width: u16,
    window_height: u16,
    window_x: u16,
    window_y: u16,
    unknown1: u32,
    unknown2: u32,
    font_size: u32,
    font_family_value: u32,
    font_weight: u32,
    face_name: String, //size is 64 bytes (Unicode string terminated by an end-of-string character)
    cursor_size: u32,
    full_screen: u32,
    insert_mode: u32,
    auto_positioning: u32,
    history_buff_size: u32,
    history_buff_count: u32,
    duplicates_allowed: u32,
    color_table: utils::ByteArray
}
impl ConsoleProperties {
    pub fn new<R: Read>(mut reader: R) -> Result<ConsoleProperties,LnkError> {
        let color_flags = reader.read_u16::<LittleEndian>()?;
        let popup_attribs = reader.read_u16::<LittleEndian>()?;
        let screen_width_buff_size = reader.read_u16::<LittleEndian>()?;
        let screen_height_buff_size = reader.read_u16::<LittleEndian>()?;
        let window_width = reader.read_u16::<LittleEndian>()?;
        let window_height = reader.read_u16::<LittleEndian>()?;
        let window_x = reader.read_u16::<LittleEndian>()?;
        let window_y = reader.read_u16::<LittleEndian>()?;
        let unknown1 = reader.read_u32::<LittleEndian>()?;
        let unknown2 = reader.read_u32::<LittleEndian>()?;
        let font_size = reader.read_u32::<LittleEndian>()?;
        let font_family_value = reader.read_u32::<LittleEndian>()?;
        let font_weight = reader.read_u32::<LittleEndian>()?;

        // Read string
        let mut face_buff = vec![0; 64];
        reader.read_exact(face_buff.as_mut_slice())?;
        let face_name = utils::read_string_u16_till_null(face_buff.as_slice())?;

        let cursor_size = reader.read_u32::<LittleEndian>()?;
        let full_screen = reader.read_u32::<LittleEndian>()?;
        let insert_mode = reader.read_u32::<LittleEndian>()?;
        let auto_positioning = reader.read_u32::<LittleEndian>()?;
        let history_buff_size = reader.read_u32::<LittleEndian>()?;
        let history_buff_count = reader.read_u32::<LittleEndian>()?;
        let duplicates_allowed = reader.read_u32::<LittleEndian>()?;

        let mut color_buff = vec![0; 64];
        reader.read_exact(color_buff.as_mut_slice())?;
        let color_table = utils::ByteArray(color_buff);

        Ok (
            ConsoleProperties {
                color_flags: color_flags,
                popup_attribs: popup_attribs,
                screen_width_buff_size: screen_width_buff_size,
                screen_height_buff_size: screen_height_buff_size,
                window_width: window_width,
                window_height: window_height,
                window_x: window_x,
                window_y: window_y,
                unknown1: unknown1,
                unknown2: unknown2,
                font_size: font_size,
                font_family_value: font_family_value,
                font_weight: font_weight,
                face_name: face_name,
                cursor_size: cursor_size,
                full_screen: full_screen,
                insert_mode: insert_mode,
                auto_positioning: auto_positioning,
                history_buff_size: history_buff_size,
                history_buff_count: history_buff_count,
                duplicates_allowed: duplicates_allowed,
                color_table: color_table
            }
        )
    }
}

#[derive(Debug)]
pub struct ExtraDataBlocks {
    pub console_properties: Option<ConsoleProperties>,
    pub environment_vars: Option<EnvironmentVars>,
    pub distributed_tracker: Option<DistributedTracker>,
    pub codepage: Option<Codepage>,
    pub special_folder: Option<SpecialFolder>
}
impl ExtraDataBlocks {
    pub fn new<Rs: Read+Seek>(mut reader: Rs) -> Result<ExtraDataBlocks,LnkError> {
        let mut console_properties = None;
        let mut environment_vars = None;
        let mut distributed_tracker = None;
        let mut codepage = None;
        let mut special_folder = None;

        let mut _offset = reader.seek(
            SeekFrom::Current(0)
        )?;

        loop {
            let size = reader.read_u32::<LittleEndian>()?;
            if size != 0 {
                let signature = reader.read_u32::<LittleEndian>()?;
                match signature {
                    0xa0000001 => {
                        environment_vars = Some(EnvironmentVars::new(&mut reader)?);
                    },
                    0xa0000002 => {
                        console_properties = Some(ConsoleProperties::new(&mut reader)?);
                    },
                    0xa0000003 => {
                        distributed_tracker = Some(DistributedTracker::new(&mut reader)?);
                    },
                    0xa0000004 => {
                        codepage = Some(Codepage::new(&mut reader)?);
                    },
                    0xa0000005 => {
                        special_folder = Some(SpecialFolder::new(&mut reader)?);
                    },
                    _ => {
                        println!(
                            "Unhandled data block with signature {} at offset {}",
                            signature,
                            _offset
                        );
                    }
                }

                _offset += size as u64;

                reader.seek(
                    SeekFrom::Start(_offset)
                )?;
            } else {
                break
            }
        }

        Ok(
            ExtraDataBlocks {
                console_properties: console_properties,
                environment_vars: environment_vars,
                distributed_tracker: distributed_tracker,
                codepage: codepage,
                special_folder: special_folder
            }
        )
    }
}
<commit_msg>Added DarwinProperties, IconLocation, and KnownFolderLocation<commit_after>use byteorder::{ReadBytesExt, LittleEndian};
use lnkpkg::errors::{LnkError};
use lnkpkg::utils;
use rwinstructs::guid::{Guid};
use std::io::SeekFrom;
use std::io::Read;
use std::io::Seek;

#[derive(Debug)]
pub struct KnownFolderLocation {
    folder_guid: Guid,
    first_child_segment_offset: u32
}
impl KnownFolderLocation {
    pub fn new<R: Read>(mut reader: R) -> Result<KnownFolderLocation,LnkError> {
        let folder_guid = Guid::new(&mut reader)?;
        let first_child_segment_offset = reader.read_u32::<LittleEndian>()?;

        Ok (
            KnownFolderLocation {
                folder_guid: folder_guid,
                first_child_segment_offset: first_child_segment_offset
            }
        )
    }
}

#[derive(Debug)]
pub struct IconLocation {
    icon_location: String,
    icon_location_unicode: String,
}
impl IconLocation {
    pub fn new<R: Read>(mut reader: R) -> Result<IconLocation,LnkError> {
        let mut icon_location_buffer = vec![0; 260];
        reader.read_exact(icon_location_buffer.as_mut_slice())?;
        let icon_location = utils::read_string_u8_till_null(
            icon_location_buffer.as_slice()
        )?;

        let mut icon_location_unicode_buffer = vec![0; 520];
        reader.read_exact(icon_location_unicode_buffer.as_mut_slice())?;
        let icon_location_unicode = utils::read_string_u8_till_null(
            icon_location_unicode_buffer.as_slice()
        )?;

        Ok (
            IconLocation {
                icon_location: icon_location,
                icon_location_unicode: icon_location_unicode
            }
        )
    }
}

#[derive(Debug)]
pub struct DarwinProperties {
    darwin_app_id: String,
    darwin_app_id_unicode: String
}
impl DarwinProperties {
    pub fn new<R: Read>(mut reader: R) -> Result<DarwinProperties,LnkError> {
        let mut darwin_app_id_buffer = vec![0; 260];
        reader.read_exact(darwin_app_id_buffer.as_mut_slice())?;
        let darwin_app_id = utils::read_string_u8_till_null(
            darwin_app_id_buffer.as_slice()
        )?;

        let mut darwin_app_id_unicode_buffer = vec![0; 520];
        reader.read_exact(darwin_app_id_unicode_buffer.as_mut_slice())?;
        let darwin_app_id_unicode = utils::read_string_u8_till_null(
            darwin_app_id_unicode_buffer.as_slice()
        )?;

        Ok (
            DarwinProperties {
                darwin_app_id: darwin_app_id,
                darwin_app_id_unicode: darwin_app_id_unicode
            }
        )
    }
}

#[derive(Debug)]
pub struct SpecialFolder {
    special_folder_id: u32,
    first_child_segment_offset: u32
}
impl SpecialFolder {
    pub fn new<R: Read>(mut reader: R) -> Result<SpecialFolder,LnkError> {
        let special_folder_id = reader.read_u32::<LittleEndian>()?;
        let first_child_segment_offset = reader.read_u32::<LittleEndian>()?;

        Ok (
            SpecialFolder {
                special_folder_id: special_folder_id,
                first_child_segment_offset: first_child_segment_offset
            }
        )
    }
}

#[derive(Debug)]
pub struct Codepage {
    codepage: u32
}
impl Codepage {
    pub fn new<R: Read>(mut reader: R) -> Result<Codepage,LnkError> {
        let codepage = reader.read_u32::<LittleEndian>()?;

        Ok (
            Codepage {
                codepage: codepage
            }
        )
    }
}

#[derive(Debug)]
pub struct DistributedTracker {
    size: u32,
    version: u32,
    machine_id: String, // 16 bytes (ascii)
    droid_volume: Guid,
    droid_file: Guid,
    birth_droid_volume: Guid,
    birth_droid_file: Guid
}
impl DistributedTracker {
    pub fn new<R: Read>(mut reader: R) -> Result<DistributedTracker,LnkError> {
        let size = reader.read_u32::<LittleEndian>()?;
        let version = reader.read_u32::<LittleEndian>()?;

        let mut buff_machine_id = vec![0; 16];
        reader.read_exact(buff_machine_id.as_mut_slice())?;
        let machine_id = utils::read_string_u8_till_null(
            buff_machine_id.as_slice()
        )?;

        let droid_volume = Guid::new(&mut reader)?;
        let droid_file = Guid::new(&mut reader)?;
        let birth_droid_volume = Guid::new(&mut reader)?;
        let birth_droid_file = Guid::new(&mut reader)?;

        Ok (
            DistributedTracker {
                size: size,
                version: version,
                machine_id: machine_id,
                droid_volume: droid_volume,
                droid_file: droid_file,
                birth_droid_volume: birth_droid_volume,
                birth_droid_file: birth_droid_file
            }
        )
    }
}

#[derive(Debug)]
pub struct EnvironmentVars {
    location: String, //size is 260 bytes (Unicode string terminated by an end-of-string character)
    location_unicode: String //size is 520 bytes (Unicode string terminated by an end-of-string character)
}
impl EnvironmentVars {
    pub fn new<R: Read>(mut reader: R) -> Result<EnvironmentVars,LnkError> {
        let mut buff_location = vec![0; 260];
        reader.read_exact(buff_location.as_mut_slice())?;
        let location = utils::read_string_u8_till_null(
            buff_location.as_slice()
        )?;

        let mut buff_location_unicode = vec![0; 520];
        reader.read_exact(buff_location_unicode.as_mut_slice())?;
        let location_unicode = utils::read_string_u16_till_null(
            buff_location_unicode.as_slice()
        )?;

        Ok(
            EnvironmentVars {
                location: location,
                location_unicode: location_unicode
            }
        )
    }
}

#[derive(Debug)]
pub struct ConsoleProperties {
    color_flags: u16,
    popup_attribs: u16,
    screen_width_buff_size: u16,
    screen_height_buff_size: u16,
    window_width: u16,
    window_height: u16,
    window_x: u16,
    window_y: u16,
    unknown1: u32,
    unknown2: u32,
    font_size: u32,
    font_family_value: u32,
    font_weight: u32,
    face_name: String, //size is 64 bytes (Unicode string terminated by an end-of-string character)
    cursor_size: u32,
    full_screen: u32,
    insert_mode: u32,
    auto_positioning: u32,
    history_buff_size: u32,
    history_buff_count: u32,
    duplicates_allowed: u32,
    color_table: utils::ByteArray
}
impl ConsoleProperties {
    pub fn new<R: Read>(mut reader: R) -> Result<ConsoleProperties,LnkError> {
        let color_flags = reader.read_u16::<LittleEndian>()?;
        let popup_attribs = reader.read_u16::<LittleEndian>()?;
        let screen_width_buff_size = reader.read_u16::<LittleEndian>()?;
        let screen_height_buff_size = reader.read_u16::<LittleEndian>()?;
        let window_width = reader.read_u16::<LittleEndian>()?;
        let window_height = reader.read_u16::<LittleEndian>()?;
        let window_x = reader.read_u16::<LittleEndian>()?;
        let window_y = reader.read_u16::<LittleEndian>()?;
        let unknown1 = reader.read_u32::<LittleEndian>()?;
        let unknown2 = reader.read_u32::<LittleEndian>()?;
        let font_size = reader.read_u32::<LittleEndian>()?;
        let font_family_value = reader.read_u32::<LittleEndian>()?;
        let font_weight = reader.read_u32::<LittleEndian>()?;

        // Read string
        let mut face_buff = vec![0; 64];
        reader.read_exact(face_buff.as_mut_slice())?;
        let face_name = utils::read_string_u16_till_null(face_buff.as_slice())?;

        let cursor_size = reader.read_u32::<LittleEndian>()?;
        let full_screen = reader.read_u32::<LittleEndian>()?;
        let insert_mode = reader.read_u32::<LittleEndian>()?;
        let auto_positioning = reader.read_u32::<LittleEndian>()?;
        let history_buff_size = reader.read_u32::<LittleEndian>()?;
        let history_buff_count = reader.read_u32::<LittleEndian>()?;
        let duplicates_allowed = reader.read_u32::<LittleEndian>()?;

        let mut color_buff = vec![0; 64];
        reader.read_exact(color_buff.as_mut_slice())?;
        let color_table = utils::ByteArray(color_buff);

        Ok (
            ConsoleProperties {
                color_flags: color_flags,
                popup_attribs: popup_attribs,
                screen_width_buff_size: screen_width_buff_size,
                screen_height_buff_size: screen_height_buff_size,
                window_width: window_width,
                window_height: window_height,
                window_x: window_x,
                window_y: window_y,
                unknown1: unknown1,
                unknown2: unknown2,
                font_size: font_size,
                font_family_value: font_family_value,
                font_weight: font_weight,
                face_name: face_name,
                cursor_size: cursor_size,
                full_screen: full_screen,
                insert_mode: insert_mode,
                auto_positioning: auto_positioning,
                history_buff_size: history_buff_size,
                history_buff_count: history_buff_count,
                duplicates_allowed: duplicates_allowed,
                color_table: color_table
            }
        )
    }
}

#[derive(Debug)]
pub struct ExtraDataBlocks {
    pub console_properties: Option<ConsoleProperties>,
    pub environment_vars: Option<EnvironmentVars>,
    pub distributed_tracker: Option<DistributedTracker>,
    pub codepage: Option<Codepage>,
    pub special_folder: Option<SpecialFolder>,
    pub darwin_properties: Option<DarwinProperties>,
    pub icon_location: Option<IconLocation>,
    pub known_folder: Option<KnownFolderLocation>
}
impl ExtraDataBlocks {
    pub fn new<Rs: Read+Seek>(mut reader: Rs) -> Result<ExtraDataBlocks,LnkError> {
        let mut console_properties = None;
        let mut environment_vars = None;
        let mut distributed_tracker = None;
        let mut codepage = None;
        let mut special_folder = None;
        let mut darwin_properties = None;
        let mut icon_location = None;
        let mut known_folder = None;

        let mut _offset = reader.seek(
            SeekFrom::Current(0)
        )?;

        loop {
            let size = reader.read_u32::<LittleEndian>()?;
            if size != 0 {
                let signature = reader.read_u32::<LittleEndian>()?;
                match signature {
                    0xa0000001 => {
                        environment_vars = Some(EnvironmentVars::new(&mut reader)?);
                    },
                    0xa0000002 => {
                        console_properties = Some(ConsoleProperties::new(&mut reader)?);
                    },
                    0xa0000003 => {
                        distributed_tracker = Some(DistributedTracker::new(&mut reader)?);
                    },
                    0xa0000004 => {
                        codepage = Some(Codepage::new(&mut reader)?);
                    },
                    0xa0000005 => {
                        special_folder = Some(SpecialFolder::new(&mut reader)?);
                    },
                    0xa0000006 => {
                        darwin_properties = Some(DarwinProperties::new(&mut reader)?);
                    },
                    0xa0000007 => {
                        icon_location = Some(IconLocation::new(&mut reader)?);
                    },
                    0xa000000b => {
                        known_folder = Some(KnownFolderLocation::new(&mut reader)?);
                    },
                    _ => {
                        println!(
                            "Unhandled data block with signature {} at offset {}",
                            signature,
                            _offset
                        );
                    }
                }

                _offset += size as u64;

                reader.seek(
                    SeekFrom::Start(_offset)
                )?;
            } else {
                break
            }
        }

        Ok(
            ExtraDataBlocks {
                console_properties: console_properties,
                environment_vars: environment_vars,
                distributed_tracker: distributed_tracker,
                codepage: codepage,
                special_folder: special_folder,
                darwin_properties: darwin_properties,
                icon_location: icon_location,
                known_folder: known_folder
            }
        )
    }
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Non-arch-specific paging.
use memory::{Addr, VAddr, PAddr, PAGE_SHIFT};
use memory::alloc::FrameAllocator;

use core::{ops, cmp};
use core::ops::Range;

pub use arch::memory::PhysicalPage;
pub use arch::memory::paging::*;

pub type PageRange = Range<VirtualPage>;
pub type FrameRange = Range<PhysicalPage>;

/// Trait for a page. These can be virtual pages or physical frames.
pub trait Page
where Self: Sized
    , Self: ops::AddAssign<usize> + ops::SubAssign<usize>
    , Self: ops::Add<usize, Output=Self> + ops::Sub<usize, Output=Self>
    , Self: cmp::PartialEq<Self> + cmp::PartialOrd<Self>
    , Self: Copy + Clone {

    /// The type of address used to address this `Page`.
    ///
    /// Typically, this is a `PAddr` or `VAddr` (but it could be a "MAddr")
    /// in schemes where we differentiate between physical and machine
    /// addresses. If we ever have those.
    type Address: Addr;

    /// Returns a new `Page` containing the given `Address`.
    ///
    /// N.B. that since trait functions cannot be `const`, implementors of
    /// this trait may wish to provide implementations of this function
    /// outside of the `impl` block and then wrap them here.
    fn containing(addr: Self::Address) -> Self;

    /// Returns the base `Address` where this page starts.
    fn base(&self) -> Self::Address;

    ///// Convert the frame into a raw pointer to the frame's base address
    //#[inline]
    //unsafe fn as_ptr<T>(&self) -> *const T {
    //    mem::transmute(self.base())
    //}
    //
    ///// Convert the frame into a raw mutable pointer to the frame's base address
    //#[inline]
    //unsafe fn as_mut_ptr<T>(&self) -> *mut T {
    //    mem::transmute(self.base())
    //}

    /// Returns a `PageRange` of this `Page` and the next `n` pages.
    #[inline]
    fn range_of(&self, n: usize) -> Range<Self> {
        self.range_until(*self + n)
    }

    /// Returns a `PageRange` on the frames from this frame until the end frame
    #[inline]
    fn range_until(&self, end: Self) -> Range<Self> {
        Range { start: *self, end: end }
    }

    fn number(&self) -> usize;

}
//
///// A range of `Page`s.
//#[derive(Copy, Clone, Debug, Eq, PartialEq)]
//pub struct Range

//where P: Page { start: P, end: P }
//
pub trait MemRange {
    /// Returns the number of `Page`s in this ranage
    #[inline]
    fn length(&self) -> usize;

    /// Remove `n` pages from the beginning of this `PageRange`
    fn drop_front(&mut self, n: usize) -> &mut Self;

    /// Remove `n` pages from the end of this `PageRange`
    fn drop_back(&mut self, n: usize) -> &mut Self;

    /// Add `n` pages at the front of this `PageRange`
    fn add_front(&mut self, n: usize) -> &mut Self;

    /// Add `n` pages at the back of this `PageRange`
    fn add_back(&mut self, n: usize) -> &mut Self;
}
    //pub const fn start(&self) -> P { self.start }
   //
   ///// Returns a `PageRange` between two pages
   //pub const fn between(start: P, end: P) -> Range
 {
   //    Range { start: start, end: end }
   //}
   //
   // /// Returns an iterator over this `PageRange`
   // pub fn iter<'a>(&'a self) -> RangeIter<'a, P> {
   //     RangeIter { range: self, current: self.start.clone() }
   // }

impl
 MemRange for Range

where P: Page {

    /// Returns the number of `Page`s in this ranage
    #[inline]
    fn length(&self) -> usize {
        self.end.number() - self.start.number()
    }

    /// Remove `n` pages from the beginning of this `PageRange`
    fn drop_front(&mut self, n: usize) -> &mut Self {
        assert!(n < self.length());
        self.start += n;
        self
    }

    /// Remove `n` pages from the end of this `PageRange`
    fn drop_back(&mut self, n: usize) -> &mut Self {
        assert!(n < self.length());
        self.end -= n;
        self
    }

    /// Add `n` pages at the front of this `PageRange`
    fn add_front(&mut self, n: usize) -> &mut Self {
        self.start -= n;
        self
    }

    /// Add `n` pages at the back of this `PageRange`
    fn add_back(&mut self, n: usize) -> &mut Self {
        self.end += n;
        self
    }
}

/// An iterator over a range of pages
pub struct RangeIter<'a, P>
where P: Page
    , P: 'a { range: &'a Range
, current: P }

impl<'a, P> Iterator for RangeIter<'a, P>
where P: Page
    , P: Clone {
    type Item = P;

    fn next(&mut self) -> Option
 {
        let end = self.range.end;
      assert!(self.range.start <= end);
      if self.current < end {
          let page = self.current.clone();
          self.current += 1;
          Some(page)
      } else {
          None
      }
  }

}

pub trait Mapper {
    type Flags;

    /// Translates a virtual address to the corresponding physical address.
    ///
    /// # Return
    /// + `Some(PAddr)` containing the physical address corresponding to
    ///                 `vaddr`, if it is mapped.
    /// + `None`: if the address is not mapped.
    fn translate(&self, vaddr: VAddr) -> Option<PAddr>;

    /// Translates a virtual page to a physical frame.
    fn translate_page(&self, page: VirtualPage) -> Option<PhysicalPage>;

    /// Modifies the page tables so that `page` maps to `frame`.
    ///
    /// # Arguments
    /// + `page`: the virtual `Page` to map
    /// + `frame`: the physical `Frame` that `Page` should map to.
    /// + `flags`: the page table entry flags.
    /// + `alloc`: a memory allocator
    fn map( &mut self, page: VirtualPage, frame: PhysicalPage
             , flags: Self::Flags, alloc: &A )
    where A: FrameAllocator;

    /// Identity map a given `frame`.
    ///
    /// # Arguments
    /// + `frame`: the physical `Frame` to identity map
    /// + `flags`: the page table entry flags.
    /// + `alloc`: a memory allocator
    fn identity_map( &mut self, frame: PhysicalPage
                      , flags: Self::Flags, alloc: &A )
    where A: FrameAllocator;

    /// Map the given `VirtualPage` to any free frame.
    ///
    /// This is like the fire and forget version of `map_to`: we just pick the
    /// first available free frame and map the page to it.
    ///
    /// # Arguments
    /// + `page`: the`VirtualPage` to map
    /// + `flags`: the page table entry flags.
    /// + `alloc`: a memory allocator
    fn map_to_any( &mut self, page: VirtualPage
                    , flags: Self::Flags
                    , alloc: &A)
    where A: FrameAllocator;

    /// Unmap the given `VirtualPage`.
    ///
    /// All freed frames are returned to the given `FrameAllocator`.
    fn unmap(&mut self, page: VirtualPage, alloc: &A)
    where A: FrameAllocator;

}

custom_derive!{
    /// A virtual page
    #[derive( Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Page(VAddr) )]
    pub struct VirtualPage { pub number: usize }
}
<commit_msg>[kernel] add convert::From implementations for PageRange<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Non-arch-specific paging.
use memory::{Addr, VAddr, PAddr, PAGE_SHIFT};
use memory::alloc::FrameAllocator;

use elf;

use core::{ops, cmp, convert};
use core::ops::Range;

pub use arch::memory::PhysicalPage;
pub use arch::memory::paging::*;

pub type PageRange = Range<VirtualPage>;
pub type FrameRange = Range<PhysicalPage>;

/// Trait for a page. These can be virtual pages or physical frames.
pub trait Page
where Self: Sized
    , Self: ops::AddAssign<usize> + ops::SubAssign<usize>
    , Self: ops::Add<usize, Output=Self> + ops::Sub<usize, Output=Self>
    , Self: cmp::PartialEq<Self> + cmp::PartialOrd<Self>
    , Self: Copy + Clone {

    /// The type of address used to address this `Page`.
    ///
    /// Typically, this is a `PAddr` or `VAddr` (but it could be a "MAddr")
    /// in schemes where we differentiate between physical and machine
    /// addresses. If we ever have those.
    type Address: Addr;

    /// Returns a new `Page` containing the given `Address`.
    ///
    /// N.B. that since trait functions cannot be `const`, implementors of
    /// this trait may wish to provide implementations of this function
    /// outside of the `impl` block and then wrap them here.
    fn containing(addr: Self::Address) -> Self;

    /// Returns the base `Address` where this page starts.
    fn base(&self) -> Self::Address;

    ///// Convert the frame into a raw pointer to the frame's base address
    //#[inline]
    //unsafe fn as_ptr<T>(&self) -> *const T {
    //    mem::transmute(self.base())
    //}
    //
    ///// Convert the frame into a raw mutable pointer to the frame's base address
    //#[inline]
    //unsafe fn as_mut_ptr<T>(&self) -> *mut T {
    //    mem::transmute(self.base())
    //}

    /// Returns a `PageRange` of this `Page` and the next `n` pages.
    #[inline]
    fn range_of(&self, n: usize) -> Range<Self> {
        self.range_until(*self + n)
    }

    /// Returns a `PageRange` on the frames from this frame until the end frame
    #[inline]
    fn range_until(&self, end: Self) -> Range<Self> {
        Range { start: *self, end: end }
    }

    fn number(&self) -> usize;

}
//
///// A range of `Page`s.
//#[derive(Copy, Clone, Debug, Eq, PartialEq)]
//pub struct Range

//where P: Page { start: P, end: P }
//
pub trait MemRange {
    /// Returns the number of `Page`s in this ranage
    #[inline]
    fn length(&self) -> usize;

    /// Remove `n` pages from the beginning of this `PageRange`
    fn drop_front(&mut self, n: usize) -> &mut Self;

    /// Remove `n` pages from the end of this `PageRange`
    fn drop_back(&mut self, n: usize) -> &mut Self;

    /// Add `n` pages at the front of this `PageRange`
    fn add_front(&mut self, n: usize) -> &mut Self;

    /// Add `n` pages at the back of this `PageRange`
    fn add_back(&mut self, n: usize) -> &mut Self;
}
    //pub const fn start(&self) -> P { self.start }
   //
   ///// Returns a `PageRange` between two pages
   //pub const fn between(start: P, end: P) -> Range
 {
   //    Range { start: start, end: end }
   //}
   //
   // /// Returns an iterator over this `PageRange`
   // pub fn iter<'a>(&'a self) -> RangeIter<'a, P> {
   //     RangeIter { range: self, current: self.start.clone() }
   // }

impl
 MemRange for Range

where P: Page {

    /// Returns the number of `Page`s in this ranage
    #[inline]
    fn length(&self) -> usize {
        self.end.number() - self.start.number()
    }

    /// Remove `n` pages from the beginning of this `PageRange`
    fn drop_front(&mut self, n: usize) -> &mut Self {
        assert!(n < self.length());
        self.start += n;
        self
    }

    /// Remove `n` pages from the end of this `PageRange`
    fn drop_back(&mut self, n: usize) -> &mut Self {
        assert!(n < self.length());
        self.end -= n;
        self
    }

    /// Add `n` pages at the front of this `PageRange`
    fn add_front(&mut self, n: usize) -> &mut Self {
        self.start -= n;
        self
    }

    /// Add `n` pages at the back of this `PageRange`
    fn add_back(&mut self, n: usize) -> &mut Self {
        self.end += n;
        self
    }
}

/// An iterator over a range of pages
pub struct RangeIter<'a, P>
where P: Page
    , P: 'a { range: &'a Range
, current: P }

impl<'a, P> Iterator for RangeIter<'a, P>
where P: Page
    , P: Clone {
    type Item = P;

    fn next(&mut self) -> Option
 {
        let end = self.range.end;
      assert!(self.range.start <= end);
      if self.current < end {
          let page = self.current.clone();
          self.current += 1;
          Some(page)
      } else {
          None
      }
  }

}

pub trait Mapper {
    type Flags;

    /// Translates a virtual address to the corresponding physical address.
    ///
    /// # Return
    /// + `Some(PAddr)` containing the physical address corresponding to
    ///                 `vaddr`, if it is mapped.
    /// + `None`: if the address is not mapped.
    fn translate(&self, vaddr: VAddr) -> Option<PAddr>;

    /// Translates a virtual page to a physical frame.
    fn translate_page(&self, page: VirtualPage) -> Option<PhysicalPage>;

    /// Modifies the page tables so that `page` maps to `frame`.
    ///
    /// # Arguments
    /// + `page`: the virtual `Page` to map
    /// + `frame`: the physical `Frame` that `Page` should map to.
    /// + `flags`: the page table entry flags.
    /// + `alloc`: a memory allocator
    fn map( &mut self, page: VirtualPage, frame: PhysicalPage
             , flags: Self::Flags, alloc: &A )
    where A: FrameAllocator;

    /// Identity map a given `frame`.
    ///
    /// # Arguments
    /// + `frame`: the physical `Frame` to identity map
    /// + `flags`: the page table entry flags.
    /// + `alloc`: a memory allocator
    fn identity_map( &mut self, frame: PhysicalPage
                      , flags: Self::Flags, alloc: &A )
    where A: FrameAllocator;

    /// Map the given `VirtualPage` to any free frame.
    ///
    /// This is like the fire and forget version of `map_to`: we just pick the
    /// first available free frame and map the page to it.
    ///
    /// # Arguments
    /// + `page`: the`VirtualPage` to map
    /// + `flags`: the page table entry flags.
    /// + `alloc`: a memory allocator
    fn map_to_any( &mut self, page: VirtualPage
                    , flags: Self::Flags
                    , alloc: &A)
    where A: FrameAllocator;

    /// Unmap the given `VirtualPage`.
    ///
    /// All freed frames are returned to the given `FrameAllocator`.
    fn unmap(&mut self, page: VirtualPage, alloc: &A)
    where A: FrameAllocator;

}

custom_derive!{
    /// A virtual page
    #[derive( Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Page(VAddr) )]
    pub struct VirtualPage { pub number: usize }
}

impl convert::From<PAddr> for PhysicalPage {
    #[inline] fn from(addr: PAddr) -> Self {
        PhysicalPage::containing(addr)
    }
}

impl convert::From<VAddr> for VirtualPage {
    #[inline] fn from(addr: VAddr) -> Self {
        VirtualPage::containing(addr)
    }
}

impl<'a> convert::From<elf::Section<'a>> for FrameRange {
    #[inline]
    fn from(section: elf::Section<'a>) -> Self {
        let start = PhysicalPage::from(PAddr::from(section.addr()));
        let end = PhysicalPage::from(PAddr::from(section.addr()));
        start .. end
    }

}
<|endoftext|>


<commit_before>// Copyright 2017 TiKV Project Authors. Licensed under Apache-2.0.

use std::sync::Arc;
use std::time::Instant;

use test_raftstore::*;

use tikv_util::config::*;

#[test]
fn test_pending_peers() {
    let mut cluster = new_node_cluster(0, 3);
    cluster.cfg.raft_store.pd_heartbeat_tick_interval = ReadableDuration::millis(100);

    let region_worker_fp = "region_apply_snap";

    let pd_client = Arc::clone(&cluster.pd_client);
    // Disable default max peer count check.
    pd_client.disable_default_operator();

    let region_id = cluster.run_conf_change();
    pd_client.must_add_peer(region_id, new_peer(2, 2));

    cluster.must_put(b"k1", b"v1");

    fail::cfg(region_worker_fp, "sleep(2000)").unwrap();
    pd_client.must_add_peer(region_id, new_peer(3, 3));
    sleep_ms(1000);
    let pending_peers = pd_client.get_pending_peers();
    // Region worker is not started, snapshot should not be applied yet.
    assert_eq!(pending_peers[&3], new_peer(3, 3));
    // But it will be applied finally.
    must_get_equal(&cluster.get_engine(3), b"k1", b"v1");
    sleep_ms(100);
    let pending_peers = pd_client.get_pending_peers();
    assert!(pending_peers.is_empty());
}

// Tests if raftstore and apply worker write truncated_state concurrently could lead to
// dirty write.
#[test]
fn test_pending_snapshot() {
    let mut cluster = new_node_cluster(0, 3);
    configure_for_snapshot(&mut cluster);
    let election_timeout = configure_for_lease_read(&mut cluster, None, Some(15));
    let gc_limit = cluster.cfg.raft_store.raft_log_gc_count_limit;
    cluster.cfg.raft_store.pd_heartbeat_tick_interval = ReadableDuration::millis(100);

    let handle_snapshot_fp = "apply_on_handle_snapshot_1_1";
    let handle_snapshot_finish_fp = "apply_on_handle_snapshot_finish_1_1";
    fail::cfg("apply_on_handle_snapshot_sync", "return").unwrap();

    let pd_client = Arc::clone(&cluster.pd_client);
    // Disable default max peer count check.
    pd_client.disable_default_operator();

    let region_id = cluster.run_conf_change();
    pd_client.must_add_peer(region_id, new_peer(2, 2));
    cluster.must_transfer_leader(region_id, new_peer(1, 1));
    cluster.must_put(b"k1", b"v1");

    fail::cfg(handle_snapshot_fp, "pause").unwrap();
    pd_client.must_add_peer(region_id, new_peer(3, 3));
    // Give some time for peer 3 to request snapshot.
    sleep_ms(100);

    // Isolate peer 1 from rest of the cluster.
    cluster.add_send_filter(IsolationFilterFactory::new(1));

    sleep_ms((election_timeout.as_millis() * 2) as _);
    cluster.reset_leader_of_region(region_id);
    // Compact logs to force requesting snapshot after clearing send filters.
    let state2 = cluster.truncated_state(1, 2);
    for i in 1..gc_limit * 10 {
        let k = i.to_string().into_bytes();
        cluster.must_put(&k, &k.clone());
    }
    cluster.wait_log_truncated(1, 2, state2.get_index() + 5 * gc_limit);

    // Make sure peer 1 has applied snapshot.
    cluster.clear_send_filters();
    let start = Instant::now();
    loop {
        if cluster.pd_client.get_pending_peers().get(&1).is_none()
            || start.elapsed() > election_timeout * 10
        {
            break;
        }
        sleep_ms(50);
    }
    let state1 = cluster.truncated_state(1, 1);

    // Peer 2 continues to handle snapshot.
    fail::cfg(handle_snapshot_finish_fp, "pause").unwrap();
    fail::remove(handle_snapshot_fp);
    sleep_ms(200);
    let state2 = cluster.truncated_state(1, 1);
    fail::remove(handle_snapshot_finish_fp);
    assert!(
        state1.get_term() <= state2.get_term(),
        "{:?} {:?}",
        state1,
        state2
    );
    assert!(
        state1.get_index() <= state2.get_index(),
        "{:?} {:?}",
        state1,
        state2
    );
}
<commit_msg>fix unstable test case test_pending_peers (#10541)<commit_after>// Copyright 2017 TiKV Project Authors. Licensed under Apache-2.0.

use std::sync::Arc;
use std::time::Instant;

use test_raftstore::*;

use tikv_util::config::*;

#[test]
fn test_pending_peers() {
    let mut cluster = new_node_cluster(0, 3);
    cluster.cfg.raft_store.pd_heartbeat_tick_interval = ReadableDuration::millis(100);

    let region_worker_fp = "region_apply_snap";

    let pd_client = Arc::clone(&cluster.pd_client);
    // Disable default max peer count check.
    pd_client.disable_default_operator();

    let region_id = cluster.run_conf_change();
    pd_client.must_add_peer(region_id, new_peer(2, 2));

    // To ensure peer 2 is not pending.
    cluster.must_put(b"k1", b"v1");
    must_get_equal(&cluster.get_engine(2), b"k1", b"v1");

    fail::cfg(region_worker_fp, "sleep(2000)").unwrap();
    pd_client.must_add_peer(region_id, new_peer(3, 3));
    sleep_ms(1000);
    let pending_peers = pd_client.get_pending_peers();
    // Region worker is not started, snapshot should not be applied yet.
    assert_eq!(pending_peers[&3], new_peer(3, 3));
    // But it will be applied finally.
    must_get_equal(&cluster.get_engine(3), b"k1", b"v1");
    sleep_ms(100);
    let pending_peers = pd_client.get_pending_peers();
    assert!(pending_peers.is_empty());
}

// Tests if raftstore and apply worker write truncated_state concurrently could lead to
// dirty write.
#[test]
fn test_pending_snapshot() {
    let mut cluster = new_node_cluster(0, 3);
    configure_for_snapshot(&mut cluster);
    let election_timeout = configure_for_lease_read(&mut cluster, None, Some(15));
    let gc_limit = cluster.cfg.raft_store.raft_log_gc_count_limit;
    cluster.cfg.raft_store.pd_heartbeat_tick_interval = ReadableDuration::millis(100);

    let handle_snapshot_fp = "apply_on_handle_snapshot_1_1";
    let handle_snapshot_finish_fp = "apply_on_handle_snapshot_finish_1_1";
    fail::cfg("apply_on_handle_snapshot_sync", "return").unwrap();

    let pd_client = Arc::clone(&cluster.pd_client);
    // Disable default max peer count check.
    pd_client.disable_default_operator();

    let region_id = cluster.run_conf_change();
    pd_client.must_add_peer(region_id, new_peer(2, 2));
    cluster.must_transfer_leader(region_id, new_peer(1, 1));
    cluster.must_put(b"k1", b"v1");

    fail::cfg(handle_snapshot_fp, "pause").unwrap();
    pd_client.must_add_peer(region_id, new_peer(3, 3));
    // Give some time for peer 3 to request snapshot.
    sleep_ms(100);

    // Isolate peer 1 from rest of the cluster.
    cluster.add_send_filter(IsolationFilterFactory::new(1));

    sleep_ms((election_timeout.as_millis() * 2) as _);
    cluster.reset_leader_of_region(region_id);
    // Compact logs to force requesting snapshot after clearing send filters.
    let state2 = cluster.truncated_state(1, 2);
    for i in 1..gc_limit * 10 {
        let k = i.to_string().into_bytes();
        cluster.must_put(&k, &k.clone());
    }
    cluster.wait_log_truncated(1, 2, state2.get_index() + 5 * gc_limit);

    // Make sure peer 1 has applied snapshot.
    cluster.clear_send_filters();
    let start = Instant::now();
    loop {
        if cluster.pd_client.get_pending_peers().get(&1).is_none()
            || start.elapsed() > election_timeout * 10
        {
            break;
        }
        sleep_ms(50);
    }
    let state1 = cluster.truncated_state(1, 1);

    // Peer 2 continues to handle snapshot.
    fail::cfg(handle_snapshot_finish_fp, "pause").unwrap();
    fail::remove(handle_snapshot_fp);
    sleep_ms(200);
    let state2 = cluster.truncated_state(1, 1);
    fail::remove(handle_snapshot_finish_fp);
    assert!(
        state1.get_term() <= state2.get_term(),
        "{:?} {:?}",
        state1,
        state2
    );
    assert!(
        state1.get_index() <= state2.get_index(),
        "{:?} {:?}",
        state1,
        state2
    );
}
<|endoftext|>


<commit_before>#![warn(clippy::new_ret_no_self)]
#![allow(dead_code)]

fn main() {}

trait R {
    type Item;
}

trait Q {
    type Item;
    type Item2;
}

struct S;

impl R for S {
    type Item = Self;
}

impl S {
    // should not trigger the lint
    pub fn new() -> impl R<Item = Self> {
        S
    }
}

struct S2;

impl R for S2 {
    type Item = Self;
}

impl S2 {
    // should not trigger the lint
    pub fn new(_: String) -> impl R<Item = Self> {
        S2
    }
}

struct S3;

impl R for S3 {
    type Item = u32;
}

impl S3 {
    // should trigger the lint
    pub fn new(_: String) -> impl R<Item = u32> {
        S3
    }
}

struct S4;

impl Q for S4 {
    type Item = u32;
    type Item2 = Self;
}

impl S4 {
    // should not trigger the lint
    pub fn new(_: String) -> impl Q<Item = u32, Item2 = Self> {
        S4
    }
}

struct T;

impl T {
    // should not trigger lint
    pub fn new() -> Self {
        unimplemented!();
    }
}

struct U;

impl U {
    // should trigger lint
    pub fn new() -> u32 {
        unimplemented!();
    }
}

struct V;

impl V {
    // should trigger lint
    pub fn new(_: String) -> u32 {
        unimplemented!();
    }
}

struct TupleReturnerOk;

impl TupleReturnerOk {
    // should not trigger lint
    pub fn new() -> (Self, u32) {
        unimplemented!();
    }
}

struct TupleReturnerOk2;

impl TupleReturnerOk2 {
    // should not trigger lint (it doesn't matter which element in the tuple is Self)
    pub fn new() -> (u32, Self) {
        unimplemented!();
    }
}

struct TupleReturnerOk3;

impl TupleReturnerOk3 {
    // should not trigger lint (tuple can contain multiple Self)
    pub fn new() -> (Self, Self) {
        unimplemented!();
    }
}

struct TupleReturnerBad;

impl TupleReturnerBad {
    // should trigger lint
    pub fn new() -> (u32, u32) {
        unimplemented!();
    }
}

struct MutPointerReturnerOk;

impl MutPointerReturnerOk {
    // should not trigger lint
    pub fn new() -> *mut Self {
        unimplemented!();
    }
}

struct MutPointerReturnerOk2;

impl MutPointerReturnerOk2 {
    // should not trigger lint
    pub fn new() -> *const Self {
        unimplemented!();
    }
}

struct MutPointerReturnerBad;

impl MutPointerReturnerBad {
    // should trigger lint
    pub fn new() -> *mut V {
        unimplemented!();
    }
}

struct GenericReturnerOk;

impl GenericReturnerOk {
    // should not trigger lint
    pub fn new() -> Option<Self> {
        unimplemented!();
    }
}

struct GenericReturnerBad;

impl GenericReturnerBad {
    // should trigger lint
    pub fn new() -> Option<u32> {
        unimplemented!();
    }
}

struct NestedReturnerOk;

impl NestedReturnerOk {
    // should not trigger lint
    pub fn new() -> (Option<Self>, u32) {
        unimplemented!();
    }
}

struct NestedReturnerOk2;

impl NestedReturnerOk2 {
    // should not trigger lint
    pub fn new() -> ((Self, u32), u32) {
        unimplemented!();
    }
}

struct NestedReturnerOk3;

impl NestedReturnerOk3 {
    // should not trigger lint
    pub fn new() -> Option<(Self, u32)> {
        unimplemented!();
    }
}
<commit_msg>Add lifetime test case for `new_ret_no_self`<commit_after>#![warn(clippy::new_ret_no_self)]
#![allow(dead_code)]

fn main() {}

trait R {
    type Item;
}

trait Q {
    type Item;
    type Item2;
}

struct S;

impl R for S {
    type Item = Self;
}

impl S {
    // should not trigger the lint
    pub fn new() -> impl R<Item = Self> {
        S
    }
}

struct S2;

impl R for S2 {
    type Item = Self;
}

impl S2 {
    // should not trigger the lint
    pub fn new(_: String) -> impl R<Item = Self> {
        S2
    }
}

struct S3;

impl R for S3 {
    type Item = u32;
}

impl S3 {
    // should trigger the lint
    pub fn new(_: String) -> impl R<Item = u32> {
        S3
    }
}

struct S4;

impl Q for S4 {
    type Item = u32;
    type Item2 = Self;
}

impl S4 {
    // should not trigger the lint
    pub fn new(_: String) -> impl Q<Item = u32, Item2 = Self> {
        S4
    }
}

struct T;

impl T {
    // should not trigger lint
    pub fn new() -> Self {
        unimplemented!();
    }
}

struct U;

impl U {
    // should trigger lint
    pub fn new() -> u32 {
        unimplemented!();
    }
}

struct V;

impl V {
    // should trigger lint
    pub fn new(_: String) -> u32 {
        unimplemented!();
    }
}

struct TupleReturnerOk;

impl TupleReturnerOk {
    // should not trigger lint
    pub fn new() -> (Self, u32) {
        unimplemented!();
    }
}

struct TupleReturnerOk2;

impl TupleReturnerOk2 {
    // should not trigger lint (it doesn't matter which element in the tuple is Self)
    pub fn new() -> (u32, Self) {
        unimplemented!();
    }
}

struct TupleReturnerOk3;

impl TupleReturnerOk3 {
    // should not trigger lint (tuple can contain multiple Self)
    pub fn new() -> (Self, Self) {
        unimplemented!();
    }
}

struct TupleReturnerBad;

impl TupleReturnerBad {
    // should trigger lint
    pub fn new() -> (u32, u32) {
        unimplemented!();
    }
}

struct MutPointerReturnerOk;

impl MutPointerReturnerOk {
    // should not trigger lint
    pub fn new() -> *mut Self {
        unimplemented!();
    }
}

struct MutPointerReturnerOk2;

impl MutPointerReturnerOk2 {
    // should not trigger lint
    pub fn new() -> *const Self {
        unimplemented!();
    }
}

struct MutPointerReturnerBad;

impl MutPointerReturnerBad {
    // should trigger lint
    pub fn new() -> *mut V {
        unimplemented!();
    }
}

struct GenericReturnerOk;

impl GenericReturnerOk {
    // should not trigger lint
    pub fn new() -> Option<Self> {
        unimplemented!();
    }
}

struct GenericReturnerBad;

impl GenericReturnerBad {
    // should trigger lint
    pub fn new() -> Option<u32> {
        unimplemented!();
    }
}

struct NestedReturnerOk;

impl NestedReturnerOk {
    // should not trigger lint
    pub fn new() -> (Option<Self>, u32) {
        unimplemented!();
    }
}

struct NestedReturnerOk2;

impl NestedReturnerOk2 {
    // should not trigger lint
    pub fn new() -> ((Self, u32), u32) {
        unimplemented!();
    }
}

struct NestedReturnerOk3;

impl NestedReturnerOk3 {
    // should not trigger lint
    pub fn new() -> Option<(Self, u32)> {
        unimplemented!();
    }
}

struct WithLifetime<'a> {
    cat: &'a str,
}

impl<'a> WithLifetime<'a> {
    // should not trigger the lint, because the lifetimes are different
    pub fn new<'b: 'a>(s: &'b str) -> WithLifetime<'b> {
        unimplemented!();
    }
}
<|endoftext|>


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

use error::Result;

#[derive(Debug)]
pub struct Uname {
    pub sys_name: String,
    pub node_name: String,
    pub release: String,
    pub version: String,
    pub machine: String,
}

pub fn uname() -> Result<Uname> {
    unimplemented!();
}
<commit_msg>stub uname results<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use error::Result;

// We can probably pull this from Win32_OperatingSystem
#[derive(Debug)]
pub struct Uname {
    pub sys_name: String, // static - Windows
    pub node_name: String, // __SERVER
    pub release: String, // Version
    pub version: String, // Caption
    pub machine: String, // OSArchitecture - but converted to standard x86_64 or i386
}

pub fn uname() -> Result<Uname> {
    Ok(Uname{
        sys_name: String::from("Windows"),
        node_name: String::from("CHEF-WIN10"),
        release: String::from("10.0.14915"),
        version: String::from("Microsoft Windows 10 Enterprise Insider Preview"),
        machine: String::from("x86_64"),
    })
}
<|endoftext|>


<commit_before>extern crate gauc;

use gauc::client::*;
use gauc::couchbase::types::error_type::ErrorType;

const DEFAULT_CONNECTION_STRING: &'static str = "couchbase://localhost/default";

#[test]
fn it_connects() {
    let client = Client::new(DEFAULT_CONNECTION_STRING);
    assert!(client.opts.version() == 3);
}

#[test]
fn it_gets_fails_when_getting_nonexisting_document() {
    let mut client = Client::new(DEFAULT_CONNECTION_STRING);

    // Get data
    client.get("non-existing-key", |res| {
        if let Err(response) = res {
            assert!(response.to_string() == "The key does not exist on the server");
        }
    });
}

#[test]
fn it_stores_document() {
    let mut client = Client::new(DEFAULT_CONNECTION_STRING);

    // Store some data
    client.store("foo", "{\"msg\": \"This is test!\"}", |res| {
        if let Ok(response) = res {
            assert!(response.rc == ErrorType::Success);
            println!("Created new document, CAS: {}", response.cas)
        }
    });
}
<commit_msg>Fix typo<commit_after>extern crate gauc;

use gauc::client::*;
use gauc::couchbase::types::error_type::ErrorType;

const DEFAULT_CONNECTION_STRING: &'static str = "couchbase://localhost/default";

#[test]
fn it_connects() {
    let client = Client::new(DEFAULT_CONNECTION_STRING);
    assert!(client.opts.version() == 3);
}

#[test]
fn it_fails_when_getting_nonexisting_document() {
    let mut client = Client::new(DEFAULT_CONNECTION_STRING);

    // Get data
    client.get("non-existing-key", |res| {
        if let Err(response) = res {
            assert!(response.to_string() == "The key does not exist on the server");
        }
    });
}

#[test]
fn it_stores_document() {
    let mut client = Client::new(DEFAULT_CONNECTION_STRING);

    // Store some data
    client.store("foo", "{\"msg\": \"This is test!\"}", |res| {
        if let Ok(response) = res {
            assert!(response.rc == ErrorType::Success);
            println!("Created new document, CAS: {}", response.cas)
        }
    });
}
<|endoftext|>


<commit_before>extern crate sentry_rs;
#[macro_use]
extern crate serde_json;

use sentry_rs::models::*;
use std::collections::HashMap;

pub fn generate_shallow_event() -> Event {
  Event {
    event_id: "event_id".to_owned(),
    message: "message".to_owned(),
    timestamp: "timestamp".to_owned(),
    level: "level".to_owned(),
    logger: "logger".to_owned(),
    platform: "platform".to_owned(),
    sdk: SDK {
      name: "sdk_name".to_owned(),
      version: "sdk_version".to_owned(),
    },
    device: Device {
      name: "device_name".to_owned(),
      version: "device_version".to_owned(),
    },
    culprit: None,
    server_name: None,
    stacktrace: None,
    release: None,
    tags: HashMap::new(),
    environment: None,
    modules: HashMap::new(),
    extra: HashMap::new(),
    fingerprint: vec![],
  }
}

pub fn generate_full_event() -> Event {
  let mut tags = HashMap::new();
  tags.insert("tag_key".to_owned(), "tag_value".to_owned());
  tags.insert("tag_key_2".to_owned(), "tag_value_2".to_owned());
  let mut modules = HashMap::new();
  modules.insert("module_key".to_owned(), "module_value".to_owned());
  modules.insert("module_key_2".to_owned(), "module_value_2".to_owned());
  let mut extras = HashMap::new();
  extras.insert("extra_key".to_owned(), json!("extra_value"));
  extras.insert("extra_key_2".to_owned(), json!("extra_value_2"));
  Event {
    event_id: "event_id".to_owned(),
    message: "message".to_owned(),
    timestamp: "timestamp".to_owned(),
    level: "level".to_owned(),
    logger: "logger".to_owned(),
    platform: "platform".to_owned(),
    sdk: SDK {
      name: "sdk_name".to_owned(),
      version: "sdk_version".to_owned(),
    },
    device: Device {
      name: "device_name".to_owned(),
      version: "device_version".to_owned(),
    },
    culprit: Some("culprit".to_owned()),
    server_name: Some("server_name".to_owned()),
    stacktrace: Some(vec![
      StackFrame {
        filename: "filename.stack.frame".to_owned(),
        function: "function.stack.frame".to_owned(),
        lineno: 10,
        pre_context: vec![
          "filename: \"filename.stack.frame\".to_owned()".to_owned(),
          "function: \"function.stack.frame\".to_owned()".to_owned(),
        ],
        context_line: "context_line: \"context_line\"".to_owned(),
        post_context: vec![
          "filename: \"filename.stack.frame\".to_owned()".to_owned(),
          "function: \"function.stack.frame\".to_owned()".to_owned(),
        ],
        in_app: true,
      },
      StackFrame {
        filename: "filename.2.stack.frame".to_owned(),
        function: "function.2.stack.frame".to_owned(),
        lineno: 12,
        pre_context: Vec::new(),
        context_line: "".to_owned(),
        post_context: Vec::new(),
        in_app: false,
      },
    ]),
    release: Some("Release".to_owned()),
    tags: tags,
    environment: Some("environment".to_owned()),
    modules: modules,
    extra: extras,
    fingerprint: vec!["fingerprint".to_owned()],
  }
}

#[test]
pub fn to_string_shallow_event() {
  let value = generate_shallow_event().to_string();
  assert_eq!(value, r#"{"culprit":null,"device":{"build":"device_build","name":"device_name","version":"device_version"},"event_id":"event_id","level":"level","logger":"logger","message":"message","platform":"platform","release":null,"sdk":{"name":"sdk_name","version":"sdk_version"},"server_name":null,"timestamp":"timestamp"}"#);
}

#[test]
pub fn to_string_full_event() {
  let value = generate_full_event().to_string();
  assert_eq!(value, r#"{"culprit":"culprit","device":{"build":"device_build","name":"device_name","version":"device_version"},"environment":"environment","event_id":"event_id","extra":{"extra_key":"extra_value","extra_key_2":"extra_value_2"},"fingerprint":["fingerprint"],"level":"level","logger":"logger","message":"message","modules":{"module_key":"module_value","module_key_2":"module_value_2"},"platform":"platform","release":"Release","sdk":{"name":"sdk_name","version":"sdk_version"},"server_name":"server_name","stacktrace":{"frames":[{"context_line":"context_line: \"context_line\"","filename":"filename.stack.frame","function":"function.stack.frame","in_app":true,"lineno":10,"post_context":["filename: \"filename.stack.frame\".to_owned()","function: \"function.stack.frame\".to_owned()"],"pre_context":["filename: \"filename.stack.frame\".to_owned()","function: \"function.stack.frame\".to_owned()"]},{"context_line":"","filename":"filename.2.stack.frame","function":"function.2.stack.frame","in_app":false,"lineno":12,"post_context":[],"pre_context":[]}]},"tags":{"tag_key":"tag_value","tag_key_2":"tag_value_2"},"timestamp":"timestamp"}"#);
}

#[test]
pub fn prep_string_cuts_off_string_in_quotes() {
  let test_string = "\"\"";
  let finalized_string = prep_string(test_string);

  assert_eq!(finalized_string, "");
}

#[test]
pub fn test_sentry_creds_parsing() {
  let test_string = "https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY@ZZZZ/AAA"
    .to_owned()
    .parse::<SentryCredentials>();
  assert!(test_string.is_ok());
  let manual_creation = SentryCredentials {
    scheme: "https".to_owned(),
    key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".to_owned(),
    secret: "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY".to_owned(),
    host: Some("zzzz".to_owned()),
    project_id: "AAA".to_owned(),
  };
  assert_eq!(test_string.unwrap(), manual_creation);
}

#[test]
pub fn test_sentry_creds_parsing_failure() {
  let first_test_string = "https://sentry.io/aaa"
    .to_owned()
    .parse::<SentryCredentials>();
  let second_test_string = "https://aaaaaa@sentry.io/aaa"
    .to_owned()
    .parse::<SentryCredentials>();
  let third_test_string = "https://aaa:bbb@sentry.io/"
    .to_owned()
    .parse::<SentryCredentials>();

  assert!(first_test_string.is_err());
  assert!(second_test_string.is_err());
  assert!(third_test_string.is_err());
}
<commit_msg>fix models_test<commit_after>extern crate sentry_rs;
#[macro_use]
extern crate serde_json;

use sentry_rs::models::*;
use std::collections::HashMap;

pub fn generate_shallow_event() -> Event {
  Event {
    event_id: "event_id".to_owned(),
    message: "message".to_owned(),
    timestamp: "timestamp".to_owned(),
    level: "level".to_owned(),
    logger: "logger".to_owned(),
    platform: "platform".to_owned(),
    sdk: SDK {
      name: "sdk_name".to_owned(),
      version: "sdk_version".to_owned(),
    },
    device: Device {
      name: "device_name".to_owned(),
      version: "device_version".to_owned(),
      build: Some("device_build".to_owned()),
    },
    culprit: None,
    server_name: None,
    stacktrace: None,
    release: None,
    tags: HashMap::new(),
    environment: None,
    modules: HashMap::new(),
    extra: HashMap::new(),
    fingerprint: vec![],
  }
}

pub fn generate_full_event() -> Event {
  let mut tags = HashMap::new();
  tags.insert("tag_key".to_owned(), "tag_value".to_owned());
  tags.insert("tag_key_2".to_owned(), "tag_value_2".to_owned());
  let mut modules = HashMap::new();
  modules.insert("module_key".to_owned(), "module_value".to_owned());
  modules.insert("module_key_2".to_owned(), "module_value_2".to_owned());
  let mut extras = HashMap::new();
  extras.insert("extra_key".to_owned(), json!("extra_value"));
  extras.insert("extra_key_2".to_owned(), json!("extra_value_2"));
  Event {
    event_id: "event_id".to_owned(),
    message: "message".to_owned(),
    timestamp: "timestamp".to_owned(),
    level: "level".to_owned(),
    logger: "logger".to_owned(),
    platform: "platform".to_owned(),
    sdk: SDK {
      name: "sdk_name".to_owned(),
      version: "sdk_version".to_owned(),
    },
    device: Device {
      name: "device_name".to_owned(),
      version: "device_version".to_owned(),
      build: Some("device_build".to_owned()),
    },
    culprit: Some("culprit".to_owned()),
    server_name: Some("server_name".to_owned()),
    stacktrace: Some(vec![
      StackFrame {
        filename: "filename.stack.frame".to_owned(),
        function: "function.stack.frame".to_owned(),
        lineno: 10,
        pre_context: vec![
          "filename: \"filename.stack.frame\".to_owned()".to_owned(),
          "function: \"function.stack.frame\".to_owned()".to_owned(),
        ],
        context_line: "context_line: \"context_line\"".to_owned(),
        post_context: vec![
          "filename: \"filename.stack.frame\".to_owned()".to_owned(),
          "function: \"function.stack.frame\".to_owned()".to_owned(),
        ],
        in_app: true,
      },
      StackFrame {
        filename: "filename.2.stack.frame".to_owned(),
        function: "function.2.stack.frame".to_owned(),
        lineno: 12,
        pre_context: Vec::new(),
        context_line: "".to_owned(),
        post_context: Vec::new(),
        in_app: false,
      },
    ]),
    release: Some("Release".to_owned()),
    tags: tags,
    environment: Some("environment".to_owned()),
    modules: modules,
    extra: extras,
    fingerprint: vec!["fingerprint".to_owned()],
  }
}

#[test]
pub fn to_string_shallow_event() {
  let value = generate_shallow_event().to_string();
  assert_eq!(value, r#"{"culprit":null,"device":{"build":"device_build","name":"device_name","version":"device_version"},"event_id":"event_id","level":"level","logger":"logger","message":"message","platform":"platform","release":null,"sdk":{"name":"sdk_name","version":"sdk_version"},"server_name":null,"timestamp":"timestamp"}"#);
}

#[test]
pub fn to_string_full_event() {
  let value = generate_full_event().to_string();
  assert_eq!(value, r#"{"culprit":"culprit","device":{"build":"device_build","name":"device_name","version":"device_version"},"environment":"environment","event_id":"event_id","extra":{"extra_key":"extra_value","extra_key_2":"extra_value_2"},"fingerprint":["fingerprint"],"level":"level","logger":"logger","message":"message","modules":{"module_key":"module_value","module_key_2":"module_value_2"},"platform":"platform","release":"Release","sdk":{"name":"sdk_name","version":"sdk_version"},"server_name":"server_name","stacktrace":{"frames":[{"context_line":"context_line: \"context_line\"","filename":"filename.stack.frame","function":"function.stack.frame","in_app":true,"lineno":10,"post_context":["filename: \"filename.stack.frame\".to_owned()","function: \"function.stack.frame\".to_owned()"],"pre_context":["filename: \"filename.stack.frame\".to_owned()","function: \"function.stack.frame\".to_owned()"]},{"context_line":"","filename":"filename.2.stack.frame","function":"function.2.stack.frame","in_app":false,"lineno":12,"post_context":[],"pre_context":[]}]},"tags":{"tag_key":"tag_value","tag_key_2":"tag_value_2"},"timestamp":"timestamp"}"#);
}

#[test]
pub fn prep_string_cuts_off_string_in_quotes() {
  let test_string = "\"\"";
  let finalized_string = prep_string(test_string);

  assert_eq!(finalized_string, "");
}

#[test]
pub fn test_sentry_creds_parsing() {
  let test_string = "https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY@ZZZZ/AAA"
    .to_owned()
    .parse::<SentryCredentials>();
  assert!(test_string.is_ok());
  let manual_creation = SentryCredentials {
    scheme: "https".to_owned(),
    key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".to_owned(),
    secret: "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY".to_owned(),
    host: Some("zzzz".to_owned()),
    project_id: "AAA".to_owned(),
  };
  assert_eq!(test_string.unwrap(), manual_creation);
}

#[test]
pub fn test_sentry_creds_parsing_failure() {
  let first_test_string = "https://sentry.io/aaa"
    .to_owned()
    .parse::<SentryCredentials>();
  let second_test_string = "https://aaaaaa@sentry.io/aaa"
    .to_owned()
    .parse::<SentryCredentials>();
  let third_test_string = "https://aaa:bbb@sentry.io/"
    .to_owned()
    .parse::<SentryCredentials>();

  assert!(first_test_string.is_err());
  assert!(second_test_string.is_err());
  assert!(third_test_string.is_err());
}
<|endoftext|>


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

use crate::bundle::{self, Bundle, Exchange, Response, Uri};
use crate::prelude::*;
use cbor_event::Len;
use std::io::Write;

use cbor_event::se::Serializer;

struct CountWrite<W> {
    count: usize,
    inner: W,
}

impl<W> CountWrite<W> {
    fn new(inner: W) -> Self {
        CountWrite { count: 0, inner }
    }
}

impl<W: Write> Write for CountWrite<W> {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        match self.inner.write(buf) {
            Ok(n) => {
                self.count += n;
                Ok(n)
            },
            Err(e) => Err(e),
        }
    }
    fn flush(&mut self) -> std::io::Result<()> {
        self.inner.flush()
    }
}

pub(crate) fn encode<W: Write + Sized>(bundle: &Bundle, write: W) -> Result<()> {
    Encoder::new(CountWrite::new(write)).encode(bundle)?;
    Ok(())
}

pub(crate) fn encode_to_vec(bundle: &Bundle) -> Result<Vec<u8>> {
    let mut write = Vec::new();
    encode(bundle, &mut write)?;
    Ok(write)
}

struct Encoder<W: Write> {
    se: Serializer<W>,
}

trait Count {
    fn count(&self) -> usize;
}

impl<W: Write> Count for Serializer<CountWrite<W>> {
    fn count(&self) -> usize {
        // Use unsafe because Serializer.0 is private.
        // TODO: Avoid to use unsafe.
        let se_ptr: *const Serializer<CountWrite<W>> = self;
        let count_write_ptr = se_ptr.cast::<CountWrite<W>>();
        unsafe { (*count_write_ptr).count }
    }
}

impl<W: Write> Encoder<W> {
    fn new(write: W) -> Self {
        Encoder {
            se: Serializer::new(write),
        }
    }

    fn write_magic(&mut self) -> Result<()> {
        self.se.write_bytes(bundle::HEADER_MAGIC_BYTES)?;
        Ok(())
    }

    fn write_version(&mut self, version: &bundle::Version) -> Result<()> {
        self.se.write_bytes(version.bytes())?;
        Ok(())
    }

    fn write_primary_url(&mut self, primary_url: &Uri) -> Result<()> {
        self.se.write_text(&primary_url.to_string())?;
        Ok(())
    }
}

impl<W: Write + Sized> Encoder<CountWrite<W>> {
    fn encode(&mut self, bundle: &Bundle) -> Result<()> {
        self.se
            .write_array(Len::Len(bundle::TOP_ARRAY_LEN as u64))?;
        self.write_magic()?;
        self.write_version(&bundle.version)?;
        self.write_primary_url(&bundle.primary_url)?;

        let sections = encode_sections(bundle)?;

        let section_length_cbor = encode_section_lengths(&sections)?;
        self.se.write_bytes(section_length_cbor)?;

        self.se.write_array(Len::Len(sections.len() as u64))?;
        for section in sections {
            self.se.write_raw_bytes(&section.bytes)?;
        }

        // Write the length of bytes
        self.se.write_unsigned_integer(self.se.count() as u64 + 8)?; // 8 is the length of u64.
        Ok(())
    }
}

struct Section {
    name: &'static str,
    bytes: Vec<u8>,
}

fn encode_sections(bundle: &Bundle) -> Result<Vec<Section>> {
    let mut sections = Vec::new();

    // manifest
    if let Some(uri) = &bundle.manifest {
        let bytes = encode_manifest_section(uri)?;
        sections.push(Section {
            name: "manifest",
            bytes,
        });
    };

    // responses
    let (response_section_bytes, response_locations) = encode_response_section(&bundle.exchanges)?;

    let response_section = Section {
        name: "responses",
        bytes: response_section_bytes,
    };

    // index from responses
    let index_section = Section {
        name: "index",
        bytes: encode_index_section(&response_locations)?,
    };

    sections.push(index_section);
    sections.push(response_section);
    Ok(sections)
}

fn encode_manifest_section(url: &Uri) -> Result<Vec<u8>> {
    let mut se = Serializer::new_vec();
    se.write_text(url.to_string())?;
    Ok(se.finalize())
}

struct ResponseLocation {
    uri: Uri,
    offset: usize,
    length: usize,
}

fn encode_response_section(exchanges: &[Exchange]) -> Result<(Vec<u8>, Vec<ResponseLocation>)> {
    let mut se = Serializer::new(CountWrite::new(Vec::new()));

    se.write_array(Len::Len(exchanges.len() as u64))?;

    let mut response_locations = Vec::new();

    for exchange in exchanges {
        let offset = se.count();

        se.write_array(Len::Len(2))?;
        se.write_bytes(&encode_headers(&exchange.response)?)?;
        se.write_bytes(&exchange.response.body())?;

        response_locations.push(ResponseLocation {
            uri: exchange.request.uri().clone(),
            offset,
            length: se.count() - offset,
        });
    }

    Ok((se.finalize().inner, response_locations))
}

fn encode_index_section(response_locations: &[ResponseLocation]) -> Result<Vec<u8>> {
    // Map keys must be sorted.
    // See [3.9. Canonical CBOR](https://tools.ietf.org/html/rfc7049#section-3.9)
    let mut map = std::collections::BTreeMap::<Vec<u8>, Vec<u8>>::new();

    for response_location in response_locations {
        let mut key = Serializer::new_vec();
        key.write_text(response_location.uri.to_string())?;

        let mut value = Serializer::new_vec();
        value.write_array(Len::Len(3))?;
        // TODO: Support variants.
        value.write_bytes(b"")?;
        value.write_unsigned_integer(response_location.offset as u64)?;
        value.write_unsigned_integer(response_location.length as u64)?;

        map.insert(key.finalize(), value.finalize());
    }

    let mut se = Serializer::new_vec();
    se.write_map(Len::Len(response_locations.len() as u64))?;
    for (key, value) in map {
        se.write_raw_bytes(&key)?;
        se.write_raw_bytes(&value)?;
    }
    Ok(se.finalize())
}

fn encode_section_lengths(sections: &[Section]) -> Result<Vec<u8>> {
    let mut se = Serializer::new_vec();

    se.write_array(Len::Len((sections.len() * 2) as u64))?;
    for section in sections {
        se.write_text(section.name)?;
        se.write_unsigned_integer(section.bytes.len() as u64)?;
    }
    Ok(se.finalize())
}

fn encode_headers(response: &Response) -> Result<Vec<u8>> {
    // Map keys must be sorted.
    // See [3.9. Canonical CBOR](https://tools.ietf.org/html/rfc7049#section-3.9)
    let mut map = std::collections::BTreeMap::<Vec<u8>, Vec<u8>>::new();

    // Write status
    let mut key = Serializer::new_vec();
    key.write_bytes(b":status")?;
    let mut value = Serializer::new_vec();
    value.write_bytes(response.status().as_u16().to_string().as_bytes())?;
    map.insert(key.finalize(), value.finalize());

    // Write headers
    for (header_name, header_value) in response.headers() {
        let mut key = Serializer::new_vec();
        key.write_bytes(header_name.as_str().as_bytes())?;
        let mut value = Serializer::new_vec();
        value.write_bytes(header_value.to_str()?.as_bytes())?;
        map.insert(key.finalize(), value.finalize());
    }

    let mut se = Serializer::new_vec();
    se.write_map(Len::Len(map.len() as u64))?;
    for (key, value) in map {
        se.write_raw_bytes(&key)?;
        se.write_raw_bytes(&value)?;
    }
    Ok(se.finalize())
}
<commit_msg>Fix fmt<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::bundle::{self, Bundle, Exchange, Response, Uri};
use crate::prelude::*;
use cbor_event::Len;
use std::io::Write;

use cbor_event::se::Serializer;

struct CountWrite<W> {
    count: usize,
    inner: W,
}

impl<W> CountWrite<W> {
    fn new(inner: W) -> Self {
        CountWrite { count: 0, inner }
    }
}

impl<W: Write> Write for CountWrite<W> {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        match self.inner.write(buf) {
            Ok(n) => {
                self.count += n;
                Ok(n)
            }
            Err(e) => Err(e),
        }
    }
    fn flush(&mut self) -> std::io::Result<()> {
        self.inner.flush()
    }
}

pub(crate) fn encode<W: Write + Sized>(bundle: &Bundle, write: W) -> Result<()> {
    Encoder::new(CountWrite::new(write)).encode(bundle)?;
    Ok(())
}

pub(crate) fn encode_to_vec(bundle: &Bundle) -> Result<Vec<u8>> {
    let mut write = Vec::new();
    encode(bundle, &mut write)?;
    Ok(write)
}

struct Encoder<W: Write> {
    se: Serializer<W>,
}

trait Count {
    fn count(&self) -> usize;
}

impl<W: Write> Count for Serializer<CountWrite<W>> {
    fn count(&self) -> usize {
        // Use unsafe because Serializer.0 is private.
        // TODO: Avoid to use unsafe.
        let se_ptr: *const Serializer<CountWrite<W>> = self;
        let count_write_ptr = se_ptr.cast::<CountWrite<W>>();
        unsafe { (*count_write_ptr).count }
    }
}

impl<W: Write> Encoder<W> {
    fn new(write: W) -> Self {
        Encoder {
            se: Serializer::new(write),
        }
    }

    fn write_magic(&mut self) -> Result<()> {
        self.se.write_bytes(bundle::HEADER_MAGIC_BYTES)?;
        Ok(())
    }

    fn write_version(&mut self, version: &bundle::Version) -> Result<()> {
        self.se.write_bytes(version.bytes())?;
        Ok(())
    }

    fn write_primary_url(&mut self, primary_url: &Uri) -> Result<()> {
        self.se.write_text(&primary_url.to_string())?;
        Ok(())
    }
}

impl<W: Write + Sized> Encoder<CountWrite<W>> {
    fn encode(&mut self, bundle: &Bundle) -> Result<()> {
        self.se
            .write_array(Len::Len(bundle::TOP_ARRAY_LEN as u64))?;
        self.write_magic()?;
        self.write_version(&bundle.version)?;
        self.write_primary_url(&bundle.primary_url)?;

        let sections = encode_sections(bundle)?;

        let section_length_cbor = encode_section_lengths(&sections)?;
        self.se.write_bytes(section_length_cbor)?;

        self.se.write_array(Len::Len(sections.len() as u64))?;
        for section in sections {
            self.se.write_raw_bytes(&section.bytes)?;
        }

        // Write the length of bytes
        self.se.write_unsigned_integer(self.se.count() as u64 + 8)?; // 8 is the length of u64.
        Ok(())
    }
}

struct Section {
    name: &'static str,
    bytes: Vec<u8>,
}

fn encode_sections(bundle: &Bundle) -> Result<Vec<Section>> {
    let mut sections = Vec::new();

    // manifest
    if let Some(uri) = &bundle.manifest {
        let bytes = encode_manifest_section(uri)?;
        sections.push(Section {
            name: "manifest",
            bytes,
        });
    };

    // responses
    let (response_section_bytes, response_locations) = encode_response_section(&bundle.exchanges)?;

    let response_section = Section {
        name: "responses",
        bytes: response_section_bytes,
    };

    // index from responses
    let index_section = Section {
        name: "index",
        bytes: encode_index_section(&response_locations)?,
    };

    sections.push(index_section);
    sections.push(response_section);
    Ok(sections)
}

fn encode_manifest_section(url: &Uri) -> Result<Vec<u8>> {
    let mut se = Serializer::new_vec();
    se.write_text(url.to_string())?;
    Ok(se.finalize())
}

struct ResponseLocation {
    uri: Uri,
    offset: usize,
    length: usize,
}

fn encode_response_section(exchanges: &[Exchange]) -> Result<(Vec<u8>, Vec<ResponseLocation>)> {
    let mut se = Serializer::new(CountWrite::new(Vec::new()));

    se.write_array(Len::Len(exchanges.len() as u64))?;

    let mut response_locations = Vec::new();

    for exchange in exchanges {
        let offset = se.count();

        se.write_array(Len::Len(2))?;
        se.write_bytes(&encode_headers(&exchange.response)?)?;
        se.write_bytes(&exchange.response.body())?;

        response_locations.push(ResponseLocation {
            uri: exchange.request.uri().clone(),
            offset,
            length: se.count() - offset,
        });
    }

    Ok((se.finalize().inner, response_locations))
}

fn encode_index_section(response_locations: &[ResponseLocation]) -> Result<Vec<u8>> {
    // Map keys must be sorted.
    // See [3.9. Canonical CBOR](https://tools.ietf.org/html/rfc7049#section-3.9)
    let mut map = std::collections::BTreeMap::<Vec<u8>, Vec<u8>>::new();

    for response_location in response_locations {
        let mut key = Serializer::new_vec();
        key.write_text(response_location.uri.to_string())?;

        let mut value = Serializer::new_vec();
        value.write_array(Len::Len(3))?;
        // TODO: Support variants.
        value.write_bytes(b"")?;
        value.write_unsigned_integer(response_location.offset as u64)?;
        value.write_unsigned_integer(response_location.length as u64)?;

        map.insert(key.finalize(), value.finalize());
    }

    let mut se = Serializer::new_vec();
    se.write_map(Len::Len(response_locations.len() as u64))?;
    for (key, value) in map {
        se.write_raw_bytes(&key)?;
        se.write_raw_bytes(&value)?;
    }
    Ok(se.finalize())
}

fn encode_section_lengths(sections: &[Section]) -> Result<Vec<u8>> {
    let mut se = Serializer::new_vec();

    se.write_array(Len::Len((sections.len() * 2) as u64))?;
    for section in sections {
        se.write_text(section.name)?;
        se.write_unsigned_integer(section.bytes.len() as u64)?;
    }
    Ok(se.finalize())
}

fn encode_headers(response: &Response) -> Result<Vec<u8>> {
    // Map keys must be sorted.
    // See [3.9. Canonical CBOR](https://tools.ietf.org/html/rfc7049#section-3.9)
    let mut map = std::collections::BTreeMap::<Vec<u8>, Vec<u8>>::new();

    // Write status
    let mut key = Serializer::new_vec();
    key.write_bytes(b":status")?;
    let mut value = Serializer::new_vec();
    value.write_bytes(response.status().as_u16().to_string().as_bytes())?;
    map.insert(key.finalize(), value.finalize());

    // Write headers
    for (header_name, header_value) in response.headers() {
        let mut key = Serializer::new_vec();
        key.write_bytes(header_name.as_str().as_bytes())?;
        let mut value = Serializer::new_vec();
        value.write_bytes(header_value.to_str()?.as_bytes())?;
        map.insert(key.finalize(), value.finalize());
    }

    let mut se = Serializer::new_vec();
    se.write_map(Len::Len(map.len() as u64))?;
    for (key, value) in map {
        se.write_raw_bytes(&key)?;
        se.write_raw_bytes(&value)?;
    }
    Ok(se.finalize())
}
<|endoftext|>


<commit_before>// TryFrom is a simple and safe type conversion that may fail in a controlled way under some circumstances.
// Basically, this is the same as From. The main difference is that this should return a Result type
// instead of the target type itself.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
use std::convert::{TryInto, TryFrom};

#[derive(Debug)]
struct Person {
    name: String,
    age: usize,
}

// I AM NOT DONE
// Your task is to complete this implementation
// in order for the line `let p = Person::try_from("Mark,20")` to compile
// and return an Ok result of inner type Person.
// Please note that you'll need to parse the age component into a `usize`
// with something like `"4".parse::<usize>()`. The outcome of this needs to
// be handled appropriately.
//
// Steps:
// 1. If the length of the provided string is 0, then return an error
// 2. Split the given string on the commas present in it
// 3. Extract the first element from the split operation and use it as the name
// 4. Extract the other element from the split operation and parse it into a `usize` as the age
// If while parsing the age, something goes wrong, then return an error
// Otherwise, then return a Result of a Person object
impl TryFrom<&str> for Person {
    type Error = String;
    fn try_from(s: &str) -> Result<Self, Self::Error> {
    }
}

fn main() {
    // Use the `from` function
    let p1 = Person::try_from("Mark,20");
    // Since From is implemented for Person, we should be able to use Into
    let p2: Result<Person, _> = "Gerald,70".try_into();
    println!("{:?}", p1);
    println!("{:?}", p2);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_bad_convert() {
        // Test that John is returned when bad string is provided
        let p = Person::try_from("");
        assert!(p.is_err());
    }
    #[test]
    fn test_good_convert() {
        // Test that "Mark,20" works
        let p = Person::try_from("Mark,20");
        assert!(p.is_ok());
        let p = p.unwrap();
        assert_eq!(p.name, "Mark");
        assert_eq!(p.age, 20);
    }
    #[test]
    #[should_panic]
    fn test_panic_empty_input() {
        let p: Person = "".try_into().unwrap();
    }
    #[test]
    #[should_panic]
    fn test_panic_bad_age() {
        let p = Person::try_from("Mark,twenty").unwrap();
    }
}<commit_msg>fix: confusing comment in conversions/try_from_into.rs<commit_after>// TryFrom is a simple and safe type conversion that may fail in a controlled way under some circumstances.
// Basically, this is the same as From. The main difference is that this should return a Result type
// instead of the target type itself.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
use std::convert::{TryInto, TryFrom};

#[derive(Debug)]
struct Person {
    name: String,
    age: usize,
}

// I AM NOT DONE
// Your task is to complete this implementation
// in order for the line `let p = Person::try_from("Mark,20")` to compile
// and return an Ok result of inner type Person.
// Please note that you'll need to parse the age component into a `usize`
// with something like `"4".parse::<usize>()`. The outcome of this needs to
// be handled appropriately.
//
// Steps:
// 1. If the length of the provided string is 0, then return an error
// 2. Split the given string on the commas present in it
// 3. Extract the first element from the split operation and use it as the name
// 4. Extract the other element from the split operation and parse it into a `usize` as the age
// If while parsing the age, something goes wrong, then return an error
// Otherwise, then return a Result of a Person object
impl TryFrom<&str> for Person {
    type Error = String;
    fn try_from(s: &str) -> Result<Self, Self::Error> {
    }
}

fn main() {
    // Use the `from` function
    let p1 = Person::try_from("Mark,20");
    // Since From is implemented for Person, we should be able to use Into
    let p2: Result<Person, _> = "Gerald,70".try_into();
    println!("{:?}", p1);
    println!("{:?}", p2);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_bad_convert() {
        // Test that error is returned when bad string is provided
        let p = Person::try_from("");
        assert!(p.is_err());
    }
    #[test]
    fn test_good_convert() {
        // Test that "Mark,20" works
        let p = Person::try_from("Mark,20");
        assert!(p.is_ok());
        let p = p.unwrap();
        assert_eq!(p.name, "Mark");
        assert_eq!(p.age, 20);
    }
    #[test]
    #[should_panic]
    fn test_panic_empty_input() {
        let p: Person = "".try_into().unwrap();
    }
    #[test]
    #[should_panic]
    fn test_panic_bad_age() {
        let p = Person::try_from("Mark,twenty").unwrap();
    }
}<|endoftext|>


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

#![allow(unused_mut)]
// ignore-wasm32
// ignore-emscripten

// compile-flags: -C debug_assertions=yes

#![stable(feature = "rustc", since = "1.0.0")]
#![feature(const_fn, libc, staged_api, rustc_attrs)]
#![allow(const_err)]

extern crate libc;

use std::env;
use std::process::{Command, Stdio};

// this will panic in debug mode and overflow in release mode
#[stable(feature = "rustc", since = "1.0.0")]
#[rustc_promotable]
const fn bar() -> usize { 0 - 1 }

fn foo() {
    let _: &'static _ = &bar();
}

#[cfg(unix)]
fn check_status(status: std::process::ExitStatus)
{
    use libc;
    use std::os::unix::process::ExitStatusExt;

    assert!(status.signal() == Some(libc::SIGILL)
            || status.signal() == Some(libc::SIGABRT));
}

#[cfg(not(unix))]
fn check_status(status: std::process::ExitStatus)
{
    assert!(!status.success());
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && args[1] == "test" {
        foo();
        return;
    }

    let mut p = Command::new(&args[0])
        .stdout(Stdio::piped())
        .stdin(Stdio::piped())
        .arg("test").output().unwrap();
    check_status(p.status);
}
<commit_msg>Rollup merge of #55575 - parched:trap, r=RalfJung<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unused_mut)]
// ignore-wasm32
// ignore-emscripten

// compile-flags: -C debug_assertions=yes

#![stable(feature = "rustc", since = "1.0.0")]
#![feature(const_fn, libc, staged_api, rustc_attrs)]
#![allow(const_err)]

extern crate libc;

use std::env;
use std::process::{Command, Stdio};

// this will panic in debug mode and overflow in release mode
#[stable(feature = "rustc", since = "1.0.0")]
#[rustc_promotable]
const fn bar() -> usize { 0 - 1 }

fn foo() {
    let _: &'static _ = &bar();
}

#[cfg(unix)]
fn check_status(status: std::process::ExitStatus)
{
    use libc;
    use std::os::unix::process::ExitStatusExt;

    assert!(status.signal() == Some(libc::SIGILL)
            || status.signal() == Some(libc::SIGTRAP)
            || status.signal() == Some(libc::SIGABRT));
}

#[cfg(not(unix))]
fn check_status(status: std::process::ExitStatus)
{
    assert!(!status.success());
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && args[1] == "test" {
        foo();
        return;
    }

    let mut p = Command::new(&args[0])
        .stdout(Stdio::piped())
        .stdin(Stdio::piped())
        .arg("test").output().unwrap();
    check_status(p.status);
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![feature(plugin, core)]

#[plugin] #[no_link] extern crate rand_macros;
extern crate rand;

use rand::Rng;

#[derive_Rand]
struct Foo {
    x: u8,
    y: isize
}

#[derive_Rand]
enum Bar {
    X(char),
    Y(f64)
}

#[test]
fn smoke() {
    let mut rng = rand::XorShiftRng::new_unseeded();

    // check nothing horrible happens internally:
    for _ in 0..100 {
        let _: Foo = rng.gen();
        let _: Bar = rng.gen();
    }
}
<commit_msg>Update to rust master<commit_after>#![allow(dead_code)]
#![feature(plugin, core)]
#![plugin(rand_macros)]

extern crate rand;

use rand::Rng;

#[derive_Rand]
struct Foo {
    x: u8,
    y: isize
}

#[derive_Rand]
enum Bar {
    X(char),
    Y(f64)
}

#[test]
fn smoke() {
    let mut rng = rand::XorShiftRng::new_unseeded();

    // check nothing horrible happens internally:
    for _ in 0..100 {
        let _: Foo = rng.gen();
        let _: Bar = rng.gen();
    }
}
<|endoftext|>


<commit_before>

use app::App;
use game_object::GameObject;
use std::any::Any;

pub trait Component {
    fn receive_message(&mut self, app: &mut App, game_object: &mut GameObject, message: &Message);
}

pub trait ComponentAny: Component + Any {
    fn as_any(&self) -> &Any;
    fn as_any_mut(&mut self) -> &mut Any;
}

impl<T> ComponentAny for T
    where T: Component + Any
{
    fn as_any(&self) -> &Any {
        self
    }

    fn as_any_mut(&mut self) -> &mut Any {
        self
    }
}

pub enum Message {
    Start { key: i32 },
    Update { delta_time: f32 },
    UserMessage(Box<Any>),
}
<commit_msg>Remove some new lines<commit_after>use app::App;
use game_object::GameObject;
use std::any::Any;

pub trait Component {
    fn receive_message(&mut self, app: &mut App, game_object: &mut GameObject, message: &Message);
}

pub trait ComponentAny: Component + Any {
    fn as_any(&self) -> &Any;
    fn as_any_mut(&mut self) -> &mut Any;
}

impl<T> ComponentAny for T
    where T: Component + Any
{
    fn as_any(&self) -> &Any {
        self
    }

    fn as_any_mut(&mut self) -> &mut Any {
        self
    }
}

pub enum Message {
    Start { key: i32 },
    Update { delta_time: f32 },
    UserMessage(Box<Any>),
}
<|endoftext|>