<commit_before>use std::thread;
use std::io;
use std::io::Read;
use std::sync::mpsc;
use std::sync::mpsc::{SyncSender, Receiver, RecvError};
use std::default::Default;
use std::marker::Send;
use std::option::Option::{None, Some};
use libc::types::common::c95::c_void;
use libc::types::common::c99::*;
use libc::types::os::arch::c95::*;

enum Error {
    Mad(MadError),
    Recv(RecvError),
}

struct Decoder {
    rx: Box<Receiver<Result<Frame, MadError>>>,
}

impl Decoder {
    #[allow(dead_code)]
    fn new(reader: Box<io::Read + Send + 'static>) -> Decoder {
        Decoder {
            rx: Box::new(decode(reader)),
        }
    }

    pub fn get_frame(&self) -> Result<Frame, Error> {
        match self.rx.recv() {
            Err(e) => Err(Error::Recv(e)),
            Ok(Err(e)) => Err(Error::Mad(e)),
            Ok(Ok(frame)) => Ok(frame),
        }
    }
}

impl Iterator for Decoder {
    type Item = Result<Frame, MadError>;
    fn next(&mut self) -> Option<Result<Frame, MadError>> {
        match self.get_frame() {
            Err(Error::Recv(_)) => None,
            Err(Error::Mad(e)) => Some(Err(e)),
            Ok(frame) => Some(Ok(frame)),
        }
    }
}

#[allow(unused, improper_ctypes)]
#[link(name = "mad")]
extern {
    fn mad_decoder_init(decoder: *mut MadDecoder,
                        message: *mut c_void,
                        input_cb: extern fn(message: *mut MadMessage,
                                                  stream: &MadStream) -> MadFlow,
                        header_cb: extern fn(),
                        filter_cb: extern fn(),
                        output_cb: extern fn(message: *mut MadMessage,
                                                   header: c_int,
                                                   pcm: &MadPcm) -> MadFlow,
                        error_cb: extern fn(message: *mut MadMessage,
                                                  stream: &MadStream,
                                                  frame: c_int) -> MadFlow,
                        message_cb: extern fn());
    #[allow(dead_code)]
    fn mad_decoder_run(input: &mut MadDecoder, mode: MadDecoderMode) -> c_int;
    fn mad_stream_buffer(stream: &MadStream, buf_start: *const u8, buf_length: size_t);
}

#[allow(unused)]
#[repr(C)]
enum MadFlow {
    Continue = 0x0000,    /* continue normally */
    Stop     = 0x0010,    /* stop decoding normally */
    Break    = 0x0011,    /* stop decoding and signal an error */
    Ignore   = 0x0020    /* ignore the current frame */
}

#[allow(unused)]
#[derive(Debug, Clone)]
#[repr(C)]
pub enum MadError {
  None           = 0x0000,    /* no error */

  BufLen         = 0x0001,    /* input buffer too small (or eof) */
  BufPtr         = 0x0002,    /* invalid (null) buffer pointer */

  NoMem          = 0x0031,    /* not enough memory */

  LostSync       = 0x0101,    /* lost synchronization */
  BadLayer       = 0x0102,    /* reserved header layer value */
  BadBitRate     = 0x0103,    /* forbidden bitrate value */
  BadSampleRate  = 0x0104,    /* reserved sample frequency value */
  BadEmphasis    = 0x0105,    /* reserved emphasis value */

  BadCRC         = 0x0201,    /* crc check failed */
  BadBitAlloc    = 0x0211,    /* forbidden bit allocation value */
  BadScaleFactor = 0x0221,    /* bad scalefactor index */
  BadMode        = 0x0222,    /* bad bitrate/mode combination */
  BadFrameLen    = 0x0231,    /* bad frame length */
  BadBigValues   = 0x0232,    /* bad big_values count */
  BadBlockType   = 0x0233,    /* reserved block_type */
  BadScFSI       = 0x0234,    /* bad scalefactor selection info */
  BadDataPtr     = 0x0235,    /* bad main_data_begin pointer */
  BadPart3Len    = 0x0236,    /* bad audio data length */
  BadHuffTable   = 0x0237,    /* bad huffman table select */
  BadHuffData    = 0x0238,    /* huffman data overrun */
  BadStereo      = 0x0239,    /* incompatible block_type for js */
}

#[allow(unused)]
#[repr(C)]
struct MadBitPtr {
    byte: size_t,
    cache: uint16_t,
    left: uint16_t,
}

#[allow(unused)]
#[repr(C)]
struct MadStream {
    buffer: size_t,
    buff_end: size_t,
    skip_len: c_ulong,
    sync: c_int,
    free_rate: c_ulong,
    this_frame: size_t,
    next_frame: size_t,
    ptr: MadBitPtr,
    anc_ptr: MadBitPtr,
    anc_bitlen: c_uint,
    buffer_mdlen: size_t,
    md_len: c_uint,
    options: c_int,
    error: MadError,
}

#[allow(unused)]
#[repr(C)]
struct MadPcm {
    sample_rate: c_uint,
    channels: uint16_t,
    length: uint16_t,
    samples: [[int32_t; 1152]; 2],
}

#[allow(unused)]
struct MadMessage<'a> {
    buffer: Box<[u8; 16384]>,
    reader: &'a mut (io::Read + 'a),
    sender: &'a SyncSender<Result<Frame, MadError>>,
}

#[allow(unused)]
#[repr(C)]
enum MadDecoderMode {
    Sync = 0,
    Async
}

impl Default for MadDecoderMode {
    fn default() -> MadDecoderMode {MadDecoderMode::Sync}
}

#[derive(Default)]
#[repr(C)]
struct MadAsyncParameters {
    pid: c_long,
    ain: c_int,
    aout: c_int,
}

#[derive(Default)]
#[repr(C)]
struct MadDecoder {
    mode: MadDecoderMode,
    options: c_int,
    async: MadAsyncParameters,
    sync: size_t,
    cb_data: size_t,
    input_func: size_t,
    header_func: size_t,
    filter_func: size_t,
    output_func: size_t,
    error_func: size_t,
    message_func: size_t,
}

#[allow(unused)]
pub struct Frame {
    pub sample_rate: u32,
    pub channels: uint16_t,
    pub length: uint16_t,
    pub samples: Vec<Vec<i32>>,
}

#[allow(unused)]
extern fn empty_cb() {

}

#[allow(unused)]
extern fn input_cb (msg: *mut MadMessage, stream: &MadStream) -> MadFlow {
    unsafe {
        let buffer_size = (*msg).buffer.len();
        let next_frame_position = (stream.next_frame - stream.buffer) as usize;
        let unused_byte_count = buffer_size - next_frame_position;

        if unused_byte_count > 0 {
            for idx in 0 .. unused_byte_count {
                (*msg).buffer[idx] = (*msg).buffer[idx + next_frame_position];
            }
        }

        let mut bytes_read = None;

        if next_frame_position == 0 {
            bytes_read = Some((*msg).reader.read(&mut *(*msg).buffer).unwrap());
        } else {
            let slice = &mut (*msg).buffer[unused_byte_count .. buffer_size];
            bytes_read = Some((*msg).reader.read(slice).unwrap());
        }

        match bytes_read {
            None    => return MadFlow::Stop,
            Some(0) => return MadFlow::Stop,
            Some(n) => mad_stream_buffer(stream, (*msg).buffer.as_ptr(), n as u64),
        }
    }

    MadFlow::Continue
}

#[allow(unused)]
extern fn error_cb(msg: *mut MadMessage,
                         stream: &MadStream,
                         frame: c_int) -> MadFlow
{
    unsafe {
        let error_type = stream.error.clone();
        (*msg).sender.send(Err(error_type));
    }
    MadFlow::Continue
}

#[allow(unused)]
extern fn output_cb(msg: *mut MadMessage, header: c_int, pcm: &MadPcm) -> MadFlow {
    let mut samples: Vec<Vec<i32>> = Vec::new();
    for channel_idx in 0..pcm.channels as usize {
        let mut channel: Vec<i32> = Vec::new();
        for sample_idx in 0 .. pcm.length as usize {
            channel.push(pcm.samples[channel_idx][sample_idx]);
        }
        samples.push(channel);
    }
    let frame = Ok(Frame {sample_rate: pcm.sample_rate,
                          channels: pcm.channels,
                          length: pcm.length,
                          samples: samples});
    unsafe {
        (*msg).sender.send(frame);
    }
    MadFlow::Continue
}

fn decode<T>(mut reader: T) -> Receiver<Result<Frame, MadError>>
    where T: io::Read + Send + 'static {
    let input_buffer = Box::new([0u8; 16384]);
    let (tx, rx) = mpsc::sync_channel::<Result<Frame, MadError>>(2);
    thread::spawn(move || {
        unsafe {
            let mut message = MadMessage {
                buffer: input_buffer,
                reader: &mut reader,
                sender: &tx,
            };
            let message_ptr = &mut message as *mut _ as *mut c_void;
            let mut decoder: MadDecoder = Default::default();
            mad_decoder_init(&mut decoder,
                             message_ptr,
                             input_cb,
                             empty_cb,
                             empty_cb,
                             output_cb,
                             error_cb,
                             empty_cb);
            mad_decoder_run(&mut decoder, MadDecoderMode::Sync);
        }
    });
    rx
}

#[test]
fn data_sizes() {
    use std::mem::size_of;
    assert_eq!(size_of::<MadError>(), 4);
    assert_eq!(size_of::<MadBitPtr>(), 16);
    assert_eq!(size_of::<MadDecoder>(), 88);
    assert_eq!(size_of::<MadPcm>(), 9224);
    assert_eq!(size_of::<MadStream>(), 120);
}

#[test]
fn test_short_file() {
    use std::path::Path;
    use std::fs::File;
    let path = Path::new("test_samples/tailtoddle_lo.mp3");
    let f = File::open(&path).unwrap();
    let decoder = Decoder::new(Box::new(f));
    let mut frame_count = 0;
    let mut error_count = 0;

    for item in decoder {
        match item {
            Err(_) => error_count += 1,
            Ok(f) => {
                frame_count += 1;
                assert_eq!(f.sample_rate, 11025);
                assert_eq!(f.channels, 2);
                assert_eq!(f.length, 576);
            }
        }
    }
    assert_eq!(frame_count, 1656);
    assert_eq!(error_count, 1);
}

<commit_msg>Cleanup<commit_after>use std::thread;
use std::io;
use std::io::Read;
use std::sync::mpsc;
use std::sync::mpsc::{SyncSender, Receiver, RecvError};
use std::default::Default;
use std::marker::Send;
use std::option::Option::{None, Some};
use libc::types::common::c95::c_void;
use libc::types::common::c99::*;
use libc::types::os::arch::c95::*;
use std::cmp::min;

enum Error {
    Mad(MadError),
    Recv(RecvError),
}

struct Decoder {
    rx: Box<Receiver<Result<Frame, MadError>>>,
}

impl Decoder {
    #[allow(dead_code)]
    fn new(reader: Box<io::Read + Send + 'static>) -> Decoder {
        Decoder {
            rx: Box::new(decode(reader)),
        }
    }

    pub fn get_frame(&self) -> Result<Frame, Error> {
        match self.rx.recv() {
            Err(e) => Err(Error::Recv(e)),
            Ok(Err(e)) => Err(Error::Mad(e)),
            Ok(Ok(frame)) => Ok(frame),
        }
    }
}

impl Iterator for Decoder {
    type Item = Result<Frame, MadError>;
    fn next(&mut self) -> Option<Result<Frame, MadError>> {
        match self.get_frame() {
            Err(Error::Recv(_)) => None,
            Err(Error::Mad(e)) => Some(Err(e)),
            Ok(frame) => Some(Ok(frame)),
        }
    }
}

#[allow(unused, improper_ctypes)]
#[link(name = "mad")]
extern {
    fn mad_decoder_init(decoder: *mut MadDecoder,
                        message: *mut c_void,
                        input_cb: extern fn(message: *mut MadMessage,
                                                  stream: &MadStream) -> MadFlow,
                        header_cb: extern fn(),
                        filter_cb: extern fn(),
                        output_cb: extern fn(message: *mut MadMessage,
                                                   header: c_int,
                                                   pcm: &MadPcm) -> MadFlow,
                        error_cb: extern fn(message: *mut MadMessage,
                                                  stream: &MadStream,
                                                  frame: c_int) -> MadFlow,
                        message_cb: extern fn());
    #[allow(dead_code)]
    fn mad_decoder_run(input: &mut MadDecoder, mode: MadDecoderMode) -> c_int;
    fn mad_stream_buffer(stream: &MadStream, buf_start: *const u8, buf_length: size_t);
}

