<commit_before>// FIXME: Needs additional cocoa setup on OS X. rust-cocoa should probably just
// be a dependency
use sdl::*;
use start;

#[test]
pub fn test_everything() {
    do start::start {
        start_tests();
    }
}

fn start_tests() {
    assert init(~[InitVideo, InitTimer]) == true;
    run_tests(~[
        general::test_was_init,
        // FIXME: Busted, segfault
        //general::test_set_error,
        //general::test_error,
        //general::test_clear_error,
        test_video::test_set_video_mode,
        test_video::test_with_lock,
        // FIXME: Doesn't work when called from a directory that
        // doesn't contain the test image file
        //test_video::test_blit,
        test_event::test_poll_event_none,
        // FIXME: This test is interactive
        //test_event::test_keyboard,

    ]);

    quit();
}

fn run_tests(tests: &[extern fn()]) {
    for tests.each |test| {
        (*test)();
    }
}

mod general {

    use sdl::*;

    pub fn test_was_init() {
        assert vec::contains(~[InitTimer], &InitTimer);
    }

    pub fn test_set_error() {
        set_error(~"test");
        assert get_error() == ~"test";
    }

    pub fn test_error() {
        clear_error();
        assert str::is_empty(get_error());
        error(ENoMem);
        assert (str::is_empty(get_error()) == false);
    }

    pub fn test_clear_error() {
        set_error(~"test");
        clear_error();
        assert str::is_empty(get_error());
    }
}

mod test_event {

    use event;
    use video;
    use keyboard;

    pub fn test_poll_event_none() {
        assert event::poll_event() == event::NoEvent;
    }

