<commit_before>pub type clock_t = c_long;
pub type time_t = c_long;
pub type suseconds_t = c_long;
pub type ino_t = u64;
pub type off_t = i64;
pub type blkcnt_t = i64;

pub type shmatt_t = ::c_ulong;
pub type msgqnum_t = ::c_ulong;
pub type msglen_t = ::c_ulong;
pub type fsblkcnt_t = ::c_ulonglong;
pub type fsfilcnt_t = ::c_ulonglong;
pub type rlim_t = ::c_ulonglong;

s! {
    pub struct aiocb {
        pub aio_fildes: ::c_int,
        pub aio_lio_opcode: ::c_int,
        pub aio_reqprio: ::c_int,
        pub aio_buf: *mut ::c_void,
        pub aio_nbytes: ::size_t,
        pub aio_sigevent: ::sigevent,
        __td: *mut ::c_void,
        __lock: [::c_int; 2],
        __err: ::c_int,
        __ret: ::ssize_t,
        pub aio_offset: off_t,
        __next: *mut ::c_void,
        __prev: *mut ::c_void,
        #[cfg(target_pointer_width = "32")]
        __dummy4: [::c_char; 24],
        #[cfg(target_pointer_width = "64")]
        __dummy4: [::c_char; 16],
    }

    pub struct sigaction {
        pub sa_sigaction: ::sighandler_t,
        pub sa_mask: ::sigset_t,
        pub sa_flags: ::c_int,
        pub sa_restorer: ::dox::Option<extern fn()>,
    }

    pub struct statvfs {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: ::fsblkcnt_t,
        pub f_bfree: ::fsblkcnt_t,
        pub f_bavail: ::fsblkcnt_t,
        pub f_files: ::fsfilcnt_t,
        pub f_ffree: ::fsfilcnt_t,
        pub f_favail: ::fsfilcnt_t,
        #[cfg(target_endian = "little")]
        pub f_fsid: ::c_ulong,
        #[cfg(target_pointer_width = "32")]
        __f_unused: ::c_int,
        #[cfg(target_endian = "big")]
        pub f_fsid: ::c_ulong,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
        __f_spare: [::c_int; 6],
    }

    pub struct termios {
        pub c_iflag: ::tcflag_t,
        pub c_oflag: ::tcflag_t,
        pub c_cflag: ::tcflag_t,
        pub c_lflag: ::tcflag_t,
        pub c_line: ::cc_t,
        pub c_cc: [::cc_t; ::NCCS],
        pub __c_ispeed: ::speed_t,
        pub __c_ospeed: ::speed_t,
    }

    pub struct flock {
        pub l_type: ::c_short,
        pub l_whence: ::c_short,
        pub l_start: ::off_t,
        pub l_len: ::off_t,
        pub l_pid: ::pid_t,
    }

    pub struct sysinfo {
        pub uptime: ::c_ulong,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub __reserved: [::c_char; 256],
    }
}

pub const SFD_CLOEXEC: ::c_int = 0x080000;

pub const NCCS: usize = 32;

pub const O_TRUNC: ::c_int = 512;
pub const O_NOATIME: ::c_int = 0o1000000;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY;

pub const EBFONT: ::c_int = 59;
pub const ENOSTR: ::c_int = 60;
pub const ENODATA: ::c_int = 61;
pub const ETIME: ::c_int = 62;
pub const ENOSR: ::c_int = 63;
pub const ENONET: ::c_int = 64;
pub const ENOPKG: ::c_int = 65;
pub const EREMOTE: ::c_int = 66;
pub const ENOLINK: ::c_int = 67;
pub const EADV: ::c_int = 68;
pub const ESRMNT: ::c_int = 69;
pub const ECOMM: ::c_int = 70;
pub const EPROTO: ::c_int = 71;
pub const EDOTDOT: ::c_int = 73;

pub const F_RDLCK: ::c_int = 0;
pub const F_WRLCK: ::c_int = 1;
pub const F_UNLCK: ::c_int = 2;

pub const SA_NODEFER: ::c_int = 0x40000000;
pub const SA_RESETHAND: ::c_int = 0x80000000;
pub const SA_RESTART: ::c_int = 0x10000000;
pub const SA_NOCLDSTOP: ::c_int = 0x00000001;

pub const EPOLL_CLOEXEC: ::c_int = 0x80000;

pub const EFD_CLOEXEC: ::c_int = 0x80000;

pub const BUFSIZ: ::c_uint = 1024;
pub const TMP_MAX: ::c_uint = 10000;
pub const FOPEN_MAX: ::c_uint = 1000;
pub const O_PATH: ::c_int = 0o10000000;
pub const O_EXEC: ::c_int = 0o10000000;
pub const O_SEARCH: ::c_int = 0o10000000;
pub const O_ACCMODE: ::c_int = 0o10000003;
pub const O_NDELAY: ::c_int = O_NONBLOCK;
pub const NI_MAXHOST: ::socklen_t = 255;
pub const PTHREAD_STACK_MIN: ::size_t = 2048;
pub const POSIX_FADV_DONTNEED: ::c_int = 4;
pub const POSIX_FADV_NOREUSE: ::c_int = 5;

pub const POSIX_MADV_DONTNEED: ::c_int = 4;

pub const RLIM_INFINITY: ::rlim_t = !0;
pub const RLIMIT_RTTIME: ::c_int = 15;

pub const MAP_ANONYMOUS: ::c_int = MAP_ANON;

pub const SOCK_DCCP: ::c_int = 6;
pub const SOCK_PACKET: ::c_int = 10;

pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15;
pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16;
pub const TCP_THIN_DUPACK: ::c_int = 17;
pub const TCP_USER_TIMEOUT: ::c_int = 18;
pub const TCP_REPAIR: ::c_int = 19;
pub const TCP_REPAIR_QUEUE: ::c_int = 20;
pub const TCP_QUEUE_SEQ: ::c_int = 21;
pub const TCP_REPAIR_OPTIONS: ::c_int = 22;
pub const TCP_FASTOPEN: ::c_int = 23;
pub const TCP_TIMESTAMP: ::c_int = 24;

pub const SIGUNUSED: ::c_int = ::SIGSYS;

pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;

pub const CPU_SETSIZE: ::c_int = 128;

pub const PTRACE_TRACEME: ::c_int = 0;
pub const PTRACE_PEEKTEXT: ::c_int = 1;
pub const PTRACE_PEEKDATA: ::c_int = 2;
pub const PTRACE_PEEKUSER: ::c_int = 3;
pub const PTRACE_POKETEXT: ::c_int = 4;
pub const PTRACE_POKEDATA: ::c_int = 5;
pub const PTRACE_POKEUSER: ::c_int = 6;
pub const PTRACE_CONT: ::c_int = 7;
pub const PTRACE_KILL: ::c_int = 8;
pub const PTRACE_SINGLESTEP: ::c_int = 9;
pub const PTRACE_GETREGS: ::c_int = 12;
pub const PTRACE_SETREGS: ::c_int = 13;
pub const PTRACE_GETFPREGS: ::c_int = 14;
pub const PTRACE_SETFPREGS: ::c_int = 15;
pub const PTRACE_ATTACH: ::c_int = 16;
pub const PTRACE_DETACH: ::c_int = 17;
pub const PTRACE_GETFPXREGS: ::c_int = 18;
pub const PTRACE_SETFPXREGS: ::c_int = 19;
pub const PTRACE_SYSCALL: ::c_int = 24;
pub const PTRACE_SETOPTIONS: ::c_int = 0x4200;
pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201;
pub const PTRACE_GETSIGINFO: ::c_int = 0x4202;
pub const PTRACE_SETSIGINFO: ::c_int = 0x4203;
pub const PTRACE_GETREGSET: ::c_int = 0x4204;
pub const PTRACE_SETREGSET: ::c_int = 0x4205;
pub const PTRACE_SEIZE: ::c_int = 0x4206;
pub const PTRACE_INTERRUPT: ::c_int = 0x4207;
pub const PTRACE_LISTEN: ::c_int = 0x4208;
pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209;

pub const EPOLLWAKEUP: ::c_int = 0x20000000;

pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK;

pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK;

pub const TCSANOW: ::c_int = 0;
pub const TCSADRAIN: ::c_int = 1;
pub const TCSAFLUSH: ::c_int = 2;

pub const RTLD_GLOBAL: ::c_int = 0x100;
pub const RTLD_NOLOAD: ::c_int = 0x4;

// TODO(#247) Temporarily musl-specific (available since musl 0.9.12 / Linux
// kernel 3.10).  See also notbsd/mod.rs
pub const CLOCK_SGI_CYCLE: ::clockid_t = 10;
pub const CLOCK_TAI: ::clockid_t = 11;

pub const B0: ::speed_t = 0o000000;
pub const B50: ::speed_t = 0o000001;
pub const B75: ::speed_t = 0o000002;
pub const B110: ::speed_t = 0o000003;
pub const B134: ::speed_t = 0o000004;
pub const B150: ::speed_t = 0o000005;
pub const B200: ::speed_t = 0o000006;
pub const B300: ::speed_t = 0o000007;
pub const B600: ::speed_t = 0o000010;
pub const B1200: ::speed_t = 0o000011;
pub const B1800: ::speed_t = 0o000012;
pub const B2400: ::speed_t = 0o000013;
pub const B4800: ::speed_t = 0o000014;
pub const B9600: ::speed_t = 0o000015;
pub const B19200: ::speed_t = 0o000016;
pub const B38400: ::speed_t = 0o000017;
pub const EXTA: ::speed_t = B19200;
pub const EXTB: ::speed_t = B38400;

pub const SO_BINDTODEVICE: ::c_int = 25;
pub const SO_TIMESTAMP: ::c_int = 29;
pub const SO_MARK: ::c_int = 36;
pub const SO_RXQ_OVFL: ::c_int = 40;
pub const SO_PEEK_OFF: ::c_int = 42;
pub const SO_BUSY_POLL: ::c_int = 46;