#[allow(unused)]
#[repr(C)]
enum MadFlow {
    Continue = 0x0000,    /* continue normally */
    Stop     = 0x0010,    /* stop decoding normally */
    Break    = 0x0011,    /* stop decoding and signal an error */
    Ignore   = 0x0020    /* ignore the current frame */
}

#[allow(unused)]
#[derive(Debug, Clone)]
#[repr(C)]
pub enum MadError {
  None           = 0x0000,    /* no error */

  BufLen         = 0x0001,    /* input buffer too small (or eof) */
  BufPtr         = 0x0002,    /* invalid (null) buffer pointer */

  NoMem          = 0x0031,    /* not enough memory */

  LostSync       = 0x0101,    /* lost synchronization */
  BadLayer       = 0x0102,    /* reserved header layer value */
  BadBitRate     = 0x0103,    /* forbidden bitrate value */
  BadSampleRate  = 0x0104,    /* reserved sample frequency value */
  BadEmphasis    = 0x0105,    /* reserved emphasis value */

  BadCRC         = 0x0201,    /* crc check failed */
  BadBitAlloc    = 0x0211,    /* forbidden bit allocation value */
  BadScaleFactor = 0x0221,    /* bad scalefactor index */
  BadMode        = 0x0222,    /* bad bitrate/mode combination */
  BadFrameLen    = 0x0231,    /* bad frame length */
  BadBigValues   = 0x0232,    /* bad big_values count */
  BadBlockType   = 0x0233,    /* reserved block_type */
  BadScFSI       = 0x0234,    /* bad scalefactor selection info */
  BadDataPtr     = 0x0235,    /* bad main_data_begin pointer */
  BadPart3Len    = 0x0236,    /* bad audio data length */
  BadHuffTable   = 0x0237,    /* bad huffman table select */
  BadHuffData    = 0x0238,    /* huffman data overrun */
  BadStereo      = 0x0239,    /* incompatible block_type for js */
}

#[allow(unused)]
#[repr(C)]
struct MadBitPtr {
    byte: size_t,
    cache: uint16_t,
    left: uint16_t,
}

#[allow(unused)]
#[repr(C)]
struct MadStream {
    buffer: size_t,
    buff_end: size_t,
    skip_len: c_ulong,
    sync: c_int,
    free_rate: c_ulong,
    this_frame: size_t,
    next_frame: size_t,
    ptr: MadBitPtr,
    anc_ptr: MadBitPtr,
    anc_bitlen: c_uint,
    buffer_mdlen: size_t,
    md_len: c_uint,
    options: c_int,
    error: MadError,
}

#[allow(unused)]
#[repr(C)]
struct MadPcm {
    sample_rate: c_uint,
    channels: uint16_t,
    length: uint16_t,
    samples: [[int32_t; 1152]; 2],
}

#[allow(unused)]
struct MadMessage<'a> {
    buffer: Box<[u8; 16384]>,
    reader: &'a mut (io::Read + 'a),
    sender: &'a SyncSender<Result<Frame, MadError>>,
}

#[allow(unused)]
#[repr(C)]
enum MadDecoderMode {
    Sync = 0,
    Async
}

impl Default for MadDecoderMode {
    fn default() -> MadDecoderMode {MadDecoderMode::Sync}
}

#[derive(Default)]
#[repr(C)]
struct MadAsyncParameters {
    pid: c_long,
    ain: c_int,
    aout: c_int,
}

#[derive(Default)]
#[repr(C)]
struct MadDecoder {
    mode: MadDecoderMode,
    options: c_int,
    async: MadAsyncParameters,
    sync: size_t,
    cb_data: size_t,
    input_func: size_t,
    header_func: size_t,
    filter_func: size_t,
    output_func: size_t,
    error_func: size_t,
    message_func: size_t,
}

#[allow(unused)]
pub struct Frame {
    pub sample_rate: u32,
    pub channels: u16,
    pub length: u16,
    pub samples: Vec<Vec<i32>>,
}

#[allow(unused)]
extern fn empty_cb() {

}

#[allow(unused)]
extern fn input_cb (msg: *mut MadMessage, stream: &MadStream) -> MadFlow {
    unsafe {
        let buffer_size = (*msg).buffer.len();
        let next_frame_position = (stream.next_frame - stream.buffer) as usize;
        let unused_byte_count = buffer_size - min(next_frame_position, buffer_size);

        if unused_byte_count > 0 {
            for idx in 0 .. unused_byte_count {
                (*msg).buffer[idx] = (*msg).buffer[idx + next_frame_position];
            }
        }

        let mut bytes_read = None;

        if next_frame_position == 0 {
            bytes_read = Some((*msg).reader.read(&mut *(*msg).buffer).unwrap());
        } else {
            let slice = &mut (*msg).buffer[unused_byte_count .. buffer_size];
            bytes_read = Some((*msg).reader.read(slice).unwrap());
        }

        match bytes_read {
            None    => return MadFlow::Stop,
            Some(0) => return MadFlow::Stop,
            Some(n) => {
                let fresh_byte_count = n as u64 + unused_byte_count as u64;
                mad_stream_buffer(stream, (*msg).buffer.as_ptr(), fresh_byte_count);
            }
        }
    }

    MadFlow::Continue
}

#[allow(unused)]
extern fn error_cb(msg: *mut MadMessage,
                         stream: &MadStream,
                         frame: c_int) -> MadFlow
{
    unsafe {
        let error_type = stream.error.clone();
        (*msg).sender.send(Err(error_type));
    }
    MadFlow::Continue
}

#[allow(unused)]
extern fn output_cb(msg: *mut MadMessage, header: c_int, pcm: &MadPcm) -> MadFlow {
    let mut samples: Vec<Vec<i32>> = Vec::new();
    for channel_idx in 0..pcm.channels as usize {
        let mut channel: Vec<i32> = Vec::new();
        for sample_idx in 0 .. pcm.length as usize {
            channel.push(pcm.samples[channel_idx][sample_idx]);
        }
        samples.push(channel);
    }
    let frame = Ok(Frame {sample_rate: pcm.sample_rate,
                          channels: pcm.channels as u16,
                          length: pcm.length as u16,
                          samples: samples});
    unsafe {
        (*msg).sender.send(frame);
    }
    MadFlow::Continue
}

fn decode<T>(mut reader: T) -> Receiver<Result<Frame, MadError>>
    where T: io::Read + Send + 'static {
    let input_buffer = Box::new([0u8; 16384]);
    let (tx, rx) = mpsc::sync_channel::<Result<Frame, MadError>>(2);
    thread::spawn(move || {
        unsafe {
            let mut message = MadMessage {
                buffer: input_buffer,
                reader: &mut reader,
                sender: &tx,
            };
            let message_ptr = &mut message as *mut _ as *mut c_void;
            let mut decoder: MadDecoder = Default::default();
            mad_decoder_init(&mut decoder,
                             message_ptr,
                             input_cb,
                             empty_cb,
                             empty_cb,
                             output_cb,
                             error_cb,
                             empty_cb);
            mad_decoder_run(&mut decoder, MadDecoderMode::Sync);
        }
    });
    rx
}

#[test]
fn data_sizes() {
    use std::mem::size_of;
    assert_eq!(size_of::<MadError>(), 4);
    assert_eq!(size_of::<MadBitPtr>(), 16);
    assert_eq!(size_of::<MadDecoder>(), 88);
    assert_eq!(size_of::<MadPcm>(), 9224);
    assert_eq!(size_of::<MadStream>(), 120);
}

#[test]
fn test_short_file() {
    use std::path::Path;
    use std::fs::File;
    let path = Path::new("test_samples/tailtoddle_lo.mp3");
    let f = File::open(&path).unwrap();
    let decoder = Decoder::new(Box::new(f));
    let mut frame_count = 0;
    let mut error_count = 0;

    for item in decoder {
        match item {
            Err(e) => {
                error_count += 1;
                println!("Error: {:?}", e);
            },
            Ok(f) => {
                frame_count += 1;
                assert_eq!(f.sample_rate, 11025);
                assert_eq!(f.channels, 2);
                assert_eq!(f.length, 576);
            }
        }
    }
    assert_eq!(frame_count, 1678);
    assert_eq!(error_count, 14);
}

#[test]
fn test_long_file() {
    use std::path::Path;
    use std::fs::File;
    let path = Path::new("test_samples/fs-242.mp3");
    let f = File::open(&path).unwrap();
    let decoder = Decoder::new(Box::new(f));
    let mut frame_count = 0;
    let mut error_count = 0;

    for item in decoder {
        match item {
            Err(e) => {
                error_count += 1;
                println!("Error: {:?}", e);
            },
            Ok(f) => {
                frame_count += 1;
                if frame_count % 1000 == 0 {
                    println!("Frames: {}", frame_count);
                }
                assert_eq!(f.sample_rate, 48000);
                assert_eq!(f.channels, 2);
                assert_eq!(f.length, 1152);
            }
        }
    }
    assert_eq!(frame_count, 241683);
    assert_eq!(error_count, 6);
}

<|endoftext|>


<commit_before>use interpreter::*;

enum Program {
    IntLiteral(u8)
}

fn emit(program: Program) -> Vec<u8> {
    let mut code = vec![];
    match program {
        Program::IntLiteral(n) => {
            code.push(OP_LOAD_U8);
            code.push(n);
            code.push(0);
            code.push(OP_RETURN);
            code.push(0);
        }
    }
    code
}

#[test]
fn test_emit() {
    let code1 = emit(Program::IntLiteral(37));
    assert_eq!(37, interpret(&code1));
}
<commit_msg>Add operation<commit_after>use interpreter::*;

pub enum Program {
    IntLiteral(u8),
    Binary {op: u8, left: u8, right: u8}
}

pub fn emit(program: Program) -> Vec<u8> {
    let mut code = vec![];
    match program {
        Program::IntLiteral(n) => {
            code.push(OP_LOAD_U8);
            code.push(n);
            code.push(0);
            code.push(OP_RETURN);
            code.push(0);
        },
        Program::Binary {op, left, right} => {
            code.push(OP_LOAD_U8);
            code.push(left);
            code.push(0);
            code.push(OP_LOAD_U8);
            code.push(right);
            code.push(1);
            code.push(op);
            code.push(0);
            code.push(1);
            code.push(2);
            code.push(OP_RETURN);
            code.push(2);
        }
    }
    code
}

#[test]
fn test_emit() {
    let code1 = emit(Program::IntLiteral(37));
    assert_eq!(37, interpret(&code1));

    let program = Program::Binary {
        op: OP_ADD,
        left: 73,
        right: 68
    };

    let code2 = emit(program);
    assert_eq!(141, interpret(&code2));
}
<|endoftext|>


<commit_before>use types::{Result, OscType, OscPacket, OscBundle, OscMessage};
use errors::OscError;
use utils;

use byteorder::{ByteOrder, BigEndian};
use std::iter;

pub fn encode_packet(packet: &OscPacket) -> Result<Vec<u8>> {
    match *packet {
        OscPacket::Message(ref msg) => encode_message(msg),
        OscPacket::Bundle(ref bundle) => encode_bundle(bundle),
    }
}

pub fn encode_message(msg: &OscMessage) -> Result<Vec<u8>> {
    let mut msg_bytes: Vec<u8> = Vec::new();

    msg_bytes.extend(encode_string(&msg.addr));
    let mut type_tags: Vec<char> = vec![','];
    let mut arg_bytes: Vec<u8> = Vec::new();

    if msg.args.is_some() {
        let args = msg.args.as_ref().unwrap();
        // Possible optimization: write this as iterator
        for arg in args {
            let (bytes, tag): (Option<Vec<u8>>, char) = try!(encode(arg));

            type_tags.push(tag);
            if bytes.is_some() {
                arg_bytes.extend(bytes.unwrap());
            }
        }
    }

    msg_bytes.extend(encode_string(&type_tags.iter()
                                             .cloned()
                                             .collect::<String>()));
    if arg_bytes.len() > 0 {
        msg_bytes.extend(arg_bytes);
    }
    Ok(msg_bytes)
}

fn encode_bundle(bundle: &OscBundle) -> Result<Vec<u8>> {
    Err(OscError::Unimplemented)
}