    pub fn test_keyboard() {
        io::println(~"press a key in the window");
        let maybe_surface = video::set_video_mode(320, 200, 32,
            ~[video::SWSurface], ~[video::DoubleBuf, video::Resizable]);

        match maybe_surface {
            result::Ok(_) => {
                let mut keydown = false;
                let mut keyup = false;
                while !keydown || !keyup {
                    match event::poll_event() {
                      event::KeyUpEvent(keyboard) => {
                          keyup = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::KeyDownEvent(keyboard) => {
                          keydown = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::QuitEvent => fail!(~"Explicit quit"),
                      _ => { }
                    }
                }
            }
            result::Err(_) => {
                fail!(~"Failed to set video mode");
            }
        }
    }
}

mod test_video {

    pub fn test_set_video_mode() {
        let maybe_surface = ::video::set_video_mode(320, 200, 32,
            ~[::video::HWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_surface);
    }

    pub fn test_blit() {
        let maybe_screen = ::video::set_video_mode(320, 200, 32,
            ~[::video::SWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_screen);

        match maybe_screen {
            result::Ok(screen) => {
                // FIXME: We need to load this from the crate instead of
                // off the filesystem
                let maybe_image = match ::video::load_bmp(~"rust-logo-128x128-blk.bmp") {
                    result::Ok(raw_image) => {
                        raw_image.display_format()
                    },
                    result::Err(err) => result::Err(err)
                };

                assert result::is_ok(&maybe_image);

                match maybe_image {
                    result::Ok(image) => {
                        for iter::repeat(1u) || {
                            screen.blit_surface(image);
                            screen.flip();
                            ::event::poll_event();
                        };
                    },
                    result::Err(_) => ()
                };
            },
            result::Err(_) => ()
        };
    }

    pub fn test_with_lock() {
        let maybe_screen = ::video::set_video_mode(320, 200, 32,
            ~[::video::SWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_screen);

        match maybe_screen {
            result::Ok(screen) => {
                //Set all the pixels to green
                do screen.with_lock |raw| {
                    for uint::range(0, raw.len() / 4) |idx| {
                        let true_idx = idx * 4;
                        raw[true_idx] = 0;
                        raw[true_idx + 1] = 0xFF;
                        raw[true_idx + 2] = 0;
                        raw[true_idx + 3] = 0xFF;
                    }
                }
                //Then check that it makes sense
                do screen.with_lock |raw| {
                    //Check the 23rd pixel
                    let start = 23 * 4;
                    assert raw[start] == 0;
                    assert raw[start + 1] == 0xFF;
                    assert raw[start + 2] == 0;
                    assert raw[start + 3] == 0xFF;
                }
            },
            result::Err(message) => fail!(message)
        };
    }
}
<commit_msg>Switched fail! out for the more correct die!<commit_after>// FIXME: Needs additional cocoa setup on OS X. rust-cocoa should probably just
// be a dependency
use sdl::*;
use start;

#[test]
pub fn test_everything() {
    do start::start {
        start_tests();
    }
}

fn start_tests() {
    assert init(~[InitVideo, InitTimer]) == true;
    run_tests(~[
        general::test_was_init,
        // FIXME: Busted, segfault
        //general::test_set_error,
        //general::test_error,
        //general::test_clear_error,
        test_video::test_set_video_mode,
        test_video::test_with_lock,
        // FIXME: Doesn't work when called from a directory that
        // doesn't contain the test image file
        //test_video::test_blit,
        test_event::test_poll_event_none,
        // FIXME: This test is interactive
        //test_event::test_keyboard,

    ]);

    quit();
}

fn run_tests(tests: &[extern fn()]) {
    for tests.each |test| {
        (*test)();
    }
}

mod general {

    use sdl::*;

    pub fn test_was_init() {
        assert vec::contains(~[InitTimer], &InitTimer);
    }

    pub fn test_set_error() {
        set_error(~"test");
        assert get_error() == ~"test";
    }

    pub fn test_error() {
        clear_error();
        assert str::is_empty(get_error());
        error(ENoMem);
        assert (str::is_empty(get_error()) == false);
    }

    pub fn test_clear_error() {
        set_error(~"test");
        clear_error();
        assert str::is_empty(get_error());
    }
}

mod test_event {

    use event;
    use video;
    use keyboard;

    pub fn test_poll_event_none() {
        assert event::poll_event() == event::NoEvent;
    }

    pub fn test_keyboard() {
        io::println(~"press a key in the window");
        let maybe_surface = video::set_video_mode(320, 200, 32,
            ~[video::SWSurface], ~[video::DoubleBuf, video::Resizable]);

        match maybe_surface {
            result::Ok(_) => {
                let mut keydown = false;
                let mut keyup = false;
                while !keydown || !keyup {
                    match event::poll_event() {
                      event::KeyUpEvent(keyboard) => {
                          keyup = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::KeyDownEvent(keyboard) => {
                          keydown = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::QuitEvent => die!(~"Explicit quit"),
                      _ => { }
                    }
                }
            }
            result::Err(_) => {
                die!(~"Failed to set video mode");
            }
        }
    }
}

mod test_video {

    pub fn test_set_video_mode() {
        let maybe_surface = ::video::set_video_mode(320, 200, 32,
            ~[::video::HWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_surface);
    }

    pub fn test_blit() {
        let maybe_screen = ::video::set_video_mode(320, 200, 32,
            ~[::video::SWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_screen);

        match maybe_screen {
            result::Ok(screen) => {
                // FIXME: We need to load this from the crate instead of
                // off the filesystem
                let maybe_image = match ::video::load_bmp(~"rust-logo-128x128-blk.bmp") {
                    result::Ok(raw_image) => {
                        raw_image.display_format()
                    },
                    result::Err(err) => result::Err(err)
                };

                assert result::is_ok(&maybe_image);

                match maybe_image {
                    result::Ok(image) => {
                        for iter::repeat(1u) || {
                            screen.blit_surface(image);
                            screen.flip();
                            ::event::poll_event();
                        };
                    },
                    result::Err(_) => ()
                };
            },
            result::Err(_) => ()
        };
    }

    pub fn test_with_lock() {
        let maybe_screen = ::video::set_video_mode(320, 200, 32,
            ~[::video::SWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_screen);

        match maybe_screen {
            result::Ok(screen) => {
                //Set all the pixels to green
                do screen.with_lock |raw| {
                    for uint::range(0, raw.len() / 4) |idx| {
                        let true_idx = idx * 4;
                        raw[true_idx] = 0;
                        raw[true_idx + 1] = 0xFF;
                        raw[true_idx + 2] = 0;
                        raw[true_idx + 3] = 0xFF;
                    }
                }
                //Then check that it makes sense
                do screen.with_lock |raw| {
                    //Check the 23rd pixel
                    let start = 23 * 4;
                    assert raw[start] == 0;
                    assert raw[start + 1] == 0xFF;
                    assert raw[start + 2] == 0;
                    assert raw[start + 3] == 0xFF;
                }
            },
            result::Err(message) => die!(message)
        };
    }
}
<|endoftext|>


<commit_before>#[feature(globs)];

extern mod OpenCL;
use OpenCL::CL::*;
use OpenCL::CL::ll::*;
use std::ptr;
use std::sys;
use std::libc;
use std::vec;
use std::cast;

#[fixed_stack_segment]
fn main()
{
	unsafe
	{
		let ker =
				~"__kernel void vector_add(__global const long *A, __global const long *B, __global long *C) {
					int i = get_global_id(0);
					C[i] = A[i] + B[i];
				 }";

		let sz: uint = 8;
		let vec_a = ~[0, 1, 2, -3, 4, 5, 6, 7];
		let vec_b = ~[-7, -6, 5, -4, 0, -1, 2, 3];

		let mut r: cl_int = 1;

		let platforms = OpenCL::hl::get_platforms();

		let device = OpenCL::hl::get_devices(platforms[0], CL_DEVICE_TYPE_ALL)[0];
		println(fmt!("%?", device.name()));

		let ctx = OpenCL::hl::create_context(device);

		let cque = OpenCL::hl::create_command_queue(&ctx, device);
		//let cque = comque.cqueue;
		let A = OpenCL::hl::create_buffer(&ctx, sz*8, CL_MEM_READ_ONLY);
		let B = OpenCL::hl::create_buffer(&ctx, sz*8, CL_MEM_READ_ONLY);
		let C = OpenCL::hl::create_buffer(&ctx, sz*8, CL_MEM_WRITE_ONLY);

		// Copy lists into memory buffers
		clEnqueueWriteBuffer(cque.cqueue,
			A.buffer,
			CL_TRUE,
			0,
			(sz * sys::size_of::<int>()) as libc::size_t,
			vec::raw::to_ptr(vec_a) as *libc::c_void,
			0,
			ptr::null(),
			ptr::null());

		clEnqueueWriteBuffer(cque.cqueue,
			B.buffer,
			CL_TRUE,
			0,
			(sz * sys::size_of::<int>()) as libc::size_t,
			vec::raw::to_ptr(vec_b) as *libc::c_void,
			0,
			ptr::null(),
			ptr::null());

		// Create a program from the kernel and build it
		do ker.as_imm_buf |bytes, len|
		{
			let prog = clCreateProgramWithSource(ctx.ctx,
						1,
						ptr::to_unsafe_ptr(&(bytes as *libc::c_char)),
						ptr::to_unsafe_ptr(&(len as libc::size_t)),
						ptr::to_unsafe_ptr(&r));

			r = clBuildProgram(prog,
				1,
				ptr::to_unsafe_ptr(&device.id),
				ptr::null(),
				cast::transmute(ptr::null::<&fn ()>()),
				ptr::null());

			if r != CL_SUCCESS as cl_int
			{ println(fmt!("Unable to build program [%?].", r)); }

			// Create the OpenCL kernel
			do "vector_add".as_imm_buf() |bytes, _|
			{
				let kernel = clCreateKernel(prog, bytes as *libc::c_char, ptr::to_unsafe_ptr(&r));
				if r != CL_SUCCESS as cl_int
				{ println(fmt!("Unable to create kernel [%?].", r)); }

				// Set the arguments of the kernel
				clSetKernelArg(kernel,
					0,
					sys::size_of::<cl_mem>() as libc::size_t,
					ptr::to_unsafe_ptr(&A.buffer)	 as *libc::c_void);

				clSetKernelArg(kernel,
					1,
					sys::size_of::<cl_mem>() as libc::size_t,
					ptr::to_unsafe_ptr(&B.buffer)	 as *libc::c_void);

				clSetKernelArg(kernel,
					2,
					sys::size_of::<cl_mem>() as libc::size_t,
					ptr::to_unsafe_ptr(&C.buffer)	 as *libc::c_void);

				let global_item_size: libc::size_t = (sz * sys::size_of::<int>()) as libc::size_t;
				let local_item_size:	libc::size_t = 64;

				// Execute the OpenCL kernel on the list
				clEnqueueNDRangeKernel(cque.cqueue,
					kernel,
					1,
					ptr::null(),
					ptr::to_unsafe_ptr(&global_item_size),
					ptr::to_unsafe_ptr(&local_item_size),
					0,
					ptr::null(),
					ptr::null());

				// Now let's read back the new list from the device
				let buf = libc::malloc((sz * sys::size_of::<int>()) as libc::size_t);

				clEnqueueReadBuffer(cque.cqueue,
					C.buffer,
					CL_TRUE,
					0,
					(sz * sys::size_of::<int>()) as libc::size_t,
					buf,
					0,
					ptr::null(),
					ptr::null());

				let vec_c = vec::from_buf(buf as *int, sz);

				libc::free(buf);

				println(fmt!("	%?", vec_a));
				println(fmt!("+	%?", vec_b));
				println(fmt!("=	%?", vec_c));

				// Cleanup
//				clReleaseKernel(kernel);
//				clReleaseProgram(prog);
			}
		}
	}
}
<commit_msg>oooh now that's pretty<commit_after>extern mod OpenCL;

use std::sys;

fn main()
{
		let ker =
				~"__kernel void vector_add(__global const long *A, __global const long *B, __global long *C) {
					int i = get_global_id(0);
					C[i] = A[i] + B[i];
				 }";

		let vec_a: &[int] = &[0, 1, 2, -3, 4, 5, 6, 7];
		let vec_b: &[int] = &[-7, -6, 5, -4, 0, -1, 2, 3];

		let ctx = OpenCL::hl::create_compute_context();

		println(fmt!("%?", ctx.device_name()));

		let A = ctx.create_buffer(vec_a.len() * sys::size_of_val(&vec_a[0]), OpenCL::CL::CL_MEM_READ_ONLY);
		let B = ctx.create_buffer(vec_a.len() * sys::size_of_val(&vec_a[0]), OpenCL::CL::CL_MEM_READ_ONLY);
		let C = ctx.create_buffer(vec_a.len() * sys::size_of_val(&vec_a[0]), OpenCL::CL::CL_MEM_WRITE_ONLY);

		A.write(ctx, vec_a);
		B.write(ctx, vec_b);

		let program = ctx.create_program_from_source(ker);

		program.build(ctx.device);

		let kernel = program.create_kernel("vector_add");

		println(fmt!("%?", program));

		kernel.set_arg(0, &A);
		kernel.set_arg(1, &B);
		kernel.set_arg(2, &C);

		OpenCL::hl::enqueue_nd_range_kernel(&ctx.q, &kernel, 1, 0, 64, 64);

		let vec_c: ~[int] = C.read(ctx);

		println(fmt!("	%?", vec_a));
		println(fmt!("+	%?", vec_b));
		println(fmt!("=	%?", vec_c));
}
<|endoftext|>


<commit_before>//! We wrap all messages in something called a tagged encoding. This encoding wraps over
//! the underlying representation to something we can read without actually decoding the raw data
//! that contains the real broadcast.

use tagged::{TaggedValue, TagType};
use result::{GossipResult, GossipError, io_err, TaggedDecodingError};
use std::io::Reader;

/// A single bytecode traditionally represented as hexadecimal. The specification has a number of
/// default bytecodes that are defined.
pub struct Bytecode(int);

/// A macro to easily create bytecodes.
macro_rules! def(
    ($inp:ident $sp:expr) => (
        pub static $inp: int = $sp;
    );
)

def!(TAG_START 0xCB)
def!(PRIORITY_CACHE_PACKED_START 0x80)
def!(PRIORITY_CACHE_PACKED_END 0xA0)
def!(STRUCT_CACHE_PACKED_START 0xA0)
def!(STRUCT_CACHE_PACKED_END 0xB0)
def!(LONG_ARRAY 0xB0)
def!(DOUBLE_ARRAY 0xB1)
def!(BOOLEAN_ARRAY 0xB2)
def!(INT_ARRAY 0xB3)
def!(FLOAT_ARRAY 0xB4)
def!(OBJECT_ARRAY 0xB5)
def!(MAP 0xC0)
def!(SET 0xC1)
def!(UUID 0xC3)
def!(REGEX 0xC4)
def!(URI 0xC5)
def!(BIGINT 0xC6)
def!(BIGDEC 0xC7)
def!(INST 0xC8)
def!(SYM 0xC9)
def!(KEY 0xCA)
def!(GET_PRIORITY_CACHE 0xCC)
def!(PUT_PRIORITY_CACHE 0xCD)
def!(PRECACHE 0xCE)
def!(FOOTER 0xCF)
def!(FOOTER_MAGIC 0xCFCFCFCF)
def!(BYTES_PACKED_LENGTH_START 0xD0)
def!(BYTES_PACKED_LENGTH_END 0xD8)
def!(BYTES_CHUNK 0xD8)
def!(BYTES 0xD9)
def!(STRING_PACKED_LENGTH_START 0xDA)
def!(STRING_PACKED_LENGTH_END 0xE2)
def!(STRING_CHUNK 0xE2)
def!(STRING 0xE3)
def!(LIST_PACKED_LENGTH_START 0xE4)
def!(LIST_PACKED_LENGTH_END 0xEC)
def!(LIST 0xEC)
def!(BEGIN_CLOSED_LIST 0xED)
def!(BEGIN_OPEN_LIST 0xEE)
def!(STRUCTTYPE 0xEF)
def!(STRUCT 0xF0)
def!(META 0xF1)
def!(ANY 0xF4)
def!(TRUE 0xF5)
def!(FALSE 0xF6)
def!(NULL 0xF7)
def!(INT 0xF8)
def!(FLOAT 0xF9)
def!(DOUBLE 0xFA)
def!(DOUBLE_0 0xFB)
def!(DOUBLE_1 0xFC)
def!(END_COLLECTION 0xFD)
def!(RESET_CACHES 0xFE)
def!(INT_PACKED_1_START 0xFF)
def!(INT_PACKED_1_END 0x40)
def!(INT_PACKED_2_START 0x40)
def!(INT_PACKED_2_ZERO 0x50)
def!(INT_PACKED_2_END 0x60)
def!(INT_PACKED_3_START 0x60)
def!(INT_PACKED_3_ZERO 0x68)
def!(INT_PACKED_3_END 0x70)
def!(INT_PACKED_4_START 0x70)
def!(INT_PACKED_4_ZERO 0x72)
def!(INT_PACKED_4_END 0x74)
def!(INT_PACKED_5_START 0x74)
def!(INT_PACKED_5_ZERO 0x76)
def!(INT_PACKED_5_END 0x78)
def!(INT_PACKED_6_START 0x78)
def!(INT_PACKED_6_ZERO 0x7A)
def!(INT_PACKED_6_END 0x7C)
def!(INT_PACKED_7_START 0x7C)
def!(INT_PACKED_7_ZERO 0x7E)
def!(INT_PACKED_7_END 0x80)

pub fn to_tag<'a>(reader: &'a mut Reader) -> GossipResult<TaggedValue> {

    // Read in the first byte to check whether it's a tagged encoding.
    if try!(reader.read_byte().map_err(io_err)) != 0xCB {
        return Err(GossipError::new("Expected the beginning marker of a tagged encoding.", TaggedDecodingError));
    }

    // Get the type of tag.
    let ty = try!(reader.read_byte().map_err(io_err));

    // Get the length of the tag type.
    let length = try!(reader.read_be_u32().map_err(io_err));
    let buf    = try!(reader.read_exact(length as uint).map_err(io_err));

    let bytes_length = try!(reader.read_be_u32().map_err(io_err));
    let mut bytes = try!(reader.read_exact(bytes_length as uint).map_err(io_err));

    let tag = TaggedValue::new(match ty {
        // String.
        0xE3 => {
            box try!(String::from_utf8(buf).map_err(|e| GossipError::new("Malformed utf8 string.", TaggedDecodingError))) as Box<TagType>
        },
        _ => {
            box 0i as Box<TagType>
        }
    }, bytes);

    Ok(tag)
}
<commit_msg>Length test is passing. Implemented u32 -> Vec<u8> function<commit_after>//! We wrap all messages in something called a tagged encoding. This encoding wraps over
//! the underlying representation to something we can read without actually decoding the raw data
//! that contains the real broadcast.

use tagged::{TaggedValue, TagType};
use result::{GossipResult, GossipError, io_err, TaggedDecodingError};
use std::io::Reader;

/// A single bytecode traditionally represented as hexadecimal. The specification has a number of
/// default bytecodes that are defined.
pub struct Bytecode(int);

/// A macro to easily create bytecodes.
macro_rules! def(
    ($inp:ident $sp:expr) => (
        pub static $inp: int = $sp;
    );
)

def!(TAG_START 0xCB)
def!(PRIORITY_CACHE_PACKED_START 0x80)
def!(PRIORITY_CACHE_PACKED_END 0xA0)
def!(STRUCT_CACHE_PACKED_START 0xA0)
def!(STRUCT_CACHE_PACKED_END 0xB0)
def!(LONG_ARRAY 0xB0)
def!(DOUBLE_ARRAY 0xB1)
def!(BOOLEAN_ARRAY 0xB2)
def!(INT_ARRAY 0xB3)
def!(FLOAT_ARRAY 0xB4)
def!(OBJECT_ARRAY 0xB5)
def!(MAP 0xC0)
def!(SET 0xC1)
def!(UUID 0xC3)
def!(REGEX 0xC4)
def!(URI 0xC5)
def!(BIGINT 0xC6)
def!(BIGDEC 0xC7)
def!(INST 0xC8)
def!(SYM 0xC9)
def!(KEY 0xCA)
def!(GET_PRIORITY_CACHE 0xCC)
def!(PUT_PRIORITY_CACHE 0xCD)
def!(PRECACHE 0xCE)
def!(FOOTER 0xCF)
def!(FOOTER_MAGIC 0xCFCFCFCF)
def!(BYTES_PACKED_LENGTH_START 0xD0)
def!(BYTES_PACKED_LENGTH_END 0xD8)
def!(BYTES_CHUNK 0xD8)
def!(BYTES 0xD9)
def!(STRING_PACKED_LENGTH_START 0xDA)
def!(STRING_PACKED_LENGTH_END 0xE2)
def!(STRING_CHUNK 0xE2)
def!(STRING 0xE3)
def!(LIST_PACKED_LENGTH_START 0xE4)
def!(LIST_PACKED_LENGTH_END 0xEC)
def!(LIST 0xEC)
def!(BEGIN_CLOSED_LIST 0xED)
def!(BEGIN_OPEN_LIST 0xEE)
def!(STRUCTTYPE 0xEF)
def!(STRUCT 0xF0)
def!(META 0xF1)
def!(ANY 0xF4)
def!(TRUE 0xF5)
def!(FALSE 0xF6)
def!(NULL 0xF7)
def!(INT 0xF8)
def!(FLOAT 0xF9)
def!(DOUBLE 0xFA)
def!(DOUBLE_0 0xFB)
def!(DOUBLE_1 0xFC)
def!(END_COLLECTION 0xFD)
def!(RESET_CACHES 0xFE)
def!(INT_PACKED_1_START 0xFF)
def!(INT_PACKED_1_END 0x40)
def!(INT_PACKED_2_START 0x40)
def!(INT_PACKED_2_ZERO 0x50)
def!(INT_PACKED_2_END 0x60)
def!(INT_PACKED_3_START 0x60)
def!(INT_PACKED_3_ZERO 0x68)
def!(INT_PACKED_3_END 0x70)
def!(INT_PACKED_4_START 0x70)
def!(INT_PACKED_4_ZERO 0x72)
def!(INT_PACKED_4_END 0x74)
def!(INT_PACKED_5_START 0x74)
def!(INT_PACKED_5_ZERO 0x76)
def!(INT_PACKED_5_END 0x78)
def!(INT_PACKED_6_START 0x78)
def!(INT_PACKED_6_ZERO 0x7A)
def!(INT_PACKED_6_END 0x7C)
def!(INT_PACKED_7_START 0x7C)
def!(INT_PACKED_7_ZERO 0x7E)
def!(INT_PACKED_7_END 0x80)

pub fn to_tag<'a>(reader: &'a mut Reader) -> GossipResult<TaggedValue> {

    // Read in the first byte to check whether it's a tagged encoding.
    if try!(reader.read_byte().map_err(io_err)) != 0xCB {
        return Err(GossipError::new("Expected the beginning marker of a tagged encoding.", TaggedDecodingError));
    }

    // Get the type of tag.
    let ty = try!(reader.read_byte().map_err(io_err));

    // Get the length of the tag type.
    let length = try!(reader.read_be_u32().map_err(io_err));
    println!("length: {}", length);
    let buf    = try!(reader.read_exact(length as uint).map_err(io_err));

    let bytes_length = try!(reader.read_be_u32().map_err(io_err));
    let mut bytes = try!(reader.read_exact(bytes_length as uint).map_err(io_err));

    let tag = TaggedValue::new(match ty {
        // String.
        0xE3 => {
            box try!(String::from_utf8(buf).map_err(|e| GossipError::new("Malformed utf8 string.", TaggedDecodingError))) as Box<TagType>
        },
        _ => {
            return Err(GossipError::new("Malformed tag encoding. Expected a proper type tag.", TaggedDecodingError));
        }
    }, bytes);

    Ok(tag)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::MemReader;

    fn num_to_bytes(v: &mut Vec<u8>, num: u32) {
        v.push((num >> 24) as u8);
        v.push((num >> 16) as u8);
        v.push((num >> 8) as u8);
        v.push((num >> 0) as u8);
    }

    #[test]
    fn invalid_encoding_byte() {
        let mut mem = MemReader::new(vec![0u8]);
        match to_tag(&mut mem) {
            Ok(tag) => fail!("Expected a failure case."),
            Err(_) => {}
        }
    }

    #[test]
    fn invalid_tag_type() {
        let mut mem = MemReader::new(vec![0xCB]);
        match to_tag(&mut mem) {
            Ok(tag) => fail!("Expected to fail because of an invalid tag type."),
            Err(_) => {}
        }
    }

    #[test]
    fn should_have_length() {
        let l: u32 = 3;
        let mut v = vec![0xCB, 0xE3];

        num_to_bytes(&mut v, l);
        v.push(102);
        v.push(111);
        v.push(111);
        num_to_bytes(&mut v, 0);

        let mut mem = MemReader::new(v);
        match to_tag(&mut mem) {
            Ok(tag) => {},
            Err(err) => fail!("Error: {}", err)
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::RefCell;

use std::vec::Vec;
use autograd::variable::*;
use RcMut;

pub struct Function<T> {
    saved_variables: Vec<SavedVariable<T>>,
    next_functions: Vec<(RcMut<Function<T>>, usize)>,
}
impl<T> Function<T> {
    pub fn new() -> Self {
        Function {
            saved_variables: Vec::new(),
            next_functions: Vec::new(),
        }
    }
}

pub trait FuncIntf<T> {
    fn delegate(&mut self) -> &mut Function<T>;
    fn forward(&mut self, input: &mut Vec<Variable<T>>) -> Vec<Variable<T>>;
    fn f(&mut self, mut input: &mut Vec<Variable<T>>) -> Vec<Variable<T>> {
        {
            let f = self.delegate();
        }
        // do start graph stuff with f
        let v = self.forward(&mut input);
        // do end graph stuff
        v
    }
}
<commit_msg>add backward and use type alias<commit_after>use std::rc::Rc;
use std::cell::RefCell;

use std::vec::Vec;
use autograd::variable::*;
use RcMut;

pub struct Function<T> {
    saved_variables: Vec<SavedVariable<T>>,
    next_functions: Vec<(RcMut<Function<T>>, usize)>,
}
impl<T> Function<T> {
    pub fn new() -> Self {
        Function {
            saved_variables: Vec::new(),
            next_functions: Vec::new(),
        }
    }
}

pub trait FuncIntf<T> {
    fn delegate(&mut self) -> &mut Function<T>;
    fn forward(&mut self, input: &mut VarList<T>) -> VarList<T>;
    fn backward(&mut self, input: &mut VarList<T>) -> VarList<T>;
    fn f(&mut self, mut input: &mut VarList<T>) -> VarList<T> {
        {
            // do start graph stuff with f
            let f = self.delegate();
        }
        let v = self.forward(&mut input);
        // do end graph stuff
        v
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Bernoulli_numbers

// Relative speeds of optimized, iterator, and naive implementations is
// 625:25:1

#![feature(test)]

extern crate num;
extern crate test;

use num::bigint::{BigInt, ToBigInt};
use num::rational::{BigRational};
use std::cmp::max;
use std::env;
use std::ops::{Mul, Sub};
use std::process;

struct Bn {
    value: BigRational,
    index: i32
}

struct Context {
    bigone_const: BigInt,
    a: Vec<BigRational>,
    index: i32              // Counter for iterator implementation
}

impl Context {
    pub fn new() -> Context {
        let bigone = 1.to_bigint().unwrap();
        let a_vec: Vec<BigRational> = vec![];
        Context {
            bigone_const: bigone,
            a: a_vec,
            index: -1
        }
    }
}

impl Iterator for Context {
    type Item = Bn;

    fn next(&mut self) -> Option<Bn> {
        self.index += 1;
        Some(Bn { value: bernoulli(self.index as usize, self), index: self.index })
    }
}

fn help() {
    println!("Usage: bernoulli_numbers <up_to>");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut up_to: usize = 60;

    match args.len() {
        1 => {},
        2 => {
            up_to = args[1].parse::<usize>().unwrap();
        },
        _ => {
            help();
            process::exit(0);
        }
    }

    let context = Context::new();
    // Collect the solutions by using the Context iterator
    // (this is not as fast as calling the optimized function directly).
    let res = context.take(up_to + 1).collect::<Vec<_>>();
    let width = res.iter().fold(0, |a, r| max(a, r.value.numer().to_string().len()));

    for r in res.iter().filter(|r| r.index % 2 == 0) {
        println!("B({:>2}) = {:>2$} / {denom}", r.index, r.value.numer(), width,
            denom = r.value.denom());
    }
}

// Implementation with no reused calculations.
fn _bernoulli_naive(n: usize, c: &mut Context) -> BigRational {
    for m in 0..n + 1 {
        c.a.push(BigRational::new(c.bigone_const.clone(), (m + 1).to_bigint().unwrap()));
        for j in (1..m + 1).rev() {
            c.a[j - 1] = (c.a[j - 1].clone().sub(c.a[j].clone())).mul(
                BigRational::new(j.to_bigint().unwrap(), c.bigone_const.clone())
            );
        }
    }
    c.a[0].reduced()
}

// Implementation with reused calculations (does not require sequential calls).
fn bernoulli(n: usize, c: &mut Context) -> BigRational {
    for i in 0..n + 1 {
        if i >= c.a.len() {
            c.a.push(BigRational::new(c.bigone_const.clone(), (i + 1).to_bigint().unwrap()));
            for j in (1..i + 1).rev() {
                c.a[j - 1] = (c.a[j - 1].clone().sub(c.a[j].clone())).mul(
                    BigRational::new(j.to_bigint().unwrap(), c.bigone_const.clone())
                );
            }
        }
    }
    c.a[0].reduced()
}

#[cfg(test)]
mod tests {
    use super::{Bn, Context, bernoulli, _bernoulli_naive};
    use num::rational::{BigRational};
    use std::str::FromStr;
    use test::Bencher;

    #[test]
    fn test_bernoulli_naive() {
        let mut context = Context::new();
        assert_eq!(_bernoulli_naive(60, &mut context), BigRational::new(
                FromStr::from_str("-1215233140483755572040304994079820246041491").unwrap(),
                FromStr::from_str("56786730").unwrap()
            )
        );
    }

    #[test]
    fn test_bernoulli() {
        let mut context = Context::new();
        assert_eq!(bernoulli(60, &mut context), BigRational::new(
                FromStr::from_str("-1215233140483755572040304994079820246041491").unwrap(),
                FromStr::from_str("56786730").unwrap()
            )
        );
    }

    #[test]
    fn test_bernoulli_iter() {
        let context = Context::new();
        let res = context.take(60 + 1).collect::<Vec<_>>();
        assert_eq!(res.last().unwrap().value, BigRational::new(
                FromStr::from_str("-1215233140483755572040304994079820246041491").unwrap(),
                FromStr::from_str("56786730").unwrap()
            )
        );
    }

    #[bench]
    fn bench_bernoulli_naive(b: &mut Bencher) {
        let mut context = Context::new();
        b.iter(|| {
            let mut res: Vec<Bn> = vec![];
            for n in 0..30 + 1 {
                let b = _bernoulli_naive(n, &mut context);
                res.push(Bn { value:b.clone(), index: n as i32});
            }
        });
    }

    #[bench]
    fn bench_bernoulli(b: &mut Bencher) {
        let mut context = Context::new();
        b.iter(|| {
            let mut res: Vec<Bn> = vec![];
            for n in 0..30 + 1 {
                let b = bernoulli(n, &mut context);
                res.push(Bn { value:b.clone(), index: n as i32});
            }
        });
    }

    #[bench]
    fn bench_bernoulli_iter(b: &mut Bencher) {
        b.iter(|| {
            let context = Context::new();
            let _res = context.take(30 + 1).collect::<Vec<_>>();
        });
    }
}
<commit_msg>comment only<commit_after>// http://rosettacode.org/wiki/Bernoulli_numbers

// 2.5 implementations here:  naive, optimized, and an iterator using
// the optimized function. The speeds vary significantly: relative
// speeds of optimized:iterator:naive implementations is 625:25:1.

#![feature(test)]

extern crate num;
extern crate test;

use num::bigint::{BigInt, ToBigInt};
use num::rational::{BigRational};
use std::cmp::max;
use std::env;
use std::ops::{Mul, Sub};
use std::process;

struct Bn {
    value: BigRational,
    index: i32
}

struct Context {
    bigone_const: BigInt,
    a: Vec<BigRational>,
    index: i32              // Counter for iterator implementation
}

impl Context {
    pub fn new() -> Context {
        let bigone = 1.to_bigint().unwrap();
        let a_vec: Vec<BigRational> = vec![];
        Context {
            bigone_const: bigone,
            a: a_vec,
            index: -1
        }
    }
}

impl Iterator for Context {
    type Item = Bn;

    fn next(&mut self) -> Option<Bn> {
        self.index += 1;
        Some(Bn { value: bernoulli(self.index as usize, self), index: self.index })
    }
}

fn help() {
    println!("Usage: bernoulli_numbers <up_to>");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut up_to: usize = 60;

    match args.len() {
        1 => {},
        2 => {
            up_to = args[1].parse::<usize>().unwrap();
        },
        _ => {
            help();
            process::exit(0);
        }
    }

    let context = Context::new();
    // Collect the solutions by using the Context iterator
    // (this is not as fast as calling the optimized function directly).
    let res = context.take(up_to + 1).collect::<Vec<_>>();
    let width = res.iter().fold(0, |a, r| max(a, r.value.numer().to_string().len()));

    for r in res.iter().filter(|r| r.index % 2 == 0) {
        println!("B({:>2}) = {:>2$} / {denom}", r.index, r.value.numer(), width,
            denom = r.value.denom());
    }
}

// Implementation with no reused calculations.
fn _bernoulli_naive(n: usize, c: &mut Context) -> BigRational {
    for m in 0..n + 1 {
        c.a.push(BigRational::new(c.bigone_const.clone(), (m + 1).to_bigint().unwrap()));
        for j in (1..m + 1).rev() {
            c.a[j - 1] = (c.a[j - 1].clone().sub(c.a[j].clone())).mul(
                BigRational::new(j.to_bigint().unwrap(), c.bigone_const.clone())
            );
        }
    }
    c.a[0].reduced()
}

// Implementation with reused calculations (does not require sequential calls).
fn bernoulli(n: usize, c: &mut Context) -> BigRational {
    for i in 0..n + 1 {
        if i >= c.a.len() {
            c.a.push(BigRational::new(c.bigone_const.clone(), (i + 1).to_bigint().unwrap()));
            for j in (1..i + 1).rev() {
                c.a[j - 1] = (c.a[j - 1].clone().sub(c.a[j].clone())).mul(
                    BigRational::new(j.to_bigint().unwrap(), c.bigone_const.clone())
                );
            }
        }
    }
    c.a[0].reduced()
}

#[cfg(test)]
mod tests {
    use super::{Bn, Context, bernoulli, _bernoulli_naive};
    use num::rational::{BigRational};
    use std::str::FromStr;
    use test::Bencher;

    #[test]
    fn test_bernoulli_naive() {
        let mut context = Context::new();
        assert_eq!(_bernoulli_naive(60, &mut context), BigRational::new(
                FromStr::from_str("-1215233140483755572040304994079820246041491").unwrap(),
                FromStr::from_str("56786730").unwrap()
            )
        );
    }

    #[test]
    fn test_bernoulli() {
        let mut context = Context::new();
        assert_eq!(bernoulli(60, &mut context), BigRational::new(
                FromStr::from_str("-1215233140483755572040304994079820246041491").unwrap(),
                FromStr::from_str("56786730").unwrap()
            )
        );
    }

    #[test]
    fn test_bernoulli_iter() {
        let context = Context::new();
        let res = context.take(60 + 1).collect::<Vec<_>>();
        assert_eq!(res.last().unwrap().value, BigRational::new(
                FromStr::from_str("-1215233140483755572040304994079820246041491").unwrap(),
                FromStr::from_str("56786730").unwrap()
            )
        );
    }

    #[bench]
    fn bench_bernoulli_naive(b: &mut Bencher) {
        let mut context = Context::new();
        b.iter(|| {
            let mut res: Vec<Bn> = vec![];
            for n in 0..30 + 1 {
                let b = _bernoulli_naive(n, &mut context);
                res.push(Bn { value:b.clone(), index: n as i32});
            }
        });
    }

    #[bench]
    fn bench_bernoulli(b: &mut Bencher) {
        let mut context = Context::new();
        b.iter(|| {
            let mut res: Vec<Bn> = vec![];
            for n in 0..30 + 1 {
                let b = bernoulli(n, &mut context);
                res.push(Bn { value:b.clone(), index: n as i32});
            }
        });
    }

    #[bench]
    fn bench_bernoulli_iter(b: &mut Bencher) {
        b.iter(|| {
            let context = Context::new();
            let _res = context.take(30 + 1).collect::<Vec<_>>();
        });
    }
}
<|endoftext|>


<commit_before>//! A Rust interface for the functionality of the Objective-C runtime.
//!
//! For more information on foreign functions, see Apple's documentation:
//! https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html

use std::ffi::{CStr, CString};
use std::fmt;
use std::ptr;
use std::str;
use libc::{c_char, c_int, c_schar, c_uint, c_void, ptrdiff_t, size_t};
use malloc_buf::{MallocBuffer, MallocString};

use {encode, Encode};

/// The Objective-C `BOOL` type.
///
/// To convert an Objective-C `BOOL` into a Rust `bool`, compare it with `NO`.
pub type BOOL = c_schar;
/// The equivalent of true for Objective-C's `BOOL` type.
pub const YES: BOOL = 1;
/// The equivalent of false for Objective-C's `BOOL` type.
pub const NO: BOOL = 0;

/// A type that represents a method selector.
#[repr(C)]
pub struct Sel {
    ptr: *const c_void,
}

/// A marker type to be embedded into other types just so that they cannot be
/// constructed externally.
#[repr(C)]
struct PrivateMarker;

/// A type that represents an instance variable.
#[repr(C)]
pub struct Ivar {
    _priv: PrivateMarker,
}

/// A type that represents a method in a class definition.
#[repr(C)]
pub struct Method {
    _priv: PrivateMarker,
}

/// A type that represents an Objective-C class.
#[repr(C)]
pub struct Class {
    _priv: PrivateMarker,
}

/// A type that represents an instance of a class.
#[repr(C)]
pub struct Object {
    _priv: PrivateMarker,
}

/// A pointer to the start of a method implementation.
pub type Imp = extern fn(*mut Object, Sel, ...) -> *mut Object;

#[link(name = "objc", kind = "dylib")]
extern {
    pub fn sel_registerName(name: *const c_char) -> Sel;
    pub fn sel_getName(sel: Sel) -> *const c_char;

    pub fn class_getName(cls: *const Class) -> *const c_char;
    pub fn class_getInstanceSize(cls: *const Class) -> size_t;
    pub fn class_getInstanceMethod(cls: *const Class, sel: Sel) -> *const Method;
    pub fn class_getInstanceVariable(cls: *const Class, name: *const c_char) -> *const Ivar;
    pub fn class_copyMethodList(cls: *const Class, outCount: *mut c_uint) -> *mut *const Method;
    pub fn class_copyIvarList(cls: *const Class, outCount: *mut c_uint) -> *mut *const Ivar;
    pub fn class_addMethod(cls: *mut Class, name: Sel, imp: Imp, types: *const c_char) -> BOOL;
    pub fn class_addIvar(cls: *mut Class, name: *const c_char, size: size_t, alignment: u8, types: *const c_char) -> BOOL;

    pub fn objc_allocateClassPair(superclass: *const Class, name: *const c_char, extraBytes: size_t) -> *mut Class;
    pub fn objc_disposeClassPair(cls: *mut Class);
    pub fn objc_registerClassPair(cls: *mut Class);

    pub fn object_getClass(obj: *const Object) -> *const Class;

    pub fn objc_getClassList(buffer: *mut *const Class, bufferLen: c_int) -> c_int;
    pub fn objc_copyClassList(outCount: *mut c_uint) -> *mut *const Class;
    pub fn objc_getClass(name: *const c_char) -> *const Class;

    pub fn ivar_getName(ivar: *const Ivar) -> *const c_char;
    pub fn ivar_getOffset(ivar: *const Ivar) -> ptrdiff_t;
    pub fn ivar_getTypeEncoding(ivar: *const Ivar) -> *const c_char;

    pub fn objc_msgSend(obj: *mut Object, op: Sel, ...) -> *mut Object;
    pub fn objc_msgSend_stret(obj: *mut Object, op: Sel, ...);

    pub fn method_getName(method: *const Method) -> Sel;
    pub fn method_getImplementation(method: *const Method) -> Imp;
    pub fn method_getTypeEncoding(method: *const Method) -> *const c_char;
    pub fn method_copyReturnType(method: *const Method) -> *mut c_char;
    pub fn method_copyArgumentType(method: *const Method, index: c_uint) -> *mut c_char;
    pub fn method_getNumberOfArguments(method: *const Method) -> c_uint;
    pub fn method_setImplementation(method: *mut Method, imp: Imp) -> Imp;
    pub fn method_exchangeImplementations(m1: *mut Method, m2: *mut Method);
}

impl Sel {
    /// Registers a method with the Objective-C runtime system,
    /// maps the method name to a selector, and returns the selector value.
    pub fn register(name: &str) -> Sel {
        let name = CString::new(name).unwrap();
        unsafe {
            sel_registerName(name.as_ptr())
        }
    }

    /// Returns the name of the method specified by self.
    pub fn name(&self) -> &str {
        let name = unsafe {
            CStr::from_ptr(sel_getName(*self))
        };
        str::from_utf8(name.to_bytes()).unwrap()
    }
}

impl PartialEq for Sel {
    fn eq(&self, other: &Sel) -> bool {
        self.ptr == other.ptr
    }
}

impl Eq for Sel { }

impl Copy for Sel { }

impl Clone for Sel {
    fn clone(&self) -> Sel { *self }
}

impl fmt::Debug for Sel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl Ivar {
    /// Returns the name of self.
    pub fn name(&self) -> &str {
        let name = unsafe {
            CStr::from_ptr(ivar_getName(self))
        };
        str::from_utf8(name.to_bytes()).unwrap()
    }

    /// Returns the offset of self.
    pub fn offset(&self) -> isize {
        let offset = unsafe {
            ivar_getOffset(self)
        };
        offset as isize
    }

    /// Returns the type string of self.
    pub fn type_encoding(&self) -> &str {
        let encoding = unsafe {
            CStr::from_ptr(ivar_getTypeEncoding(self))
        };
        str::from_utf8(encoding.to_bytes()).unwrap()
    }
}

impl Method {
    /// Returns the name of self.
    pub fn name(&self) -> Sel {
        unsafe {
            method_getName(self)
        }
    }

    /// Returns a string describing self's parameter and return types.
    pub fn type_encoding(&self) -> &str {
        let encoding = unsafe {
            CStr::from_ptr(method_getTypeEncoding(self))
        };
        str::from_utf8(encoding.to_bytes()).unwrap()
    }

    /// Returns a string describing self's return type.
    pub fn return_type(&self) -> MallocString {
        unsafe {
            let encoding = method_copyReturnType(self);
            MallocString::new(encoding).unwrap()
        }
    }

    /// Returns a string describing a single parameter type of self, or
    /// `None` if self has no parameter at the given index.
    pub fn argument_type(&self, index: usize) -> Option<MallocString> {
        unsafe {
            let encoding = method_copyArgumentType(self, index as c_uint);
            if encoding.is_null() {
                None
            } else {
                Some(MallocString::new(encoding).unwrap())
            }
        }
    }

    /// Returns the number of arguments accepted by self.
    pub fn arguments_count(&self) -> usize {
        unsafe {
            method_getNumberOfArguments(self) as usize
        }
    }

    /// Returns the implementation of self.
    pub fn implementation(&self) -> Imp {
        unsafe {
            method_getImplementation(self)
        }
    }

    /// Sets the implementation of self.
    /// Unsafe because the caller must ensure the implementation has the
    /// correct self, return, and argument types for the method.
    pub unsafe fn set_implementation(&mut self, imp: Imp) -> Imp {
        method_setImplementation(self, imp)
    }

    /// Exchanges the implementations of self with another `Method`.
    /// Unsafe because the caller must ensure the two methods have the same
    /// self, return, and argument types.
    pub unsafe fn exchange_implementation(&mut self, other: &mut Method) {
        method_exchangeImplementations(self, other);
    }
}

impl Class {
    /// Returns the class definition of a specified class, or `None` if the
    /// class is not registered with the Objective-C runtime.
    pub fn get(name: &str) -> Option<&'static Class> {
        let name = CString::new(name).unwrap();
        unsafe {
            objc_getClass(name.as_ptr()).as_ref()
        }
    }

    /// Obtains the list of registered class definitions.
    pub fn classes() -> MallocBuffer<&'static Class> {
        unsafe {
            let mut count: c_uint = 0;
            let classes = objc_copyClassList(&mut count);
            MallocBuffer::new(classes as *mut _, count as usize).unwrap()
        }
    }

    /// Returns the total number of registered classes.
    pub fn classes_count() -> usize {
        unsafe {
            objc_getClassList(ptr::null_mut(), 0) as usize
        }
    }

    /// Returns the name of self.
    pub fn name(&self) -> &str {
        let name = unsafe {
            CStr::from_ptr(class_getName(self))
        };
        str::from_utf8(name.to_bytes()).unwrap()
    }

    /// Returns the size of instances of self.
    pub fn instance_size(&self) -> usize {
        unsafe {
            class_getInstanceSize(self) as usize
        }
    }

    /// Returns a specified instance method for self, or `None` if self and
    /// its superclasses do not contain an instance method with the
    /// specified selector.
    pub fn instance_method(&self, sel: Sel) -> Option<&Method> {
        unsafe {
            class_getInstanceMethod(self, sel).as_ref()
        }
    }

    /// Returns the ivar for a specified instance variable of self, or `None`
    /// if self has no ivar with the given name.
    pub fn instance_variable(&self, name: &str) -> Option<&Ivar> {
        let name = CString::new(name).unwrap();
        unsafe {
            class_getInstanceVariable(self, name.as_ptr()).as_ref()
        }
    }

    /// Describes the instance methods implemented by self.
    pub fn instance_methods(&self) -> MallocBuffer<&Method> {
        unsafe {
            let mut count: c_uint = 0;
            let methods = class_copyMethodList(self, &mut count);
            MallocBuffer::new(methods as *mut _, count as usize).unwrap()
        }

    }

    /// Describes the instance variables declared by self.
    pub fn instance_variables(&self) -> MallocBuffer<&Ivar> {
        unsafe {
            let mut count: c_uint = 0;
            let ivars = class_copyIvarList(self, &mut count);
            MallocBuffer::new(ivars as *mut _, count as usize).unwrap()
        }
    }
}

impl PartialEq for Class {
    fn eq(&self, other: &Class) -> bool {
        self as *const Class == other as *const Class
    }
}

impl Eq for Class { }

impl fmt::Debug for Class {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl Object {
    /// Returns the class of self.
    pub fn class(&self) -> &Class {
        unsafe {
            &*object_getClass(self)
        }
    }

    /// Returns a reference to the ivar of self with the given name.
    /// Panics if self has no ivar with the given name.
    /// Unsafe because the caller must ensure that the ivar is actually
    /// of type `T`.
    pub unsafe fn get_ivar<T>(&self, name: &str) -> &T where T: Encode {
        let cls = self.class();
        let ptr = match cls.instance_variable(name) {
            Some(ivar) => {
                assert!(ivar.type_encoding() == encode::<T>());
                let offset = ivar.offset();
                let self_ptr = self as *const Object;
                (self_ptr as *const u8).offset(offset) as *const T
            }
            None => panic!("Ivar {} not found on class {}", name, cls.name()),
        };
        &*ptr
    }

    /// Returns a mutable reference to the ivar of self with the given name.
    /// Panics if self has no ivar with the given name.
    /// Unsafe because the caller must ensure that the ivar is actually
    /// of type `T`.
    pub unsafe fn get_mut_ivar<T>(&mut self, name: &str) -> &mut T
            where T: Encode {
        let cls = self.class();
        let ptr = match cls.instance_variable(name) {
            Some(ivar) => {
                assert!(ivar.type_encoding() == encode::<T>());
                let offset = ivar.offset();
                let self_ptr = self as *mut Object;
                (self_ptr as *mut u8).offset(offset) as *mut T
            }
            None => panic!("Ivar {} not found on class {}", name, cls.name()),
        };
        &mut *ptr
    }

    /// Sets the value of the ivar of self with the given name.
    /// Panics if self has no ivar with the given name.
    /// Unsafe because the caller must ensure that the ivar is actually
    /// of type `T`.
    pub unsafe fn set_ivar<T>(&mut self, name: &str, value: T)
            where T: Encode {
        *self.get_mut_ivar::<T>(name) = value;
    }
}

impl fmt::Debug for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<{:?}: {:?}>", self.class(), self as *const Object)
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use test_utils;
    use super::{Class, Sel};

    #[test]
    fn test_ivar() {
        let cls = Class::get("NSObject").unwrap();
        let ivar = cls.instance_variable("isa").unwrap();
        assert!(ivar.name() == "isa");
        assert!(ivar.type_encoding() == "#");
        assert!(ivar.offset() == 0);

        let ivars = cls.instance_variables();
        assert!(ivars.len() > 0);
    }

    #[test]
    fn test_method() {
        let cls = Class::get("NSObject").unwrap();
        let sel = Sel::register("description");
        let method = cls.instance_method(sel).unwrap();
        assert!(method.name().name() == "description");
        assert!(method.type_encoding() != "");
        assert!(method.arguments_count() == 2);
        assert!(&*method.return_type() == "@");
        assert!(&*method.argument_type(1).unwrap() == ":");

        let methods = cls.instance_methods();
        assert!(methods.len() > 0);
    }

    #[test]
    fn test_class() {
        let cls = Class::get("NSObject").unwrap();
        assert!(cls.name() == "NSObject");
        assert!(cls.instance_size() == mem::size_of::<*const Class>());
    }

    #[test]
    fn test_classes() {
        let classes_count = Class::classes_count();
        assert!(classes_count > 0);

        let classes = Class::classes();
        assert!(classes.len() == classes_count);
    }

    #[test]
    fn test_object() {
        let cls = Class::get("NSObject").unwrap();
        let obj = test_utils::sample_object();
        assert!(obj.class() == cls);
        let isa = unsafe { *obj.get_ivar("isa") };
        assert!(isa == cls as *const Class);
    }
}
<commit_msg>Added getters for superclass and metaclass.<commit_after>//! A Rust interface for the functionality of the Objective-C runtime.
//!
//! For more information on foreign functions, see Apple's documentation:
//! https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html

use std::ffi::{CStr, CString};
use std::fmt;
use std::ptr;
use std::str;
use libc::{c_char, c_int, c_schar, c_uint, c_void, ptrdiff_t, size_t};
use malloc_buf::{MallocBuffer, MallocString};

use {encode, Encode};

/// The Objective-C `BOOL` type.
///
/// To convert an Objective-C `BOOL` into a Rust `bool`, compare it with `NO`.
pub type BOOL = c_schar;
/// The equivalent of true for Objective-C's `BOOL` type.
pub const YES: BOOL = 1;
/// The equivalent of false for Objective-C's `BOOL` type.
pub const NO: BOOL = 0;

/// A type that represents a method selector.
#[repr(C)]
pub struct Sel {
    ptr: *const c_void,
}

/// A marker type to be embedded into other types just so that they cannot be
/// constructed externally.
#[repr(C)]
struct PrivateMarker;

/// A type that represents an instance variable.
#[repr(C)]
pub struct Ivar {
    _priv: PrivateMarker,
}

/// A type that represents a method in a class definition.
#[repr(C)]
pub struct Method {
    _priv: PrivateMarker,
}

/// A type that represents an Objective-C class.
#[repr(C)]
pub struct Class {
    _priv: PrivateMarker,
}

/// A type that represents an instance of a class.
#[repr(C)]
pub struct Object {
    _priv: PrivateMarker,
}

/// A pointer to the start of a method implementation.
pub type Imp = extern fn(*mut Object, Sel, ...) -> *mut Object;

#[link(name = "objc", kind = "dylib")]
extern {
    pub fn sel_registerName(name: *const c_char) -> Sel;
    pub fn sel_getName(sel: Sel) -> *const c_char;

    pub fn class_getName(cls: *const Class) -> *const c_char;
    pub fn class_getSuperclass(cls: *const Class) -> *const Class;
    pub fn class_getInstanceSize(cls: *const Class) -> size_t;
    pub fn class_getInstanceMethod(cls: *const Class, sel: Sel) -> *const Method;
    pub fn class_getInstanceVariable(cls: *const Class, name: *const c_char) -> *const Ivar;
    pub fn class_copyMethodList(cls: *const Class, outCount: *mut c_uint) -> *mut *const Method;
    pub fn class_copyIvarList(cls: *const Class, outCount: *mut c_uint) -> *mut *const Ivar;
    pub fn class_addMethod(cls: *mut Class, name: Sel, imp: Imp, types: *const c_char) -> BOOL;
    pub fn class_addIvar(cls: *mut Class, name: *const c_char, size: size_t, alignment: u8, types: *const c_char) -> BOOL;

    pub fn objc_allocateClassPair(superclass: *const Class, name: *const c_char, extraBytes: size_t) -> *mut Class;
    pub fn objc_disposeClassPair(cls: *mut Class);
    pub fn objc_registerClassPair(cls: *mut Class);

    pub fn object_getClass(obj: *const Object) -> *const Class;

    pub fn objc_getClassList(buffer: *mut *const Class, bufferLen: c_int) -> c_int;
    pub fn objc_copyClassList(outCount: *mut c_uint) -> *mut *const Class;
    pub fn objc_getClass(name: *const c_char) -> *const Class;

    pub fn ivar_getName(ivar: *const Ivar) -> *const c_char;
    pub fn ivar_getOffset(ivar: *const Ivar) -> ptrdiff_t;
    pub fn ivar_getTypeEncoding(ivar: *const Ivar) -> *const c_char;

    pub fn objc_msgSend(obj: *mut Object, op: Sel, ...) -> *mut Object;
    pub fn objc_msgSend_stret(obj: *mut Object, op: Sel, ...);

    pub fn method_getName(method: *const Method) -> Sel;
    pub fn method_getImplementation(method: *const Method) -> Imp;
    pub fn method_getTypeEncoding(method: *const Method) -> *const c_char;
    pub fn method_copyReturnType(method: *const Method) -> *mut c_char;
    pub fn method_copyArgumentType(method: *const Method, index: c_uint) -> *mut c_char;
    pub fn method_getNumberOfArguments(method: *const Method) -> c_uint;
    pub fn method_setImplementation(method: *mut Method, imp: Imp) -> Imp;
    pub fn method_exchangeImplementations(m1: *mut Method, m2: *mut Method);
}

impl Sel {
    /// Registers a method with the Objective-C runtime system,
    /// maps the method name to a selector, and returns the selector value.
    pub fn register(name: &str) -> Sel {
        let name = CString::new(name).unwrap();
        unsafe {
            sel_registerName(name.as_ptr())
        }
    }

    /// Returns the name of the method specified by self.
    pub fn name(&self) -> &str {
        let name = unsafe {
            CStr::from_ptr(sel_getName(*self))
        };
        str::from_utf8(name.to_bytes()).unwrap()
    }
}

impl PartialEq for Sel {
    fn eq(&self, other: &Sel) -> bool {
        self.ptr == other.ptr
    }
}

impl Eq for Sel { }

impl Copy for Sel { }

impl Clone for Sel {
    fn clone(&self) -> Sel { *self }
}

impl fmt::Debug for Sel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl Ivar {
    /// Returns the name of self.
    pub fn name(&self) -> &str {
        let name = unsafe {
            CStr::from_ptr(ivar_getName(self))
        };
        str::from_utf8(name.to_bytes()).unwrap()
    }

    /// Returns the offset of self.
    pub fn offset(&self) -> isize {
        let offset = unsafe {
            ivar_getOffset(self)
        };
        offset as isize
    }

    /// Returns the type string of self.
    pub fn type_encoding(&self) -> &str {
        let encoding = unsafe {
            CStr::from_ptr(ivar_getTypeEncoding(self))
        };
        str::from_utf8(encoding.to_bytes()).unwrap()
    }
}

impl Method {
    /// Returns the name of self.
    pub fn name(&self) -> Sel {
        unsafe {
            method_getName(self)
        }
    }

    /// Returns a string describing self's parameter and return types.
    pub fn type_encoding(&self) -> &str {
        let encoding = unsafe {
            CStr::from_ptr(method_getTypeEncoding(self))
        };
        str::from_utf8(encoding.to_bytes()).unwrap()
    }

    /// Returns a string describing self's return type.
    pub fn return_type(&self) -> MallocString {
        unsafe {
            let encoding = method_copyReturnType(self);
            MallocString::new(encoding).unwrap()
        }
    }

    /// Returns a string describing a single parameter type of self, or
    /// `None` if self has no parameter at the given index.
    pub fn argument_type(&self, index: usize) -> Option<MallocString> {
        unsafe {
            let encoding = method_copyArgumentType(self, index as c_uint);
            if encoding.is_null() {
                None
            } else {
                Some(MallocString::new(encoding).unwrap())
            }
        }
    }

    /// Returns the number of arguments accepted by self.
    pub fn arguments_count(&self) -> usize {
        unsafe {
            method_getNumberOfArguments(self) as usize
        }
    }

    /// Returns the implementation of self.
    pub fn implementation(&self) -> Imp {
        unsafe {
            method_getImplementation(self)
        }
    }

    /// Sets the implementation of self.
    /// Unsafe because the caller must ensure the implementation has the
    /// correct self, return, and argument types for the method.
    pub unsafe fn set_implementation(&mut self, imp: Imp) -> Imp {
        method_setImplementation(self, imp)
    }

    /// Exchanges the implementations of self with another `Method`.
    /// Unsafe because the caller must ensure the two methods have the same
    /// self, return, and argument types.
    pub unsafe fn exchange_implementation(&mut self, other: &mut Method) {
        method_exchangeImplementations(self, other);
    }
}

impl Class {
    /// Returns the class definition of a specified class, or `None` if the
    /// class is not registered with the Objective-C runtime.
    pub fn get(name: &str) -> Option<&'static Class> {
        let name = CString::new(name).unwrap();
        unsafe {
            objc_getClass(name.as_ptr()).as_ref()
        }
    }

    /// Obtains the list of registered class definitions.
    pub fn classes() -> MallocBuffer<&'static Class> {
        unsafe {
            let mut count: c_uint = 0;
            let classes = objc_copyClassList(&mut count);
            MallocBuffer::new(classes as *mut _, count as usize).unwrap()
        }
    }

    /// Returns the total number of registered classes.
    pub fn classes_count() -> usize {
        unsafe {
            objc_getClassList(ptr::null_mut(), 0) as usize
        }
    }

    /// Returns the name of self.
    pub fn name(&self) -> &str {
        let name = unsafe {
            CStr::from_ptr(class_getName(self))
        };
        str::from_utf8(name.to_bytes()).unwrap()
    }

    /// Returns the superclass of self, or `None` if self is a root class.
    pub fn superclass(&self) -> Option<&Class> {
        unsafe {
            class_getSuperclass(self).as_ref()
        }
    }

    /// Returns the metaclass of self.
    pub fn metaclass(&self) -> &Class {
        unsafe {
            let obj = self as *const Class as *const Object;
            &*object_getClass(obj)
        }
    }

    /// Returns the size of instances of self.
    pub fn instance_size(&self) -> usize {
        unsafe {
            class_getInstanceSize(self) as usize
        }
    }

    /// Returns a specified instance method for self, or `None` if self and
    /// its superclasses do not contain an instance method with the
    /// specified selector.
    pub fn instance_method(&self, sel: Sel) -> Option<&Method> {
        unsafe {
            class_getInstanceMethod(self, sel).as_ref()
        }
    }

    /// Returns the ivar for a specified instance variable of self, or `None`
    /// if self has no ivar with the given name.
    pub fn instance_variable(&self, name: &str) -> Option<&Ivar> {
        let name = CString::new(name).unwrap();
        unsafe {
            class_getInstanceVariable(self, name.as_ptr()).as_ref()
        }
    }

    /// Describes the instance methods implemented by self.
    pub fn instance_methods(&self) -> MallocBuffer<&Method> {
        unsafe {
            let mut count: c_uint = 0;
            let methods = class_copyMethodList(self, &mut count);
            MallocBuffer::new(methods as *mut _, count as usize).unwrap()
        }

    }

    /// Describes the instance variables declared by self.
    pub fn instance_variables(&self) -> MallocBuffer<&Ivar> {
        unsafe {
            let mut count: c_uint = 0;
            let ivars = class_copyIvarList(self, &mut count);
            MallocBuffer::new(ivars as *mut _, count as usize).unwrap()
        }
    }
}

impl PartialEq for Class {
    fn eq(&self, other: &Class) -> bool {
        self as *const Class == other as *const Class
    }
}

impl Eq for Class { }

impl fmt::Debug for Class {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl Object {
    /// Returns the class of self.
    pub fn class(&self) -> &Class {
        unsafe {
            &*object_getClass(self)
        }
    }

    /// Returns a reference to the ivar of self with the given name.
    /// Panics if self has no ivar with the given name.
    /// Unsafe because the caller must ensure that the ivar is actually
    /// of type `T`.
    pub unsafe fn get_ivar<T>(&self, name: &str) -> &T where T: Encode {
        let cls = self.class();
        let ptr = match cls.instance_variable(name) {
            Some(ivar) => {
                assert!(ivar.type_encoding() == encode::<T>());
                let offset = ivar.offset();
                let self_ptr = self as *const Object;
                (self_ptr as *const u8).offset(offset) as *const T
            }
            None => panic!("Ivar {} not found on class {}", name, cls.name()),
        };
        &*ptr
    }

    /// Returns a mutable reference to the ivar of self with the given name.
    /// Panics if self has no ivar with the given name.
    /// Unsafe because the caller must ensure that the ivar is actually
    /// of type `T`.
    pub unsafe fn get_mut_ivar<T>(&mut self, name: &str) -> &mut T
            where T: Encode {
        let cls = self.class();
        let ptr = match cls.instance_variable(name) {
            Some(ivar) => {
                assert!(ivar.type_encoding() == encode::<T>());
                let offset = ivar.offset();
                let self_ptr = self as *mut Object;
                (self_ptr as *mut u8).offset(offset) as *mut T
            }
            None => panic!("Ivar {} not found on class {}", name, cls.name()),
        };
        &mut *ptr
    }

    /// Sets the value of the ivar of self with the given name.
    /// Panics if self has no ivar with the given name.
    /// Unsafe because the caller must ensure that the ivar is actually
    /// of type `T`.
    pub unsafe fn set_ivar<T>(&mut self, name: &str, value: T)
            where T: Encode {
        *self.get_mut_ivar::<T>(name) = value;
    }
}

impl fmt::Debug for Object {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<{:?}: {:?}>", self.class(), self as *const Object)
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use test_utils;
    use super::{Class, Sel};

    #[test]
    fn test_ivar() {
        let cls = Class::get("NSObject").unwrap();
        let ivar = cls.instance_variable("isa").unwrap();
        assert!(ivar.name() == "isa");
        assert!(ivar.type_encoding() == "#");
        assert!(ivar.offset() == 0);

        let ivars = cls.instance_variables();
        assert!(ivars.len() > 0);
    }

    #[test]
    fn test_method() {
        let cls = Class::get("NSObject").unwrap();
        let sel = Sel::register("description");
        let method = cls.instance_method(sel).unwrap();
        assert!(method.name().name() == "description");
        assert!(method.type_encoding() != "");
        assert!(method.arguments_count() == 2);
        assert!(&*method.return_type() == "@");
        assert!(&*method.argument_type(1).unwrap() == ":");

        let methods = cls.instance_methods();
        assert!(methods.len() > 0);
    }

    #[test]
    fn test_class() {
        let cls = Class::get("NSObject").unwrap();
        assert!(cls.name() == "NSObject");
        assert!(cls.instance_size() == mem::size_of::<*const Class>());
        assert!(cls.superclass().is_none());

        let metaclass = cls.metaclass();
        assert!(metaclass.instance_size() > 0);

        let subclass = test_utils::custom_class();
        assert!(subclass.superclass().unwrap() == cls);
    }

    #[test]
    fn test_classes() {
        let classes_count = Class::classes_count();
        assert!(classes_count > 0);

        let classes = Class::classes();
        assert!(classes.len() == classes_count);
    }

    #[test]
    fn test_object() {
        let cls = Class::get("NSObject").unwrap();
        let obj = test_utils::sample_object();
        assert!(obj.class() == cls);
        let isa = unsafe { *obj.get_ivar("isa") };
        assert!(isa == cls as *const Class);
    }
}
<|endoftext|>


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

use io;
use mem;
use rand::Rng;
use sys::c;

pub struct OsRng {
    hcryptprov: c::HCRYPTPROV
}

impl OsRng {
    /// Create a new `OsRng`.
    pub fn new() -> io::Result<OsRng> {
        let mut hcp = 0;
        let ret = unsafe {
            c::CryptAcquireContextA(&mut hcp, 0 as c::LPCSTR, 0 as c::LPCSTR,
                                    c::PROV_RSA_FULL,
                                    c::CRYPT_VERIFYCONTEXT | c::CRYPT_SILENT)
        };

        if ret == 0 {
            Err(io::Error::last_os_error())
        } else {
            Ok(OsRng { hcryptprov: hcp })
        }
    }
}

impl Rng for OsRng {
    fn next_u32(&mut self) -> u32 {
        let mut v = [0; 4];
        self.fill_bytes(&mut v);
        unsafe { mem::transmute(v) }
    }
    fn next_u64(&mut self) -> u64 {
        let mut v = [0; 8];
        self.fill_bytes(&mut v);
        unsafe { mem::transmute(v) }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        let ret = unsafe {
            c::CryptGenRandom(self.hcryptprov, v.len() as c::DWORD,
                              v.as_mut_ptr())
        };
        if ret == 0 {
            panic!("couldn't generate random bytes: {}",
                   io::Error::last_os_error());
        }
    }
}

impl Drop for OsRng {
    fn drop(&mut self) {
        let ret = unsafe {
            c::CryptReleaseContext(self.hcryptprov, 0)
        };
        if ret == 0 {
            panic!("couldn't release context: {}",
                   io::Error::last_os_error());
        }
    }
}
<commit_msg>rand: Fix filling buffers 4 GiB or larger with OsRng::fill_bytes on Windows<commit_after>// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use io;
use mem;
use rand::Rng;
use sys::c;

pub struct OsRng {
    hcryptprov: c::HCRYPTPROV
}

impl OsRng {
    /// Create a new `OsRng`.
    pub fn new() -> io::Result<OsRng> {
        let mut hcp = 0;
        let ret = unsafe {
            c::CryptAcquireContextA(&mut hcp, 0 as c::LPCSTR, 0 as c::LPCSTR,
                                    c::PROV_RSA_FULL,
                                    c::CRYPT_VERIFYCONTEXT | c::CRYPT_SILENT)
        };

        if ret == 0 {
            Err(io::Error::last_os_error())
        } else {
            Ok(OsRng { hcryptprov: hcp })
        }
    }
}

impl Rng for OsRng {
    fn next_u32(&mut self) -> u32 {
        let mut v = [0; 4];
        self.fill_bytes(&mut v);
        unsafe { mem::transmute(v) }
    }
    fn next_u64(&mut self) -> u64 {
        let mut v = [0; 8];
        self.fill_bytes(&mut v);
        unsafe { mem::transmute(v) }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        // CryptGenRandom takes a DWORD (u32) for the length so we need to
        // split up the buffer.
        for slice in v.chunks_mut(<c::DWORD>::max_value() as usize) {
            let ret = unsafe {
                c::CryptGenRandom(self.hcryptprov, slice.len() as c::DWORD,
                                  slice.as_mut_ptr())
            };
            if ret == 0 {
                panic!("couldn't generate random bytes: {}",
                       io::Error::last_os_error());
            }
        }
    }
}

impl Drop for OsRng {
    fn drop(&mut self) {
        let ret = unsafe {
            c::CryptReleaseContext(self.hcryptprov, 0)
        };
        if ret == 0 {
            panic!("couldn't release context: {}",
                   io::Error::last_os_error());
        }
    }
}
<|endoftext|>


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

// An "interner" is a data structure that associates values with uint tags and
// allows bidirectional lookup; i.e. given a value, one can easily find the
// type, and vice versa.

use core::prelude::*;

use core::dvec::DVec;
use std::map::HashMap;
use std::map;

type hash_interner<T: Const> =
    {map: HashMap<T, uint>,
     vect: DVec<T>};

fn mk<T:Eq IterBytes Hash Const Copy>() -> Interner<T> {
    let m = map::HashMap::<T, uint>();
    let hi: hash_interner<T> =
        {map: m, vect: DVec()};
    move ((move hi) as Interner::<T>)
}

fn mk_prefill<T:Eq IterBytes Hash Const Copy>(init: &[T]) -> Interner<T> {
    let rv = mk();
    for init.each() |v| { rv.intern(*v); }
    return rv;
}

/* when traits can extend traits, we should extend index<uint,T> to get [] */
trait Interner<T:Eq IterBytes Hash Const Copy> {
    fn intern(T) -> uint;
    fn gensym(T) -> uint;
    pure fn get(uint) -> T;
    fn len() -> uint;
}

impl <T:Eq IterBytes Hash Const Copy> hash_interner<T>: Interner<T> {
    fn intern(val: T) -> uint {
        match self.map.find(val) {
          Some(idx) => return idx,
          None => {
            let new_idx = self.vect.len();
            self.map.insert(val, new_idx);
            self.vect.push(val);
            return new_idx;
          }
        }
    }
    fn gensym(val: T) -> uint {
        let new_idx = self.vect.len();
        // leave out of .map to avoid colliding
        self.vect.push(val);
        return new_idx;
    }

    // this isn't "pure" in the traditional sense, because it can go from
    // failing to returning a value as items are interned. But for typestate,
    // where we first check a pred and then rely on it, ceasing to fail is ok.
    pure fn get(idx: uint) -> T { self.vect.get_elt(idx) }

    fn len() -> uint { return self.vect.len(); }
}

#[test]
#[should_fail]
fn i1 () {
    let i : Interner<@~str> = mk();
    i.get(13);
}

#[test]
fn i2 () {
    let i : Interner<@~str> = mk();
    // first one is zero:
    assert i.intern (@~"dog") == 0;
    // re-use gets the same entry:
    assert i.intern (@~"dog") == 0;
    // different string gets a different #:
    assert i.intern (@~"cat") == 1;
    assert i.intern (@~"cat") == 1;
    // dog is still at zero
    assert i.intern (@~"dog") == 0;
    // gensym gets 3
    assert i.gensym (@~"zebra" ) == 2;
    // gensym of same string gets new number :
    assert i.gensym (@~"zebra" ) == 3;
    // gensym of *existing* string gets new number:
    assert i.gensym (@~"dog") == 4;
    assert i.get(0) == @~"dog";
    assert i.get(1) == @~"cat";
    assert i.get(2) == @~"zebra";
    assert i.get(3) == @~"zebra";
    assert i.get(4) == @~"dog";
}

#[test]
fn i3 () {
    let i : Interner<@~str> = mk_prefill([@~"Alan",@~"Bob",@~"Carol"]);
    assert i.get(0) == @~"Alan";
    assert i.get(1) == @~"Bob";
    assert i.get(2) == @~"Carol";
    assert i.intern(@~"Bob") == 1;
}
<commit_msg>fix trailing whitepace<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// An "interner" is a data structure that associates values with uint tags and
// allows bidirectional lookup; i.e. given a value, one can easily find the
// type, and vice versa.

use core::prelude::*;

use core::dvec::DVec;
use std::map::HashMap;
use std::map;

type hash_interner<T: Const> =
    {map: HashMap<T, uint>,
     vect: DVec<T>};

fn mk<T:Eq IterBytes Hash Const Copy>() -> Interner<T> {
    let m = map::HashMap::<T, uint>();
    let hi: hash_interner<T> =
        {map: m, vect: DVec()};
    move ((move hi) as Interner::<T>)
}

fn mk_prefill<T:Eq IterBytes Hash Const Copy>(init: &[T]) -> Interner<T> {
    let rv = mk();
    for init.each() |v| { rv.intern(*v); }
    return rv;
}

/* when traits can extend traits, we should extend index<uint,T> to get [] */
trait Interner<T:Eq IterBytes Hash Const Copy> {
    fn intern(T) -> uint;
    fn gensym(T) -> uint;
    pure fn get(uint) -> T;
    fn len() -> uint;
}

impl <T:Eq IterBytes Hash Const Copy> hash_interner<T>: Interner<T> {
    fn intern(val: T) -> uint {
        match self.map.find(val) {
          Some(idx) => return idx,
          None => {
            let new_idx = self.vect.len();
            self.map.insert(val, new_idx);
            self.vect.push(val);
            return new_idx;
          }
        }
    }
    fn gensym(val: T) -> uint {
        let new_idx = self.vect.len();
        // leave out of .map to avoid colliding
        self.vect.push(val);
        return new_idx;
    }

    // this isn't "pure" in the traditional sense, because it can go from
    // failing to returning a value as items are interned. But for typestate,
    // where we first check a pred and then rely on it, ceasing to fail is ok.
    pure fn get(idx: uint) -> T { self.vect.get_elt(idx) }

    fn len() -> uint { return self.vect.len(); }
}

#[test]
#[should_fail]
fn i1 () {
    let i : Interner<@~str> = mk();
    i.get(13);
}

#[test]
fn i2 () {
    let i : Interner<@~str> = mk();
    // first one is zero:
    assert i.intern (@~"dog") == 0;
    // re-use gets the same entry:
    assert i.intern (@~"dog") == 0;
    // different string gets a different #:
    assert i.intern (@~"cat") == 1;
    assert i.intern (@~"cat") == 1;
    // dog is still at zero
    assert i.intern (@~"dog") == 0;
    // gensym gets 3
    assert i.gensym (@~"zebra" ) == 2;
    // gensym of same string gets new number :
    assert i.gensym (@~"zebra" ) == 3;
    // gensym of *existing* string gets new number:
    assert i.gensym (@~"dog") == 4;
    assert i.get(0) == @~"dog";
    assert i.get(1) == @~"cat";
    assert i.get(2) == @~"zebra";
    assert i.get(3) == @~"zebra";
    assert i.get(4) == @~"dog";
}

#[test]
fn i3 () {
    let i : Interner<@~str> = mk_prefill([@~"Alan",@~"Bob",@~"Carol"]);
    assert i.get(0) == @~"Alan";
    assert i.get(1) == @~"Bob";
    assert i.get(2) == @~"Carol";
    assert i.intern(@~"Bob") == 1;
}
<|endoftext|>


<commit_before>extern crate pureconfig;

use pureconfig::Config;
use pureconfig::ParseError;

#[test]
fn root_level_empty() {
    let config: Config = "".parse().unwrap();
    assert_eq!(config.get("hostname"), None);
}

#[test]
fn root_level_single_property() {
    let config: Config = "hostname = \"dynamo\"".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo"));
}

#[test]
fn root_level_three_properties() {
    let config: Config = "hostname = \"dynamo\"\nport = \"5153\"\npath = \"/foo/bar\""
        .parse()
        .unwrap();
    assert_eq!(config.get("path"), Some("/foo/bar"));
}

#[test]
fn just_a_word() {
    assert_eq!("hostname".parse::<Config>().unwrap_err(),
               ParseError::Syntax);
}

#[test]
fn word_and_equals() {
    assert_eq!("hostname = ".parse::<Config>().unwrap_err(),
               ParseError::Syntax);
}

#[test]
fn root_level_property_with_dots() {
    let config: Config = "host.name = \"dynamo\"".parse().unwrap();
    println!("config: {:?}", config);
    assert_eq!(config.get("host.name"), Some("dynamo"));
}

#[test]
fn root_level_property_with_many_dots_together() {
    assert_eq!("host..name = \"dynamo\"".parse::<Config>().unwrap_err(),
               ParseError::Syntax);
}

#[test]
fn bare_words() {
    let config: Config = "hostname = dynamo".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo"));
}

#[test]
fn multiline_bare_words() {
    let config: Config = "hostname = dynamo\nport = 5153\npath = /foo/bar".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo"));
    assert_eq!(config.get("path"), Some("/foo/bar"));
}

#[test]
fn bare_words_until_end_of_line() {
    let config: Config = "hostname = dynamo is bae".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo is bae"));
}

#[test]
fn quoted_word_with_stuff_after() {
    assert_eq!("host..name = \"dynamo\"great".parse::<Config>().unwrap_err(),
               ParseError::Syntax);
    assert_eq!("host..name = \"dynamo\" great".parse::<Config>().unwrap_err(),
               ParseError::Syntax);
}
<commit_msg>extract syntax error helper<commit_after>extern crate pureconfig;

use pureconfig::Config;

fn assert_syntax_error(contents: &str) {
    assert_eq!(contents.parse::<Config>().unwrap_err(),
               pureconfig::ParseError::Syntax);
}

#[test]
fn root_level_empty() {
    let config: Config = "".parse().unwrap();
    assert_eq!(config.get("hostname"), None);
}

#[test]
fn root_level_single_property() {
    let config: Config = "hostname = \"dynamo\"".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo"));
}

#[test]
fn root_level_three_properties() {
    let config: Config = "hostname = \"dynamo\"\nport = \"5153\"\npath = \"/foo/bar\""
        .parse()
        .unwrap();
    assert_eq!(config.get("path"), Some("/foo/bar"));
}

#[test]
fn just_a_word() {
    assert_syntax_error("hostname");
}

#[test]
fn word_and_equals() {
    assert_syntax_error("hostname = ");
}

#[test]
fn root_level_property_with_dots() {
    let config: Config = "host.name = \"dynamo\"".parse().unwrap();
    assert_eq!(config.get("host.name"), Some("dynamo"));
}

#[test]
fn root_level_property_with_many_dots_together() {
    assert_syntax_error("host..name = \"dynamo\"");
}

#[test]
fn bare_words() {
    let config: Config = "hostname = dynamo".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo"));
}

#[test]
fn multiline_bare_words() {
    let config: Config = "hostname = dynamo\nport = 5153\npath = /foo/bar".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo"));
    assert_eq!(config.get("path"), Some("/foo/bar"));
}

#[test]
fn bare_words_until_end_of_line() {
    let config: Config = "hostname = dynamo is bae".parse().unwrap();
    assert_eq!(config.get("hostname"), Some("dynamo is bae"));
}

#[test]
fn quoted_word_with_stuff_after() {
    assert_syntax_error("host..name = \"dynamo\"great");
    assert_syntax_error("host..name = \"dynamo\" great");
}
<|endoftext|>


<commit_before>extern crate lang;

use lang::sexp;

fn ast(code: &str) -> String {
    sexp::parse(code.to_owned()).dump()
}

fn match_ast(actual: &str, expected: &str) {
    let actual = actual.trim();
    let expected = expected.trim();
    if actual != expected {
        panic!("Actual:\n{}\nExpected:\n{}\n", actual, expected)
    }
}

#[test]
fn simple() {
    match_ast(
        &ast("( hello ( world )  )"), r#"
FILE
  LIST
    LPAREN "("
    WHITESPACE " "
    ATOM "hello"
    WHITESPACE " "
    LIST
      LPAREN "("
      WHITESPACE " "
      ATOM "world"
      WHITESPACE " "
      ERROR
        RPAREN ")"
        WHITESPACE "  "
        RPAREN ")"
"#)
}
<commit_msg>Test for empty file and whitespace<commit_after>extern crate lang;

use lang::sexp;

fn ast(code: &str) -> String {
    sexp::parse(code.to_owned()).dump()
}

fn match_ast(actual: &str, expected: &str) {
    let actual = actual.trim();
    let expected = expected.trim();
    if actual != expected {
        panic!("Actual:\n{}\nExpected:\n{}\n", actual, expected)
    }
}

#[test]
fn empty_file() {
    match_ast(&ast(""), r#"FILE """#);
    match_ast(&ast(" \n "), r#"
FILE
  WHITESPACE " \n "
"#)
}

#[test]
fn trailing_ws() {
    match_ast(&ast(" a "), r#"
FILE
  WHITESPACE " "
  ATOM "a"
  WHITESPACE " "
"#)
}

#[test]
fn simple() {
    match_ast(
        &ast("( hello ( world )  )"), r#"
FILE
  LIST
    LPAREN "("
    WHITESPACE " "
    ATOM "hello"
    WHITESPACE " "
    LIST
      LPAREN "("
      WHITESPACE " "
      ATOM "world"
      WHITESPACE " "
      ERROR
        RPAREN ")"
        WHITESPACE "  "
        RPAREN ")"
"#)
}
<|endoftext|>


<commit_before>extern crate serde_bytes;
use serde_bytes::{ByteBuf, Bytes};

extern crate serde_test;
use serde_test::{assert_de_tokens, assert_ser_tokens, assert_tokens, Token};

#[test]
fn test_bytes() {
    let empty = Bytes::new(&[]);
    assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
    assert_ser_tokens(&empty, &[Token::Bytes(b"")]);
    assert_ser_tokens(&empty, &[Token::ByteBuf(b"")]);
    assert_de_tokens(&empty, &[Token::BorrowedStr("")]);

    let buf = vec![65, 66, 67];
    let bytes = Bytes::new(&buf);
    assert_tokens(&bytes, &[Token::BorrowedBytes(b"ABC")]);
    assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]);
    assert_ser_tokens(&bytes, &[Token::ByteBuf(b"ABC")]);
    assert_de_tokens(&bytes, &[Token::BorrowedStr("ABC")]);
}

#[test]
fn test_byte_buf() {
    let empty = ByteBuf::new();
    assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
    assert_tokens(&empty, &[Token::Bytes(b"")]);
    assert_tokens(&empty, &[Token::ByteBuf(b"")]);
    assert_de_tokens(&empty, &[Token::BorrowedStr("")]);
    assert_de_tokens(&empty, &[Token::Str("")]);
    assert_de_tokens(&empty, &[Token::String("")]);
    assert_de_tokens(&empty, &[Token::Seq { len: None }, Token::SeqEnd]);
    assert_de_tokens(&empty, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);

    let buf = ByteBuf::from(vec![65, 66, 67]);
    assert_tokens(&buf, &[Token::BorrowedBytes(b"ABC")]);
    assert_tokens(&buf, &[Token::Bytes(b"ABC")]);
    assert_tokens(&buf, &[Token::ByteBuf(b"ABC")]);
    assert_de_tokens(&buf, &[Token::BorrowedStr("ABC")]);
    assert_de_tokens(&buf, &[Token::Str("ABC")]);
    assert_de_tokens(&buf, &[Token::String("ABC")]);
    assert_de_tokens(
        &buf,
        &[
            Token::Seq { len: None },
            Token::U8(65),
            Token::U8(66),
            Token::U8(67),
            Token::SeqEnd,
        ],
    );
    assert_de_tokens(
        &buf,
        &[
            Token::Seq { len: Some(3) },
            Token::U8(65),
            Token::U8(66),
            Token::U8(67),
            Token::SeqEnd,
        ],
    );
}
<commit_msg>Update tests to 2018 edition<commit_after>use serde_bytes::{ByteBuf, Bytes};
use serde_test::{assert_de_tokens, assert_ser_tokens, assert_tokens, Token};

#[test]
fn test_bytes() {
    let empty = Bytes::new(&[]);
    assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
    assert_ser_tokens(&empty, &[Token::Bytes(b"")]);
    assert_ser_tokens(&empty, &[Token::ByteBuf(b"")]);
    assert_de_tokens(&empty, &[Token::BorrowedStr("")]);

    let buf = vec![65, 66, 67];
    let bytes = Bytes::new(&buf);
    assert_tokens(&bytes, &[Token::BorrowedBytes(b"ABC")]);
    assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]);
    assert_ser_tokens(&bytes, &[Token::ByteBuf(b"ABC")]);
    assert_de_tokens(&bytes, &[Token::BorrowedStr("ABC")]);
}

#[test]
fn test_byte_buf() {
    let empty = ByteBuf::new();
    assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
    assert_tokens(&empty, &[Token::Bytes(b"")]);
    assert_tokens(&empty, &[Token::ByteBuf(b"")]);
    assert_de_tokens(&empty, &[Token::BorrowedStr("")]);
    assert_de_tokens(&empty, &[Token::Str("")]);
    assert_de_tokens(&empty, &[Token::String("")]);
    assert_de_tokens(&empty, &[Token::Seq { len: None }, Token::SeqEnd]);
    assert_de_tokens(&empty, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);

    let buf = ByteBuf::from(vec![65, 66, 67]);
    assert_tokens(&buf, &[Token::BorrowedBytes(b"ABC")]);
    assert_tokens(&buf, &[Token::Bytes(b"ABC")]);
    assert_tokens(&buf, &[Token::ByteBuf(b"ABC")]);
    assert_de_tokens(&buf, &[Token::BorrowedStr("ABC")]);
    assert_de_tokens(&buf, &[Token::Str("ABC")]);
    assert_de_tokens(&buf, &[Token::String("ABC")]);
    assert_de_tokens(
        &buf,
        &[
            Token::Seq { len: None },
            Token::U8(65),
            Token::U8(66),
            Token::U8(67),
            Token::SeqEnd,
        ],
    );
    assert_de_tokens(
        &buf,
        &[
            Token::Seq { len: Some(3) },
            Token::U8(65),
            Token::U8(66),
            Token::U8(67),
            Token::SeqEnd,
        ],
    );
}
<|endoftext|>