extern {
    pub fn ptrace(request: ::c_int, ...) -> ::c_long;
    pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int;
    pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int;
}

cfg_if! {
    if #[cfg(any(target_arch = "x86_64",
                 target_arch = "aarch64",
                 target_arch = "powerpc64"))] {
        mod b64;
        pub use self::b64::*;
    } else if #[cfg(any(target_arch = "x86",
                        target_arch = "mips",
                        target_arch = "arm",
                        target_arch = "powerpc"))] {
        mod b32;
        pub use self::b32::*;
    } else { }
}
<commit_msg>Auto merge of #1146 - mwanner:musl-pthread-affinity, r=alexcrichton<commit_after>pub type clock_t = c_long;
pub type time_t = c_long;
pub type suseconds_t = c_long;
pub type ino_t = u64;
pub type off_t = i64;
pub type blkcnt_t = i64;

pub type shmatt_t = ::c_ulong;
pub type msgqnum_t = ::c_ulong;
pub type msglen_t = ::c_ulong;
pub type fsblkcnt_t = ::c_ulonglong;
pub type fsfilcnt_t = ::c_ulonglong;
pub type rlim_t = ::c_ulonglong;

s! {
    pub struct aiocb {
        pub aio_fildes: ::c_int,
        pub aio_lio_opcode: ::c_int,
        pub aio_reqprio: ::c_int,
        pub aio_buf: *mut ::c_void,
        pub aio_nbytes: ::size_t,
        pub aio_sigevent: ::sigevent,
        __td: *mut ::c_void,
        __lock: [::c_int; 2],
        __err: ::c_int,
        __ret: ::ssize_t,
        pub aio_offset: off_t,
        __next: *mut ::c_void,
        __prev: *mut ::c_void,
        #[cfg(target_pointer_width = "32")]
        __dummy4: [::c_char; 24],
        #[cfg(target_pointer_width = "64")]
        __dummy4: [::c_char; 16],
    }

    pub struct sigaction {
        pub sa_sigaction: ::sighandler_t,
        pub sa_mask: ::sigset_t,
        pub sa_flags: ::c_int,
        pub sa_restorer: ::dox::Option<extern fn()>,
    }

    pub struct statvfs {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: ::fsblkcnt_t,
        pub f_bfree: ::fsblkcnt_t,
        pub f_bavail: ::fsblkcnt_t,
        pub f_files: ::fsfilcnt_t,
        pub f_ffree: ::fsfilcnt_t,
        pub f_favail: ::fsfilcnt_t,
        #[cfg(target_endian = "little")]
        pub f_fsid: ::c_ulong,
        #[cfg(target_pointer_width = "32")]
        __f_unused: ::c_int,
        #[cfg(target_endian = "big")]
        pub f_fsid: ::c_ulong,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
        __f_spare: [::c_int; 6],
    }

    pub struct termios {
        pub c_iflag: ::tcflag_t,
        pub c_oflag: ::tcflag_t,
        pub c_cflag: ::tcflag_t,
        pub c_lflag: ::tcflag_t,
        pub c_line: ::cc_t,
        pub c_cc: [::cc_t; ::NCCS],
        pub __c_ispeed: ::speed_t,
        pub __c_ospeed: ::speed_t,
    }

    pub struct flock {
        pub l_type: ::c_short,
        pub l_whence: ::c_short,
        pub l_start: ::off_t,
        pub l_len: ::off_t,
        pub l_pid: ::pid_t,
    }

    pub struct sysinfo {
        pub uptime: ::c_ulong,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub __reserved: [::c_char; 256],
    }
}

pub const SFD_CLOEXEC: ::c_int = 0x080000;

pub const NCCS: usize = 32;

pub const O_TRUNC: ::c_int = 512;
pub const O_NOATIME: ::c_int = 0o1000000;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY;

pub const EBFONT: ::c_int = 59;
pub const ENOSTR: ::c_int = 60;
pub const ENODATA: ::c_int = 61;
pub const ETIME: ::c_int = 62;
pub const ENOSR: ::c_int = 63;
pub const ENONET: ::c_int = 64;
pub const ENOPKG: ::c_int = 65;
pub const EREMOTE: ::c_int = 66;
pub const ENOLINK: ::c_int = 67;
pub const EADV: ::c_int = 68;
pub const ESRMNT: ::c_int = 69;
pub const ECOMM: ::c_int = 70;
pub const EPROTO: ::c_int = 71;
pub const EDOTDOT: ::c_int = 73;

pub const F_RDLCK: ::c_int = 0;
pub const F_WRLCK: ::c_int = 1;
pub const F_UNLCK: ::c_int = 2;

pub const SA_NODEFER: ::c_int = 0x40000000;
pub const SA_RESETHAND: ::c_int = 0x80000000;
pub const SA_RESTART: ::c_int = 0x10000000;
pub const SA_NOCLDSTOP: ::c_int = 0x00000001;

pub const EPOLL_CLOEXEC: ::c_int = 0x80000;

pub const EFD_CLOEXEC: ::c_int = 0x80000;

pub const BUFSIZ: ::c_uint = 1024;
pub const TMP_MAX: ::c_uint = 10000;
pub const FOPEN_MAX: ::c_uint = 1000;
pub const O_PATH: ::c_int = 0o10000000;
pub const O_EXEC: ::c_int = 0o10000000;
pub const O_SEARCH: ::c_int = 0o10000000;
pub const O_ACCMODE: ::c_int = 0o10000003;
pub const O_NDELAY: ::c_int = O_NONBLOCK;
pub const NI_MAXHOST: ::socklen_t = 255;
pub const PTHREAD_STACK_MIN: ::size_t = 2048;
pub const POSIX_FADV_DONTNEED: ::c_int = 4;
pub const POSIX_FADV_NOREUSE: ::c_int = 5;

pub const POSIX_MADV_DONTNEED: ::c_int = 4;

pub const RLIM_INFINITY: ::rlim_t = !0;
pub const RLIMIT_RTTIME: ::c_int = 15;

pub const MAP_ANONYMOUS: ::c_int = MAP_ANON;

pub const SOCK_DCCP: ::c_int = 6;
pub const SOCK_PACKET: ::c_int = 10;

pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15;
pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16;
pub const TCP_THIN_DUPACK: ::c_int = 17;
pub const TCP_USER_TIMEOUT: ::c_int = 18;
pub const TCP_REPAIR: ::c_int = 19;
pub const TCP_REPAIR_QUEUE: ::c_int = 20;
pub const TCP_QUEUE_SEQ: ::c_int = 21;
pub const TCP_REPAIR_OPTIONS: ::c_int = 22;
pub const TCP_FASTOPEN: ::c_int = 23;
pub const TCP_TIMESTAMP: ::c_int = 24;

pub const SIGUNUSED: ::c_int = ::SIGSYS;

pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;

pub const CPU_SETSIZE: ::c_int = 128;

pub const PTRACE_TRACEME: ::c_int = 0;
pub const PTRACE_PEEKTEXT: ::c_int = 1;
pub const PTRACE_PEEKDATA: ::c_int = 2;
pub const PTRACE_PEEKUSER: ::c_int = 3;
pub const PTRACE_POKETEXT: ::c_int = 4;
pub const PTRACE_POKEDATA: ::c_int = 5;
pub const PTRACE_POKEUSER: ::c_int = 6;
pub const PTRACE_CONT: ::c_int = 7;
pub const PTRACE_KILL: ::c_int = 8;
pub const PTRACE_SINGLESTEP: ::c_int = 9;
pub const PTRACE_GETREGS: ::c_int = 12;
pub const PTRACE_SETREGS: ::c_int = 13;
pub const PTRACE_GETFPREGS: ::c_int = 14;
pub const PTRACE_SETFPREGS: ::c_int = 15;
pub const PTRACE_ATTACH: ::c_int = 16;
pub const PTRACE_DETACH: ::c_int = 17;
pub const PTRACE_GETFPXREGS: ::c_int = 18;
pub const PTRACE_SETFPXREGS: ::c_int = 19;
pub const PTRACE_SYSCALL: ::c_int = 24;
pub const PTRACE_SETOPTIONS: ::c_int = 0x4200;
pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201;
pub const PTRACE_GETSIGINFO: ::c_int = 0x4202;
pub const PTRACE_SETSIGINFO: ::c_int = 0x4203;
pub const PTRACE_GETREGSET: ::c_int = 0x4204;
pub const PTRACE_SETREGSET: ::c_int = 0x4205;
pub const PTRACE_SEIZE: ::c_int = 0x4206;
pub const PTRACE_INTERRUPT: ::c_int = 0x4207;
pub const PTRACE_LISTEN: ::c_int = 0x4208;
pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209;

pub const EPOLLWAKEUP: ::c_int = 0x20000000;

pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK;

pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK;

pub const TCSANOW: ::c_int = 0;
pub const TCSADRAIN: ::c_int = 1;
pub const TCSAFLUSH: ::c_int = 2;

pub const RTLD_GLOBAL: ::c_int = 0x100;
pub const RTLD_NOLOAD: ::c_int = 0x4;

// TODO(#247) Temporarily musl-specific (available since musl 0.9.12 / Linux
// kernel 3.10).  See also notbsd/mod.rs
pub const CLOCK_SGI_CYCLE: ::clockid_t = 10;
pub const CLOCK_TAI: ::clockid_t = 11;