fn encode(arg: &OscType) -> Result<(Option<Vec<u8>>, char)> {
    match arg {
        &OscType::Int(ref x) => {
            let mut bytes = vec![0u8; 4];
            BigEndian::write_i32(&mut bytes, *x);
            Ok((Some(bytes), 'i'))
        }
        &OscType::Long(ref x) => {
            let mut bytes = vec![0u8; 8];
            BigEndian::write_i64(&mut bytes, *x);
            Ok((Some(bytes), 'h'))
        }
        &OscType::Float(ref x) => {
            let mut bytes = vec![0u8; 4];
            BigEndian::write_f32(&mut bytes, *x);
            Ok((Some(bytes), 'f'))
        }
        &OscType::Double(ref x) => {
            let mut bytes = vec![0u8; 8];
            BigEndian::write_f64(&mut bytes, *x);
            Ok((Some(bytes), 'd'))
        }
        &OscType::Char(ref x) => {
            let mut bytes = vec![0u8; 4];
            BigEndian::write_u32(&mut bytes, *x as u32);
            Ok((Some(bytes), 'c'))
        }
        &OscType::String(ref x) => {
            Ok((Some(encode_string(&x)), 's'))
        }
        &OscType::Blob(ref x) => {
            // let mut bytes = x.clone();
            let padded_blob_length: usize = utils::pad(x.len() as u64) as usize;
            let mut bytes = vec![0u8; 4 + padded_blob_length];
            // write length
            BigEndian::write_i32(&mut bytes[..4], x.len() as i32);
            for (i, v) in x.iter().enumerate() {
                bytes[i + 4] = *v;
            }
            Ok((Some(bytes), 'b'))
        }
        &OscType::Time(ref x, ref y) => {
            Ok((Some(encode_time_tag(*x, *y)), 't'))
        }
        &OscType::Midi(ref x) => {
            Ok((Some(vec![x.port, x.status, x.data1, x.data2]), 'm'))
        }
        &OscType::Color(ref x) => {
            Ok((Some(vec![x.red, x.green, x.blue, x.alpha]), 'r'))
        }
        &OscType::Bool(ref x) => {
            if *x {
                Ok((None, 'T'))
            } else {
                Ok((None, 'F'))
            }
        }
        &OscType::Nil => {
            Ok((None, 'N'))
        }
        &OscType::Inf => {
            Ok((None, 'I'))
        }
        _ => Err(OscError::Unimplemented),
    }
}

fn encode_string(s: &String) -> Vec<u8> {
    let mut bytes: Vec<u8> = s.as_bytes()
                              .iter()
                              .cloned()
                              .chain(iter::once(0u8))
                              .collect();
    pad_bytes(&mut bytes);
    bytes
}

fn pad_bytes(bytes: &mut Vec<u8>) {
    let padded_lengh = utils::pad(bytes.len() as u64);
    while bytes.len() < padded_lengh as usize {
        bytes.push(0u8)
    }
}

fn encode_time_tag(sec: u32, frac: u32) -> Vec<u8> {
    let mut bytes = vec![0u8; 8];
    BigEndian::write_u32(&mut bytes[..4], sec);
    BigEndian::write_u32(&mut bytes[4..], frac);
    bytes
}
<commit_msg>Implement OSC Bundle encoding<commit_after>use types::{Result, OscType, OscPacket, OscBundle, OscMessage};
use errors::OscError;
use utils;

use byteorder::{ByteOrder, BigEndian};
use std::iter;

pub fn encode_packet(packet: &OscPacket) -> Result<Vec<u8>> {
    match *packet {
        OscPacket::Message(ref msg) => encode_message(msg),
        OscPacket::Bundle(ref bundle) => encode_bundle(bundle),
    }
}

pub fn encode_message(msg: &OscMessage) -> Result<Vec<u8>> {
    let mut msg_bytes: Vec<u8> = Vec::new();

    msg_bytes.extend(encode_string(&msg.addr));
    let mut type_tags: Vec<char> = vec![','];
    let mut arg_bytes: Vec<u8> = Vec::new();

    if msg.args.is_some() {
        let args = msg.args.as_ref().unwrap();
        // Possible optimization: write this as iterator
        for arg in args {
            let (bytes, tag): (Option<Vec<u8>>, char) = try!(encode(arg));

            type_tags.push(tag);
            if bytes.is_some() {
                arg_bytes.extend(bytes.unwrap());
            }
        }
    }

    msg_bytes.extend(encode_string(&type_tags.iter()
                                             .cloned()
                                             .collect::<String>()));
    if arg_bytes.len() > 0 {
        msg_bytes.extend(arg_bytes);
    }
    Ok(msg_bytes)
}

fn encode_bundle(bundle: &OscBundle) -> Result<Vec<u8>> {
    let mut buf: Vec<u8> = Vec::new();
    buf.extend(encode_string(&"#bundle".to_string())
                   .iter()
                   .cloned());

    match try!(encode(&bundle.timetag)) {
        (Some(x), _) => {
            buf.extend(x.iter().cloned());
        },
        (None, _) => {
            return Err(OscError::BadBundle("Missing time tag!"));
        }
    }

    for packet in &bundle.content {
        match packet {
            &OscPacket::Message(ref m) =>{
                let msg = try!(encode_message(m));
                let mut msg_size = vec![0u8; 4];
                BigEndian::write_u32(&mut msg_size, msg.len() as u32);
                buf.extend(msg_size.iter().chain(msg.iter()).cloned());
            }
            &OscPacket::Bundle(ref b) => {
                let bdl = try!(encode_bundle(b));
                let mut bdl_size = vec![0u8; 4];
                BigEndian::write_u32(&mut bdl_size, bdl.len() as u32);
                buf.extend(bdl_size.iter().chain(bdl.iter()).cloned());
            }
        }
    }

    Err(OscError::Unimplemented)
}

fn encode(arg: &OscType) -> Result<(Option<Vec<u8>>, char)> {
    match arg {
        &OscType::Int(ref x) => {
            let mut bytes = vec![0u8; 4];
            BigEndian::write_i32(&mut bytes, *x);
            Ok((Some(bytes), 'i'))
        }
        &OscType::Long(ref x) => {
            let mut bytes = vec![0u8; 8];
            BigEndian::write_i64(&mut bytes, *x);
            Ok((Some(bytes), 'h'))
        }
        &OscType::Float(ref x) => {
            let mut bytes = vec![0u8; 4];
            BigEndian::write_f32(&mut bytes, *x);
            Ok((Some(bytes), 'f'))
        }
        &OscType::Double(ref x) => {
            let mut bytes = vec![0u8; 8];
            BigEndian::write_f64(&mut bytes, *x);
            Ok((Some(bytes), 'd'))
        }
        &OscType::Char(ref x) => {
            let mut bytes = vec![0u8; 4];
            BigEndian::write_u32(&mut bytes, *x as u32);
            Ok((Some(bytes), 'c'))
        }
        &OscType::String(ref x) => {
            Ok((Some(encode_string(&x)), 's'))
        }
        &OscType::Blob(ref x) => {
            // let mut bytes = x.clone();
            let padded_blob_length: usize = utils::pad(x.len() as u64) as usize;
            let mut bytes = vec![0u8; 4 + padded_blob_length];
            // write length
            BigEndian::write_i32(&mut bytes[..4], x.len() as i32);
            for (i, v) in x.iter().enumerate() {
                bytes[i + 4] = *v;
            }
            Ok((Some(bytes), 'b'))
        }
        &OscType::Time(ref x, ref y) => {
            Ok((Some(encode_time_tag(*x, *y)), 't'))
        }
        &OscType::Midi(ref x) => {
            Ok((Some(vec![x.port, x.status, x.data1, x.data2]), 'm'))
        }
        &OscType::Color(ref x) => {
            Ok((Some(vec![x.red, x.green, x.blue, x.alpha]), 'r'))
        }
        &OscType::Bool(ref x) => {
            if *x {
                Ok((None, 'T'))
            } else {
                Ok((None, 'F'))
            }
        }
        &OscType::Nil => {
            Ok((None, 'N'))
        }
        &OscType::Inf => {
            Ok((None, 'I'))
        }
        _ => Err(OscError::Unimplemented),
    }
}

fn encode_string(s: &String) -> Vec<u8> {
    let mut bytes: Vec<u8> = s.as_bytes()
                              .iter()
                              .cloned()
                              .chain(iter::once(0u8))
                              .collect();
    pad_bytes(&mut bytes);
    bytes
}

fn pad_bytes(bytes: &mut Vec<u8>) {
    let padded_lengh = utils::pad(bytes.len() as u64);
    while bytes.len() < padded_lengh as usize {
        bytes.push(0u8)
    }
}

fn encode_time_tag(sec: u32, frac: u32) -> Vec<u8> {
    let mut bytes = vec![0u8; 8];
    BigEndian::write_u32(&mut bytes[..4], sec);
    BigEndian::write_u32(&mut bytes[4..], frac);
    bytes
}
<|endoftext|>


<commit_before>#![crate_name = "uu_env"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: env (GNU coreutils) 8.13 */

#[macro_use]
extern crate clap;

use clap::{App, AppSettings, Arg};
use ini::Ini;
use std::borrow::Cow;
use std::env;
use std::io::{self, Write};
use std::process::Command;

const USAGE: &str = "env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
const AFTER_HELP: &str = "\
A mere - implies -i. If no COMMAND, print the resulting environment.
";

struct Options<'a> {
    ignore_env: bool,
    null: bool,
    files: Vec<&'a str>,
    unsets: Vec<&'a str>,
    sets: Vec<(&'a str, &'a str)>,
    program: Vec<&'a str>,
}

// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
    let stdout_raw = io::stdout();
    let mut stdout = stdout_raw.lock();
    for (n, v) in env::vars() {
        write!(stdout, "{}={}{}", n, v, if null { '\0' } else { '\n' }).unwrap();
    }
}

fn parse_name_value_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<bool, i32> {
    // is it a NAME=VALUE like opt ?
    if let Some(idx) = opt.find('=') {
        // yes, so push name, value pair
        let (name, value) = opt.split_at(idx);
        opts.sets.push((name, &value['='.len_utf8()..]));

        Ok(false)
    } else {
        // no, it's a program-like opt
        parse_program_opt(opts, opt).map(|_| true)
    }
}

fn parse_program_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<(), i32> {
    if opts.null {
        eprintln!("{}: cannot specify --null (-0) with command", crate_name!());
        eprintln!("Type \"{} --help\" for detailed information", crate_name!());
        Err(1)
    } else {
        opts.program.push(opt);
        Ok(())
    }
}

fn load_config_file(opts: &mut Options) -> Result<(), i32> {
    // NOTE: config files are parsed using an INI parser b/c it's available and compatible with ".env"-style files
    //   ... * but support for actual INI files, although working, is not intended, nor claimed
    for &file in &opts.files {
        let conf = if file == "-" {
            let stdin = io::stdin();
            let mut stdin_locked = stdin.lock();
            Ini::read_from(&mut stdin_locked)
        } else {
            Ini::load_from_file(file)
        };

        let conf = match conf {
            Ok(config) => config,
            Err(error) => {
                eprintln!("env: error: \"{}\": {}", file, error);
                return Err(1);
            }
        };

        for (_, prop) in &conf { // ignore all INI section lines (treat them as comments)
            for (key, value) in prop {
                env::set_var(key, value);
            }
        }
    }

    Ok(())
}

#[cfg(not(windows))]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    let progname = Cow::from(args[0]);
    (progname, &args[1..])
}

#[cfg(windows)]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    args.insert(0, "/d/c");
    let progname = env::var("ComSpec")
        .map(Cow::from)
        .unwrap_or_else(|| Cow::from("cmd"));

    (progname, &args[..])
}

fn create_app() -> App<'static, 'static> {
    App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .usage(USAGE)
        .after_help(AFTER_HELP)
        .setting(AppSettings::AllowExternalSubcommands)
        .arg(Arg::with_name("ignore-environment")
            .short("i")
            .long("ignore-environment")
            .help("start with an empty environment"))
        .arg(Arg::with_name("null")
            .short("0")
            .long("null")
            .help("end each output line with a 0 byte rather than a newline (only valid when \
                    printing the environment)"))
        .arg(Arg::with_name("file")
            .short("f")
            .long("file")
            .takes_value(true)
            .number_of_values(1)
            .value_name("PATH")
            .multiple(true)
            .help("read and set variables from a \".env\"-style configuration file (prior to any \
                    unset and/or set)"))
        .arg(Arg::with_name("unset")
            .short("u")
            .long("unset")
            .takes_value(true)
            .number_of_values(1)
            .value_name("NAME")
            .multiple(true)
            .help("remove variable from the environment"))
}

fn run_env(args: Vec<String>) -> Result<(), i32> {
    let app = create_app();
    let matches = app.get_matches_from(args);

    let ignore_env = matches.is_present("ignore-environment");
    let null = matches.is_present("null");
    let files = matches
        .values_of("file")
        .map(|v| v.collect())
        .unwrap_or_else(|| Vec::with_capacity(0));
    let unsets = matches
        .values_of("unset")
        .map(|v| v.collect())
        .unwrap_or_else(|| Vec::with_capacity(0));

    let mut opts = Options {
        ignore_env,
        null,
        files,
        unsets,
        sets: vec![],
        program: vec![],
    };

    // we handle the name, value pairs and the program to be executed by treating them as external
    // subcommands in clap
    if let (external, Some(matches)) = matches.subcommand() {
        let mut begin_prog_opts = false;

        if external == "-" {
            // "-" implies -i and stop parsing opts
            opts.ignore_env = true;
        } else {
            begin_prog_opts = parse_name_value_opt(&mut opts, external)?;
        }

        if let Some(mut iter) = matches.values_of("") {
            // read NAME=VALUE arguments (and up to a single program argument)
            while !begin_prog_opts {
                if let Some(opt) = iter.next() {
                    begin_prog_opts = parse_name_value_opt(&mut opts, opt)?;
                } else {
                    break;
                }
            }

            // read any leftover program arguments
            for opt in iter {
                parse_program_opt(&mut opts, opt)?;
            }
        }
    }

    // NOTE: we manually set and unset the env vars below rather than using Command::env() to more
    //       easily handle the case where no command is given

    // remove all env vars if told to ignore presets
    if opts.ignore_env {
        for (ref name, _) in env::vars() {
            env::remove_var(name);
        }
    }

    // load .env-style config file prior to those given on the command-line
    load_config_file(&mut opts)?;

    // unset specified env vars
    for name in &opts.unsets {
        env::remove_var(name);
    }

    // set specified env vars
    for &(ref name, ref val) in &opts.sets {
        // FIXME: set_var() panics if name is an empty string
        env::set_var(name, val);
    }

    if !opts.program.is_empty() {
        // we need to execute a command
        let (prog, args) = build_command(&mut opts.program);

        // FIXME: this should just use execvp() (no fork()) on Unix-like systems
        match Command::new(&*prog).args(args).status() {
            Ok(exit) => {
                if !exit.success() {
                    return Err(exit.code().unwrap());
                }
            }
            Err(ref err) if err.kind() == io::ErrorKind::NotFound => return Err(127),
            Err(_) => return Err(126),
        }
    } else {
        // no program provided, so just dump all env vars to stdout
        print_env(opts.null);
    }

    Ok(())
}

pub fn uumain(args: Vec<String>) -> i32 {
    match run_env(args) {
        Ok(()) => 0,
        Err(code) => code,
    }
}
<commit_msg>env: fix build on Windows<commit_after>#![crate_name = "uu_env"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: env (GNU coreutils) 8.13 */

#[macro_use]
extern crate clap;

use clap::{App, AppSettings, Arg};
use ini::Ini;
use std::borrow::Cow;
use std::env;
use std::io::{self, Write};
use std::process::Command;

const USAGE: &str = "env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
const AFTER_HELP: &str = "\
A mere - implies -i. If no COMMAND, print the resulting environment.
";

struct Options<'a> {
    ignore_env: bool,
    null: bool,
    files: Vec<&'a str>,
    unsets: Vec<&'a str>,
    sets: Vec<(&'a str, &'a str)>,
    program: Vec<&'a str>,
}

// print name=value env pairs on screen
// if null is true, separate pairs with a \0, \n otherwise
fn print_env(null: bool) {
    let stdout_raw = io::stdout();
    let mut stdout = stdout_raw.lock();
    for (n, v) in env::vars() {
        write!(stdout, "{}={}{}", n, v, if null { '\0' } else { '\n' }).unwrap();
    }
}

fn parse_name_value_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<bool, i32> {
    // is it a NAME=VALUE like opt ?
    if let Some(idx) = opt.find('=') {
        // yes, so push name, value pair
        let (name, value) = opt.split_at(idx);
        opts.sets.push((name, &value['='.len_utf8()..]));

        Ok(false)
    } else {
        // no, it's a program-like opt
        parse_program_opt(opts, opt).map(|_| true)
    }
}

fn parse_program_opt<'a>(opts: &mut Options<'a>, opt: &'a str) -> Result<(), i32> {
    if opts.null {
        eprintln!("{}: cannot specify --null (-0) with command", crate_name!());
        eprintln!("Type \"{} --help\" for detailed information", crate_name!());
        Err(1)
    } else {
        opts.program.push(opt);
        Ok(())
    }
}

fn load_config_file(opts: &mut Options) -> Result<(), i32> {
    // NOTE: config files are parsed using an INI parser b/c it's available and compatible with ".env"-style files
    //   ... * but support for actual INI files, although working, is not intended, nor claimed
    for &file in &opts.files {
        let conf = if file == "-" {
            let stdin = io::stdin();
            let mut stdin_locked = stdin.lock();
            Ini::read_from(&mut stdin_locked)
        } else {
            Ini::load_from_file(file)
        };

        let conf = match conf {
            Ok(config) => config,
            Err(error) => {
                eprintln!("env: error: \"{}\": {}", file, error);
                return Err(1);
            }
        };

        for (_, prop) in &conf { // ignore all INI section lines (treat them as comments)
            for (key, value) in prop {
                env::set_var(key, value);
            }
        }
    }

    Ok(())
}

#[cfg(not(windows))]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    let progname = Cow::from(args[0]);
    (progname, &args[1..])
}

#[cfg(windows)]
fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b str]) {
    args.insert(0, "/d/c");
    let progname = env::var("ComSpec")
        .map(Cow::from)
        .unwrap_or_else(|_| Cow::from("cmd"));

    (progname, &args[..])
}

fn create_app() -> App<'static, 'static> {
    App::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!())
        .about(crate_description!())
        .usage(USAGE)
        .after_help(AFTER_HELP)
        .setting(AppSettings::AllowExternalSubcommands)
        .arg(Arg::with_name("ignore-environment")
            .short("i")
            .long("ignore-environment")
            .help("start with an empty environment"))
        .arg(Arg::with_name("null")
            .short("0")
            .long("null")
            .help("end each output line with a 0 byte rather than a newline (only valid when \
                    printing the environment)"))
        .arg(Arg::with_name("file")
            .short("f")
            .long("file")
            .takes_value(true)
            .number_of_values(1)
            .value_name("PATH")
            .multiple(true)
            .help("read and set variables from a \".env\"-style configuration file (prior to any \
                    unset and/or set)"))
        .arg(Arg::with_name("unset")
            .short("u")
            .long("unset")
            .takes_value(true)
            .number_of_values(1)
            .value_name("NAME")
            .multiple(true)
            .help("remove variable from the environment"))
}

fn run_env(args: Vec<String>) -> Result<(), i32> {
    let app = create_app();
    let matches = app.get_matches_from(args);

    let ignore_env = matches.is_present("ignore-environment");
    let null = matches.is_present("null");
    let files = matches
        .values_of("file")
        .map(|v| v.collect())
        .unwrap_or_else(|| Vec::with_capacity(0));
    let unsets = matches
        .values_of("unset")
        .map(|v| v.collect())
        .unwrap_or_else(|| Vec::with_capacity(0));

    let mut opts = Options {
        ignore_env,
        null,
        files,
        unsets,
        sets: vec![],
        program: vec![],
    };

    // we handle the name, value pairs and the program to be executed by treating them as external
    // subcommands in clap
    if let (external, Some(matches)) = matches.subcommand() {
        let mut begin_prog_opts = false;

        if external == "-" {
            // "-" implies -i and stop parsing opts
            opts.ignore_env = true;
        } else {
            begin_prog_opts = parse_name_value_opt(&mut opts, external)?;
        }

        if let Some(mut iter) = matches.values_of("") {
            // read NAME=VALUE arguments (and up to a single program argument)
            while !begin_prog_opts {
                if let Some(opt) = iter.next() {
                    begin_prog_opts = parse_name_value_opt(&mut opts, opt)?;
                } else {
                    break;
                }
            }

            // read any leftover program arguments
            for opt in iter {
                parse_program_opt(&mut opts, opt)?;
            }
        }
    }

    // NOTE: we manually set and unset the env vars below rather than using Command::env() to more
    //       easily handle the case where no command is given

    // remove all env vars if told to ignore presets
    if opts.ignore_env {
        for (ref name, _) in env::vars() {
            env::remove_var(name);
        }
    }

    // load .env-style config file prior to those given on the command-line
    load_config_file(&mut opts)?;

    // unset specified env vars
    for name in &opts.unsets {
        env::remove_var(name);
    }

    // set specified env vars
    for &(ref name, ref val) in &opts.sets {
        // FIXME: set_var() panics if name is an empty string
        env::set_var(name, val);
    }

    if !opts.program.is_empty() {
        // we need to execute a command
        let (prog, args) = build_command(&mut opts.program);

        // FIXME: this should just use execvp() (no fork()) on Unix-like systems
        match Command::new(&*prog).args(args).status() {
            Ok(exit) => {
                if !exit.success() {
                    return Err(exit.code().unwrap());
                }
            }
            Err(ref err) if err.kind() == io::ErrorKind::NotFound => return Err(127),
            Err(_) => return Err(126),
        }
    } else {
        // no program provided, so just dump all env vars to stdout
        print_env(opts.null);
    }

    Ok(())
}

pub fn uumain(args: Vec<String>) -> i32 {
    match run_env(args) {
        Ok(()) => 0,
        Err(code) => code,
    }
}
<|endoftext|>


<commit_before>extern crate tar;
extern crate flate2;

use std::fs::File;
use std::io::{BufReader, Read, Write};
use std::path::Path;

use self::tar::Archive;
use self::flate2::read::GzDecoder;

macro_rules! custom_try {
    ($x:expr) => (match $x {
        Ok(x) => x,
        Err(why) => panic!("An error occured during extraction. {}", why),
    });
}

pub fn extract_tar(input: &Path, output: &Path) {
    let file = custom_try!(File::open(input));
    let mut archive = Archive::new(file);

    archive.unpack(output).ok();
}

pub fn extract_gz(input: &Path, output: &Path) {
    let file = custom_try!(File::open(input));
    let archive = custom_try!(GzDecoder::new(BufReader::new(file)));
    let mut target = custom_try!(File::create(output));

    for byte in archive.bytes() {
        target.write(&[byte.unwrap()]);
    }
}
<commit_msg>Return Result<T,E> in extract.rs<commit_after>extern crate tar;
extern crate flate2;

use std::fs::File;
use std::io::{BufReader, Read, Write};
use std::path::Path;

use self::tar::Archive;
use self::flate2::read::GzDecoder;

macro_rules! custom_try {
    ($x:expr) => (match $x {
        Ok(x) => x,
        Err(why) => return Err(format!("An error occured during extraction. {}", why)),
    });
}

pub fn extract_tar(input: &Path, output: &Path) -> Result<(), String> {
    let file = custom_try!(File::open(input));
    let mut archive = Archive::new(file);

    archive.unpack(output).ok();
}

pub fn extract_gz(input: &Path, output: &Path) -> Result<(), String> {
    let file = custom_try!(File::open(input));
    let archive = custom_try!(GzDecoder::new(BufReader::new(file)));
    let mut target = custom_try!(File::create(output));

    for byte in archive.bytes() {
        target.write(&[byte.unwrap()]);
    }
}
<|endoftext|>


<commit_before>

use chrono::*;
use std::fmt;
use timeclock::timeentry::TimeEntry;

#[derive(Clone,Debug)]
pub struct DateRecord {
    date_: Date<FixedOffset>,
    duration: f64,
    memo_: String,
}

impl DateRecord {
    pub fn from_time_entries(start: &TimeEntry, end: &TimeEntry) -> DateRecord {
        let mut temp_memo = String::new();
        if !start.memo.is_empty() {
            temp_memo.push_str(start.memo.trim());
        }
        if !end.memo.is_empty() {
            if !start.memo.is_empty() {
                temp_memo.push_str(", ");
            }
            temp_memo.push_str(end.memo.trim());
        }
        DateRecord {
            date_: start.time.date(),
            duration: (end.time - start.time).num_seconds() as f64,
            memo_: temp_memo,
        }
    }

    /// Get the duration, expressed in seconds
    pub fn seconds(&self) -> f64 {
        self.duration
    }