pub const B0: ::speed_t = 0o000000;
pub const B50: ::speed_t = 0o000001;
pub const B75: ::speed_t = 0o000002;
pub const B110: ::speed_t = 0o000003;
pub const B134: ::speed_t = 0o000004;
pub const B150: ::speed_t = 0o000005;
pub const B200: ::speed_t = 0o000006;
pub const B300: ::speed_t = 0o000007;
pub const B600: ::speed_t = 0o000010;
pub const B1200: ::speed_t = 0o000011;
pub const B1800: ::speed_t = 0o000012;
pub const B2400: ::speed_t = 0o000013;
pub const B4800: ::speed_t = 0o000014;
pub const B9600: ::speed_t = 0o000015;
pub const B19200: ::speed_t = 0o000016;
pub const B38400: ::speed_t = 0o000017;
pub const EXTA: ::speed_t = B19200;
pub const EXTB: ::speed_t = B38400;

pub const SO_BINDTODEVICE: ::c_int = 25;
pub const SO_TIMESTAMP: ::c_int = 29;
pub const SO_MARK: ::c_int = 36;
pub const SO_RXQ_OVFL: ::c_int = 40;
pub const SO_PEEK_OFF: ::c_int = 42;
pub const SO_BUSY_POLL: ::c_int = 46;

extern {
    pub fn ptrace(request: ::c_int, ...) -> ::c_long;
    pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int;
    pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int;
    pub fn pthread_getaffinity_np(thread: ::pthread_t,
                                  cpusetsize: ::size_t,
                                  cpuset: *mut ::cpu_set_t) -> ::c_int;
    pub fn pthread_setaffinity_np(thread: ::pthread_t,
                                  cpusetsize: ::size_t,
                                  cpuset: *const ::cpu_set_t) -> ::c_int;
    pub fn sched_getcpu() -> ::c_int;
}

cfg_if! {
    if #[cfg(any(target_arch = "x86_64",
                 target_arch = "aarch64",
                 target_arch = "powerpc64"))] {
        mod b64;
        pub use self::b64::*;
    } else if #[cfg(any(target_arch = "x86",
                        target_arch = "mips",
                        target_arch = "arm",
                        target_arch = "powerpc"))] {
        mod b32;
        pub use self::b32::*;
    } else { }
}
<|endoftext|>


<commit_before>extern crate serialize;

use serialize::{Encoder, Decoder};
use std::io;
use std::io::{IoResult, Reader, Writer, IoError};
use std::char::from_u32;

pub struct BinaryDecoder<R: Reader> { reader: R }

impl<R: Reader> serialize::Decoder for BinaryDecoder<R>
{
    pub type Error = IoError;

    fn read_nil(&mut self)  -> IoResult<()> { Ok(()) }

    fn read_uint(&mut self) -> IoResult<uint>   { self.reader.read_le_uint() }
    fn read_u64(&mut self)  -> IoResult<u64>    { self.reader.read_le_u64() }
    fn read_u32(&mut self)  -> IoResult<u32>    { self.reader.read_le_u32() }
    fn read_u16(&mut self)  -> IoResult<u16>    { self.reader.read_le_u16() }
    fn read_u8(&mut self)   -> IoResult<u8>     { self.reader.read_u8() }

    fn read_int(&mut self)  -> IoResult<int>    { self.reader.read_le_int() }
    fn read_i64(&mut self)  -> IoResult<i64>    { self.reader.read_le_i64() }
    fn read_i32(&mut self)  -> IoResult<i32>    { self.reader.read_le_i32() }
    fn read_i16(&mut self)  -> IoResult<i16>    { self.reader.read_le_i16() }
    fn read_i8(&mut self)   -> IoResult<i8>     { self.reader.read_i8() }
    fn read_bool(&mut self) -> IoResult<bool>   { Ok(try!(self.reader.read_u8()) != 0) }

    fn read_f64(&mut self)  -> IoResult<f64>    { self.reader.read_le_f64() }
    fn read_f32(&mut self)  -> IoResult<f32>    { self.reader.read_le_f32() }

    fn read_char(&mut self) -> IoResult<char>   { self.reader.read_le_u32().map(|x| from_u32(x).unwrap()) }
    fn read_str(&mut self)  -> IoResult<String> { self.reader.read_to_string() }