    #[allow(dead_code)]
    /// Get the duration, expressed in minutes
    pub fn minutes(&self) -> f64 {
        self.duration / 60.0
    }

    /// Get the duration, expressed in hours
    pub fn hours(&self) -> f64 {
        self.duration / 3600.0
    }

    pub fn date(&self) -> Date<FixedOffset> {
        self.date_
    }

    pub fn add_seconds(&mut self, secs: f64) {
        self.duration += secs;
    }

    /// Returns the memo
    pub fn memo(&self) -> &str {
        &self.memo_
    }

    /// Append &str to the memo
    pub fn append_memo(&mut self, memo: &str) {
        if !self.memo_.is_empty() && !memo.is_empty() {
            self.memo_.push_str(", ");
            self.memo_.push_str(memo);
        } else if self.memo_.is_empty() {
            self.memo_.push_str(memo);
        }
    }
}

impl fmt::Display for DateRecord {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {:.2} {}", self.date(), self.hours(), self.memo())
    }
}
<commit_msg>Simplfied DateRecord::from_time_entries()<commit_after>

use chrono::*;
use std::fmt;
use timeclock::timeentry::TimeEntry;

#[derive(Clone,Debug)]
pub struct DateRecord {
    date_: Date<FixedOffset>,
    duration: f64,
    memo_: String,
}

impl DateRecord {
    pub fn from_time_entries(start: &TimeEntry, end: &TimeEntry) -> DateRecord {
        let mut dr = DateRecord {
            date_: start.time.date(),
            duration: (end.time - start.time).num_seconds() as f64,
            memo_: String::new(),
        };
        dr.append_memo(&start.memo);
        dr.append_memo(&end.memo);
        return dr;
    }

    /// Get the duration, expressed in seconds
    pub fn seconds(&self) -> f64 {
        self.duration
    }

    #[allow(dead_code)]
    /// Get the duration, expressed in minutes
    pub fn minutes(&self) -> f64 {
        self.duration / 60.0
    }

    /// Get the duration, expressed in hours
    pub fn hours(&self) -> f64 {
        self.duration / 3600.0
    }

    pub fn date(&self) -> Date<FixedOffset> {
        self.date_
    }

    pub fn add_seconds(&mut self, secs: f64) {
        self.duration += secs;
    }

    /// Returns the memo
    pub fn memo(&self) -> &str {
        &self.memo_
    }

    /// Append &str to the memo
    pub fn append_memo(&mut self, memo: &str) {
        if !self.memo_.is_empty() && !memo.is_empty() {
            self.memo_.push_str(", ");
            self.memo_.push_str(memo);
        } else if self.memo_.is_empty() {
            self.memo_.push_str(memo);
        }
    }
}

impl fmt::Display for DateRecord {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} {:.2} {}", self.date(), self.hours(), self.memo())
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(not(feature = "gtk_3_10"), allow(unused_variables, unused_mut))]

extern crate gtk;
extern crate gdk;

use gtk::traits::*;
use gtk::signal::Inhibit;
use gdk::enums::modifier_type;

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(not(feature = "gtk_3_10"))]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        ()
    );
    ($bl:block) => {
        ()
    }
}

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(feature = "gtk_3_10")]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        $ex
    );
    ($bl:block) => {
        $bl
    }
}

fn about_clicked(_: gtk::Button) {
    let dialog = gtk::AboutDialog::new().unwrap();

    let crew = [
        "James T. Kirk",
        "Spock",
        "Leonard McCoy",
    ];

    dialog.set_authors(&crew);
    dialog.set_artists(&crew[1..]);

    println!("Authors: {:?}", dialog.get_authors());
    println!("Artists: {:?}", dialog.get_artists());
    println!("Documenters: {:?}", dialog.get_documenters());

    dialog.run();
    dialog.destroy();
}

fn main() {
    gtk::init().unwrap_or_else(|_| panic!("Failed to initialize GTK."));
    println!("Major: {}, Minor: {}", gtk::get_major_version(), gtk::get_minor_version());
    let window = gtk::Window::new(gtk::WindowType::Toplevel).unwrap();
    let frame = gtk::Frame::new(Some("Yep a frame")).unwrap();
    let _box = gtk::Box::new(gtk::Orientation::Horizontal, 10).unwrap();
    let v_box = gtk::Box::new(gtk::Orientation::Horizontal, 10).unwrap();
    let button_box = gtk::ButtonBox::new(gtk::Orientation::Horizontal).unwrap();
    let label = gtk::Label::new("Yeah a wonderful label too !").unwrap();
    let button = gtk::Button::new_with_label("Whattttt a button !").unwrap();
    let button_about = gtk::Button::new_with_label("About?").unwrap();
    let button_recent = gtk::Button::new_with_label("Choose a recent one !").unwrap();
    let button_font = gtk::Button::new_with_label("Choose a font !").unwrap();
    let app_button = gtk::Button::new_with_label("App ?").unwrap();
    let file_button = gtk::Button::new_with_label("file ?").unwrap();
    let font_button = gtk::FontButton::new().unwrap();
    let toggle_button = gtk::ToggleButton::new_with_label("Toggle Me !").unwrap();
    let check_button = gtk::CheckButton::new_with_label("Labeled check button").unwrap();
    let color_button = gtk::ColorButton::new().unwrap();
    let menu_button = with_gtk_3_10!(
        gtk::MenuButton::new().unwrap()
    );
    let link_button = gtk::LinkButton::new("www.rust-lang.org").unwrap();
    let volume_button = gtk::VolumeButton::new().unwrap();
    let entry = gtk::Entry::new().unwrap();
    let search_entry = with_gtk_3_10!(
        gtk::SearchEntry::new().unwrap()
    );
    let separator = gtk::Separator::new(gtk::Orientation::Horizontal).unwrap();
    let separator2 = gtk::Separator::new(gtk::Orientation::Horizontal).unwrap();
    let switch = gtk::Switch::new().unwrap();
    let switch2 = gtk::Switch::new().unwrap();
    let scale = gtk::Scale::new_with_range(gtk::Orientation::Horizontal, 0., 100., 1.).unwrap();
    let level_bar = with_gtk_3_10!(
        gtk::LevelBar::new_for_interval(0., 100.).unwrap()
    );
    let spin_button = gtk::SpinButton::new_with_range(0., 100., 1.).unwrap();
    let spinner = gtk::Spinner::new().unwrap();
    let image = gtk::Image::new_from_file("./test/resources/gtk.jpg").unwrap();
    let progress_bar = gtk::ProgressBar::new().unwrap();
    let arrow = gtk::Arrow::new(gtk::ArrowType::Right, gtk::ShadowType::EtchedOut).unwrap();
    let calendar = gtk::Calendar::new().unwrap();
    let info_bar = gtk::InfoBar::new().unwrap();
    let tmp_button = with_gtk_3_10!(
        gtk::Button::new_from_icon_name("edit-clear", gtk::IconSize::Button).unwrap()
    );

    println!("test");

    with_gtk_3_10! {{
        info_bar.show_close_button(true);
    }}

    /*info_bar.connect(signals::Response::new(|response_id| {
        info_bar.hide()
    }));*/ //TODO: Why does this not work?

    progress_bar.set_fraction(0.7);
    spinner.start();
    with_gtk_3_10! {{
        level_bar.set_value(37.);
    }}
    switch2.set_active(true);
    frame.set_border_width(10);
    _box.set_border_width(5);
    entry.set_placeholder("An Entry with a placeholder !");
    volume_button.set_orientation(gtk::Orientation::Horizontal);
    label.set_justify(gtk::Justification::Left);
    window.set_title("Yeah a beautiful window with gtk !");
    window.set_window_position(gtk::WindowPosition::Center);
    window.add(&frame);

    let entry_clone = entry.clone();
    button.connect_clicked(move |_| {
        let dialog = gtk::Dialog::with_buttons(
            "Hello!", None, gtk::DIALOG_MODAL,
            [("No", 0), ("Yes", 1), ("Yes!", 2)]);

        let ret = dialog.run();

        dialog.destroy();

        entry_clone.set_text(&format!("Clicked {}", ret));
    });

    // use a plain function instead of a closure
    button_about.connect_clicked(about_clicked);

    button_font.connect_clicked(|_| {
        let dialog = gtk::FontChooserDialog::new("Font chooser test", None).unwrap();

        dialog.run();
        dialog.destroy();
    });

    button_recent.connect_clicked(|_| {
        let dialog = gtk::RecentChooserDialog::new(
            "Recent chooser test", None,
            [("Ok", gtk::ResponseType::Ok), ("Cancel", gtk::ResponseType::Cancel)]);

        dialog.run();
        dialog.destroy();
    });

    file_button.connect_clicked(|_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::FileChooserDialog::new(
            "Choose a file", None, gtk::FileChooserAction::Open,
            [("Open", gtk::ResponseType::Ok), ("Cancel", gtk::ResponseType::Cancel)]);

        dialog.set_select_multiple(true);
        dialog.run();
        let files = dialog.get_filenames();
        dialog.destroy();

        println!("Files: {:?}", files);
    });

    app_button.connect_clicked(|_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::AppChooserDialog::new_for_content_type(None, gtk::DIALOG_MODAL, "sh").unwrap();

        dialog.run();
        dialog.destroy();
    });

    let entry_clone = entry.clone();
    window.connect_key_press_event(move |_, key| {
        let keyval = key.keyval;
        let keystate = key.state;

        println!("key pressed: {} / {:?}", keyval, keystate);
        println!("text: {}", entry_clone.get_text().unwrap());

        if keystate.intersects(modifier_type::ControlMask) {
            println!("You pressed Ctrl!");
        }

        Inhibit(false)
    });

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(true)
    });

    frame.add(&_box);
    with_gtk_3_10! {{
        button_box.add(&tmp_button)
    }};
    button_box.add(&button);
    button_box.add(&button_about);
    button_box.add(&button_font);
    button_box.add(&button_recent);
    button_box.add(&file_button);
    button_box.add(&app_button);
    button_box.add(&font_button);
    button_box.add(&toggle_button);
    button_box.add(&color_button);
    button_box.add(&volume_button);
    v_box.add(&switch);
    with_gtk_3_10! {{
        v_box.add(&menu_button);
    }}
    v_box.add(&switch2);
    v_box.add(&check_button);
    v_box.add(&link_button);
    v_box.add(&spin_button);
    _box.add(&info_bar);
    _box.add(&v_box);
    _box.add(&scale);
    with_gtk_3_10! {{
        _box.add(&level_bar);
    }}
    _box.add(&button_box);
    _box.add(&progress_bar);
    _box.add(&separator);
    _box.add(&label);
    _box.add(&entry);
    _box.add(&separator2);
    with_gtk_3_10! {{
        _box.add(&search_entry);
    }}
    _box.add(&spinner);
    _box.add(&image);
    _box.add(&arrow);
    _box.add(&calendar);
    _box.set_orientation(gtk::Orientation::Vertical);
    // window.set_decorated(false);
    window.set_decorated(true);
    window.show_all();
    gtk::main();
}
<commit_msg>Add a missing IconSize to i32 cast<commit_after>#![cfg_attr(not(feature = "gtk_3_10"), allow(unused_variables, unused_mut))]

extern crate gtk;
extern crate gdk;

use gtk::traits::*;
use gtk::signal::Inhibit;
use gdk::enums::modifier_type;

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(not(feature = "gtk_3_10"))]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        ()
    );
    ($bl:block) => {
        ()
    }
}

/// Expands to its argument if GTK+ 3.10 support is configured and to `()` otherwise
#[cfg(feature = "gtk_3_10")]
macro_rules! with_gtk_3_10 {
    ($ex:expr) => (
        $ex
    );
    ($bl:block) => {
        $bl
    }
}

fn about_clicked(_: gtk::Button) {
    let dialog = gtk::AboutDialog::new().unwrap();

    let crew = [
        "James T. Kirk",
        "Spock",
        "Leonard McCoy",
    ];

    dialog.set_authors(&crew);
    dialog.set_artists(&crew[1..]);

    println!("Authors: {:?}", dialog.get_authors());
    println!("Artists: {:?}", dialog.get_artists());
    println!("Documenters: {:?}", dialog.get_documenters());

    dialog.run();
    dialog.destroy();
}

fn main() {
    gtk::init().unwrap_or_else(|_| panic!("Failed to initialize GTK."));
    println!("Major: {}, Minor: {}", gtk::get_major_version(), gtk::get_minor_version());
    let window = gtk::Window::new(gtk::WindowType::Toplevel).unwrap();
    let frame = gtk::Frame::new(Some("Yep a frame")).unwrap();
    let _box = gtk::Box::new(gtk::Orientation::Horizontal, 10).unwrap();
    let v_box = gtk::Box::new(gtk::Orientation::Horizontal, 10).unwrap();
    let button_box = gtk::ButtonBox::new(gtk::Orientation::Horizontal).unwrap();
    let label = gtk::Label::new("Yeah a wonderful label too !").unwrap();
    let button = gtk::Button::new_with_label("Whattttt a button !").unwrap();
    let button_about = gtk::Button::new_with_label("About?").unwrap();
    let button_recent = gtk::Button::new_with_label("Choose a recent one !").unwrap();
    let button_font = gtk::Button::new_with_label("Choose a font !").unwrap();
    let app_button = gtk::Button::new_with_label("App ?").unwrap();
    let file_button = gtk::Button::new_with_label("file ?").unwrap();
    let font_button = gtk::FontButton::new().unwrap();
    let toggle_button = gtk::ToggleButton::new_with_label("Toggle Me !").unwrap();
    let check_button = gtk::CheckButton::new_with_label("Labeled check button").unwrap();
    let color_button = gtk::ColorButton::new().unwrap();
    let menu_button = with_gtk_3_10!(
        gtk::MenuButton::new().unwrap()
    );
    let link_button = gtk::LinkButton::new("www.rust-lang.org").unwrap();
    let volume_button = gtk::VolumeButton::new().unwrap();
    let entry = gtk::Entry::new().unwrap();
    let search_entry = with_gtk_3_10!(
        gtk::SearchEntry::new().unwrap()
    );
    let separator = gtk::Separator::new(gtk::Orientation::Horizontal).unwrap();
    let separator2 = gtk::Separator::new(gtk::Orientation::Horizontal).unwrap();
    let switch = gtk::Switch::new().unwrap();
    let switch2 = gtk::Switch::new().unwrap();
    let scale = gtk::Scale::new_with_range(gtk::Orientation::Horizontal, 0., 100., 1.).unwrap();
    let level_bar = with_gtk_3_10!(
        gtk::LevelBar::new_for_interval(0., 100.).unwrap()
    );
    let spin_button = gtk::SpinButton::new_with_range(0., 100., 1.).unwrap();
    let spinner = gtk::Spinner::new().unwrap();
    let image = gtk::Image::new_from_file("./test/resources/gtk.jpg").unwrap();
    let progress_bar = gtk::ProgressBar::new().unwrap();
    let arrow = gtk::Arrow::new(gtk::ArrowType::Right, gtk::ShadowType::EtchedOut).unwrap();
    let calendar = gtk::Calendar::new().unwrap();
    let info_bar = gtk::InfoBar::new().unwrap();
    let tmp_button = with_gtk_3_10!(
        gtk::Button::new_from_icon_name("edit-clear", gtk::IconSize::Button as i32).unwrap()
    );

    println!("test");

    with_gtk_3_10! {{
        info_bar.show_close_button(true);
    }}

    /*info_bar.connect(signals::Response::new(|response_id| {
        info_bar.hide()
    }));*/ //TODO: Why does this not work?

    progress_bar.set_fraction(0.7);
    spinner.start();
    with_gtk_3_10! {{
        level_bar.set_value(37.);
    }}
    switch2.set_active(true);
    frame.set_border_width(10);
    _box.set_border_width(5);
    entry.set_placeholder("An Entry with a placeholder !");
    volume_button.set_orientation(gtk::Orientation::Horizontal);
    label.set_justify(gtk::Justification::Left);
    window.set_title("Yeah a beautiful window with gtk !");
    window.set_window_position(gtk::WindowPosition::Center);
    window.add(&frame);

    let entry_clone = entry.clone();
    button.connect_clicked(move |_| {
        let dialog = gtk::Dialog::with_buttons(
            "Hello!", None, gtk::DIALOG_MODAL,
            [("No", 0), ("Yes", 1), ("Yes!", 2)]);

        let ret = dialog.run();

        dialog.destroy();

        entry_clone.set_text(&format!("Clicked {}", ret));
    });

    // use a plain function instead of a closure
    button_about.connect_clicked(about_clicked);

    button_font.connect_clicked(|_| {
        let dialog = gtk::FontChooserDialog::new("Font chooser test", None).unwrap();

        dialog.run();
        dialog.destroy();
    });

    button_recent.connect_clicked(|_| {
        let dialog = gtk::RecentChooserDialog::new(
            "Recent chooser test", None,
            [("Ok", gtk::ResponseType::Ok), ("Cancel", gtk::ResponseType::Cancel)]);

        dialog.run();
        dialog.destroy();
    });

    file_button.connect_clicked(|_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::FileChooserDialog::new(
            "Choose a file", None, gtk::FileChooserAction::Open,
            [("Open", gtk::ResponseType::Ok), ("Cancel", gtk::ResponseType::Cancel)]);

        dialog.set_select_multiple(true);
        dialog.run();
        let files = dialog.get_filenames();
        dialog.destroy();

        println!("Files: {:?}", files);
    });

    app_button.connect_clicked(|_| {
        //entry.set_text("Clicked!");
        let dialog = gtk::AppChooserDialog::new_for_content_type(None, gtk::DIALOG_MODAL, "sh").unwrap();

        dialog.run();
        dialog.destroy();
    });

    let entry_clone = entry.clone();
    window.connect_key_press_event(move |_, key| {
        let keyval = key.keyval;
        let keystate = key.state;

        println!("key pressed: {} / {:?}", keyval, keystate);
        println!("text: {}", entry_clone.get_text().unwrap());

        if keystate.intersects(modifier_type::ControlMask) {
            println!("You pressed Ctrl!");
        }

        Inhibit(false)
    });

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(true)
    });

    frame.add(&_box);
    with_gtk_3_10! {{
        button_box.add(&tmp_button)
    }};
    button_box.add(&button);
    button_box.add(&button_about);
    button_box.add(&button_font);
    button_box.add(&button_recent);
    button_box.add(&file_button);
    button_box.add(&app_button);
    button_box.add(&font_button);
    button_box.add(&toggle_button);
    button_box.add(&color_button);
    button_box.add(&volume_button);
    v_box.add(&switch);
    with_gtk_3_10! {{
        v_box.add(&menu_button);
    }}
    v_box.add(&switch2);
    v_box.add(&check_button);
    v_box.add(&link_button);
    v_box.add(&spin_button);
    _box.add(&info_bar);
    _box.add(&v_box);
    _box.add(&scale);
    with_gtk_3_10! {{
        _box.add(&level_bar);
    }}
    _box.add(&button_box);
    _box.add(&progress_bar);
    _box.add(&separator);
    _box.add(&label);
    _box.add(&entry);
    _box.add(&separator2);
    with_gtk_3_10! {{
        _box.add(&search_entry);
    }}
    _box.add(&spinner);
    _box.add(&image);
    _box.add(&arrow);
    _box.add(&calendar);
    _box.set_orientation(gtk::Orientation::Vertical);
    // window.set_decorated(false);
    window.set_decorated(true);
    window.show_all();
    gtk::main();
}
<|endoftext|>


<commit_before>//! Random number generation

#[allow(non_camel_case_types)] // runtime type
enum rctx {}

#[abi = "cdecl"]
extern mod rustrt {
    #[legacy_exports];
    fn rand_seed() -> ~[u8];
    fn rand_new() -> *rctx;
    fn rand_new_seeded(seed: ~[u8]) -> *rctx;
    fn rand_next(c: *rctx) -> u32;
    fn rand_free(c: *rctx);
}

/// A random number generator
pub trait Rng {
    /// Return the next random integer
    fn next() -> u32;
}

/// A value with a particular weight compared to other values
pub type Weighted<T> = { weight: uint, item: T };

/// Extension methods for random number generators
impl Rng {

    /// Return a random int
    fn gen_int() -> int {
        self.gen_i64() as int
    }

    /**
     * Return an int randomly chosen from the range [start, end),
     * failing if start >= end
     */
    fn gen_int_range(start: int, end: int) -> int {
        assert start < end;
        start + int::abs(self.gen_int() % (end - start))
    }

    /// Return a random i8
    fn gen_i8() -> i8 {
        self.next() as i8
    }

    /// Return a random i16
    fn gen_i16() -> i16 {
        self.next() as i16
    }

    /// Return a random i32
    fn gen_i32() -> i32 {
        self.next() as i32
    }

    /// Return a random i64
    fn gen_i64() -> i64 {
        (self.next() as i64 << 32) | self.next() as i64
    }

    /// Return a random uint
    fn gen_uint() -> uint {
        self.gen_u64() as uint
    }

    /**
     * Return a uint randomly chosen from the range [start, end),
     * failing if start >= end
     */
    fn gen_uint_range(start: uint, end: uint) -> uint {
        assert start < end;
        start + (self.gen_uint() % (end - start))
    }

    /// Return a random u8
    fn gen_u8() -> u8 {
        self.next() as u8
    }

    /// Return a random u16
    fn gen_u16() -> u16 {
        self.next() as u16
    }

    /// Return a random u32
    fn gen_u32() -> u32 {
        self.next()
    }

    /// Return a random u64
    fn gen_u64() -> u64 {
        (self.next() as u64 << 32) | self.next() as u64
    }

    /// Return a random float in the interval [0,1]
    fn gen_float() -> float {
        self.gen_f64() as float
    }

    /// Return a random f32 in the interval [0,1]
    fn gen_f32() -> f32 {
        self.gen_f64() as f32
    }

    /// Return a random f64 in the interval [0,1]
    fn gen_f64() -> f64 {
        let u1 = self.next() as f64;
        let u2 = self.next() as f64;
        let u3 = self.next() as f64;
        const scale : f64 = (u32::max_value as f64) + 1.0f64;
        return ((u1 / scale + u2) / scale + u3) / scale;
    }

    /// Return a random char
    fn gen_char() -> char {
        self.next() as char
    }

    /**
     * Return a char randomly chosen from chars, failing if chars is empty
     */
    fn gen_char_from(chars: ~str) -> char {
        assert !chars.is_empty();
        self.choose(str::chars(chars))
    }

    /// Return a random bool
    fn gen_bool() -> bool {
        self.next() & 1u32 == 1u32
    }

    /// Return a bool with a 1 in n chance of true
    fn gen_weighted_bool(n: uint) -> bool {
        if n == 0u {
            true
        } else {
            self.gen_uint_range(1u, n + 1u) == 1u
        }
    }

    /**
     * Return a random string of the specified length composed of A-Z,a-z,0-9
     */
    fn gen_str(len: uint) -> ~str {
        let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                       abcdefghijklmnopqrstuvwxyz\
                       0123456789";
        let mut s = ~"";
        let mut i = 0u;
        while (i < len) {
            s = s + str::from_char(self.gen_char_from(charset));
            i += 1u;
        }
        move s
    }

    /// Return a random byte string of the specified length
    fn gen_bytes(len: uint) -> ~[u8] {
        do vec::from_fn(len) |_i| {
            self.gen_u8()
        }
    }

    /// Choose an item randomly, failing if values is empty
    fn choose<T:Copy>(values: &[T]) -> T {
        self.choose_option(values).get()
    }

    /// Choose Some(item) randomly, returning None if values is empty
    fn choose_option<T:Copy>(values: &[T]) -> Option<T> {
        if values.is_empty() {
            None
        } else {
            Some(values[self.gen_uint_range(0u, values.len())])
        }
    }

    /**
     * Choose an item respecting the relative weights, failing if the sum of
     * the weights is 0
     */
    fn choose_weighted<T: Copy>(v : &[Weighted<T>]) -> T {
        self.choose_weighted_option(v).get()
    }

    /**
     * Choose Some(item) respecting the relative weights, returning none if
     * the sum of the weights is 0
     */
    fn choose_weighted_option<T:Copy>(v: &[Weighted<T>]) -> Option<T> {
        let mut total = 0u;
        for v.each |item| {
            total += item.weight;
        }
        if total == 0u {
            return None;
        }
        let chosen = self.gen_uint_range(0u, total);
        let mut so_far = 0u;
        for v.each |item| {
            so_far += item.weight;
            if so_far > chosen {
                return Some(item.item);
            }
        }
        util::unreachable();
    }

    /**
     * Return a vec containing copies of the items, in order, where
     * the weight of the item determines how many copies there are
     */
    fn weighted_vec<T:Copy>(v: &[Weighted<T>]) -> ~[T] {
        let mut r = ~[];
        for v.each |item| {
            for uint::range(0u, item.weight) |_i| {
                vec::push(r, item.item);
            }
        }
        move r
    }