    fn read_enum<T, F>(&mut self, _name: &str, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_enum_variant<T, F>(&mut self, _names: &[&str], f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, uint) -> IoResult<T>
        { let variant = try!(self.reader.read_le_uint()); f(self, variant) }
    fn read_enum_variant_arg<T, F>(&mut self, _a_idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, uint) -> IoResult<T>
        { let variant = try!(self.reader.read_le_uint()); f(self, variant) }
    fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T>
        { f(self) }

    fn read_struct<T, F>(&mut self, _s_name: &str, _len: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T>
        { f(self) }
    fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn read_tuple<T, F>(&mut self, _len: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_tuple_arg<T, F>(&mut self, _a_idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn read_option<T, F>(&mut self, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, bool) -> IoResult<T>
        { let some = try!(self.reader.read_u8()); f(self, some != 0) }

    fn read_seq<T, F>(&mut self, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, uint) -> IoResult<T>
        { let len = try!(self.reader.read_le_uint()); f(self, len) }
    fn read_seq_elt<T, F>(&mut self, _idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn read_map<T, F>(&mut self, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, uint) -> IoResult<T>
        { let len = try!(self.reader.read_le_uint()); f(self, len) }
    fn read_map_elt_key<T, F>(&mut self, _idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_map_elt_val<T, F>(&mut self, _idx: uint, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn error(&mut self, _err: &str) -> io::IoError { IoError::last_error() }
}

pub struct BinaryEncoder<R: Writer> { writer: R }

impl<R: Writer> serialize::Encoder for BinaryEncoder<R>
{
    pub type Error = IoError;

    fn emit_nil(&mut self)            -> IoResult<()> { Ok(()) }

    fn emit_uint(&mut self, v: uint)  -> IoResult<()> { self.writer.write_le_uint(v) }
    fn emit_u64(&mut self, v: u64)    -> IoResult<()> { self.writer.write_le_u64(v) }
    fn emit_u32(&mut self, v: u32)    -> IoResult<()> { self.writer.write_le_u32(v) }
    fn emit_u16(&mut self, v: u16)    -> IoResult<()> { self.writer.write_le_u16(v) }
    fn emit_u8(&mut self, v: u8)      -> IoResult<()> { self.writer.write_u8(v) }

    fn emit_int(&mut self, v: int)    -> IoResult<()> { self.writer.write_le_int(v) }
    fn emit_i64(&mut self, v: i64)    -> IoResult<()> { self.writer.write_le_i64(v) }
    fn emit_i32(&mut self, v: i32)    -> IoResult<()> { self.writer.write_le_i32(v) }
    fn emit_i16(&mut self, v: i16)    -> IoResult<()> { self.writer.write_le_i16(v) }
    fn emit_i8(&mut self, v: i8)      -> IoResult<()> { self.writer.write_i8(v) }

    fn emit_bool(&mut self, v: bool)  -> IoResult<()> { self.writer.write_u8(if v { 1 } else { 0 }) }

    fn emit_f64(&mut self, v: f64)    -> IoResult<()> { self.writer.write_le_f64(v) }
    fn emit_f32(&mut self, v: f32)    -> IoResult<()> { self.writer.write_le_f32(v) }

    fn emit_char(&mut self, _v: char) -> IoResult<()> { self.writer.write_le_u32(_v as u32) }
    fn emit_str(&mut self, v: &str)   -> IoResult<()> { self.writer.write_str(v) }

    fn emit_enum<F>(&mut self, _name: &str, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_enum_variant<F>(&mut self, _v_name: &str, v_id: uint, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(v_id)); f(self) }
    fn emit_enum_variant_arg<F>(&mut self, _a_idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_enum_struct_variant<F>(&mut self, _v_name: &str, v_id: uint, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(v_id)); f(self) }
    fn emit_enum_struct_variant_field<F>(&mut self, _f_name: &str, _f_idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { f(self) }

    fn emit_struct<F>(&mut self, _name: &str, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_struct_field<F>(&mut self, _f_name: &str, _f_idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }

    fn emit_tuple<F>(&mut self, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_tuple_arg<F>(&mut self, _idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_tuple_struct<F>(&mut self, _name: &str, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_tuple_struct_arg<F>(&mut self, _f_idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }

    fn emit_option<F>(&mut self, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_option_none(&mut self) -> IoResult<()> { try!(self.writer.write_u8(0)); Ok(()) }
    fn emit_option_some<F>(&mut self, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_u8(1)); f(self) }

    fn emit_seq<F>(&mut self, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(_len)); f(self) }
    fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }

    fn emit_map<F>(&mut self, _len: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(_len)); f(self) }
    fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
}
<commit_msg>serialization uint/int update<commit_after>extern crate serialize;

use serialize::{Encoder, Decoder};
use std::io;
use std::io::{IoResult, Reader, Writer, IoError};
use std::char::from_u32;

pub struct BinaryDecoder<R: Reader> { reader: R }

impl<R: Reader> serialize::Decoder for BinaryDecoder<R>
{
    pub type Error = IoError;

    fn read_nil(&mut self)  -> IoResult<()> { Ok(()) }

    fn read_uint(&mut self) -> IoResult<usize>   { self.reader.read_le_uint() }
    fn read_u64(&mut self)  -> IoResult<u64>    { self.reader.read_le_u64() }
    fn read_u32(&mut self)  -> IoResult<u32>    { self.reader.read_le_u32() }
    fn read_u16(&mut self)  -> IoResult<u16>    { self.reader.read_le_u16() }
    fn read_u8(&mut self)   -> IoResult<u8>     { self.reader.read_u8() }

    fn read_int(&mut self)  -> IoResult<isize>    { self.reader.read_le_int() }
    fn read_i64(&mut self)  -> IoResult<i64>    { self.reader.read_le_i64() }
    fn read_i32(&mut self)  -> IoResult<i32>    { self.reader.read_le_i32() }
    fn read_i16(&mut self)  -> IoResult<i16>    { self.reader.read_le_i16() }
    fn read_i8(&mut self)   -> IoResult<i8>     { self.reader.read_i8() }
    fn read_bool(&mut self) -> IoResult<bool>   { Ok(try!(self.reader.read_u8()) != 0) }

    fn read_f64(&mut self)  -> IoResult<f64>    { self.reader.read_le_f64() }
    fn read_f32(&mut self)  -> IoResult<f32>    { self.reader.read_le_f32() }

    fn read_char(&mut self) -> IoResult<char>   { self.reader.read_le_u32().map(|x| from_u32(x).unwrap()) }
    fn read_str(&mut self)  -> IoResult<String> { self.reader.read_to_string() }

    fn read_enum<T, F>(&mut self, _name: &str, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_enum_variant<T, F>(&mut self, _names: &[&str], f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, usize) -> IoResult<T>
        { let variant = try!(self.reader.read_le_uint()); f(self, variant) }
    fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, usize) -> IoResult<T>
        { let variant = try!(self.reader.read_le_uint()); f(self, variant) }
    fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T>
        { f(self) }

    fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T>
        { f(self) }
    fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn read_option<T, F>(&mut self, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, bool) -> IoResult<T>
        { let some = try!(self.reader.read_u8()); f(self, some != 0) }

    fn read_seq<T, F>(&mut self, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, usize) -> IoResult<T>
        { let len = try!(self.reader.read_le_uint()); f(self, len) }
    fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn read_map<T, F>(&mut self, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>, usize) -> IoResult<T>
        { let len = try!(self.reader.read_le_uint()); f(self, len) }
    fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }
    fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> IoResult<T>
        where F: FnOnce(&mut BinaryDecoder<R>) -> IoResult<T> { f(self) }

    fn error(&mut self, _err: &str) -> io::IoError { IoError::last_error() }
}

pub struct BinaryEncoder<R: Writer> { writer: R }

impl<R: Writer> serialize::Encoder for BinaryEncoder<R>
{
    pub type Error = IoError;

    fn emit_nil(&mut self)            -> IoResult<()> { Ok(()) }

    fn emit_uint(&mut self, v: usize)  -> IoResult<()> { self.writer.write_le_uint(v) }
    fn emit_u64(&mut self, v: u64)    -> IoResult<()> { self.writer.write_le_u64(v) }
    fn emit_u32(&mut self, v: u32)    -> IoResult<()> { self.writer.write_le_u32(v) }
    fn emit_u16(&mut self, v: u16)    -> IoResult<()> { self.writer.write_le_u16(v) }
    fn emit_u8(&mut self, v: u8)      -> IoResult<()> { self.writer.write_u8(v) }

    fn emit_int(&mut self, v: isize)    -> IoResult<()> { self.writer.write_le_int(v) }
    fn emit_i64(&mut self, v: i64)    -> IoResult<()> { self.writer.write_le_i64(v) }
    fn emit_i32(&mut self, v: i32)    -> IoResult<()> { self.writer.write_le_i32(v) }
    fn emit_i16(&mut self, v: i16)    -> IoResult<()> { self.writer.write_le_i16(v) }
    fn emit_i8(&mut self, v: i8)      -> IoResult<()> { self.writer.write_i8(v) }

    fn emit_bool(&mut self, v: bool)  -> IoResult<()> { self.writer.write_u8(if v { 1 } else { 0 }) }

    fn emit_f64(&mut self, v: f64)    -> IoResult<()> { self.writer.write_le_f64(v) }
    fn emit_f32(&mut self, v: f32)    -> IoResult<()> { self.writer.write_le_f32(v) }

    fn emit_char(&mut self, _v: char) -> IoResult<()> { self.writer.write_le_u32(_v as u32) }
    fn emit_str(&mut self, v: &str)   -> IoResult<()> { self.writer.write_str(v) }

    fn emit_enum<F>(&mut self, _name: &str, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_enum_variant<F>(&mut self, _v_name: &str, v_id: usize, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(v_id)); f(self) }
    fn emit_enum_variant_arg<F>(&mut self, _a_idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_enum_struct_variant<F>(&mut self, _v_name: &str, v_id: usize, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(v_id)); f(self) }
    fn emit_enum_struct_variant_field<F>(&mut self, _f_name: &str, _f_idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { f(self) }

    fn emit_struct<F>(&mut self, _name: &str, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_struct_field<F>(&mut self, _f_name: &str, _f_idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }

    fn emit_tuple<F>(&mut self, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_tuple_arg<F>(&mut self, _idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_tuple_struct<F>(&mut self, _name: &str, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_tuple_struct_arg<F>(&mut self, _f_idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }

    fn emit_option<F>(&mut self, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_option_none(&mut self) -> IoResult<()> { try!(self.writer.write_u8(0)); Ok(()) }
    fn emit_option_some<F>(&mut self, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_u8(1)); f(self) }

    fn emit_seq<F>(&mut self, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(_len)); f(self) }
    fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }

    fn emit_map<F>(&mut self, _len: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()>
        { try!(self.writer.write_le_uint(_len)); f(self) }
    fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> IoResult<()>
        where F: FnOnce(&mut BinaryEncoder<R>) -> IoResult<()> { f(self) }
}
<|endoftext|>


<commit_before>use futures::Poll;
use futures::Async::*;

use std::str;

use server::boundary::BoundaryFinder;
use server::{BodyChunk, StreamError};

use helpers::*;

#[derive(Default, Debug)]
pub struct CollectStr {
    accum: String,
    limit: Option<u64>,
}

impl CollectStr {
    pub fn collect<S: Stream>(&mut self, stream: &mut BoundaryFinder<S>) -> Poll<String, S::Error>
    where S::Item: BodyChunk, S::Item: StreamError {

        loop {
            let chunk = match try_ready!(stream.body_chunk()) {
                Some(val) => val,
                N => break,
            };

            if let Some(limit) = self.limit {
                if (self.accum.len() as u64).saturating_add(chunk.len()) {
                    stream.push_chunk(chunk);
                }
            }

            let split_idx = match str::from_utf8(chunk.as_slice()) {
                Ok(s) => { self.accum.push_str(s); continue },
                Err(e) => match e.error_len() {
                    Some(_) => return error(e),
                    None => e.valid_up_to(),
                },
            };

            let (valid, invalid) = chunk.split_at(split_idx);

            let [first, second] = try_opt_ready!(stream.another_chunk(invalid));

        }

        ready(replace_default(&mut self.accum))
    }

}

<commit_msg>WIP a little bit more in server/field/collect<commit_after>use futures::Poll;
use futures::Async::*;

use std::str;

use server::boundary::BoundaryFinder;
use server::{BodyChunk, StreamError};

use helpers::*;

#[derive(Default, Debug)]
pub struct CollectStr {
    accum: String,
    limit: Option<u64>,
}

impl CollectStr {
    pub fn collect<S: Stream>(&mut self, stream: &mut BoundaryFinder<S>) -> Poll<String, S::Error>
    where S::Item: BodyChunk, S::Item: StreamError {

        loop {
            let chunk = match try_ready!(stream.body_chunk()) {
                Some(val) => val,
                N => break,
            };

            if let Some(limit) = self.limit {
                if (self.accum.len() as u64).saturating_add(chunk.len()) {
                    stream.push_chunk(chunk);
                }
            }

            let split_idx = match str::from_utf8(chunk.as_slice()) {
                Ok(s) => { self.accum.push_str(s); continue },
                Err(e) => match e.error_len() {
                    Some(_) => return error(e),
                    None => e.valid_up_to(),
                },
            };

            let (valid, invalid) = chunk.split_at(split_idx);

            let [first, second] = try_opt_ready!(stream.another_chunk(invalid));

            self.accum.push_str(str::from_utf8(first.as_slice())
                .expect("this was UTF-8 before"));

            buf[..second.len()].copy_from_slice(second.as_slice());

        }

        ready(replace_default(&mut self.accum))
    }

}

<|endoftext|>


<commit_before>#[feature(globs)];
#[feature(struct_variant)];

extern mod allegro5;
extern mod extra;

use extra::getopts::groups::*;
use std::os;
use std::num::Zero;
use std::c_str::*;
use allegro5::*;

#[start]
fn start(argc: int, argv: **u8) -> int
{
    allegro5::run(argc, argv, main)
}

fn main()
{
	let args = os::args();

	let opts = ~[
        optflag("i", "init-only", "only initialize Allegro, don't do anything else")
    ];

    let matches = match getopts(args.tail(), opts)
    {
		Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
	};

	let init_only = matches.opt_present("i");

	let mut core = Core::init().expect("Your Allegro version does not match this Rust binding");

	if init_only
	{
		return;
	}

	let disp = core.create_display(800, 600).unwrap();
	disp.set_window_title(&"Rust example".to_c_str());

	core.install_keyboard();
	core.install_mouse();

	let timer = core.create_timer(1.0 / 60.0).unwrap();

	let q = core.create_event_queue().unwrap();
	q.register_event_source(disp.get_event_source());
	q.register_event_source(core.get_keyboard_event_source().unwrap());
	q.register_event_source(core.get_mouse_event_source().unwrap());
	q.register_event_source(timer.get_event_source());

	let bmp = core.create_bitmap(256, 256).unwrap();

	let (mon_x1, mon_y1, mon_x2, mon_y2) = core.get_monitor_info(0).unwrap();
	println!("{} {} {} {}", mon_x1, mon_y1, mon_x2, mon_y2);

	bmp.clear_to_color(core.map_rgb_f(0.0, 0.0, 1.0));

	let sub_bmp = bmp.create_sub_bitmap(64, 64, 64, 64).unwrap();
	sub_bmp.clear_to_color(core.map_rgb_f(0.0, 1.0, 1.0));

	let mut theta = 0.0f32;
	let mut redraw = true;
	timer.start();
	'exit: loop
	{
		if redraw && q.is_empty()
		{
			disp.clear_to_color(core.map_rgb_f(0.0, 0.0, 0.0));
			disp.draw_rotated_bitmap(&bmp, 0.0, 0.0, (disp.get_width() / 2) as f32, (disp.get_height() / 2) as f32, theta, Zero::zero());
			disp.flip();
			redraw = false;
		}

		match q.wait_for_event()
		{
			DisplayClose{source: src, ..} =>
			{
				assert!(disp.get_event_source().get_event_source() == src)
				println!("Display close event...")
				break 'exit;
			},
			KeyDown{keycode: k, ..} if k == key::Escape =>
			{
				println!("Pressed Escape!");
				break 'exit;
			},
			KeyChar{unichar: c, ..} =>
			{
				println!("Entered a character: {}", c);
			},
			TimerTick{..} =>
			{
				redraw = true;
				theta = theta + 0.01;
			},
			MouseButtonDown{button: b, ..} =>
			{
				println!("Mouse button {} pressed", b);
			},
			_ => println!("Some other event...")
		}
	}
}
<commit_msg>Fix example whitespace<commit_after>#[feature(globs)];
#[feature(struct_variant)];

extern mod allegro5;
extern mod extra;

use extra::getopts::groups::*;
use std::os;
use std::num::Zero;
use std::c_str::*;
use allegro5::*;

#[start]
fn start(argc: int, argv: **u8) -> int
{
	allegro5::run(argc, argv, main)
}

fn main()
{
	let args = os::args();

	let opts = ~[
		optflag("i", "init-only", "only initialize Allegro, don't do anything else")
	];

	let matches = match getopts(args.tail(), opts)
	{
		Ok(m) => { m }
		Err(f) => { fail!(f.to_err_msg()) }
	};

	let init_only = matches.opt_present("i");

	let mut core = Core::init().expect("Your Allegro version does not match this Rust binding");

	if init_only
	{
		return;
	}

	let disp = core.create_display(800, 600).unwrap();
	disp.set_window_title(&"Rust example".to_c_str());

	core.install_keyboard();
	core.install_mouse();

	let timer = core.create_timer(1.0 / 60.0).unwrap();

	let q = core.create_event_queue().unwrap();
	q.register_event_source(disp.get_event_source());
	q.register_event_source(core.get_keyboard_event_source().unwrap());
	q.register_event_source(core.get_mouse_event_source().unwrap());
	q.register_event_source(timer.get_event_source());

	let bmp = core.create_bitmap(256, 256).unwrap();

	let (mon_x1, mon_y1, mon_x2, mon_y2) = core.get_monitor_info(0).unwrap();
	println!("{} {} {} {}", mon_x1, mon_y1, mon_x2, mon_y2);

	bmp.clear_to_color(core.map_rgb_f(0.0, 0.0, 1.0));

	let sub_bmp = bmp.create_sub_bitmap(64, 64, 64, 64).unwrap();
	sub_bmp.clear_to_color(core.map_rgb_f(0.0, 1.0, 1.0));

	let mut theta = 0.0f32;
	let mut redraw = true;
	timer.start();
	'exit: loop
	{
		if redraw && q.is_empty()
		{
			disp.clear_to_color(core.map_rgb_f(0.0, 0.0, 0.0));
			disp.draw_rotated_bitmap(&bmp, 0.0, 0.0, (disp.get_width() / 2) as f32, (disp.get_height() / 2) as f32, theta, Zero::zero());
			disp.flip();
			redraw = false;
		}

		match q.wait_for_event()
		{
			DisplayClose{source: src, ..} =>
			{
				assert!(disp.get_event_source().get_event_source() == src)
				println!("Display close event...")
				break 'exit;
			},
			KeyDown{keycode: k, ..} if k == key::Escape =>
			{
				println!("Pressed Escape!");
				break 'exit;
			},
			KeyChar{unichar: c, ..} =>
			{
				println!("Entered a character: {}", c);
			},
			TimerTick{..} =>
			{
				redraw = true;
				theta = theta + 0.01;
			},
			MouseButtonDown{button: b, ..} =>
			{
				println!("Mouse button {} pressed", b);
			},
			_ => println!("Some other event...")
		}
	}
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub, Mul, Index, IndexMut};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Coord {
    pub y: i32,
    pub x: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LoopCoord {
    pub y: i32,
    pub x: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Dir {
    pub y: i32,
    pub x: i32,
}
impl Add<Dir> for Coord {
    type Output = Coord;
    fn add(self, rhs: Dir) -> Coord {
        Coord {
            y: self.y + rhs.y,
            x: self.x + rhs.x,
        }
    }
}
impl Sub<Dir> for Coord {
    type Output = Coord;
    fn sub(self, rhs: Dir) -> Coord {
        Coord {
            y: self.y - rhs.y,
            x: self.x - rhs.x,
        }
    }
}
impl Add<Dir> for LoopCoord {
    type Output = LoopCoord;
    fn add(self, rhs: Dir) -> LoopCoord {
        LoopCoord {
            y: self.y + rhs.y,
            x: self.x + rhs.x,
        }
    }
}
impl Sub<Dir> for LoopCoord {
    type Output = LoopCoord;
    fn sub(self, rhs: Dir) -> LoopCoord {
        LoopCoord {
            y: self.y - rhs.y,
            x: self.x - rhs.x,
        }
    }
}
impl Add<Dir> for Dir {
    type Output = Dir;
    fn add(self, rhs: Dir) -> Dir {
        Dir {
            y: self.y + rhs.y,
            x: self.x + rhs.x,
        }
    }
}
impl Sub<Dir> for Dir {
    type Output = Dir;
    fn sub(self, rhs: Dir) -> Dir {
        Dir {
            y: self.y - rhs.y,
            x: self.x - rhs.x,
        }
    }
}
impl Mul<i32> for Dir {
    type Output = Dir;
    fn mul(self, rhs: i32) -> Dir {
        Dir {
            y: self.y * rhs,
            x: self.x * rhs,
        }
    }
}

#[derive(Debug, Clone)]
pub struct Grid<T: Clone> {
    height: i32,
    width: i32,
    data: Vec<T>,
}
impl<T: Clone> Grid<T> {
    pub fn new(height: i32, width: i32, default: T) -> Grid<T> {
        Grid {
            height: height,
            width: width,
            data: vec![default; (height * width) as usize],
        }
    }
    pub fn height(&self) -> i32 {
        self.height
    }
    pub fn width(&self) -> i32 {
        self.width
    }
    fn index(&self, cd: Coord) -> usize {
        (cd.y * self.width + cd.x) as usize
    }
    fn index_loop(&self, cd: LoopCoord) -> usize {
        (cd.y * self.width + cd.x) as usize
    }
}
impl<T: Clone> Index<Coord> for Grid<T> {
    type Output = T;
    fn index<'a>(&'a self, idx: Coord) -> &'a T {
        let idx = self.index(idx);
        &self.data[idx]
    }
}
impl<T: Clone> IndexMut<Coord> for Grid<T> {
    fn index_mut<'a>(&'a mut self, idx: Coord) -> &'a mut T {
        let idx = self.index(idx);
        &mut self.data[idx]
    }
}
impl<T: Clone> Index<LoopCoord> for Grid<T> {
    type Output = T;
    fn index<'a>(&'a self, idx: LoopCoord) -> &'a T {
        let idx = self.index_loop(idx);
        &self.data[idx]
    }
}
impl<T: Clone> IndexMut<LoopCoord> for Grid<T> {
    fn index_mut<'a>(&'a mut self, idx: LoopCoord) -> &'a mut T {
        let idx = self.index_loop(idx);
        &mut self.data[idx]
    }
}
impl<T: Clone> Index<usize> for Grid<T> {
    type Output = T;
    fn index<'a>(&'a self, idx: usize) -> &'a T {
        &self.data[idx]
    }
}
impl<T: Clone> IndexMut<usize> for Grid<T> {
    fn index_mut<'a>(&'a mut self, idx: usize) -> &'a mut T {
        &mut self.data[idx]
    }
}
#[cfg(test)]
pub fn vec_to_grid<T>(v: &Vec<Vec<T>>) -> Grid<T>
where
    T: Copy,
{
    if v.len() == 0 {
        panic!("Attempted to convert empty Vec to Grid");
    }
    let ref_len = v[0].len();
    for r in v {
        if r.len() != ref_len {
            panic!("Each element in v must contain the same number of elements");
        }
    }
    let mut flat = vec![];
    for r in v {
        for &x in r {
            flat.push(x);
        }
    }
    Grid {
        height: v.len() as i32,
        width: ref_len as i32,
        data: flat,
    }
}
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_common_types_operators() {
        assert_eq!(
            Coord { y: 1, x: 2 } + Dir { y: 3, x: 5 },
            Coord { y: 4, x: 7 }
        );
        assert_eq!(
            Coord { y: 1, x: 2 } - Dir { y: 3, x: 5 },
            Coord { y: -2, x: -3 }
        );
        assert_eq!(
            LoopCoord { y: 1, x: 2 } + Dir { y: 3, x: 5 },
            LoopCoord { y: 4, x: 7 }
        );
        assert_eq!(
            LoopCoord { y: 1, x: 2 } - Dir { y: 3, x: 5 },
            LoopCoord { y: -2, x: -3 }
        );
        assert_eq!(
            Dir { y: 1, x: 2 } + Dir { y: 3, x: 5 },
            Dir { y: 4, x: 7 }
        );
        assert_eq!(
            Dir { y: 1, x: 2 } - Dir { y: 3, x: 5 },
            Dir { y: -2, x: -3 }
        );
        assert_eq!(Dir { y: 1, x: 2 } * 3, Dir { y: 3, x: 6 });
    }

    #[test]
    fn test_grid() {
        let mut grid = Grid::new(3, 3, 0);
        assert_eq!(grid.height(), 3);
        assert_eq!(grid.width(), 3);
        assert_eq!(grid[LoopCoord { y: 1, x: 1 }], 0);
        grid[LoopCoord { y: 1, x: 1 }] = 4;
        assert_eq!(grid[LoopCoord { y: 1, x: 1 }], 4);
        assert_eq!(grid[LoopCoord { y: 1, x: 0 }], 0);
        assert_eq!(grid[LoopCoord { y: 2, x: 0 }], 0);
        assert_eq!(grid[4], 4);
    }
}
<commit_msg>Grid: make index and index_loop pub<commit_after>use std::ops::{Add, Sub, Mul, Index, IndexMut};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Coord {
    pub y: i32,
    pub x: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LoopCoord {
    pub y: i32,
    pub x: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Dir {
    pub y: i32,
    pub x: i32,
}
impl Add<Dir> for Coord {
    type Output = Coord;
    fn add(self, rhs: Dir) -> Coord {
        Coord {
            y: self.y + rhs.y,
            x: self.x + rhs.x,
        }
    }
}
impl Sub<Dir> for Coord {
    type Output = Coord;
    fn sub(self, rhs: Dir) -> Coord {
        Coord {
            y: self.y - rhs.y,
            x: self.x - rhs.x,
        }
    }
}
impl Add<Dir> for LoopCoord {
    type Output = LoopCoord;
    fn add(self, rhs: Dir) -> LoopCoord {
        LoopCoord {
            y: self.y + rhs.y,
            x: self.x + rhs.x,
        }
    }
}
impl Sub<Dir> for LoopCoord {
    type Output = LoopCoord;
    fn sub(self, rhs: Dir) -> LoopCoord {
        LoopCoord {
            y: self.y - rhs.y,
            x: self.x - rhs.x,
        }
    }
}
impl Add<Dir> for Dir {
    type Output = Dir;
    fn add(self, rhs: Dir) -> Dir {
        Dir {
            y: self.y + rhs.y,
            x: self.x + rhs.x,
        }
    }
}
impl Sub<Dir> for Dir {
    type Output = Dir;
    fn sub(self, rhs: Dir) -> Dir {
        Dir {
            y: self.y - rhs.y,
            x: self.x - rhs.x,
        }
    }
}
impl Mul<i32> for Dir {
    type Output = Dir;
    fn mul(self, rhs: i32) -> Dir {
        Dir {
            y: self.y * rhs,
            x: self.x * rhs,
        }
    }
}

#[derive(Debug, Clone)]
pub struct Grid<T: Clone> {
    height: i32,
    width: i32,
    data: Vec<T>,
}
impl<T: Clone> Grid<T> {
    pub fn new(height: i32, width: i32, default: T) -> Grid<T> {
        Grid {
            height: height,
            width: width,
            data: vec![default; (height * width) as usize],
        }
    }
    pub fn height(&self) -> i32 {
        self.height
    }
    pub fn width(&self) -> i32 {
        self.width
    }
    pub fn index(&self, cd: Coord) -> usize {
        (cd.y * self.width + cd.x) as usize
    }
    pub fn index_loop(&self, cd: LoopCoord) -> usize {
        (cd.y * self.width + cd.x) as usize
    }
}
impl<T: Clone> Index<Coord> for Grid<T> {
    type Output = T;
    fn index<'a>(&'a self, idx: Coord) -> &'a T {
        let idx = self.index(idx);
        &self.data[idx]
    }
}
impl<T: Clone> IndexMut<Coord> for Grid<T> {
    fn index_mut<'a>(&'a mut self, idx: Coord) -> &'a mut T {
        let idx = self.index(idx);
        &mut self.data[idx]
    }
}
impl<T: Clone> Index<LoopCoord> for Grid<T> {
    type Output = T;
    fn index<'a>(&'a self, idx: LoopCoord) -> &'a T {
        let idx = self.index_loop(idx);
        &self.data[idx]
    }
}
impl<T: Clone> IndexMut<LoopCoord> for Grid<T> {
    fn index_mut<'a>(&'a mut self, idx: LoopCoord) -> &'a mut T {
        let idx = self.index_loop(idx);
        &mut self.data[idx]
    }
}
impl<T: Clone> Index<usize> for Grid<T> {
    type Output = T;
    fn index<'a>(&'a self, idx: usize) -> &'a T {
        &self.data[idx]
    }
}
impl<T: Clone> IndexMut<usize> for Grid<T> {
    fn index_mut<'a>(&'a mut self, idx: usize) -> &'a mut T {
        &mut self.data[idx]
    }
}
#[cfg(test)]
pub fn vec_to_grid<T>(v: &Vec<Vec<T>>) -> Grid<T>
where
    T: Copy,
{
    if v.len() == 0 {
        panic!("Attempted to convert empty Vec to Grid");
    }
    let ref_len = v[0].len();
    for r in v {
        if r.len() != ref_len {
            panic!("Each element in v must contain the same number of elements");
        }
    }
    let mut flat = vec![];
    for r in v {
        for &x in r {
            flat.push(x);
        }
    }
    Grid {
        height: v.len() as i32,
        width: ref_len as i32,
        data: flat,
    }
}
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_common_types_operators() {
        assert_eq!(
            Coord { y: 1, x: 2 } + Dir { y: 3, x: 5 },
            Coord { y: 4, x: 7 }
        );
        assert_eq!(
            Coord { y: 1, x: 2 } - Dir { y: 3, x: 5 },
            Coord { y: -2, x: -3 }
        );
        assert_eq!(
            LoopCoord { y: 1, x: 2 } + Dir { y: 3, x: 5 },
            LoopCoord { y: 4, x: 7 }
        );
        assert_eq!(
            LoopCoord { y: 1, x: 2 } - Dir { y: 3, x: 5 },
            LoopCoord { y: -2, x: -3 }
        );
        assert_eq!(
            Dir { y: 1, x: 2 } + Dir { y: 3, x: 5 },
            Dir { y: 4, x: 7 }
        );
        assert_eq!(
            Dir { y: 1, x: 2 } - Dir { y: 3, x: 5 },
            Dir { y: -2, x: -3 }
        );
        assert_eq!(Dir { y: 1, x: 2 } * 3, Dir { y: 3, x: 6 });
    }

    #[test]
    fn test_grid() {
        let mut grid = Grid::new(3, 3, 0);
        assert_eq!(grid.height(), 3);
        assert_eq!(grid.width(), 3);
        assert_eq!(grid[LoopCoord { y: 1, x: 1 }], 0);
        grid[LoopCoord { y: 1, x: 1 }] = 4;
        assert_eq!(grid[LoopCoord { y: 1, x: 1 }], 4);
        assert_eq!(grid[LoopCoord { y: 1, x: 0 }], 0);
        assert_eq!(grid[LoopCoord { y: 2, x: 0 }], 0);
        assert_eq!(grid[4], 4);
    }
}
<|endoftext|>