    /// Shuffle a vec
    fn shuffle<T:Copy>(values: &[T]) -> ~[T] {
        let mut m = vec::from_slice(values);
        self.shuffle_mut(m);
        move m
    }

    /// Shuffle a mutable vec in place
    fn shuffle_mut<T>(values: &[mut T]) {
        let mut i = values.len();
        while i >= 2u {
            // invariant: elements with index >= i have been locked in place.
            i -= 1u;
            // lock element i in place.
            vec::swap(values, i, self.gen_uint_range(0u, i + 1u));
        }
    }

}

struct RandRes {
    c: *rctx,
    drop { rustrt::rand_free(self.c); }
}

fn RandRes(c: *rctx) -> RandRes {
    RandRes {
        c: c
    }
}

impl @RandRes: Rng {
    fn next() -> u32 { return rustrt::rand_next((*self).c); }
}

/// Create a new random seed for seeded_rng
pub fn seed() -> ~[u8] {
    rustrt::rand_seed()
}

/// Create a random number generator with a system specified seed
pub fn Rng() -> Rng {
    @RandRes(rustrt::rand_new()) as Rng
}

/**
 * Create a random number generator using the specified seed. A generator
 * constructed with a given seed will generate the same sequence of values as
 * all other generators constructed with the same seed. The seed may be any
 * length.
 */
pub fn seeded_rng(seed: ~[u8]) -> Rng {
    @RandRes(rustrt::rand_new_seeded(seed)) as Rng
}

type XorShiftState = {
    mut x: u32,
    mut y: u32,
    mut z: u32,
    mut w: u32
};

impl XorShiftState: Rng {
    fn next() -> u32 {
        let x = self.x;
        let mut t = x ^ (x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        let w = self.w;
        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
        self.w
    }
}

pub fn xorshift() -> Rng {
    // constants taken from http://en.wikipedia.org/wiki/Xorshift
    seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32)
}

pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
    {mut x: x, mut y: y, mut z: z, mut w: w} as Rng
}

#[cfg(test)]
pub mod tests {
    #[test]
    pub fn rng_seeded() {
        let seed = rand::seed();
        let ra = rand::seeded_rng(seed);
        let rb = rand::seeded_rng(seed);
        assert ra.gen_str(100u) == rb.gen_str(100u);
    }