<commit_before>//! Main entry point to the library.
//! See examples for documentation on how to use this struct.

use manager::{InputManager, InputManagerHandler, OutputManager, OutputManagerHandler};
use std::cell::UnsafeCell;
use std::env;
use std::ffi::CStr;
use types::server_decoration::ServerDecorationManager;
use wayland_sys::server::{WAYLAND_SERVER_HANDLE, wl_display, wl_event_loop};
use wayland_sys::server::signal::wl_signal_add;
use wlroots_sys::{wlr_backend, wlr_backend_autocreate, wlr_backend_destroy, wlr_backend_start};

/// Global compositor pointer, used to refer to the compositor state unsafely.
static mut COMPOSITOR_PTR: *mut Compositor = 0 as *mut _;

#[allow(dead_code)]
pub struct Compositor {
    input_manager: Box<InputManager>,
    output_manager: Box<OutputManager>,
    backend: *mut wlr_backend,
    display: *mut wl_display,
    event_loop: *mut wl_event_loop,
    pub server_decoration_manager: Option<ServerDecorationManager>
}

impl Compositor {
    /// Makes a new compositor that handles the setup of the graphical backend
    /// (e.g, Wayland, X11, or DRM).
    ///
    /// Also automatically opens the socket for clients to communicate to the
    /// compositor with.
    pub fn new(input_manager_handler: Box<InputManagerHandler>,
               output_manager_handler: Box<OutputManagerHandler>)
               -> Self {
        unsafe {
            let display = ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_create,) as
                *mut wl_display;
            let event_loop =
                ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_get_event_loop, display);
            let backend = wlr_backend_autocreate(display as *mut _);
            if backend.is_null() {
                // NOTE Rationale for panicking:
                // * Won't be in C land just yet, so it's safe to panic
                // * Can always be returned in a Result instead, but for now
                //   if you auto create it's assumed you can't recover.
                panic!("Could not auto-create backend");
            }
            let mut input_manager = InputManager::new((vec![], input_manager_handler));
            let mut output_manager = OutputManager::new((vec![], output_manager_handler));
            wl_signal_add(&mut (*backend).events.input_add as *mut _ as _,
                          input_manager.add_listener() as *mut _ as _);
            wl_signal_add(&mut (*backend).events.input_remove as *mut _ as _,
                          input_manager.remove_listener() as *mut _ as _);
            wl_signal_add(&mut (*backend).events.output_add as *mut _ as _,
                          output_manager.add_listener() as *mut _ as _);
            wl_signal_add(&mut (*backend).events.output_remove as *mut _ as _,
                          output_manager.remove_listener() as *mut _ as _);

            let socket = ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_add_socket_auto, display);
            if socket.is_null() {
                // NOTE Rationale for panicking:
                // * Won't be in C land just yet, so it's safe to panic
                // * Can always be returned in a Result instead, but for now
                //   if you auto create it's assumed you can't recover.
                panic!("Unable to open wayland socket");
            }
            let socket_name = CStr::from_ptr(socket).to_string_lossy().into_owned();
            wlr_log!(L_DEBUG,
                     "Running compositor on wayland display {}",
                     socket_name);
            env::set_var("_WAYLAND_DISPLAY", socket_name);
            Compositor {
                input_manager,
                output_manager,
                backend,
                display,
                event_loop,
                server_decoration_manager: None
            }
        }
    }

    /// Enters the wayland event loop. Won't return until the compositor is
    /// shut off
    pub fn run(self) {
        unsafe {
            let compositor = UnsafeCell::new(self);
            if COMPOSITOR_PTR != 0 as _ {
                // NOTE Rationale for panicking:
                // * Nicer than an abort
                // * Not yet in C land
                panic!("A compositor is already running!")
            }
            COMPOSITOR_PTR = compositor.get();
            wlr_log!(L_INFO, "Starting compositor");
            if !wlr_backend_start((*compositor.get()).backend) {
                wlr_backend_destroy((*compositor.get()).backend);
                // NOTE Rationale for panicking:
                // * Won't be in C land just yet, so it's safe to panic
                // * Can always be returned in a Result instead, but for now
                //   if you auto create it's assumed you can't recover.
                panic!("Failed to start backend");
            }
            ffi_dispatch!(WAYLAND_SERVER_HANDLE,
                          wl_display_run,
                          (*compositor.get()).display);
        }
        // TODO Clean up
    }

    /// Adds the server decoration manager protocol.
    pub fn add_server_decoration_manager(&mut self) {
        if self.server_decoration_manager.is_some() {
            wlr_log!(L_ERROR, "Server decoration manager already loaded!");
            return
        }
        unsafe {
            self.server_decoration_manager = ServerDecorationManager::new(self.display);
            if self.server_decoration_manager.is_none() {
                wlr_log!(L_ERROR, "Server decoration manager could not be loaded");
            }
        }
    }

    pub fn server_decoration_manager(&mut self) -> Option<&mut ServerDecorationManager> {
        self.server_decoration_manager.as_mut()
    }

    pub fn terminate(&mut self) {
        unsafe {
            ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_terminate, self.display);
        }
    }
}