    #[test]
    pub fn rng_seeded_custom_seed() {
        // much shorter than generated seeds which are 1024 bytes
        let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8];
        let ra = rand::seeded_rng(seed);
        let rb = rand::seeded_rng(seed);
        assert ra.gen_str(100u) == rb.gen_str(100u);
    }

    #[test]
    pub fn rng_seeded_custom_seed2() {
        let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8];
        let ra = rand::seeded_rng(seed);
        // Regression test that isaac is actually using the above vector
        let r = ra.next();
        error!("%?", r);
        assert r == 890007737u32 // on x86_64
            || r == 2935188040u32; // on x86
    }

    #[test]
    pub fn gen_int_range() {
        let r = rand::Rng();
        let a = r.gen_int_range(-3, 42);
        assert a >= -3 && a < 42;
        assert r.gen_int_range(0, 1) == 0;
        assert r.gen_int_range(-12, -11) == -12;
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    pub fn gen_int_from_fail() {
        rand::Rng().gen_int_range(5, -2);
    }

    #[test]
    pub fn gen_uint_range() {
        let r = rand::Rng();
        let a = r.gen_uint_range(3u, 42u);
        assert a >= 3u && a < 42u;
        assert r.gen_uint_range(0u, 1u) == 0u;
        assert r.gen_uint_range(12u, 13u) == 12u;
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    pub fn gen_uint_range_fail() {
        rand::Rng().gen_uint_range(5u, 2u);
    }

    #[test]
    pub fn gen_float() {
        let r = rand::Rng();
        let a = r.gen_float();
        let b = r.gen_float();
        log(debug, (a, b));
    }

    #[test]
    pub fn gen_weighted_bool() {
        let r = rand::Rng();
        assert r.gen_weighted_bool(0u) == true;
        assert r.gen_weighted_bool(1u) == true;
    }

    #[test]
    pub fn gen_str() {
        let r = rand::Rng();
        log(debug, r.gen_str(10u));
        log(debug, r.gen_str(10u));
        log(debug, r.gen_str(10u));
        assert r.gen_str(0u).len() == 0u;
        assert r.gen_str(10u).len() == 10u;
        assert r.gen_str(16u).len() == 16u;
    }

    #[test]
    pub fn gen_bytes() {
        let r = rand::Rng();
        assert r.gen_bytes(0u).len() == 0u;
        assert r.gen_bytes(10u).len() == 10u;
        assert r.gen_bytes(16u).len() == 16u;
    }

    #[test]
    pub fn choose() {
        let r = rand::Rng();
        assert r.choose([1, 1, 1]) == 1;
    }

    #[test]
    pub fn choose_option() {
        let r = rand::Rng();
        let x: Option<int> = r.choose_option([]);
        assert x.is_none();
        assert r.choose_option([1, 1, 1]) == Some(1);
    }

    #[test]
    pub fn choose_weighted() {
        let r = rand::Rng();
        assert r.choose_weighted(~[{weight: 1u, item: 42}]) == 42;
        assert r.choose_weighted(~[
            {weight: 0u, item: 42},
            {weight: 1u, item: 43}
        ]) == 43;
    }

    #[test]
    pub fn choose_weighted_option() {
        let r = rand::Rng();
        assert r.choose_weighted_option(~[{weight: 1u, item: 42}]) ==
               Some(42);
        assert r.choose_weighted_option(~[
            {weight: 0u, item: 42},
            {weight: 1u, item: 43}
        ]) == Some(43);
        let v: Option<int> = r.choose_weighted_option([]);
        assert v.is_none();
    }

    #[test]
    pub fn weighted_vec() {
        let r = rand::Rng();
        let empty: ~[int] = ~[];
        assert r.weighted_vec(~[]) == empty;
        assert r.weighted_vec(~[
            {weight: 0u, item: 3u},
            {weight: 1u, item: 2u},
            {weight: 2u, item: 1u}
        ]) == ~[2u, 1u, 1u];
    }

    #[test]
    pub fn shuffle() {
        let r = rand::Rng();
        let empty: ~[int] = ~[];
        assert r.shuffle(~[]) == empty;
        assert r.shuffle(~[1, 1, 1]) == ~[1, 1, 1];
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Demode vec::push (and convert to method)<commit_after>//! Random number generation

#[allow(non_camel_case_types)] // runtime type
enum rctx {}

#[abi = "cdecl"]
extern mod rustrt {
    #[legacy_exports];
    fn rand_seed() -> ~[u8];
    fn rand_new() -> *rctx;
    fn rand_new_seeded(seed: ~[u8]) -> *rctx;
    fn rand_next(c: *rctx) -> u32;
    fn rand_free(c: *rctx);
}

/// A random number generator
pub trait Rng {
    /// Return the next random integer
    fn next() -> u32;
}

/// A value with a particular weight compared to other values
pub type Weighted<T> = { weight: uint, item: T };

/// Extension methods for random number generators
impl Rng {

    /// Return a random int
    fn gen_int() -> int {
        self.gen_i64() as int
    }

    /**
     * Return an int randomly chosen from the range [start, end),
     * failing if start >= end
     */
    fn gen_int_range(start: int, end: int) -> int {
        assert start < end;
        start + int::abs(self.gen_int() % (end - start))
    }

    /// Return a random i8
    fn gen_i8() -> i8 {
        self.next() as i8
    }

    /// Return a random i16
    fn gen_i16() -> i16 {
        self.next() as i16
    }

    /// Return a random i32
    fn gen_i32() -> i32 {
        self.next() as i32
    }

    /// Return a random i64
    fn gen_i64() -> i64 {
        (self.next() as i64 << 32) | self.next() as i64
    }

    /// Return a random uint
    fn gen_uint() -> uint {
        self.gen_u64() as uint
    }

    /**
     * Return a uint randomly chosen from the range [start, end),
     * failing if start >= end
     */
    fn gen_uint_range(start: uint, end: uint) -> uint {
        assert start < end;
        start + (self.gen_uint() % (end - start))
    }

    /// Return a random u8
    fn gen_u8() -> u8 {
        self.next() as u8
    }

    /// Return a random u16
    fn gen_u16() -> u16 {
        self.next() as u16
    }

    /// Return a random u32
    fn gen_u32() -> u32 {
        self.next()
    }

    /// Return a random u64
    fn gen_u64() -> u64 {
        (self.next() as u64 << 32) | self.next() as u64
    }

    /// Return a random float in the interval [0,1]
    fn gen_float() -> float {
        self.gen_f64() as float
    }

    /// Return a random f32 in the interval [0,1]
    fn gen_f32() -> f32 {
        self.gen_f64() as f32
    }

    /// Return a random f64 in the interval [0,1]
    fn gen_f64() -> f64 {
        let u1 = self.next() as f64;
        let u2 = self.next() as f64;
        let u3 = self.next() as f64;
        const scale : f64 = (u32::max_value as f64) + 1.0f64;
        return ((u1 / scale + u2) / scale + u3) / scale;
    }

    /// Return a random char
    fn gen_char() -> char {
        self.next() as char
    }

    /**
     * Return a char randomly chosen from chars, failing if chars is empty
     */
    fn gen_char_from(chars: ~str) -> char {
        assert !chars.is_empty();
        self.choose(str::chars(chars))
    }

    /// Return a random bool
    fn gen_bool() -> bool {
        self.next() & 1u32 == 1u32
    }

    /// Return a bool with a 1 in n chance of true
    fn gen_weighted_bool(n: uint) -> bool {
        if n == 0u {
            true
        } else {
            self.gen_uint_range(1u, n + 1u) == 1u
        }
    }

    /**
     * Return a random string of the specified length composed of A-Z,a-z,0-9
     */
    fn gen_str(len: uint) -> ~str {
        let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                       abcdefghijklmnopqrstuvwxyz\
                       0123456789";
        let mut s = ~"";
        let mut i = 0u;
        while (i < len) {
            s = s + str::from_char(self.gen_char_from(charset));
            i += 1u;
        }
        move s
    }

    /// Return a random byte string of the specified length
    fn gen_bytes(len: uint) -> ~[u8] {
        do vec::from_fn(len) |_i| {
            self.gen_u8()
        }
    }

    /// Choose an item randomly, failing if values is empty
    fn choose<T:Copy>(values: &[T]) -> T {
        self.choose_option(values).get()
    }

    /// Choose Some(item) randomly, returning None if values is empty
    fn choose_option<T:Copy>(values: &[T]) -> Option<T> {
        if values.is_empty() {
            None
        } else {
            Some(values[self.gen_uint_range(0u, values.len())])
        }
    }

    /**
     * Choose an item respecting the relative weights, failing if the sum of
     * the weights is 0
     */
    fn choose_weighted<T: Copy>(v : &[Weighted<T>]) -> T {
        self.choose_weighted_option(v).get()
    }

    /**
     * Choose Some(item) respecting the relative weights, returning none if
     * the sum of the weights is 0
     */
    fn choose_weighted_option<T:Copy>(v: &[Weighted<T>]) -> Option<T> {
        let mut total = 0u;
        for v.each |item| {
            total += item.weight;
        }
        if total == 0u {
            return None;
        }
        let chosen = self.gen_uint_range(0u, total);
        let mut so_far = 0u;
        for v.each |item| {
            so_far += item.weight;
            if so_far > chosen {
                return Some(item.item);
            }
        }
        util::unreachable();
    }

    /**
     * Return a vec containing copies of the items, in order, where
     * the weight of the item determines how many copies there are
     */
    fn weighted_vec<T:Copy>(v: &[Weighted<T>]) -> ~[T] {
        let mut r = ~[];
        for v.each |item| {
            for uint::range(0u, item.weight) |_i| {
                r.push(item.item);
            }
        }
        move r
    }

    /// Shuffle a vec
    fn shuffle<T:Copy>(values: &[T]) -> ~[T] {
        let mut m = vec::from_slice(values);
        self.shuffle_mut(m);
        move m
    }

    /// Shuffle a mutable vec in place
    fn shuffle_mut<T>(values: &[mut T]) {
        let mut i = values.len();
        while i >= 2u {
            // invariant: elements with index >= i have been locked in place.
            i -= 1u;
            // lock element i in place.
            vec::swap(values, i, self.gen_uint_range(0u, i + 1u));
        }
    }

}

struct RandRes {
    c: *rctx,
    drop { rustrt::rand_free(self.c); }
}

fn RandRes(c: *rctx) -> RandRes {
    RandRes {
        c: c
    }
}

impl @RandRes: Rng {
    fn next() -> u32 { return rustrt::rand_next((*self).c); }
}

/// Create a new random seed for seeded_rng
pub fn seed() -> ~[u8] {
    rustrt::rand_seed()
}

/// Create a random number generator with a system specified seed
pub fn Rng() -> Rng {
    @RandRes(rustrt::rand_new()) as Rng
}

/**
 * Create a random number generator using the specified seed. A generator
 * constructed with a given seed will generate the same sequence of values as
 * all other generators constructed with the same seed. The seed may be any
 * length.
 */
pub fn seeded_rng(seed: ~[u8]) -> Rng {
    @RandRes(rustrt::rand_new_seeded(seed)) as Rng
}

type XorShiftState = {
    mut x: u32,
    mut y: u32,
    mut z: u32,
    mut w: u32
};

impl XorShiftState: Rng {
    fn next() -> u32 {
        let x = self.x;
        let mut t = x ^ (x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        let w = self.w;
        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
        self.w
    }
}

pub fn xorshift() -> Rng {
    // constants taken from http://en.wikipedia.org/wiki/Xorshift
    seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32)
}

pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
    {mut x: x, mut y: y, mut z: z, mut w: w} as Rng
}

#[cfg(test)]
pub mod tests {
    #[test]
    pub fn rng_seeded() {
        let seed = rand::seed();
        let ra = rand::seeded_rng(seed);
        let rb = rand::seeded_rng(seed);
        assert ra.gen_str(100u) == rb.gen_str(100u);
    }

    #[test]
    pub fn rng_seeded_custom_seed() {
        // much shorter than generated seeds which are 1024 bytes
        let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8];
        let ra = rand::seeded_rng(seed);
        let rb = rand::seeded_rng(seed);
        assert ra.gen_str(100u) == rb.gen_str(100u);
    }

    #[test]
    pub fn rng_seeded_custom_seed2() {
        let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8];
        let ra = rand::seeded_rng(seed);
        // Regression test that isaac is actually using the above vector
        let r = ra.next();
        error!("%?", r);
        assert r == 890007737u32 // on x86_64
            || r == 2935188040u32; // on x86
    }

    #[test]
    pub fn gen_int_range() {
        let r = rand::Rng();
        let a = r.gen_int_range(-3, 42);
        assert a >= -3 && a < 42;
        assert r.gen_int_range(0, 1) == 0;
        assert r.gen_int_range(-12, -11) == -12;
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    pub fn gen_int_from_fail() {
        rand::Rng().gen_int_range(5, -2);
    }

    #[test]
    pub fn gen_uint_range() {
        let r = rand::Rng();
        let a = r.gen_uint_range(3u, 42u);
        assert a >= 3u && a < 42u;
        assert r.gen_uint_range(0u, 1u) == 0u;
        assert r.gen_uint_range(12u, 13u) == 12u;
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    pub fn gen_uint_range_fail() {
        rand::Rng().gen_uint_range(5u, 2u);
    }

    #[test]
    pub fn gen_float() {
        let r = rand::Rng();
        let a = r.gen_float();
        let b = r.gen_float();
        log(debug, (a, b));
    }

    #[test]
    pub fn gen_weighted_bool() {
        let r = rand::Rng();
        assert r.gen_weighted_bool(0u) == true;
        assert r.gen_weighted_bool(1u) == true;
    }

    #[test]
    pub fn gen_str() {
        let r = rand::Rng();
        log(debug, r.gen_str(10u));
        log(debug, r.gen_str(10u));
        log(debug, r.gen_str(10u));
        assert r.gen_str(0u).len() == 0u;
        assert r.gen_str(10u).len() == 10u;
        assert r.gen_str(16u).len() == 16u;
    }

    #[test]
    pub fn gen_bytes() {
        let r = rand::Rng();
        assert r.gen_bytes(0u).len() == 0u;
        assert r.gen_bytes(10u).len() == 10u;
        assert r.gen_bytes(16u).len() == 16u;
    }

    #[test]
    pub fn choose() {
        let r = rand::Rng();
        assert r.choose([1, 1, 1]) == 1;
    }

    #[test]
    pub fn choose_option() {
        let r = rand::Rng();
        let x: Option<int> = r.choose_option([]);
        assert x.is_none();
        assert r.choose_option([1, 1, 1]) == Some(1);
    }

    #[test]
    pub fn choose_weighted() {
        let r = rand::Rng();
        assert r.choose_weighted(~[{weight: 1u, item: 42}]) == 42;
        assert r.choose_weighted(~[
            {weight: 0u, item: 42},
            {weight: 1u, item: 43}
        ]) == 43;
    }

    #[test]
    pub fn choose_weighted_option() {
        let r = rand::Rng();
        assert r.choose_weighted_option(~[{weight: 1u, item: 42}]) ==
               Some(42);
        assert r.choose_weighted_option(~[
            {weight: 0u, item: 42},
            {weight: 1u, item: 43}
        ]) == Some(43);
        let v: Option<int> = r.choose_weighted_option([]);
        assert v.is_none();
    }

    #[test]
    pub fn weighted_vec() {
        let r = rand::Rng();
        let empty: ~[int] = ~[];
        assert r.weighted_vec(~[]) == empty;
        assert r.weighted_vec(~[
            {weight: 0u, item: 3u},
            {weight: 1u, item: 2u},
            {weight: 2u, item: 1u}
        ]) == ~[2u, 1u, 1u];
    }

    #[test]
    pub fn shuffle() {
        let r = rand::Rng();
        let empty: ~[int] = ~[];
        assert r.shuffle(~[]) == empty;
        assert r.shuffle(~[1, 1, 1]) == ~[1, 1, 1];
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>use core::ops;

macro_rules! hty {
    ($ty:ty) => {
        <$ty as LargeInt>::HighHalf
    }
}

macro_rules! os_ty {
    ($ty:ty) => {
        <$ty as Int>::OtherSign
    }
}

pub mod mul;
pub mod sdiv;
pub mod shift;
pub mod udiv;

/// Trait for some basic operations on integers
pub trait Int:
    Copy +
    PartialEq  +
    ops::Shl<u32, Output = Self> +
    ops::Shr<u32, Output = Self> +
    ops::BitOr<Output = Self> +
    // ops::BitAnd<Output = Self> +
{
    /// Type with the same width but other signedness
    type OtherSign: Int;
    /// Unsigned version of Self
    type UnsignedInt: Int;

    /// Returns the bitwidth of the int type
    fn bits() -> u32;

    /// Returns the zero representation of this number
    fn zero() -> Self;

    /// Extracts the sign from self and returns a tuple.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let i = -25_i32;
    /// let (sign, u) = i.extract_sign();
    /// assert_eq!(sign, true);
    /// assert_eq!(u, 25_u32);
    /// ```
    fn extract_sign(self) -> (bool, Self::UnsignedInt);

    /// Convert to a signed representation
    fn unsigned(self) -> Self::UnsignedInt;
}

macro_rules! int_impl {
    ($ity:ty, $uty:ty, $bits:expr) => {
        impl Int for $uty {
            type OtherSign = $ity;
            type UnsignedInt = $uty;

            fn zero() -> Self {
                0
            }

            fn bits() -> u32 {
                $bits
            }

            fn extract_sign(self) -> (bool, $uty) {
                (false, self)
            }

            fn unsigned(self) -> $uty {
                self
            }
        }

        impl Int for $ity {
            type OtherSign = $uty;
            type UnsignedInt = $uty;

            fn bits() -> u32 {
                $bits
            }

            fn zero() -> Self {
                0
            }

            fn extract_sign(self) -> (bool, $uty) {
                if self < 0 {
                    (true, (!(self as $uty)).wrapping_add(1))
                } else {
                    (false, self as $uty)
                }
            }

            fn unsigned(self) -> $uty {
                self as $uty
            }
        }
    }
}

int_impl!(i32, u32, 32);
int_impl!(i64, u64, 64);
int_impl!(i128, u128, 128);

/// Trait to convert an integer to/from smaller parts
pub trait LargeInt: Int {
    type LowHalf: Int;
    type HighHalf: Int;

    fn low(self) -> Self::LowHalf;
    fn high(self) -> Self::HighHalf;
    fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
}

macro_rules! large_int {
    ($ty:ty, $tylow:ty, $tyhigh:ty, $halfbits:expr) => {
        impl LargeInt for $ty {
            type LowHalf = $tylow;
            type HighHalf = $tyhigh;

            fn low(self) -> $tylow {
                self as $tylow
            }
            fn high(self) -> $tyhigh {
                (self >> $halfbits) as $tyhigh
            }
            fn from_parts(low: $tylow, high: $tyhigh) -> $ty {
                low as $ty | ((high as $ty) << $halfbits)
            }
        }
    }
}

large_int!(u64, u32, u32, 32);
large_int!(i64, u32, i32, 32);
large_int!(u128, u64, u64, 64);
large_int!(i128, u64, i64, 64);
<commit_msg>Remove executable bit from mod.rs<commit_after>use core::ops;

macro_rules! hty {
    ($ty:ty) => {
        <$ty as LargeInt>::HighHalf
    }
}

macro_rules! os_ty {
    ($ty:ty) => {
        <$ty as Int>::OtherSign
    }
}

pub mod mul;
pub mod sdiv;
pub mod shift;
pub mod udiv;

/// Trait for some basic operations on integers
pub trait Int:
    Copy +
    PartialEq  +
    ops::Shl<u32, Output = Self> +
    ops::Shr<u32, Output = Self> +
    ops::BitOr<Output = Self> +
    // ops::BitAnd<Output = Self> +
{
    /// Type with the same width but other signedness
    type OtherSign: Int;
    /// Unsigned version of Self
    type UnsignedInt: Int;

    /// Returns the bitwidth of the int type
    fn bits() -> u32;

    /// Returns the zero representation of this number
    fn zero() -> Self;

    /// Extracts the sign from self and returns a tuple.
    ///
    /// # Examples
    ///
    /// ```rust,ignore
    /// let i = -25_i32;
    /// let (sign, u) = i.extract_sign();
    /// assert_eq!(sign, true);
    /// assert_eq!(u, 25_u32);
    /// ```
    fn extract_sign(self) -> (bool, Self::UnsignedInt);

    /// Convert to a signed representation
    fn unsigned(self) -> Self::UnsignedInt;
}

macro_rules! int_impl {
    ($ity:ty, $uty:ty, $bits:expr) => {
        impl Int for $uty {
            type OtherSign = $ity;
            type UnsignedInt = $uty;

            fn zero() -> Self {
                0
            }

            fn bits() -> u32 {
                $bits
            }

            fn extract_sign(self) -> (bool, $uty) {
                (false, self)
            }

            fn unsigned(self) -> $uty {
                self
            }
        }

        impl Int for $ity {
            type OtherSign = $uty;
            type UnsignedInt = $uty;

            fn bits() -> u32 {
                $bits
            }

            fn zero() -> Self {
                0
            }

            fn extract_sign(self) -> (bool, $uty) {
                if self < 0 {
                    (true, (!(self as $uty)).wrapping_add(1))
                } else {
                    (false, self as $uty)
                }
            }

            fn unsigned(self) -> $uty {
                self as $uty
            }
        }
    }
}

int_impl!(i32, u32, 32);
int_impl!(i64, u64, 64);
int_impl!(i128, u128, 128);

/// Trait to convert an integer to/from smaller parts
pub trait LargeInt: Int {
    type LowHalf: Int;
    type HighHalf: Int;

    fn low(self) -> Self::LowHalf;
    fn high(self) -> Self::HighHalf;
    fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
}

macro_rules! large_int {
    ($ty:ty, $tylow:ty, $tyhigh:ty, $halfbits:expr) => {
        impl LargeInt for $ty {
            type LowHalf = $tylow;
            type HighHalf = $tyhigh;

            fn low(self) -> $tylow {
                self as $tylow
            }
            fn high(self) -> $tyhigh {
                (self >> $halfbits) as $tyhigh
            }
            fn from_parts(low: $tylow, high: $tyhigh) -> $ty {
                low as $ty | ((high as $ty) << $halfbits)
            }
        }
    }
}

large_int!(u64, u32, u32, 32);
large_int!(i64, u32, i32, 32);
large_int!(u128, u64, u64, 64);
large_int!(i128, u64, i64, 64);
<|endoftext|>