/// Terminates the compositor.
/// If one is not running, does nothing
pub fn terminate() {
    unsafe {
        if COMPOSITOR_PTR != 0 as _ {
            (*COMPOSITOR_PTR).terminate();
            COMPOSITOR_PTR = 0 as _
        }
    }
}
<commit_msg>Don't make Compositor::terminate pub<commit_after>//! Main entry point to the library.
//! See examples for documentation on how to use this struct.

use manager::{InputManager, InputManagerHandler, OutputManager, OutputManagerHandler};
use std::cell::UnsafeCell;
use std::env;
use std::ffi::CStr;
use types::server_decoration::ServerDecorationManager;
use wayland_sys::server::{WAYLAND_SERVER_HANDLE, wl_display, wl_event_loop};
use wayland_sys::server::signal::wl_signal_add;
use wlroots_sys::{wlr_backend, wlr_backend_autocreate, wlr_backend_destroy, wlr_backend_start};

/// Global compositor pointer, used to refer to the compositor state unsafely.
static mut COMPOSITOR_PTR: *mut Compositor = 0 as *mut _;

#[allow(dead_code)]
pub struct Compositor {
    input_manager: Box<InputManager>,
    output_manager: Box<OutputManager>,
    backend: *mut wlr_backend,
    display: *mut wl_display,
    event_loop: *mut wl_event_loop,
    pub server_decoration_manager: Option<ServerDecorationManager>
}

impl Compositor {
    /// Makes a new compositor that handles the setup of the graphical backend
    /// (e.g, Wayland, X11, or DRM).
    ///
    /// Also automatically opens the socket for clients to communicate to the
    /// compositor with.
    pub fn new(input_manager_handler: Box<InputManagerHandler>,
               output_manager_handler: Box<OutputManagerHandler>)
               -> Self {
        unsafe {
            let display = ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_create,) as
                *mut wl_display;
            let event_loop =
                ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_get_event_loop, display);
            let backend = wlr_backend_autocreate(display as *mut _);
            if backend.is_null() {
                // NOTE Rationale for panicking:
                // * Won't be in C land just yet, so it's safe to panic
                // * Can always be returned in a Result instead, but for now
                //   if you auto create it's assumed you can't recover.
                panic!("Could not auto-create backend");
            }
            let mut input_manager = InputManager::new((vec![], input_manager_handler));
            let mut output_manager = OutputManager::new((vec![], output_manager_handler));
            wl_signal_add(&mut (*backend).events.input_add as *mut _ as _,
                          input_manager.add_listener() as *mut _ as _);
            wl_signal_add(&mut (*backend).events.input_remove as *mut _ as _,
                          input_manager.remove_listener() as *mut _ as _);
            wl_signal_add(&mut (*backend).events.output_add as *mut _ as _,
                          output_manager.add_listener() as *mut _ as _);
            wl_signal_add(&mut (*backend).events.output_remove as *mut _ as _,
                          output_manager.remove_listener() as *mut _ as _);

            let socket = ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_add_socket_auto, display);
            if socket.is_null() {
                // NOTE Rationale for panicking:
                // * Won't be in C land just yet, so it's safe to panic
                // * Can always be returned in a Result instead, but for now
                //   if you auto create it's assumed you can't recover.
                panic!("Unable to open wayland socket");
            }
            let socket_name = CStr::from_ptr(socket).to_string_lossy().into_owned();
            wlr_log!(L_DEBUG,
                     "Running compositor on wayland display {}",
                     socket_name);
            env::set_var("_WAYLAND_DISPLAY", socket_name);
            Compositor {
                input_manager,
                output_manager,
                backend,
                display,
                event_loop,
                server_decoration_manager: None
            }
        }
    }

    /// Enters the wayland event loop. Won't return until the compositor is
    /// shut off
    pub fn run(self) {
        unsafe {
            let compositor = UnsafeCell::new(self);
            if COMPOSITOR_PTR != 0 as _ {
                // NOTE Rationale for panicking:
                // * Nicer than an abort
                // * Not yet in C land
                panic!("A compositor is already running!")
            }
            COMPOSITOR_PTR = compositor.get();
            wlr_log!(L_INFO, "Starting compositor");
            if !wlr_backend_start((*compositor.get()).backend) {
                wlr_backend_destroy((*compositor.get()).backend);
                // NOTE Rationale for panicking:
                // * Won't be in C land just yet, so it's safe to panic
                // * Can always be returned in a Result instead, but for now
                //   if you auto create it's assumed you can't recover.
                panic!("Failed to start backend");
            }
            ffi_dispatch!(WAYLAND_SERVER_HANDLE,
                          wl_display_run,
                          (*compositor.get()).display);
        }
        // TODO Clean up
    }

    /// Adds the server decoration manager protocol.
    pub fn add_server_decoration_manager(&mut self) {
        if self.server_decoration_manager.is_some() {
            wlr_log!(L_ERROR, "Server decoration manager already loaded!");
            return
        }
        unsafe {
            self.server_decoration_manager = ServerDecorationManager::new(self.display);
            if self.server_decoration_manager.is_none() {
                wlr_log!(L_ERROR, "Server decoration manager could not be loaded");
            }
        }
    }

    pub fn server_decoration_manager(&mut self) -> Option<&mut ServerDecorationManager> {
        self.server_decoration_manager.as_mut()
    }

    fn terminate(&mut self) {
        unsafe {
            ffi_dispatch!(WAYLAND_SERVER_HANDLE, wl_display_terminate, self.display);
        }
    }
}

/// Terminates the compositor.
/// If one is not running, does nothing
pub fn terminate() {
    unsafe {
        if COMPOSITOR_PTR != 0 as _ {
            (*COMPOSITOR_PTR).terminate();
            COMPOSITOR_PTR = 0 as _
        }
    }
}
<|endoftext|>


<commit_before>use message::{Message, PatternId};
use MiliSec;
use state::State;

const FIRST_OPENS_DEFAULT: bool = false;
const LAST_CLOSES_DEFAULT: bool = false;

#[derive(Clone, Debug)]
pub struct Conditions {
    pub timeout: MiliSec,
    pub renew_timeout: Option<MiliSec>,
    pub first_opens: Option<bool>,
    pub last_closes: Option<bool>,
    pub max_size: Option<usize>,
    pub patterns: Vec<PatternId>
}

impl Conditions {
    fn new(timeout: MiliSec) -> Conditions {
        Conditions {
            timeout: timeout,
            renew_timeout: None,
            first_opens: None,
            last_closes: None,
            max_size: None,
            patterns: Vec::new()
        }
    }

    pub fn is_opening(&self, message: &Message) -> bool {
        if self.first_opens.unwrap_or(FIRST_OPENS_DEFAULT) {
            self.patterns.first().unwrap() == message.uuid()
        } else {
            true
        }
    }

    pub fn is_closing(&self, state: &State) -> bool {
        self.is_max_size_reached(state) || self.is_closing_message(state) || self.is_any_timer_expired(state)
    }

    fn is_max_size_reached(&self, state: &State) -> bool {
        self.max_size.map_or(false, |max_size| state.messages().len() >= max_size)
    }

    fn is_closing_message(&self, state: &State) -> bool {
        if self.last_closes.unwrap_or(LAST_CLOSES_DEFAULT) {
            self.patterns.last().unwrap() == state.messages().last().unwrap().uuid()
        } else {
            false
        }
    }

    fn is_any_timer_expired(&self, state: &State) -> bool {
        self.is_timeout_expired(state) || self.is_renew_timeout_expired(state)
    }

    fn is_timeout_expired(&self, state: &State) -> bool {
        state.elapsed_time() >= self.timeout
    }

    fn is_renew_timeout_expired(&self, state: &State) -> bool {
        self.renew_timeout.map_or(false, |renew_timeout| {
            state.elapsed_time_since_last_message() >= renew_timeout
        })
    }
}

pub struct Builder {
    conditions: Conditions
}

impl Builder {
    pub fn new(timeout: MiliSec) -> Builder {
        Builder{
            conditions: Conditions::new(timeout)
        }
    }

    pub fn renew_timeout(&mut self, timeout: MiliSec) -> &mut Builder {
        self.conditions.renew_timeout = Some(timeout);
        self
    }

    pub fn first_opens(&mut self, first_opens: bool) -> &mut Builder {
        self.conditions.first_opens = Some(first_opens);
        self
    }

    pub fn last_closes(&mut self, last_closes: bool) -> &mut Builder {
        self.conditions.last_closes = Some(last_closes);
        self
    }
    pub fn max_size(&mut self, max_size: usize) -> &mut Builder {
        self.conditions.max_size = Some(max_size);
        self
    }

    pub fn patterns(&mut self, patterns: Vec<PatternId>) -> &mut Builder {
        self.conditions.patterns = patterns;
        self
    }

    pub fn build(&mut self) -> Conditions {
        self.conditions.clone()
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;

    use message;
    use message::{PatternId};
    use state::State;
    use super::Builder;

    #[test]
    fn test_given_condition_when_an_opening_message_is_received_then_the_state_becomes_opened() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
        ];
        let condition = Builder::new(timeout).patterns(patterns).first_opens(true).build();
        let msg_which_should_not_be_ignored = message::Builder::new(&msg_id1).build();
        let msg_which_should_be_ignored = message::Builder::new(&msg_id2).build();
        assert_false!(condition.is_opening(&msg_which_should_be_ignored));
        assert_true!(condition.is_opening(&msg_which_should_not_be_ignored));
    }

    #[test]
    fn test_given_condition_when_a_closing_message_is_received_then_the_state_becomes_closed() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
            PatternId::Uuid(msg_id2.clone()),
        ];
        let mut state = State::new();
        let condition = Builder::new(timeout).patterns(patterns).last_closes(true).build();
        let msg_1 = message::Builder::new(&msg_id1).build();
        let msg_closing = Rc::new(message::Builder::new(&msg_id2).build());
        assert_true!(condition.is_opening(&msg_1));
        state.open();
        state.add_message(msg_closing);
        assert_true!(condition.is_closing(&mut state));
    }
}
<commit_msg>Conditions: implement serde::Deserialize<commit_after>use message::{Message, PatternId};
use MiliSec;
use state::State;

const FIRST_OPENS_DEFAULT: bool = false;
const LAST_CLOSES_DEFAULT: bool = false;

#[derive(Clone, Debug)]
pub struct Conditions {
    pub timeout: MiliSec,
    pub renew_timeout: Option<MiliSec>,
    pub first_opens: Option<bool>,
    pub last_closes: Option<bool>,
    pub max_size: Option<usize>,
    pub patterns: Vec<PatternId>
}

impl Conditions {
    fn new(timeout: MiliSec) -> Conditions {
        Conditions {
            timeout: timeout,
            renew_timeout: None,
            first_opens: None,
            last_closes: None,
            max_size: None,
            patterns: Vec::new()
        }
    }

    pub fn is_opening(&self, message: &Message) -> bool {
        if self.first_opens.unwrap_or(FIRST_OPENS_DEFAULT) {
            self.patterns.first().unwrap() == message.uuid()
        } else {
            true
        }
    }

    pub fn is_closing(&self, state: &State) -> bool {
        self.is_max_size_reached(state) || self.is_closing_message(state) || self.is_any_timer_expired(state)
    }

    fn is_max_size_reached(&self, state: &State) -> bool {
        self.max_size.map_or(false, |max_size| state.messages().len() >= max_size)
    }

    fn is_closing_message(&self, state: &State) -> bool {
        if self.last_closes.unwrap_or(LAST_CLOSES_DEFAULT) {
            self.patterns.last().unwrap() == state.messages().last().unwrap().uuid()
        } else {
            false
        }
    }

    fn is_any_timer_expired(&self, state: &State) -> bool {
        self.is_timeout_expired(state) || self.is_renew_timeout_expired(state)
    }

    fn is_timeout_expired(&self, state: &State) -> bool {
        state.elapsed_time() >= self.timeout
    }

    fn is_renew_timeout_expired(&self, state: &State) -> bool {
        self.renew_timeout.map_or(false, |renew_timeout| {
            state.elapsed_time_since_last_message() >= renew_timeout
        })
    }
}

pub struct Builder {
    conditions: Conditions
}

impl Builder {
    pub fn new(timeout: MiliSec) -> Builder {
        Builder{
            conditions: Conditions::new(timeout)
        }
    }

    pub fn renew_timeout(&mut self, timeout: MiliSec) -> &mut Builder {
        self.conditions.renew_timeout = Some(timeout);
        self
    }

    pub fn first_opens(&mut self, first_opens: bool) -> &mut Builder {
        self.conditions.first_opens = Some(first_opens);
        self
    }

    pub fn last_closes(&mut self, last_closes: bool) -> &mut Builder {
        self.conditions.last_closes = Some(last_closes);
        self
    }
    pub fn max_size(&mut self, max_size: usize) -> &mut Builder {
        self.conditions.max_size = Some(max_size);
        self
    }

    pub fn patterns(&mut self, patterns: Vec<PatternId>) -> &mut Builder {
        self.conditions.patterns = patterns;
        self
    }

    pub fn build(&mut self) -> Conditions {
        self.conditions.clone()
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;

    use message;
    use message::{PatternId};
    use state::State;
    use super::Builder;

    #[test]
    fn test_given_condition_when_an_opening_message_is_received_then_the_state_becomes_opened() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
        ];
        let condition = Builder::new(timeout).patterns(patterns).first_opens(true).build();
        let msg_which_should_not_be_ignored = message::Builder::new(&msg_id1).build();
        let msg_which_should_be_ignored = message::Builder::new(&msg_id2).build();
        assert_false!(condition.is_opening(&msg_which_should_be_ignored));
        assert_true!(condition.is_opening(&msg_which_should_not_be_ignored));
    }

    #[test]
    fn test_given_condition_when_a_closing_message_is_received_then_the_state_becomes_closed() {
        let timeout = 100;
        let msg_id1 = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let msg_id2 = "21eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
        let patterns = vec![
            PatternId::Uuid(msg_id1.clone()),
            PatternId::Uuid(msg_id2.clone()),
        ];
        let mut state = State::new();
        let condition = Builder::new(timeout).patterns(patterns).last_closes(true).build();
        let msg_1 = message::Builder::new(&msg_id1).build();
        let msg_closing = Rc::new(message::Builder::new(&msg_id2).build());
        assert_true!(condition.is_opening(&msg_1));
        state.open();
        state.add_message(msg_closing);
        assert_true!(condition.is_closing(&mut state));
    }
}

mod deser {

    use super::Conditions;
    use serde;
    use serde::de::Deserialize;

    impl serde::Deserialize for Conditions {
        fn deserialize<D>(deserializer: &mut D) -> Result<Conditions, D::Error>
            where D: serde::de::Deserializer
        {
            deserializer.visit_struct("Conditions", &[], ConditionsVisitor)
        }
    }

    enum Field {
        TIMEOUT,
        RENEW_TIMEOUT,
        FIRST_OPENS,
        LAST_CLOSES,
        MAX_SIZE,
        PATTERNS,
    }

    impl serde::Deserialize for Field {
        fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
            where D: serde::de::Deserializer
        {
            struct FieldVisitor;

            impl serde::de::Visitor for FieldVisitor {
                type Value = Field;

                fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                    where E: serde::de::Error
                {
                    match value {
                        "timeout" => Ok(Field::TIMEOUT),
                        "renew_timeout" => Ok(Field::RENEW_TIMEOUT),
                        "first_opens" => Ok(Field::FIRST_OPENS),
                        "last_closes" => Ok(Field::LAST_CLOSES),
                        "max_size" => Ok(Field::MAX_SIZE),
                        "patterns" => Ok(Field::PATTERNS),
                        name @ _ => Err(serde::de::Error::syntax(&format!("Unexpected field: {}", name))),
                    }
                }
            }

            deserializer.visit(FieldVisitor)
        }
    }

    struct ConditionsVisitor;

    impl serde::de::Visitor for ConditionsVisitor {
        type Value = Conditions;

        fn visit_map<V>(&mut self, mut visitor: V) -> Result<Conditions, V::Error>
            where V: serde::de::MapVisitor
        {
            let mut timeout = None;
            let mut renew_timeout = None;
            let mut first_opens = None;
            let mut last_closes = None;
            let mut max_size = None;
            let mut patterns = None;
            let mut values = None;

            loop {
                match try!(visitor.visit_key()) {
                    Some(Field::TIMEOUT) => { timeout = Some(try!(visitor.visit_value())); }
                    Some(Field::RENEW_TIMEOUT) => { renew_timeout = Some(try!(visitor.visit_value())); }
                    Some(Field::FIRST_OPENS) => { first_opens = Some(try!(visitor.visit_value())); }
                    Some(Field::LAST_CLOSES) => { last_closes = Some(try!(visitor.visit_value())); }
                    Some(Field::MAX_SIZE) => { max_size = Some(try!(visitor.visit_value())); }
                    Some(Field::PATTERNS) => { patterns = Some(try!(visitor.visit_value())); }
                    None => { break; }
                }
            }

            let timeout = try!(timeout.ok_or(visitor.missing_field("timeout")));

            try!(visitor.end());

            Ok(
                Conditions {
                    timeout: timeout,
                    renew_timeout: renew_timeout,
                    first_opens: first_opens,
                    last_closes: last_closes,
                    max_size: max_size,
                    patterns: patterns.unwrap_or(Vec::new())
                }
            )
        }
    }
}
<|endoftext|>