<commit_before>//! Asynchronous green-threads.
//!
//! ## What are Tasks?
//!
//! A _task_ is a light weight, non-blocking unit of execution. A task is similar
//! to an OS thread, but rather than being managed by the OS scheduler, they are
//! managed by the [Tokio runtime][rt]. Another name for this general patterh is
//! [green threads]. If you are familiar with [Go's goroutines], [Kotlin's
//! coroutines], or [Erlang's processes], you can think of Tokio's tasks as
//! something similar.
//!
//! Key points about tasks include:
//!
//! * Tasks are **light weight**. Because tasks are scheduled by the Tokio
//!   runtime rather than the operating system, creating new tasks or switching
//!   between tasks does not require a context switch and has fairly low
//!   overhead. Creating, running, and destroying large numbers of tasks is
//!   quite cheap, especially compared to OS threads.
//!
//! * Tasks are scheduled **cooperatively**. Most operating systems implement
//!   _preemptive multitasking_. This is a scheduling technique where the
//!   operating system allows each thread to run for a period of time, and then
//!   _preempts_ it, temporarily pausing that thread and switching to another.
//!   Tasks, on the other hand, implement _cooperative multitasking_. In
//!   cooperative multitasking, a task is allowed to run until it _yields_,
//!   indicating to the Tokio runtime's scheduler that it cannot currently
//!   continue executing. When a task yields, the Tokio runtime switches to
//!   executing the next task.
//!
//! * Tasks are **non-blocking**. Typically, when an OS thread performs I/O or
//!   must synchronize with another thread, it _blocks_, allowing the OS to
//!   schedule another thread. When a task cannot continue executing, it must
//!   yield instead, allowing the Tokio runtime to schedule another task. Tasks
//!   should generally not perform system calls or other operations that could
//!   block a thread, as this would prevent other tasks running on the same
//!   thread from executing as well. Instead, this module provides APIs for
//!   running blocking operations in an asynchronous context.
//!
//! [rt]: crate::runtime
//! [green threads]: https://en.wikipedia.org/wiki/Green_threads
//! [Go's goroutines]: https://tour.golang.org/concurrency/1
//! [Kotlin's coroutines]: https://kotlinlang.org/docs/reference/coroutines-overview.html
//! [Erlang's processes]: http://erlang.org/doc/getting_started/conc_prog.html#processes
//!
//! ## Working with Tasks
//!
//! This module provides the following APIs for working with tasks:
//!
//! ### Spawning
//!
//! Perhaps the most important function in this module is [`task::spawn`]. This
//! function can be thought of as an async equivalent to the standard library's
//! [`thread::spawn`][`std::thread::spawn`]. It takes an `async` block or other
//! [future], and creates a new task to run that work concurrently:
//!
//! ```
//! use tokio::task;
//!
//! # async fn doc() {
//! task::spawn(async {
//!     // perform some work here...
//! });
//! # }
//! ```
//!
//! Like [`std::thread::spawn`], `task::spawn` returns a [`JoinHandle`] struct.
//! A `JoinHandle` is itself a future which may be used to await the output of
//! the spawned task. For example:
//!
//! ```
//! use tokio::task;
//!
//! # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let join = task::spawn(async {
//!     // ...
//!     "hello world!"
//! });
//!
//! // ...
//!
//! // Await the result of the spawned task.
//! let result = join.await?;
//! assert_eq!(result, "hello world!");
//! # Ok(())
//! # }
//! ```
//!
//! Again, like `std::thread`'s [`JoinHandle` type][thread_join], if the spawned
//! task panics, awaiting its `JoinHandle` will return a [`JoinError`]`. For
//! example:
//!
//! ```
//! use tokio::task;
//!
//! # #[tokio::main] async fn main() {
//! let join = task::spawn(async {
//!     panic!("something bad happened!")
//! });
//!
//! // The returned result indicates that the task failed.
//! assert!(join.await.is_err());
//! # }
//! ```
//!
//! `spawn`, `JoinHandle`, and `JoinError` are present when the "rt-core"
//! feature flag is enabled.
//!
//! [`task::spawn`]: crate::task::spawn()
//! [future]: std::future::Future
//! [`std::thread::spawn`]: std::thread::spawn
//! [`JoinHandle`]: crate::task::JoinHandle
//! [thread_join]: std::thread::JoinHandle
//! [`JoinError`]: crate::task::JoinError
//!
//! ### Blocking and Yielding
//!
//! As we discussed above, code running in asynchronous tasks should not perform
//! operations that can block. A blocking operation performed in a task running
//! on a thread that is also running other tasks would block the entire thread,
//! preventing other tasks from running.
//!
//! Instead, Tokio provides two APIs for running blocking operations in an
//! asynchronous context: [`task::spawn_blocking`] and [`task::block_in_place`].
//!
//! The `task::spawn_blocking` function is similar to the `task::spawn` function
//! discussed in the previous section, but rather than spawning an
//! _non-blocking_ future on the Tokio runtime, it instead spawns a
//! _blocking_ function on a dedicated thread pool for blocking tasks. For
//! example:
//!
//! ```
//! use tokio::task;
//!
//! # async fn docs() {
//! task::spawn_blocking(|| {
//!     // do some compute-heavy work or call synchronous code
//! });
//! # }
//! ```
//!
//! Just like `task::spawn`, `task::spawn_blocking` returns a `JoinHandle`
//! which we can use to await the result of the blocking operation:
//!
//! ```rust
//! # use tokio::task;
//! # async fn docs() -> Result<(), Box<dyn std::error::Error>>{
//! let join = task::spawn_blocking(|| {
//!     // do some compute-heavy work or call synchronous code
//!     "blocking completed"
//! });
//!
//! let result = join.await?;
//! assert_eq!(result, "blocking completed");
//! # Ok(())
//! # }
//! ```
//!
//! When using the [threaded runtime][rt-threaded], the [`task::block_in_place`]
//! function is also available. Like `task::spawn_blocking`, this function
//! allows running a blocking operation from an asynchronous context. Unlike
//! `spawn_blocking`, however, `block_in_place` works by transitioning the
//! _current_ worker thread to a blocking thread, moving other tasks running on
//! that thread to another worker thread. This can improve performance by avoiding
//! context switches.
//!
//! For example:
//!
//! ```
//! use tokio::task;
//!
//! # async fn docs() {
//! let result = task::block_in_place(|| {
//!     // do some compute-heavy work or call synchronous code
//!     "blocking completed"
//! });
//!
//! assert_eq!(result, "blocking completed");
//! # }
//! ```
//!
//! In addition, this module also provides a [`task::yield_now`] async function
//! that is analogous to the standard library's [`thread::yield_now`]. Calling and
//! `await`ing this function will cause the current task to yield to the Tokio
//! runtime's scheduler, allowing another task to be scheduled. Eventually, the
//! yielding task will be polled again, allowing it to execute. For example:
//!
//! ```rust
//! use tokio::task;
//!
//! # #[tokio::main] async fn main() {
//! async {
//!     task::spawn(async {
//!         // ...
//!         println!("spawned task done!")
//!     });
//!
//!     // Yield, allowing the newly-spawned task to execute first.
//!     task::yield_now().await;
//!     println!("main task done!");
//! }
//! # .await;
//! # }
//! ```
//!
//! [`task::spawn_blocking`]: crate::task::spawn_blocking
//! [`task::block_in_place`]: crate::task::block_in_place
//! [rt-threaded]: ../runtime/index.html#threaded-scheduler
//! [`task::yield_now`]: crate::task::yield_now()
//! [`thread::yield_now`]: std::thread::yield_now
cfg_blocking! {
    mod blocking;
    pub use blocking::spawn_blocking;

    cfg_rt_threaded! {
        pub use blocking::block_in_place;
    }
}

cfg_rt_core! {
    mod core;
    use self::core::Cell;
    pub(crate) use self::core::Header;

    mod error;
    pub use self::error::JoinError;

    mod harness;
    use self::harness::Harness;

    mod join;
    #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
    pub use self::join::JoinHandle;

    mod list;
    pub(crate) use self::list::OwnedList;

    mod raw;
    use self::raw::RawTask;

    mod spawn;
    pub use spawn::spawn;

    mod stack;
    pub(crate) use self::stack::TransferStack;

    mod state;
    use self::state::{Snapshot, State};

    mod waker;

    mod yield_now;
    pub use yield_now::yield_now;
}

cfg_rt_util! {
    mod local;
    pub use local::{spawn_local, LocalSet};
}

cfg_rt_core! {
    /// Unit tests
    #[cfg(test)]
    mod tests;

    use std::future::Future;
    use std::marker::PhantomData;
    use std::ptr::NonNull;
    use std::{fmt, mem};

    /// An owned handle to the task, tracked by ref count
    pub(crate) struct Task<S: 'static> {
        raw: RawTask,
        _p: PhantomData<S>,
    }

    unsafe impl<S: ScheduleSendOnly + 'static> Send for Task<S> {}

    /// Task result sent back
    pub(crate) type Result<T> = std::result::Result<T, JoinError>;

    pub(crate) trait Schedule: Sized + 'static {
        /// Bind a task to the executor.
        ///
        /// Guaranteed to be called from the thread that called `poll` on the task.
        fn bind(&self, task: &Task<Self>);

        /// The task has completed work and is ready to be released. The scheduler
        /// is free to drop it whenever.
        fn release(&self, task: Task<Self>);

        /// The has been completed by the executor it was bound to.
        fn release_local(&self, task: &Task<Self>);

        /// Schedule the task
        fn schedule(&self, task: Task<Self>);
    }

    /// Marker trait indicating that a scheduler can only schedule tasks which
    /// implement `Send`.
    ///
    /// Schedulers that implement this trait may not schedule `!Send` futures. If
    /// trait is implemented, the corresponding `Task` type will implement `Send`.
    pub(crate) trait ScheduleSendOnly: Schedule + Send + Sync {}

    /// Create a new task with an associated join handle
    pub(crate) fn joinable<T, S>(task: T) -> (Task<S>, JoinHandle<T::Output>)
    where
        T: Future + Send + 'static,
        S: ScheduleSendOnly,
    {
        let raw = RawTask::new_joinable::<_, S>(task);

        let task = Task {
            raw,
            _p: PhantomData,
        };

        let join = JoinHandle::new(raw);

        (task, join)
    }

    cfg_rt_util! {
        /// Create a new `!Send` task with an associated join handle
        pub(crate) fn joinable_local<T, S>(task: T) -> (Task<S>, JoinHandle<T::Output>)
        where
            T: Future + 'static,
            S: Schedule,
        {
            let raw = RawTask::new_joinable_local::<_, S>(task);

            let task = Task {
                raw,
                _p: PhantomData,
            };

            let join = JoinHandle::new(raw);

            (task, join)
        }
    }

    impl<S: 'static> Task<S> {
        pub(crate) unsafe fn from_raw(ptr: NonNull<Header>) -> Task<S> {
            Task {
                raw: RawTask::from_raw(ptr),
                _p: PhantomData,
            }
        }

        pub(crate) fn header(&self) -> &Header {
            self.raw.header()
        }

        pub(crate) fn into_raw(self) -> NonNull<Header> {
            let raw = self.raw.into_raw();
            mem::forget(self);
            raw
        }
    }

    impl<S: Schedule> Task<S> {
        /// Returns `self` when the task needs to be immediately re-scheduled
        pub(crate) fn run<F>(self, mut executor: F) -> Option<Self>
        where
            F: FnMut() -> Option<NonNull<S>>,
        {
            if unsafe {
                self.raw
                    .poll(&mut || executor().map(|ptr| ptr.cast::<()>()))
            } {
                Some(self)
            } else {
                // Cleaning up the `Task` instance is done from within the poll
                // function.
                mem::forget(self);
                None
            }
        }

        /// Pre-emptively cancel the task as part of the shutdown process.
        pub(crate) fn shutdown(self) {
            self.raw.cancel_from_queue();
            mem::forget(self);
        }
    }

    impl<S: 'static> Drop for Task<S> {
        fn drop(&mut self) {
            self.raw.drop_task();
        }
    }

    impl<S> fmt::Debug for Task<S> {
        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
            fmt.debug_struct("Task").finish()
        }
    }
}
<commit_msg>Fixing minor spelling mistake in task docs (#1889)<commit_after>//! Asynchronous green-threads.
//!
//! ## What are Tasks?
//!
//! A _task_ is a light weight, non-blocking unit of execution. A task is similar
//! to an OS thread, but rather than being managed by the OS scheduler, they are
//! managed by the [Tokio runtime][rt]. Another name for this general pattern is
//! [green threads]. If you are familiar with [Go's goroutines], [Kotlin's
//! coroutines], or [Erlang's processes], you can think of Tokio's tasks as
//! something similar.
//!
//! Key points about tasks include:
//!
//! * Tasks are **light weight**. Because tasks are scheduled by the Tokio
//!   runtime rather than the operating system, creating new tasks or switching
//!   between tasks does not require a context switch and has fairly low
//!   overhead. Creating, running, and destroying large numbers of tasks is
//!   quite cheap, especially compared to OS threads.
//!
//! * Tasks are scheduled **cooperatively**. Most operating systems implement
//!   _preemptive multitasking_. This is a scheduling technique where the
//!   operating system allows each thread to run for a period of time, and then
//!   _preempts_ it, temporarily pausing that thread and switching to another.
//!   Tasks, on the other hand, implement _cooperative multitasking_. In
//!   cooperative multitasking, a task is allowed to run until it _yields_,
//!   indicating to the Tokio runtime's scheduler that it cannot currently
//!   continue executing. When a task yields, the Tokio runtime switches to
//!   executing the next task.
//!
//! * Tasks are **non-blocking**. Typically, when an OS thread performs I/O or
//!   must synchronize with another thread, it _blocks_, allowing the OS to
//!   schedule another thread. When a task cannot continue executing, it must
//!   yield instead, allowing the Tokio runtime to schedule another task. Tasks
//!   should generally not perform system calls or other operations that could
//!   block a thread, as this would prevent other tasks running on the same
//!   thread from executing as well. Instead, this module provides APIs for
//!   running blocking operations in an asynchronous context.
//!
//! [rt]: crate::runtime
//! [green threads]: https://en.wikipedia.org/wiki/Green_threads
//! [Go's goroutines]: https://tour.golang.org/concurrency/1
//! [Kotlin's coroutines]: https://kotlinlang.org/docs/reference/coroutines-overview.html
//! [Erlang's processes]: http://erlang.org/doc/getting_started/conc_prog.html#processes
//!
//! ## Working with Tasks
//!
//! This module provides the following APIs for working with tasks:
//!
//! ### Spawning
//!
//! Perhaps the most important function in this module is [`task::spawn`]. This
//! function can be thought of as an async equivalent to the standard library's
//! [`thread::spawn`][`std::thread::spawn`]. It takes an `async` block or other
//! [future], and creates a new task to run that work concurrently:
//!
//! ```
//! use tokio::task;
//!
//! # async fn doc() {
//! task::spawn(async {
//!     // perform some work here...
//! });
//! # }
//! ```
//!
//! Like [`std::thread::spawn`], `task::spawn` returns a [`JoinHandle`] struct.
//! A `JoinHandle` is itself a future which may be used to await the output of
//! the spawned task. For example:
//!
//! ```
//! use tokio::task;
//!
//! # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let join = task::spawn(async {
//!     // ...
//!     "hello world!"
//! });
//!
//! // ...
//!
//! // Await the result of the spawned task.
//! let result = join.await?;
//! assert_eq!(result, "hello world!");
//! # Ok(())
//! # }
//! ```
//!
//! Again, like `std::thread`'s [`JoinHandle` type][thread_join], if the spawned
//! task panics, awaiting its `JoinHandle` will return a [`JoinError`]`. For
//! example:
//!
//! ```
//! use tokio::task;
//!
//! # #[tokio::main] async fn main() {
//! let join = task::spawn(async {
//!     panic!("something bad happened!")
//! });
//!
//! // The returned result indicates that the task failed.
//! assert!(join.await.is_err());
//! # }
//! ```
//!
//! `spawn`, `JoinHandle`, and `JoinError` are present when the "rt-core"
//! feature flag is enabled.
//!
//! [`task::spawn`]: crate::task::spawn()
//! [future]: std::future::Future
//! [`std::thread::spawn`]: std::thread::spawn
//! [`JoinHandle`]: crate::task::JoinHandle
//! [thread_join]: std::thread::JoinHandle
//! [`JoinError`]: crate::task::JoinError
//!
//! ### Blocking and Yielding
//!
//! As we discussed above, code running in asynchronous tasks should not perform
//! operations that can block. A blocking operation performed in a task running
//! on a thread that is also running other tasks would block the entire thread,
//! preventing other tasks from running.
//!
//! Instead, Tokio provides two APIs for running blocking operations in an
//! asynchronous context: [`task::spawn_blocking`] and [`task::block_in_place`].
//!
//! The `task::spawn_blocking` function is similar to the `task::spawn` function
//! discussed in the previous section, but rather than spawning an
//! _non-blocking_ future on the Tokio runtime, it instead spawns a
//! _blocking_ function on a dedicated thread pool for blocking tasks. For
//! example:
//!
//! ```
//! use tokio::task;
//!
//! # async fn docs() {
//! task::spawn_blocking(|| {
//!     // do some compute-heavy work or call synchronous code
//! });
//! # }
//! ```
//!
//! Just like `task::spawn`, `task::spawn_blocking` returns a `JoinHandle`
//! which we can use to await the result of the blocking operation:
//!
//! ```rust
//! # use tokio::task;
//! # async fn docs() -> Result<(), Box<dyn std::error::Error>>{
//! let join = task::spawn_blocking(|| {
//!     // do some compute-heavy work or call synchronous code
//!     "blocking completed"
//! });
//!
//! let result = join.await?;
//! assert_eq!(result, "blocking completed");
//! # Ok(())
//! # }
//! ```
//!
//! When using the [threaded runtime][rt-threaded], the [`task::block_in_place`]
//! function is also available. Like `task::spawn_blocking`, this function
//! allows running a blocking operation from an asynchronous context. Unlike
//! `spawn_blocking`, however, `block_in_place` works by transitioning the
//! _current_ worker thread to a blocking thread, moving other tasks running on
//! that thread to another worker thread. This can improve performance by avoiding
//! context switches.
//!
//! For example:
//!
//! ```
//! use tokio::task;
//!
//! # async fn docs() {
//! let result = task::block_in_place(|| {
//!     // do some compute-heavy work or call synchronous code
//!     "blocking completed"
//! });
//!
//! assert_eq!(result, "blocking completed");
//! # }
//! ```
//!
//! In addition, this module also provides a [`task::yield_now`] async function
//! that is analogous to the standard library's [`thread::yield_now`]. Calling and
//! `await`ing this function will cause the current task to yield to the Tokio
//! runtime's scheduler, allowing another task to be scheduled. Eventually, the
//! yielding task will be polled again, allowing it to execute. For example:
//!
//! ```rust
//! use tokio::task;
//!
//! # #[tokio::main] async fn main() {
//! async {
//!     task::spawn(async {
//!         // ...
//!         println!("spawned task done!")
//!     });
//!
//!     // Yield, allowing the newly-spawned task to execute first.
//!     task::yield_now().await;
//!     println!("main task done!");
//! }
//! # .await;
//! # }
//! ```
//!
//! [`task::spawn_blocking`]: crate::task::spawn_blocking
//! [`task::block_in_place`]: crate::task::block_in_place
//! [rt-threaded]: ../runtime/index.html#threaded-scheduler
//! [`task::yield_now`]: crate::task::yield_now()
//! [`thread::yield_now`]: std::thread::yield_now
cfg_blocking! {
    mod blocking;
    pub use blocking::spawn_blocking;

    cfg_rt_threaded! {
        pub use blocking::block_in_place;
    }
}

cfg_rt_core! {
    mod core;
    use self::core::Cell;
    pub(crate) use self::core::Header;

    mod error;
    pub use self::error::JoinError;

    mod harness;
    use self::harness::Harness;

    mod join;
    #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
    pub use self::join::JoinHandle;

    mod list;
    pub(crate) use self::list::OwnedList;

    mod raw;
    use self::raw::RawTask;

    mod spawn;
    pub use spawn::spawn;

    mod stack;
    pub(crate) use self::stack::TransferStack;

    mod state;
    use self::state::{Snapshot, State};

    mod waker;

    mod yield_now;
    pub use yield_now::yield_now;
}

cfg_rt_util! {
    mod local;
    pub use local::{spawn_local, LocalSet};
}

cfg_rt_core! {
    /// Unit tests
    #[cfg(test)]
    mod tests;

    use std::future::Future;
    use std::marker::PhantomData;
    use std::ptr::NonNull;
    use std::{fmt, mem};

    /// An owned handle to the task, tracked by ref count
    pub(crate) struct Task<S: 'static> {
        raw: RawTask,
        _p: PhantomData<S>,
    }

    unsafe impl<S: ScheduleSendOnly + 'static> Send for Task<S> {}

    /// Task result sent back
    pub(crate) type Result<T> = std::result::Result<T, JoinError>;

    pub(crate) trait Schedule: Sized + 'static {
        /// Bind a task to the executor.
        ///
        /// Guaranteed to be called from the thread that called `poll` on the task.
        fn bind(&self, task: &Task<Self>);

        /// The task has completed work and is ready to be released. The scheduler
        /// is free to drop it whenever.
        fn release(&self, task: Task<Self>);

        /// The has been completed by the executor it was bound to.
        fn release_local(&self, task: &Task<Self>);

        /// Schedule the task
        fn schedule(&self, task: Task<Self>);
    }

    /// Marker trait indicating that a scheduler can only schedule tasks which
    /// implement `Send`.
    ///
    /// Schedulers that implement this trait may not schedule `!Send` futures. If
    /// trait is implemented, the corresponding `Task` type will implement `Send`.
    pub(crate) trait ScheduleSendOnly: Schedule + Send + Sync {}

    /// Create a new task with an associated join handle
    pub(crate) fn joinable<T, S>(task: T) -> (Task<S>, JoinHandle<T::Output>)
    where
        T: Future + Send + 'static,
        S: ScheduleSendOnly,
    {
        let raw = RawTask::new_joinable::<_, S>(task);

        let task = Task {
            raw,
            _p: PhantomData,
        };

        let join = JoinHandle::new(raw);

        (task, join)
    }

    cfg_rt_util! {
        /// Create a new `!Send` task with an associated join handle
        pub(crate) fn joinable_local<T, S>(task: T) -> (Task<S>, JoinHandle<T::Output>)
        where
            T: Future + 'static,
            S: Schedule,
        {
            let raw = RawTask::new_joinable_local::<_, S>(task);

            let task = Task {
                raw,
                _p: PhantomData,
            };

            let join = JoinHandle::new(raw);

            (task, join)
        }
    }

    impl<S: 'static> Task<S> {
        pub(crate) unsafe fn from_raw(ptr: NonNull<Header>) -> Task<S> {
            Task {
                raw: RawTask::from_raw(ptr),
                _p: PhantomData,
            }
        }

        pub(crate) fn header(&self) -> &Header {
            self.raw.header()
        }

        pub(crate) fn into_raw(self) -> NonNull<Header> {
            let raw = self.raw.into_raw();
            mem::forget(self);
            raw
        }
    }

    impl<S: Schedule> Task<S> {
        /// Returns `self` when the task needs to be immediately re-scheduled
        pub(crate) fn run<F>(self, mut executor: F) -> Option<Self>
        where
            F: FnMut() -> Option<NonNull<S>>,
        {
            if unsafe {
                self.raw
                    .poll(&mut || executor().map(|ptr| ptr.cast::<()>()))
            } {
                Some(self)
            } else {
                // Cleaning up the `Task` instance is done from within the poll
                // function.
                mem::forget(self);
                None
            }
        }

        /// Pre-emptively cancel the task as part of the shutdown process.
        pub(crate) fn shutdown(self) {
            self.raw.cancel_from_queue();
            mem::forget(self);
        }
    }

    impl<S: 'static> Drop for Task<S> {
        fn drop(&mut self) {
            self.raw.drop_task();
        }
    }

    impl<S> fmt::Debug for Task<S> {
        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
            fmt.debug_struct("Task").finish()
        }
    }
}
<|endoftext|>


<commit_before>use bit_field::BitField;

use register::Reg;
use instruction::Op;

#[allow(non_snake_case)]
pub fn decode_LDR_imm_t2(command: u16) -> Op {
    Op::LDR_imm {
        rt: Reg::from_u16(command.get_bits(8..11)).unwrap(),
        rn: Reg::PC,
        imm32: (command.get_bits(0..8) as u32) << 2,
    }
}
#[allow(non_snake_case)]
pub fn decode_LDR_imm_t1(command: u16) -> Op {
    Op::LDR_imm {
        rt: Reg::from_u16(command.get_bits(0..3)).unwrap(),
        rn: Reg::from_u16(command.get_bits(3..6)).unwrap(),
        imm32: (command.get_bits(6..11) as u32) << 2,
    }
}

#[allow(non_snake_case)]
pub fn decode_LDR_lit_t1(command: u16) -> Op {
    Op::LDR_lit {
        rt: Reg::from_u16(command.get_bits(8..11)).unwrap(),
        imm32: (command.get_bits(0..8) as u32) << 2,
    }
}

#[allow(non_snake_case)]
pub fn decode_LDR_reg_t1(command: u16) -> Op {
    Op::LDR_reg {
        rt: Reg::from_u16(command.get_bits(0..3)).unwrap(),
        rn: Reg::from_u16(command.get_bits(3..6)).unwrap(),
        rm: Reg::from_u16(command.get_bits(6..9)).unwrap(),
    }
}

<commit_msg>fix bug, SP instead of PC in LDR imm type 2 decoding<commit_after>use bit_field::BitField;

use register::Reg;
use instruction::Op;

#[allow(non_snake_case)]
pub fn decode_LDR_imm_t2(command: u16) -> Op {
    Op::LDR_imm {
        rt: Reg::from_u16(command.get_bits(8..11)).unwrap(),
        rn: Reg::SP,
        imm32: (command.get_bits(0..8) as u32) << 2,
    }
}
#[allow(non_snake_case)]
pub fn decode_LDR_imm_t1(command: u16) -> Op {
    Op::LDR_imm {
        rt: Reg::from_u16(command.get_bits(0..3)).unwrap(),
        rn: Reg::from_u16(command.get_bits(3..6)).unwrap(),
        imm32: (command.get_bits(6..11) as u32) << 2,
    }
}

#[allow(non_snake_case)]
pub fn decode_LDR_lit_t1(command: u16) -> Op {
    Op::LDR_lit {
        rt: Reg::from_u16(command.get_bits(8..11)).unwrap(),
        imm32: (command.get_bits(0..8) as u32) << 2,
    }
}

#[allow(non_snake_case)]
pub fn decode_LDR_reg_t1(command: u16) -> Op {
    Op::LDR_reg {
        rt: Reg::from_u16(command.get_bits(0..3)).unwrap(),
        rn: Reg::from_u16(command.get_bits(3..6)).unwrap(),
        rm: Reg::from_u16(command.get_bits(6..9)).unwrap(),
    }
}

<|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 4]>
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let triangles = &self.triangles;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(WHITE, gl);

            let transform = c.transform.trans(0.0, 0.0);

            for t in triangles {
              polygon(BLACK, t, transform, gl);
            }
        });
    }
}

fn main() {
    let opengl = OpenGL::V3_2;

    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = vec![[[100.0, 200.0], [200.0, 200.0],
                          [150.0, 100.0], [100.0, 200.0]],
                          [[250.0, 200.0], [350.0, 200.0],
                          [300.0, 100.0], [250.0, 200.0]]];

    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles};

    for e in window.events() {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
    }
}
<commit_msg>Got recursive function working. Just need correct coords now<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 4]>
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let triangles = &self.triangles;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(WHITE, gl);

            let transform = c.transform.trans(0.0, 0.0);

            for t in triangles {
              polygon(BLACK, t, transform, gl);
            }
        });
    }
}

fn sierpinski(depth: i32, vertices: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d @ _ => {
            // TODO: Break into four triangles. Push first. And then recurse on the rest.
            triangles.push([[100.0, 200.0], [200.0, 200.0],
                            [150.0, 100.0], [100.0, 200.0]]);

            for t in sierpinski(d - 1, [[100.0, 200.0], [200.0, 200.0], [150.0, 100.0], [100.0, 200.0]]) {
                triangles.push(t);
            }
            for t in sierpinski(d - 1, [[100.0, 200.0], [200.0, 200.0], [150.0, 100.0], [100.0, 200.0]]) {
                triangles.push(t);
            }
            for t in sierpinski(d - 1, [[100.0, 200.0], [200.0, 200.0], [150.0, 100.0], [100.0, 200.0]]) {
                triangles.push(t);
            }

            triangles
        },
    }
}

fn main() {
    let opengl = OpenGL::V3_2;

    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(4, [[100.0, 200.0], [200.0, 200.0],
                                   [150.0, 100.0], [100.0, 200.0]]);

    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles};

    for e in window.events().max_fps(1) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
    }
}
<|endoftext|>


<commit_before>// extern crate centralgithook;
extern crate git2;
extern crate clap;
extern crate env_logger;

use std::path::Path;
use super::RepoHost;
use super::Scratch;
use super::ReviewUploadResult;
use super::Hooks;

pub fn dispatch(pargs: Vec<String>, hooks: &Hooks, host: &RepoHost, scratch: &Scratch) -> i32
{
    let hook = &pargs[0];
    let args = clap::App::new("centralgithook")
        .arg(clap::Arg::with_name("branch").long("branch").takes_value(true))
        .arg(clap::Arg::with_name("change").long("change").takes_value(true))
        .arg(clap::Arg::with_name("change-owner").long("change-owner").takes_value(true))
        .arg(clap::Arg::with_name("change-url").long("change-url").takes_value(true))
        .arg(clap::Arg::with_name("commit").long("commit").takes_value(true))
        .arg(clap::Arg::with_name("head").long("head").takes_value(true))
        .arg(clap::Arg::with_name("newrev").long("newrev").takes_value(true))
        .arg(clap::Arg::with_name("oldrev").long("oldrev").takes_value(true))
        .arg(clap::Arg::with_name("project").long("project").takes_value(true))
        .arg(clap::Arg::with_name("refname").long("refname").takes_value(true))
        .arg(clap::Arg::with_name("submitter").long("submitter").takes_value(true))
        .arg(clap::Arg::with_name("topic").long("topic").takes_value(true))
        .arg(clap::Arg::with_name("uploader").long("uploader").takes_value(true))
        .get_matches_from(&pargs);

    let commit = args.value_of("commit").unwrap_or("");
    let newrev = args.value_of("newrev").unwrap_or("");
    let oldrev = args.value_of("oldrev").unwrap_or("");
    let project = args.value_of("project").unwrap_or("");
    let refname = args.value_of("refname").unwrap_or("");

    println!("PP {:?} {:?} {:?}",pargs, project, host.prefix());
    let (_, project) = project.split_at(host.prefix().len());
    println!("PJECT: {}", project);

    let this_project = Path::new(&host.local_path(project)).to_path_buf();

    // ref-update: fired after push
    // change-merged: fired after gerrit-submit
    let is_update = hook.ends_with("ref-update");
    let is_submit = hook.ends_with("change-merged");
    let is_project_created = hook.ends_with("project-created");

    let is_review = is_update && refname == "refs/for/master";
    let is_module = project != format!("{}{}", host.prefix(), host.central());
    let is_initial = !is_module && oldrev == "0000000000000000000000000000000000000000";

    let uploader = args.value_of("uploader").unwrap_or("");
    if is_update && !is_review && !uploader.contains("Automation") {
        println!(".");
        // debug!("==== uploader: {}", uploader);
        println!("{} {} {}", is_update, is_review, uploader.contains("Automation"));
        println!("===================================================================");
        println!("================= Do not push directly to master! =================");
        println!("===================================================================");
        return 1;
    }

    if is_submit {
        // submit to central
        hooks.central_submit(&scratch, scratch.transfer(commit, &this_project));
    }
    else if is_project_created {
        hooks.project_created(&scratch);
        println!("==== project_created");
    }
    else if is_review {
        // module was pushed, get changes to central
        match hooks.review_upload(&scratch, scratch.transfer(newrev, &this_project), project) {
            ReviewUploadResult::RejectNoFF => {
                println!(".");
                println!("===================================================================");
                println!("=========== Commit not based on master, rebase first! =============");
                println!("===================================================================");
            }
            ReviewUploadResult::NoChanges => {}
            ReviewUploadResult::RejectMerge => {
                println!(".");
                println!("===================================================================");
                println!("=================== Do not submit merge commits! ==================");
                println!("===================================================================");
            }
            ReviewUploadResult::Uploaded(oid) => {
                println!("================ Doing actual upload in central git ===============");

                println!("{}", scratch.push(oid, host.central(), "refs/for/master"));
                println!("==== The review upload may have worked, even if it says error below. \
                          Look UP! ====")
            }
            ReviewUploadResult::Central => return 0,
        }

        // stop host from allowing push to module directly
        return 1;
    }
    else if !is_module && is_update && !is_review {
        // direct push to master-branch of central
        if is_initial {
            println!(".\n\n##### INITIAL IMPORT ######");
            hooks.central_submit(&scratch, scratch.transfer(newrev, &this_project));
            return 0;
        }
    }
    return 0;
}
<commit_msg>tests<commit_after>// extern crate centralgithook;
extern crate git2;
extern crate clap;
extern crate env_logger;

use std::path::Path;
use super::RepoHost;
use super::Scratch;
use super::ReviewUploadResult;
use super::Hooks;

pub fn dispatch(pargs: Vec<String>, hooks: &Hooks, host: &RepoHost, scratch: &Scratch) -> i32
{
    let hook = &pargs[0];
    let args = clap::App::new("centralgithook")
        .arg(clap::Arg::with_name("branch").long("branch").takes_value(true))
        .arg(clap::Arg::with_name("change").long("change").takes_value(true))
        .arg(clap::Arg::with_name("change-owner").long("change-owner").takes_value(true))
        .arg(clap::Arg::with_name("change-url").long("change-url").takes_value(true))
        .arg(clap::Arg::with_name("commit").long("commit").takes_value(true))
        .arg(clap::Arg::with_name("head").long("head").takes_value(true))
        .arg(clap::Arg::with_name("newrev").long("newrev").takes_value(true))
        .arg(clap::Arg::with_name("oldrev").long("oldrev").takes_value(true))
        .arg(clap::Arg::with_name("project").long("project").takes_value(true))
        .arg(clap::Arg::with_name("refname").long("refname").takes_value(true))
        .arg(clap::Arg::with_name("submitter").long("submitter").takes_value(true))
        .arg(clap::Arg::with_name("topic").long("topic").takes_value(true))
        .arg(clap::Arg::with_name("uploader").long("uploader").takes_value(true))
        .get_matches_from(&pargs);

    let commit = args.value_of("commit").unwrap_or("");
    let newrev = args.value_of("newrev").unwrap_or("");
    let oldrev = args.value_of("oldrev").unwrap_or("");
    let project = args.value_of("project").unwrap_or("");
    let refname = args.value_of("refname").unwrap_or("");

    println!("PP {:?} {:?} {:?}",pargs, project, host.prefix());
    let (_, project) = project.split_at(host.prefix().len());
    println!("PJECT: {}", project);

    let this_project = Path::new(&host.local_path(project)).to_path_buf();

    // ref-update: fired after push
    // change-merged: fired after gerrit-submit
    let is_update = hook.ends_with("ref-update");
    let is_submit = hook.ends_with("change-merged");
    let is_project_created = hook.ends_with("project-created");

    let is_review = is_update && refname == "refs/for/master";
    let is_module = project != format!("{}{}", host.prefix(), host.central());
    let is_initial = !is_module && oldrev == "0000000000000000000000000000000000000000";

    let uploader = args.value_of("uploader").unwrap_or("");
    if is_update && !is_review && !uploader.contains("Automation") { // FIXME: hardcoded
        println!(".");
        // debug!("==== uploader: {}", uploader);
        println!("{} {} {}", is_update, is_review, uploader.contains("Automation"));
        println!("===================================================================");
        println!("================= Do not push directly to master! =================");
        println!("===================================================================");
        return 1;
    }

    if is_submit {
        // submit to central
        hooks.central_submit(&scratch, scratch.transfer(commit, &this_project));
    }
    else if is_project_created {
        hooks.project_created(&scratch);
        println!("==== project_created");
    }
    else if is_review {
        // module was pushed, get changes to central
        match hooks.review_upload(&scratch, scratch.transfer(newrev, &this_project), project) {
            ReviewUploadResult::RejectNoFF => {
                println!(".");
                println!("===================================================================");
                println!("=========== Commit not based on master, rebase first! =============");
                println!("===================================================================");
            }
            ReviewUploadResult::NoChanges => {}
            ReviewUploadResult::RejectMerge => {
                println!(".");
                println!("===================================================================");
                println!("=================== Do not submit merge commits! ==================");
                println!("===================================================================");
            }
            ReviewUploadResult::Uploaded(oid) => {
                println!("================ Doing actual upload in central git ===============");

                println!("{}", scratch.push(oid, host.central(), "refs/for/master"));
                println!("==== The review upload may have worked, even if it says error below. \
                          Look UP! ====")
            }
            ReviewUploadResult::Central => return 0,
        }

        // stop host from allowing push to module directly
        return 1;
    }
    return 0;
}
<|endoftext|>


<commit_before>use std::thread;
use std::sync::mpsc;
use websocket::{Server, Message, Sender, Receiver};
use websocket::server::sender;
use websocket::stream::WebSocketStream;
use std::io::prelude::*;
use std::fs::OpenOptions;
use std::num::ToPrimitive;
use rustc_serialize::json::{Json, ToJson};
use std::mem::replace;

use value::{Value, Tuple};
use index;
use flow::{Changes, Flow};
use compiler::compile;

trait FromJson {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self;
}

impl ToJson for Value {
    fn to_json(&self) -> Json {
        match *self {
            Value::Bool(bool) => Json::Boolean(bool),
            Value::String(ref string) => Json::String(string.clone()),
            Value::Float(float) => Json::F64(float),
            Value::Tuple(ref tuple) => tuple.to_json(),
            Value::Relation(ref relation) => Json::Object(vec![
                ("relation".to_string(), relation.iter().map(ToJson::to_json).collect::<Vec<_>>().to_json())
                ].into_iter().collect()),
        }
    }
}

impl FromJson for Value {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self {
        match *json {
            Json::Boolean(bool) => Value::Bool(bool),
            Json::String(ref string) => Value::String(string.clone()),
            Json::F64(float) => Value::Float(float),
            Json::I64(int) => Value::Float(int.to_f64().unwrap()),
            Json::U64(uint) => Value::Float(uint.to_f64().unwrap()),
            Json::Array(ref array) => Value::Tuple(array.iter().map(|j| Value::from_json(j, next_eid)).collect()),
            Json::Object(ref object) => {
                assert!(object.len() == 1);
                match object.get("eid") {
                    Some(value) => {
                        assert_eq!(value.as_string().unwrap(), "auto");
                        let eid = next_eid.to_f64().unwrap();
                        *next_eid += 1;
                        Value::Float(eid)
                    }
                    None => {
                        let relation: Vec<Tuple> = FromJson::from_json(&object["relation"], next_eid);
                        Value::Relation(relation.into_iter().collect())
                    }
                }
            },
            _ => panic!("Cannot decode {:?} as Value", json),
        }
    }
}

impl<T: FromJson> FromJson for Vec<T> {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self {
        json.as_array().unwrap().iter().map(|t| FromJson::from_json(t, next_eid)).collect()
    }
}

pub struct Event {
    changes: Changes,
}

// TODO need to change encoding to list of changes instead of object

impl ToJson for Event {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("changes".to_string(), Json::Object(
                self.changes.iter().map(|&(ref view_id, ref view_changes)| {
                    (view_id.to_string(), Json::Object(vec![
                        ("inserted".to_string(), view_changes.inserted.to_json()),
                        ("removed".to_string(), view_changes.removed.to_json()),
                        ].into_iter().collect()))
                }).collect()))].into_iter().collect())
    }
}

impl FromJson for Event {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self {
        Event{
            changes: json.as_object().unwrap()["changes"]
            .as_object().unwrap().iter().map(|(view_id, view_changes)| {
                (view_id.to_string(), index::Changes{
                    inserted: FromJson::from_json(&view_changes.as_object().unwrap()["inserted"], next_eid),
                    removed: FromJson::from_json(&view_changes.as_object().unwrap()["removed"], next_eid),
                })
            }).collect()
        }
    }
}

pub enum ServerEvent {
    Message(String),
    NewClient(sender::Sender<WebSocketStream>),
}

// TODO holy crap why is everything blocking? this is a mess
pub fn serve() -> mpsc::Receiver<ServerEvent> {
    let (event_sender, event_receiver) = mpsc::channel();
    thread::spawn(move || {
        let server = Server::bind("0.0.0.0:2794").unwrap();
        for connection in server {
            let event_sender = event_sender.clone();
            thread::spawn(move || {
                // accept request
                let request = connection.unwrap().read_request().unwrap();
                request.validate().unwrap();
                let response = request.accept();
                let (mut sender, mut receiver) = response.send().unwrap().split();

                let ip = sender.get_mut().peer_addr().unwrap();
                println!("Connection from {}", ip);
                ::std::io::stdout().flush().unwrap(); // TODO is this actually necessary?

                // hand over sender
                event_sender.send(ServerEvent::NewClient(sender)).unwrap();

                // handle messages
                for message in receiver.incoming_messages() {
                    let message = message.unwrap();
                    match message {
                        Message::Text(text) => {
                            event_sender.send(ServerEvent::Message(text)).unwrap();
                        }
                        _ => println!("Unknown message: {:?}", message)
                    }
                }
            });
        }
    });
    event_receiver
}

// TODO arbitrary limit - needs tuning
static MAX_BATCH_SIZE: usize = 100;

fn recv_batch(event_receiver: &mpsc::Receiver<ServerEvent>, server_events: &mut Vec<ServerEvent>) {
    server_events.push(event_receiver.recv().unwrap()); // block until first event
    for _ in 0..MAX_BATCH_SIZE {
        match event_receiver.try_recv() {
            Ok(event) => server_events.push(event),
            Err(mpsc::TryRecvError::Empty) => break,
            Err(mpsc::TryRecvError::Disconnected) => panic!(),
        }
    }
}

pub fn compile_and_run(flow: Flow) -> (Flow, Changes) {
    let mut new_flow = compile(flow);
    new_flow.run();
    let changes = {
        let Flow {ref mut changes, ..} = new_flow;
        replace(changes, Vec::new())
    };
    (new_flow, changes)
}

pub fn run() {
    let empty_flow = Flow::new();
    let next_eid = &mut 0;
    let mut flow = Flow::new();

    time!("reading saved state", {
        let mut events = OpenOptions::new().create(true).open("./events").unwrap();
        let mut old_events = String::new();
        events.read_to_string(&mut old_events).unwrap();
        for line in old_events.lines() {
            let json = Json::from_str(&line).unwrap();
            let event: Event = FromJson::from_json(&json, next_eid);
            flow.change(event.changes);
        }
        drop(events);
        let (new_flow, _changes) = compile_and_run(flow);
        flow = new_flow;
        });

    let mut events = OpenOptions::new().write(true).append(true).open("./events").unwrap();
    let mut senders: Vec<sender::Sender<_>> = Vec::new();
    let mut server_events: Vec<ServerEvent> = Vec::with_capacity(MAX_BATCH_SIZE);
    let event_receiver = serve();
    loop {
        time!("entire batch", {
            recv_batch(&event_receiver, &mut server_events);
            println!("batch size: {:?}", server_events.len());

            for event in server_events.drain() {
                match event {
                    ServerEvent::NewClient(mut sender) => {
                        time!("sending initial state", {
                            let changes = flow.changes_since(&empty_flow);
                            let text = format!("{}", Event{changes: changes}.to_json());
                            match sender.send_message(Message::Text(text)) {
                                Ok(_) => (),
                                Err(error) => println!("Send error: {}", error),
                            };
                            senders.push(sender)
                        })
                    }
                    ServerEvent::Message(input_text) => {
                        time!("sending update", {
                            let json = Json::from_str(&input_text).unwrap();
                            let input_event: Event = FromJson::from_json(&json, next_eid);
                            events.write_all(input_text.as_bytes()).unwrap();
                            events.write_all("\n".as_bytes()).unwrap();
                            flow.change(input_event.changes);
                        })
                    }
                }
            }

            let (new_flow, changes) = compile_and_run(flow);
            flow = new_flow;
            let output_event = Event{changes: changes};
            let output_text = format!("{}", output_event.to_json());
            events.flush().unwrap();
            for sender in senders.iter_mut() {
                match sender.send_message(Message::Text(output_text.clone())) {
                    Ok(_) => (),
                    Err(error) => println!("Send error: {}", error),
                };
            }
        })
    }
}
<commit_msg>Time batches correctly - dont include the wait time before the first event<commit_after>use std::thread;
use std::sync::mpsc;
use websocket::{Server, Message, Sender, Receiver};
use websocket::server::sender;
use websocket::stream::WebSocketStream;
use std::io::prelude::*;
use std::fs::OpenOptions;
use std::num::ToPrimitive;
use rustc_serialize::json::{Json, ToJson};
use std::mem::replace;

use value::{Value, Tuple};
use index;
use flow::{Changes, Flow};
use compiler::compile;

trait FromJson {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self;
}

impl ToJson for Value {
    fn to_json(&self) -> Json {
        match *self {
            Value::Bool(bool) => Json::Boolean(bool),
            Value::String(ref string) => Json::String(string.clone()),
            Value::Float(float) => Json::F64(float),
            Value::Tuple(ref tuple) => tuple.to_json(),
            Value::Relation(ref relation) => Json::Object(vec![
                ("relation".to_string(), relation.iter().map(ToJson::to_json).collect::<Vec<_>>().to_json())
                ].into_iter().collect()),
        }
    }
}

impl FromJson for Value {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self {
        match *json {
            Json::Boolean(bool) => Value::Bool(bool),
            Json::String(ref string) => Value::String(string.clone()),
            Json::F64(float) => Value::Float(float),
            Json::I64(int) => Value::Float(int.to_f64().unwrap()),
            Json::U64(uint) => Value::Float(uint.to_f64().unwrap()),
            Json::Array(ref array) => Value::Tuple(array.iter().map(|j| Value::from_json(j, next_eid)).collect()),
            Json::Object(ref object) => {
                assert!(object.len() == 1);
                match object.get("eid") {
                    Some(value) => {
                        assert_eq!(value.as_string().unwrap(), "auto");
                        let eid = next_eid.to_f64().unwrap();
                        *next_eid += 1;
                        Value::Float(eid)
                    }
                    None => {
                        let relation: Vec<Tuple> = FromJson::from_json(&object["relation"], next_eid);
                        Value::Relation(relation.into_iter().collect())
                    }
                }
            },
            _ => panic!("Cannot decode {:?} as Value", json),
        }
    }
}

impl<T: FromJson> FromJson for Vec<T> {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self {
        json.as_array().unwrap().iter().map(|t| FromJson::from_json(t, next_eid)).collect()
    }
}

pub struct Event {
    changes: Changes,
}

// TODO need to change encoding to list of changes instead of object

impl ToJson for Event {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("changes".to_string(), Json::Object(
                self.changes.iter().map(|&(ref view_id, ref view_changes)| {
                    (view_id.to_string(), Json::Object(vec![
                        ("inserted".to_string(), view_changes.inserted.to_json()),
                        ("removed".to_string(), view_changes.removed.to_json()),
                        ].into_iter().collect()))
                }).collect()))].into_iter().collect())
    }
}

impl FromJson for Event {
    fn from_json(json: &Json, next_eid: &mut u64) -> Self {
        Event{
            changes: json.as_object().unwrap()["changes"]
            .as_object().unwrap().iter().map(|(view_id, view_changes)| {
                (view_id.to_string(), index::Changes{
                    inserted: FromJson::from_json(&view_changes.as_object().unwrap()["inserted"], next_eid),
                    removed: FromJson::from_json(&view_changes.as_object().unwrap()["removed"], next_eid),
                })
            }).collect()
        }
    }
}

pub enum ServerEvent {
    Message(String),
    NewClient(sender::Sender<WebSocketStream>),
}

// TODO holy crap why is everything blocking? this is a mess
pub fn serve() -> mpsc::Receiver<ServerEvent> {
    let (event_sender, event_receiver) = mpsc::channel();
    thread::spawn(move || {
        let server = Server::bind("0.0.0.0:2794").unwrap();
        for connection in server {
            let event_sender = event_sender.clone();
            thread::spawn(move || {
                // accept request
                let request = connection.unwrap().read_request().unwrap();
                request.validate().unwrap();
                let response = request.accept();
                let (mut sender, mut receiver) = response.send().unwrap().split();

                let ip = sender.get_mut().peer_addr().unwrap();
                println!("Connection from {}", ip);
                ::std::io::stdout().flush().unwrap(); // TODO is this actually necessary?

                // hand over sender
                event_sender.send(ServerEvent::NewClient(sender)).unwrap();

                // handle messages
                for message in receiver.incoming_messages() {
                    let message = message.unwrap();
                    match message {
                        Message::Text(text) => {
                            event_sender.send(ServerEvent::Message(text)).unwrap();
                        }
                        _ => println!("Unknown message: {:?}", message)
                    }
                }
            });
        }
    });
    event_receiver
}

// TODO arbitrary limit - needs tuning
static MAX_BATCH_SIZE: usize = 100;

fn recv_batch(event_receiver: &mpsc::Receiver<ServerEvent>, server_events: &mut Vec<ServerEvent>) {
    server_events.push(event_receiver.recv().unwrap()); // block until first event
    for _ in 0..MAX_BATCH_SIZE {
        match event_receiver.try_recv() {
            Ok(event) => server_events.push(event),
            Err(mpsc::TryRecvError::Empty) => break,
            Err(mpsc::TryRecvError::Disconnected) => panic!(),
        }
    }
}

pub fn compile_and_run(flow: Flow) -> (Flow, Changes) {
    let mut new_flow = compile(flow);
    new_flow.run();
    let changes = {
        let Flow {ref mut changes, ..} = new_flow;
        replace(changes, Vec::new())
    };
    (new_flow, changes)
}

pub fn run() {
    let empty_flow = Flow::new();
    let next_eid = &mut 0;
    let mut flow = Flow::new();

    time!("reading saved state", {
        let mut events = OpenOptions::new().create(true).open("./events").unwrap();
        let mut old_events = String::new();
        events.read_to_string(&mut old_events).unwrap();
        for line in old_events.lines() {
            let json = Json::from_str(&line).unwrap();
            let event: Event = FromJson::from_json(&json, next_eid);
            flow.change(event.changes);
        }
        drop(events);
        let (new_flow, _changes) = compile_and_run(flow);
        flow = new_flow;
        });

    let mut events = OpenOptions::new().write(true).append(true).open("./events").unwrap();
    let mut senders: Vec<sender::Sender<_>> = Vec::new();
    let mut server_events: Vec<ServerEvent> = Vec::with_capacity(MAX_BATCH_SIZE);
    let event_receiver = serve();
    loop {
            recv_batch(&event_receiver, &mut server_events);
            println!("batch size: {:?}", server_events.len());

        time!("entire batch", {
            for event in server_events.drain() {
                match event {
                    ServerEvent::NewClient(mut sender) => {
                        time!("sending initial state", {
                            let changes = flow.changes_since(&empty_flow);
                            let text = format!("{}", Event{changes: changes}.to_json());
                            match sender.send_message(Message::Text(text)) {
                                Ok(_) => (),
                                Err(error) => println!("Send error: {}", error),
                            };
                            senders.push(sender)
                        })
                    }
                    ServerEvent::Message(input_text) => {
                        time!("sending update", {
                            let json = Json::from_str(&input_text).unwrap();
                            let input_event: Event = FromJson::from_json(&json, next_eid);
                            events.write_all(input_text.as_bytes()).unwrap();
                            events.write_all("\n".as_bytes()).unwrap();
                            flow.change(input_event.changes);
                        })
                    }
                }
            }

            let (new_flow, changes) = compile_and_run(flow);
            flow = new_flow;
            let output_event = Event{changes: changes};
            let output_text = format!("{}", output_event.to_json());
            events.flush().unwrap();
            for sender in senders.iter_mut() {
                match sender.send_message(Message::Text(output_text.clone())) {
                    Ok(_) => (),
                    Err(error) => println!("Send error: {}", error),
                };
            }
        })
    }
}
<|endoftext|>


<commit_before>use ebml::{vid, vint};

#[derive(Debug,Clone,PartialEq)]
pub enum SegmentElement {
    SeekHead(SeekHead),
    Info(Info),
    Tracks(Tracks),
    Chapters(Chapters),
    Cluster(Cluster),
    Cues(Cues),
    Attachments(Attachments),
    Tags(Tags),
    Unknown(u64, Option<u64>),
}

// https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.3
named!(pub segment<(u64, Option<u64>)>,
  do_parse!(
    id:   verify!(vid, |val:u64| val == 0x18538067) >>
    size: opt!(vint)   >>
    (id, size)
  )
);

named!(skip,
       do_parse!(
    size: vint >> data: take!(size) >> (data)
  ));

#[macro_export]
macro_rules! sub_element(
  ($i:expr, $parser:ident) => ({
    do_parse!($i,
         size: vint
      >> element: flat_map!(take!(size as usize), dbg_dmp!($parser))
      >> (element)
    )
  })
);

// Segment, the root element, has id 0x18538067
named!(pub segment_element<SegmentElement>,
  switch!(vid,
    0x114D9B74 => sub_element!(seek_head) |
    0x1549A966 => sub_element!(info)      |

    unknown    => do_parse!(
        size: opt!(vint) >>
              cond!((size.is_some()), take!( (size.unwrap() as usize) )) >>
              (SegmentElement::Unknown(unknown, size))
      )
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct SeekHead {
    positions: Vec<Seek>,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.4
named!(pub seek_head<SegmentElement>,
  do_parse!(
    positions: many1!(seek) >>
    (SegmentElement::SeekHead(SeekHead {
      positions: positions,
    }))
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct Seek {
    id: Vec<u8>,
    position: u64,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.4
named!(pub seek<Seek>,
  ebml_master!(0x4DBB,
    do_parse!(
      t: permutation!(
        ebml_binary!(0x53AB), // SeekID
        ebml_uint!(0x53AC)    // SeekPosition
      ) >>
      (Seek {
        id:       t.0,
        position: t.1,
      })
    )
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct Info {
    pub segment_uid: Option<Vec<u8>>,
    pub segment_filename: Option<String>,
    pub prev_uid: Option<Vec<u8>>,
    pub prev_filename: Option<String>,
    pub next_uid: Option<Vec<u8>>,
    pub next_filename: Option<String>,
    pub segment_family: Option<Vec<u8>>,
    pub chapter_translate: Option<ChapterTranslate>,
    pub timecode_scale: u64,
    pub duration: Option<f64>, // FIXME should be float
    pub date_utc: Option<Vec<u8>>, //FIXME: should be date
    pub title: Option<String>,
    pub muxing_app: String,
    pub writing_app: String,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.8
named!(pub info<SegmentElement>,
  do_parse!(
    t: permutation_opt!(
      dbg_dmp!(complete!(ebml_binary!(0x73A4)))?, // SegmentUID
      dbg_dmp!(complete!(ebml_str!(0x7384)))?,    // SegmentFIlename FIXME SHOULD BE UTF-8 not str
      complete!(ebml_binary!(0x3CB923))?,         // PrevUID
      complete!(ebml_str!(0x3C83AB))?,            // PrevFilename FIXME SHOULD BE UTF-8 not str
      complete!(ebml_binary!(0x3EB923))?,         // NextUID
      complete!(ebml_str!(0x3E83BB))?,            // NextFilename FIXME SHOULD BE UTF-8 not str
      complete!(ebml_binary!(0x4444))?,           // SegmentFamily
      complete!(chapter_translate)?,              //
      complete!(ebml_uint!(0x2AD7B1)),            // TimecodeScale
      complete!(ebml_float!(0x4489))?,           // Duration: FIXME should be float
      complete!(ebml_binary!(0x4461))?,           // DateUTC FIXME: should be date
      complete!(ebml_str!(0x7BA9))?,              // Title FIXME SHOULD BE UTF-8 not str
      complete!(ebml_str!(0x4D80)),               // MuxingApp FIXME SHOULD BE UTF-8 not str
      complete!(ebml_str!(0x5741))                // WritingApp FIXME SHOULD BE UTF-8 not str
    ) >> (SegmentElement::Info(Info {
      segment_uid: t.0,
      segment_filename: t.1,
      prev_uid: t.2,
      prev_filename: t.3,
      next_uid: t.4,
      next_filename: t.5,
      segment_family: t.6,
      chapter_translate: t.7,
      timecode_scale:   t.8,
      duration: t.9,
      date_utc: t.10,
      title: t.11,
      muxing_app: t.12,
      writing_app: t.13
    }))
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct ChapterTranslate {}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.16
//TODO
named!(pub chapter_translate<ChapterTranslate>,
  dbg_dmp!(ebml_master!(0x6924, value!(ChapterTranslate{})))
);

#[derive(Debug,Clone,PartialEq)]
pub struct Tracks {}

#[derive(Debug,Clone,PartialEq)]
pub struct Chapters {}

#[derive(Debug,Clone,PartialEq)]
pub struct Cluster {}

#[derive(Debug,Clone,PartialEq)]
pub struct Cues {}

#[derive(Debug,Clone,PartialEq)]
pub struct Attachments {}

#[derive(Debug,Clone,PartialEq)]
pub struct Tags {}

#[cfg(test)]
mod tests {
    use super::*;
    use nom::{HexDisplay, IResult, Offset};
    use std::cmp::min;

    const mkv: &'static [u8] = include_bytes!("../assets/single_stream.mkv");

    #[test]
    fn segment_root() {
        let res = segment(&mkv[47..100]);
        println!("{:?}", res);

        if let IResult::Done(i, _) = res {
            println!("consumed {} bytes after header", (&mkv[47..]).offset(i));
        }

        panic!();
    }

    #[test]
    fn segment_elements() {
        let mut index: usize = 59;

        loop {
            let res = segment_element(&mkv[index..]);

            match res {
                IResult::Done(i, o) => {
                    let new_index = mkv.offset(i);
                    match o {
                        SegmentElement::Unknown(id, size) => {
                            println!("[{} -> {}] Unknown {{ id: 0x{:x}, size: {:?} }}",
                                     index,
                                     new_index,
                                     id,
                                     size);
                        }
                        o => {
                            println!("[{} -> {}] {:#?}", index, new_index, o);
                        }
                    };

                    index = new_index as usize;
                }
                e => {
                    let max_index = min(mkv.len(), index + 200);
                    println!("[{}] {:#?}:\n{}",
                             index,
                             e,
                             (&mkv[index..max_index]).to_hex(16));
                    break;
                }
            }
        }

        panic!();
    }
}
<commit_msg> parse parts of the Cluster element<commit_after>use ebml::{vid, vint};

#[derive(Debug,Clone,PartialEq)]
pub enum SegmentElement {
    SeekHead(SeekHead),
    Info(Info),
    Tracks(Tracks),
    Chapters(Chapters),
    Cluster(Cluster),
    Cues(Cues),
    Attachments(Attachments),
    Tags(Tags),
    Unknown(u64, Option<u64>),
}

// https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.3
named!(pub segment<(u64, Option<u64>)>,
  do_parse!(
    id:   verify!(vid, |val:u64| val == 0x18538067) >>
    size: opt!(vint)   >>
    (id, size)
  )
);

named!(skip,
       do_parse!(
    size: vint >> data: take!(size) >> (data)
  ));

#[macro_export]
macro_rules! sub_element(
  ($i:expr, $parser:ident) => ({
    do_parse!($i,
         size: vint
      >> element: flat_map!(take!(size as usize), dbg_dmp!($parser))
      >> (element)
    )
  })
);

// Segment, the root element, has id 0x18538067
named!(pub segment_element<SegmentElement>,
  switch!(vid,
    0x114D9B74 => sub_element!(seek_head) |
    0x1549A966 => sub_element!(info)      |
    0x1F43B675 => sub_element!(cluster)   |

    unknown    => do_parse!(
        size: opt!(vint) >>
              cond!((size.is_some()), take!( (size.unwrap() as usize) )) >>
              (SegmentElement::Unknown(unknown, size))
      )
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct SeekHead {
    positions: Vec<Seek>,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.4
named!(pub seek_head<SegmentElement>,
  do_parse!(
    positions: many1!(seek) >>
    (SegmentElement::SeekHead(SeekHead {
      positions: positions,
    }))
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct Seek {
    id: Vec<u8>,
    position: u64,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.4
named!(pub seek<Seek>,
  ebml_master!(0x4DBB,
    do_parse!(
      t: permutation!(
        ebml_binary!(0x53AB), // SeekID
        ebml_uint!(0x53AC)    // SeekPosition
      ) >>
      (Seek {
        id:       t.0,
        position: t.1,
      })
    )
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct Info {
    pub segment_uid: Option<Vec<u8>>,
    pub segment_filename: Option<String>,
    pub prev_uid: Option<Vec<u8>>,
    pub prev_filename: Option<String>,
    pub next_uid: Option<Vec<u8>>,
    pub next_filename: Option<String>,
    pub segment_family: Option<Vec<u8>>,
    pub chapter_translate: Option<ChapterTranslate>,
    pub timecode_scale: u64,
    pub duration: Option<f64>, // FIXME should be float
    pub date_utc: Option<Vec<u8>>, //FIXME: should be date
    pub title: Option<String>,
    pub muxing_app: String,
    pub writing_app: String,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.8
named!(pub info<SegmentElement>,
  do_parse!(
    t: permutation_opt!(
      dbg_dmp!(complete!(ebml_binary!(0x73A4)))?, // SegmentUID
      dbg_dmp!(complete!(ebml_str!(0x7384)))?,    // SegmentFIlename FIXME SHOULD BE UTF-8 not str
      complete!(ebml_binary!(0x3CB923))?,         // PrevUID
      complete!(ebml_str!(0x3C83AB))?,            // PrevFilename FIXME SHOULD BE UTF-8 not str
      complete!(ebml_binary!(0x3EB923))?,         // NextUID
      complete!(ebml_str!(0x3E83BB))?,            // NextFilename FIXME SHOULD BE UTF-8 not str
      complete!(ebml_binary!(0x4444))?,           // SegmentFamily
      complete!(chapter_translate)?,              //
      complete!(ebml_uint!(0x2AD7B1)),            // TimecodeScale
      complete!(ebml_float!(0x4489))?,           // Duration: FIXME should be float
      complete!(ebml_binary!(0x4461))?,           // DateUTC FIXME: should be date
      complete!(ebml_str!(0x7BA9))?,              // Title FIXME SHOULD BE UTF-8 not str
      complete!(ebml_str!(0x4D80)),               // MuxingApp FIXME SHOULD BE UTF-8 not str
      complete!(ebml_str!(0x5741))                // WritingApp FIXME SHOULD BE UTF-8 not str
    ) >> (SegmentElement::Info(Info {
      segment_uid: t.0,
      segment_filename: t.1,
      prev_uid: t.2,
      prev_filename: t.3,
      next_uid: t.4,
      next_filename: t.5,
      segment_family: t.6,
      chapter_translate: t.7,
      timecode_scale:   t.8,
      duration: t.9,
      date_utc: t.10,
      title: t.11,
      muxing_app: t.12,
      writing_app: t.13
    }))
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct ChapterTranslate {}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.16
//TODO
named!(pub chapter_translate<ChapterTranslate>,
  dbg_dmp!(ebml_master!(0x6924, value!(ChapterTranslate{})))
);

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.26
#[derive(Debug,Clone,PartialEq)]
pub struct Cluster {
    pub timecode: u64,
    pub silent_tracks: Option<SilentTracks>,
    pub position: Option<u64>,
    pub prev_size: Option<u64>,
    pub simple_block: Option<Vec<u8>>,
    pub block_group: Option<BlockGroup>,
    pub encrypted_block: Option<Vec<u8>>,
}

named!(pub cluster<SegmentElement>,
  do_parse!(
    t: permutation_opt!(
      complete!(ebml_uint!(0xE7)),
      complete!(silent_tracks)?,
      complete!(ebml_uint!(0xA7))?,
      complete!(ebml_uint!(0xAB))?,
      complete!(ebml_binary!(0xA3))?,
      complete!(block_group)?,
      complete!(ebml_binary!(0xAF))?
    ) >> (SegmentElement::Cluster(Cluster {
      timecode: t.0,
      silent_tracks: t.1,
      position: t.2,
      prev_size: t.3,
      simple_block: t.4,
      block_group: t.5,
      encrypted_block: t.6,
    }))
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct SilentTracks {
    numbers: Vec<u64>,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.16
named!(pub silent_tracks<SilentTracks>,
  dbg_dmp!(ebml_master!(0x5854, map!(many0!(ebml_uint!(0x58D7)), |v| SilentTracks { numbers: v })))
);

#[derive(Debug,Clone,PartialEq)]
pub struct BlockGroup {
    pub block: Vec<u8>,
    pub block_virtual: Option<Vec<u8>>,
    pub block_additions: Option<BlockAdditions>,
    pub block_duration: Option<u64>,
    pub reference_priority: u64,
    pub reference_block: Option<u64>,
    pub reference_virtual: Option<i64>,
    pub codec_state: Option<Vec<u8>>,
    pub discard_padding: Option<i64>,
    pub slices: Option<Slices>,
    pub reference_frame: Option<ReferenceFrame>,
}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.16
//TODO
named!(pub block_group<BlockGroup>,
  ebml_master!(0x5854,
    do_parse!(
      t: permutation_opt!(
        complete!(ebml_binary!(0xA1)),
        complete!(ebml_binary!(0xA2))?,
        complete!(block_additions)?,
        complete!(ebml_uint!(0x9B))?,
        complete!(ebml_uint!(0xFA)),
        complete!(ebml_uint!(0xFB))?,
        complete!(ebml_int!(0xFD))?,
        complete!(ebml_binary!(0xA4))?,
        complete!(ebml_int!(0x75A2))?,
        complete!(slices)?,
        complete!(reference_frame)?

      ) >> (BlockGroup {
        block: t.0,
        block_virtual: t.1,
        block_additions: t.2,
        block_duration: t.3,
        reference_priority: t.4,
        reference_block: t.5,
        reference_virtual: t.6,
        codec_state: t.7,
        discard_padding: t.8,
        slices: t.9,
        reference_frame: t.10
      })
    )
  )
);

#[derive(Debug,Clone,PartialEq)]
pub struct BlockAdditions {}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.16
//TODO
named!(pub block_additions<BlockAdditions>,
  ebml_master!(0x75A1, value!(BlockAdditions {}))
);

#[derive(Debug,Clone,PartialEq)]
pub struct Slices {}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.46
//TODO
named!(pub slices<Slices>,
  ebml_master!(0x8E, value!(Slices {}))
);

#[derive(Debug,Clone,PartialEq)]
pub struct ReferenceFrame {}

//https://datatracker.ietf.org/doc/html/draft-lhomme-cellar-matroska-03#section-7.3.53
//TODO
named!(pub reference_frame<ReferenceFrame>,
  ebml_master!(0xC8, value!(ReferenceFrame {}))
);

#[derive(Debug,Clone,PartialEq)]
pub struct Tracks {}

#[derive(Debug,Clone,PartialEq)]
pub struct Chapters {}

#[derive(Debug,Clone,PartialEq)]
pub struct Cues {}

#[derive(Debug,Clone,PartialEq)]
pub struct Attachments {}

#[derive(Debug,Clone,PartialEq)]
pub struct Tags {}

#[cfg(test)]
mod tests {
    use super::*;
    use nom::{HexDisplay, IResult, Offset};
    use std::cmp::min;

    const mkv: &'static [u8] = include_bytes!("../assets/single_stream.mkv");

    #[test]
    fn segment_root() {
        let res = segment(&mkv[47..100]);
        println!("{:?}", res);

        if let IResult::Done(i, _) = res {
            println!("consumed {} bytes after header", (&mkv[47..]).offset(i));
        }

        panic!();
    }

    #[test]
    fn segment_elements() {
        let mut index: usize = 59;

        loop {
            let res = segment_element(&mkv[index..]);

            match res {
                IResult::Done(i, o) => {
                    let new_index = mkv.offset(i);
                    match o {
                        SegmentElement::Unknown(id, size) => {
                            println!("[{} -> {}] Unknown {{ id: 0x{:x}, size: {:?} }}",
                                     index,
                                     new_index,
                                     id,
                                     size);
                        }
                        o => {
                            println!("[{} -> {}] {:#?}", index, new_index, o);
                        }
                    };

                    index = new_index as usize;
                }
                e => {
                    let max_index = min(mkv.len(), index + 200);
                    println!("[{}] {:#?}:\n{}",
                             index,
                             e,
                             (&mkv[index..max_index]).to_hex(16));
                    break;
                }
            }
        }

        panic!();
    }
}
<|endoftext|>


<commit_before>use serde::ser::Serialize;

use crate::algorithms::AlgorithmFamily;
use crate::crypto;
use crate::errors::{new_error, ErrorKind, Result};
use crate::header::Header;
use crate::pem::decoder::PemEncodedKey;
use crate::serialization::b64_encode_part;

/// A key to encode a JWT with. Can be a secret, a PEM-encoded key or a DER-encoded key.
/// This key can be re-used so make sure you only initialize it once if you can for better performance
#[derive(Debug, Clone, PartialEq)]
pub struct EncodingKey {
    pub(crate) family: AlgorithmFamily,
    content: Vec<u8>,
}

impl EncodingKey {
    /// If you're using a HMAC secret that is not base64, use that.
    pub fn from_secret(secret: &[u8]) -> Self {
        EncodingKey { family: AlgorithmFamily::Hmac, content: secret.to_vec() }
    }

    /// If you have a base64 HMAC secret, use that.
    pub fn from_base64_secret(secret: &str) -> Result<Self> {
        let out = base64::decode(&secret)?;
        Ok(EncodingKey { family: AlgorithmFamily::Hmac, content: out })
    }

    /// If you are loading a RSA key from a .pem file.
    /// This errors if the key is not a valid RSA key.
    pub fn from_rsa_pem(key: &[u8]) -> Result<Self> {
        let pem_key = PemEncodedKey::new(key)?;
        let content = pem_key.as_rsa_key()?;
        Ok(EncodingKey { family: AlgorithmFamily::Rsa, content: content.to_vec() })
    }

    /// If you are loading a ECDSA key from a .pem file
    /// This errors if the key is not a valid private EC key
    pub fn from_ec_pem(key: &[u8]) -> Result<Self> {
        let pem_key = PemEncodedKey::new(key)?;
        let content = pem_key.as_ec_private_key()?;
        Ok(EncodingKey { family: AlgorithmFamily::Ec, content: content.to_vec() })
    }

    /// If you know what you're doing and have the DER-encoded key, for RSA only
    pub fn from_rsa_der(der: &[u8]) -> Self {
        EncodingKey { family: AlgorithmFamily::Rsa, content: der.to_vec() }
    }

    /// If you know what you're doing and have the DER-encoded key, for ECDSA
    pub fn from_ec_der(der: &[u8]) -> Self {
        EncodingKey { family: AlgorithmFamily::Ec, content: der.to_vec() }
    }

    pub(crate) fn inner(&self) -> &[u8] {
        &self.content
    }
}

/// Encode the header and claims given and sign the payload using the algorithm from the header and the key.
/// If the algorithm given is RSA or EC, the key needs to be in the PEM format.
///
/// ```rust
/// use serde::{Deserialize, Serialize};
/// use jsonwebtoken::{encode, Algorithm, Header, EncodingKey};
///
/// #[derive(Debug, Serialize, Deserialize)]
/// struct Claims {
///    sub: String,
///    company: String
/// }
///
/// let my_claims = Claims {
///     sub: "b@b.com".to_owned(),
///     company: "ACME".to_owned()
/// };
///
/// // my_claims is a struct that implements Serialize
/// // This will create a JWT using HS256 as algorithm
/// let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref())).unwrap();
/// ```
pub fn encode<T: Serialize>(header: &Header, claims: &T, key: &EncodingKey) -> Result<String> {
    if key.family != header.alg.family() {
        return Err(new_error(ErrorKind::InvalidAlgorithm));
    }
    let encoded_header = b64_encode_part(&header)?;
    let encoded_claims = b64_encode_part(&claims)?;
    let message = [encoded_header.as_ref(), encoded_claims.as_ref()].join(".");
    let signature = crypto::sign(&*message, key, header.alg)?;

    Ok([message, signature].join("."))
}
<commit_msg>Add note about encoding keys (#163)<commit_after>use serde::ser::Serialize;

use crate::algorithms::AlgorithmFamily;
use crate::crypto;
use crate::errors::{new_error, ErrorKind, Result};
use crate::header::Header;
use crate::pem::decoder::PemEncodedKey;
use crate::serialization::b64_encode_part;

/// A key to encode a JWT with. Can be a secret, a PEM-encoded key or a DER-encoded key.
/// This key can be re-used so make sure you only initialize it once if you can for better performance
#[derive(Debug, Clone, PartialEq)]
pub struct EncodingKey {
    pub(crate) family: AlgorithmFamily,
    content: Vec<u8>,
}

impl EncodingKey {
    /// If you're using a HMAC secret that is not base64, use that.
    pub fn from_secret(secret: &[u8]) -> Self {
        EncodingKey { family: AlgorithmFamily::Hmac, content: secret.to_vec() }
    }

    /// If you have a base64 HMAC secret, use that.
    pub fn from_base64_secret(secret: &str) -> Result<Self> {
        let out = base64::decode(&secret)?;
        Ok(EncodingKey { family: AlgorithmFamily::Hmac, content: out })
    }

    /// If you are loading a RSA key from a .pem file.
    /// This errors if the key is not a valid RSA key.
    ///
    /// # NOTE
    ///
    /// According to the [ring doc](https://briansmith.org/rustdoc/ring/signature/struct.RsaKeyPair.html#method.from_pkcs8),
    /// the key should be at least 2047 bits.
    ///
    pub fn from_rsa_pem(key: &[u8]) -> Result<Self> {
        let pem_key = PemEncodedKey::new(key)?;
        let content = pem_key.as_rsa_key()?;
        Ok(EncodingKey { family: AlgorithmFamily::Rsa, content: content.to_vec() })
    }

    /// If you are loading a ECDSA key from a .pem file
    /// This errors if the key is not a valid private EC key
    ///
    /// # NOTE
    ///
    /// The key should be in PKCS#8 form.
    ///
    /// You can generate a key with the following:
    ///
    /// ```sh
    /// openssl ecparam -genkey -noout -name prime256v1 \
    ///     | openssl pkcs8 -topk8 -nocrypt -out ec-private.pem
    /// ```
    pub fn from_ec_pem(key: &[u8]) -> Result<Self> {
        let pem_key = PemEncodedKey::new(key)?;
        let content = pem_key.as_ec_private_key()?;
        Ok(EncodingKey { family: AlgorithmFamily::Ec, content: content.to_vec() })
    }

    /// If you know what you're doing and have the DER-encoded key, for RSA only
    pub fn from_rsa_der(der: &[u8]) -> Self {
        EncodingKey { family: AlgorithmFamily::Rsa, content: der.to_vec() }
    }

    /// If you know what you're doing and have the DER-encoded key, for ECDSA
    pub fn from_ec_der(der: &[u8]) -> Self {
        EncodingKey { family: AlgorithmFamily::Ec, content: der.to_vec() }
    }

    pub(crate) fn inner(&self) -> &[u8] {
        &self.content
    }
}

/// Encode the header and claims given and sign the payload using the algorithm from the header and the key.
/// If the algorithm given is RSA or EC, the key needs to be in the PEM format.
///
/// ```rust
/// use serde::{Deserialize, Serialize};
/// use jsonwebtoken::{encode, Algorithm, Header, EncodingKey};
///
/// #[derive(Debug, Serialize, Deserialize)]
/// struct Claims {
///    sub: String,
///    company: String
/// }
///
/// let my_claims = Claims {
///     sub: "b@b.com".to_owned(),
///     company: "ACME".to_owned()
/// };
///
/// // my_claims is a struct that implements Serialize
/// // This will create a JWT using HS256 as algorithm
/// let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref())).unwrap();
/// ```
pub fn encode<T: Serialize>(header: &Header, claims: &T, key: &EncodingKey) -> Result<String> {
    if key.family != header.alg.family() {
        return Err(new_error(ErrorKind::InvalidAlgorithm));
    }
    let encoded_header = b64_encode_part(&header)?;
    let encoded_claims = b64_encode_part(&claims)?;
    let message = [encoded_header.as_ref(), encoded_claims.as_ref()].join(".");
    let signature = crypto::sign(&*message, key, header.alg)?;

    Ok([message, signature].join("."))
}
<|endoftext|>


<commit_before>
use fb::FixedBitSet;
use std::default::Default;
use {Graph, Directed, Undirected, EdgeType};
use graph::NodeIndex;

/*
pub struct DAG {
    size: usize,
    bits: FixedBitSet,
}

// A DAG has the property that the adjacency matrix is lower triangular,
// diagonal zero.
//
// This means we only allow edges i → j where i < j.
//
// The set of all DAG of a particular size is simply the power set of all
// possible edges.
//
// For a graph of n=3 nodes we have (n - 1) * n / 2 = 3 possible edges.
//
// Gray code
//
// gray(x) { x ^ (x >> 1) }
//
// See fxtbook on gray codes
//
// Use a gray code sequence to efficiently step through the whole set of edges

impl DAG {
    pub fn new(size: usize) -> Self {
        DAG {
            size: size,
            bits: FixedBitSet::with_capacity(size),
        }
    }

    fn state_to_graph(&self) -> Graph<(), (), Directed> {
        let popcount = self.bits.as_slice().iter()
                                .fold(0, |acc, x| acc + x.count_ones() as usize);
        Graph::with_capacity(self.size, popcount)
    }
}
*/

pub struct Generator<Ty> {
    acyclic: bool,
    selfloops: bool,
    nodes: usize,
    /// number of possible edges
    nedges: usize,
    /// current edge bitmap
    bits: u64,
    g: Graph<(), (), Ty>,
}

impl Generator<Directed> {
    /// Generate all possible Directed acyclic graphs (DAGs) of a particular number of vertices.
    ///
    /// For a graph of *k* vertices there are *e = (k - 1) k / 2* possible edges and
    /// *2e* DAGs.
    pub fn directed_acyclic(nodes: usize) -> Self {
        assert!(nodes != 0);
        let nedges = (nodes - 1) * nodes / 2;
        assert!(nedges < 64);
        Generator {
            acyclic: true,
            selfloops: false,
            nodes: nodes,
            nedges:nedges,
            bits: !0,
            g: Graph::with_capacity(nodes, nedges),
        }
    }
}

impl<Ty: EdgeType> Generator<Ty> {
    /// Generate all possible graphs of a particular number of vertices.
    ///
    /// For a graph of *k* vertices there are *e = k²* possible edges and
    /// *2k2* graphs.
    pub fn all(nodes: usize, allow_selfloops: bool) -> Self {
        let scale = if Ty::is_directed() { 1 } else { 2 };
        let nedges = if allow_selfloops {
            (nodes * nodes - nodes) / scale + nodes
        } else {
            (nodes * nodes) / scale - nodes
        };
        assert!(nedges < 64);
        Generator {
            acyclic: false,
            selfloops: allow_selfloops,
            nodes: nodes,
            nedges: nedges,
            bits: !0,
            g: Graph::with_capacity(nodes, nedges),
        }
    }

    fn state_to_graph(&mut self) -> &Graph<(), (), Ty> {
        let popcount = self.bits.count_ones() as usize;
        self.g.clear();
        for _ in 0..self.nodes {
            self.g.add_node(());
        }
        // For a DAG:
        // interpret the bits in order, it's a lower triangular matrix:
        //   a b c d
        // a x x x x
        // b 0 x x x
        // c 1 2 x x
        // d 3 4 5 x
        let mut bit = 0;
        for i in 0..self.nodes {
            let start = if self.acyclic || !self.g.is_directed() { i } else { 0 };
            for j in start..self.nodes {
                if i == j && !self.selfloops {
                    continue;
                }
                if self.bits & (1u64 << bit) != 0 {
                    self.g.add_edge(NodeIndex::new(i), NodeIndex::new(j), ());
                }

                bit += 1;
            }
        }
        &self.g
    }

    pub fn next_ref(&mut self) -> Option<&Graph<(), (), Ty>> {
        if self.bits == !0 {
            self.bits = 0;
        } else {
            self.bits += 1;
            if self.bits >= 1u64 << self.nedges {
                return None;
            }
        }
        Some(self.state_to_graph())
    }
}

impl<Ty: EdgeType> Iterator for Generator<Ty> {
    type Item = Graph<(), (), Ty>;

    fn next(&mut self) -> Option<Self::Item> {
        self.next_ref().cloned()
    }
}
<commit_msg>generate: Update docs<commit_after>
use fb::FixedBitSet;
use std::default::Default;
use {Graph, Directed, Undirected, EdgeType};
use graph::NodeIndex;

// A DAG has the property that the adjacency matrix is lower triangular,
// diagonal zero.
//
// This means we only allow edges i → j where i < j.
//
// The set of all DAG of a particular size is simply the power set of all
// possible edges.
//
// For a graph of n=3 nodes we have (n - 1) * n / 2 = 3 possible edges.

/// A graph generator of “all” graphs of a particular size.
pub struct Generator<Ty> {
    acyclic: bool,
    selfloops: bool,
    nodes: usize,
    /// number of possible edges
    nedges: usize,
    /// current edge bitmap
    bits: u64,
    g: Graph<(), (), Ty>,
}

impl Generator<Directed> {
    /// Generate all possible Directed acyclic graphs (DAGs) of a particular number of vertices.
    ///
    /// These are only generated with one per isomorphism, so they use
    /// one canonical node labeling where node *i* can only have edges to node *j* if *i < j*.
    ///
    /// For a graph of *k* vertices there are *e = (k - 1) k / 2* possible edges and
    /// *2e* DAGs.
    pub fn directed_acyclic(nodes: usize) -> Self {
        assert!(nodes != 0);
        let nedges = (nodes - 1) * nodes / 2;
        assert!(nedges < 64);
        Generator {
            acyclic: true,
            selfloops: false,
            nodes: nodes,
            nedges:nedges,
            bits: !0,
            g: Graph::with_capacity(nodes, nedges),
        }
    }
}

impl<Ty: EdgeType> Generator<Ty> {
    /// Generate all possible graphs of a particular number of vertices.
    ///
    /// All permutations are generated, so the graphs are not unique down to isomorphim.
    ///
    /// For a graph of *k* vertices there are *e = k²* possible edges and
    /// *2k2* graphs.
    pub fn all(nodes: usize, allow_selfloops: bool) -> Self {
        let scale = if Ty::is_directed() { 1 } else { 2 };
        let nedges = if allow_selfloops {
            (nodes * nodes - nodes) / scale + nodes
        } else {
            (nodes * nodes) / scale - nodes
        };
        assert!(nedges < 64);
        Generator {
            acyclic: false,
            selfloops: allow_selfloops,
            nodes: nodes,
            nedges: nedges,
            bits: !0,
            g: Graph::with_capacity(nodes, nedges),
        }
    }

    fn state_to_graph(&mut self) -> &Graph<(), (), Ty> {
        let popcount = self.bits.count_ones() as usize;
        self.g.clear();
        for _ in 0..self.nodes {
            self.g.add_node(());
        }
        // For a DAG:
        // interpret the bits in order, it's a lower triangular matrix:
        //   a b c d
        // a x x x x
        // b 0 x x x
        // c 1 2 x x
        // d 3 4 5 x
        let mut bit = 0;
        for i in 0..self.nodes {
            let start = if self.acyclic || !self.g.is_directed() { i } else { 0 };
            for j in start..self.nodes {
                if i == j && !self.selfloops {
                    continue;
                }
                if self.bits & (1u64 << bit) != 0 {
                    self.g.add_edge(NodeIndex::new(i), NodeIndex::new(j), ());
                }

                bit += 1;
            }
        }
        &self.g
    }

    pub fn next_ref(&mut self) -> Option<&Graph<(), (), Ty>> {
        if self.bits == !0 {
            self.bits = 0;
        } else {
            self.bits += 1;
            if self.bits >= 1u64 << self.nedges {
                return None;
            }
        }
        Some(self.state_to_graph())
    }
}

impl<Ty: EdgeType> Iterator for Generator<Ty> {
    type Item = Graph<(), (), Ty>;

    fn next(&mut self) -> Option<Self::Item> {
        self.next_ref().cloned()
    }
}
<|endoftext|>


<commit_before>use math::{Point2, Point3};

pub mod cuboid;
pub mod ellipse;
pub mod graph;
pub mod line;
pub mod polyline;
pub mod polygon;
pub mod quad;
pub mod range;
pub mod rect;
pub mod tri;
pub mod vertex;

pub use self::cuboid::Cuboid;
pub use self::ellipse::Ellipse;
pub use self::graph::Graph;
pub use self::line::Line;
pub use self::polygon::Polygon;
pub use self::polyline::Polyline;
pub use self::quad::Quad;
pub use self::range::{Align, Edge, Range};
pub use self::rect::{Corner, Padding, Rect};
pub use self::tri::Tri;
pub use self::vertex::{DefaultScalar, Vertex, Vertex2d, Vertex3d};

// General geometry utility functions

/// The `Rect` that bounds the given sequence of vertices.
///
/// Returns `None` if the given iterator is empty.
pub fn bounding_rect<I>(vertices: I) -> Option<Rect<<I::Item as Vertex>::Scalar>>
where
    I: IntoIterator,
    I::Item: Vertex2d,
{
    let mut vertices = vertices.into_iter();
    vertices.next()
        .map(|first| {
            let Point2 { x, y } = first.point2();
            let bounds = Rect {
                x: Range::new(x, x),
                y: Range::new(y, y),
            };
            vertices.fold(bounds, |b, v| {
                let Point2 { x, y } = v.point2();
                let point = Point2 { x, y };
                b.stretch_to_point(point)
            })
        })
}

/// The `Cuboid` that bounds the given sequence of vertices.
///
/// Returns `None` if the given iterator is empty.
pub fn bounding_cuboid<I>(vertices: I) -> Option<Cuboid<<I::Item as Vertex>::Scalar>>
where
    I: IntoIterator,
    I::Item: Vertex3d,
{
    let mut vertices = vertices.into_iter();
    vertices.next()
        .map(|first| {
            let Point3 { x, y, z } = first.point3();
            let bounds = Cuboid {
                x: Range::new(x, x),
                y: Range::new(y, y),
                z: Range::new(z, z),
            };
            vertices.fold(bounds, |b, v| {
                let Point3 { x, y, z } = v.point3();
                let point = Point3 { x, y, z };
                b.stretch_to_point(point)
            })
        })
}
<commit_msg>Add geom centroid function<commit_after>use math::{BaseFloat, EuclideanSpace, Point2, Point3};
use math::num_traits::cast;
use std::ops;

pub mod cuboid;
pub mod ellipse;
pub mod graph;
pub mod line;
pub mod polyline;
pub mod polygon;
pub mod quad;
pub mod range;
pub mod rect;
pub mod tri;
pub mod vertex;

pub use self::cuboid::Cuboid;
pub use self::ellipse::Ellipse;
pub use self::graph::Graph;
pub use self::line::Line;
pub use self::polygon::Polygon;
pub use self::polyline::Polyline;
pub use self::quad::Quad;
pub use self::range::{Align, Edge, Range};
pub use self::rect::{Corner, Padding, Rect};
pub use self::tri::Tri;
pub use self::vertex::{DefaultScalar, Vertex, Vertex2d, Vertex3d};

// General geometry utility functions

/// The `Rect` that bounds the given sequence of vertices.
///
/// Returns `None` if the given iterator is empty.
pub fn bounding_rect<I>(vertices: I) -> Option<Rect<<I::Item as Vertex>::Scalar>>
where
    I: IntoIterator,
    I::Item: Vertex2d,
{
    let mut vertices = vertices.into_iter();
    vertices.next()
        .map(|first| {
            let Point2 { x, y } = first.point2();
            let bounds = Rect {
                x: Range::new(x, x),
                y: Range::new(y, y),
            };
            vertices.fold(bounds, |b, v| {
                let Point2 { x, y } = v.point2();
                let point = Point2 { x, y };
                b.stretch_to_point(point)
            })
        })
}

/// The `Cuboid` that bounds the given sequence of vertices.
///
/// Returns `None` if the given iterator is empty.
pub fn bounding_cuboid<I>(vertices: I) -> Option<Cuboid<<I::Item as Vertex>::Scalar>>
where
    I: IntoIterator,
    I::Item: Vertex3d,
{
    let mut vertices = vertices.into_iter();
    vertices.next()
        .map(|first| {
            let Point3 { x, y, z } = first.point3();
            let bounds = Cuboid {
                x: Range::new(x, x),
                y: Range::new(y, y),
                z: Range::new(z, z),
            };
            vertices.fold(bounds, |b, v| {
                let Point3 { x, y, z } = v.point3();
                let point = Point3 { x, y, z };
                b.stretch_to_point(point)
            })
        })
}

/// The `centroid` (average position) of all vertices in the given iterator.
///
/// Returns `None` if the given iterator contains no vertices.
pub fn centroid<I, S>(vertices: I) -> Option<I::Item>
where
    I: IntoIterator,
    I::Item: Vertex<Scalar = S> + EuclideanSpace<Scalar = S>,
    <I::Item as EuclideanSpace>::Diff: ops::Div<S, Output = <I::Item as EuclideanSpace>::Diff>,
    S: BaseFloat,
{
    let mut vertices = vertices.into_iter();
    vertices.next()
        .map(|first| {
            let init = (1, first.to_vec());
            let (len, total) = vertices.fold(init, |(i, acc), p| (i + 1, acc + p.to_vec()));
            EuclideanSpace::from_vec(total / cast(len).unwrap())
        })
}
<|endoftext|>


<commit_before>use getopts::{Options,Matches};
use std::net::{TcpListener,TcpStream};
use std::io::{Read,BufStream,BufRead};
use std::old_io::{LineBufferedWriter,stdio};

pub fn listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let listener = TcpListener::bind(s.as_slice()).unwrap();
    // block until we get connection
    match listener.accept() {
        Ok(res) => {
            let (stream, socket_addr) = res;
            // nc doesn't handle multiple connections, so no need to do `handle_client`
            // in thread.
            handle_client(stream);
        },
        Err(f) => {
            panic!(f.to_string());
        }
    }
}

fn handle_client(stream: TcpStream) {
    let mut buf_stream = BufStream::new(stream);
    let mut read_buf = [0; 4096];
    let mut writer = LineBufferedWriter::new(stdio::stdout());
    loop {
        match(buf_stream.read(&mut read_buf)) {
            Ok(n) => {
                if n > 0 {
                    writer.write_all(&read_buf);
                }
                else {
                    return;
                }
            }
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<commit_msg>Simplify listener `match` a bit.<commit_after>use getopts::{Options,Matches};
use std::net::{TcpListener,TcpStream};
use std::io::{Read,BufStream,BufRead};
use std::old_io::{LineBufferedWriter,stdio};

pub fn listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let listener = TcpListener::bind(s.as_slice()).unwrap();
    // block until we get connection
    match listener.accept() {
        Ok((stream, socket_addr)) => {
            // nc doesn't handle multiple connections, so no need to do `handle_client`
            // in thread.
            handle_client(stream);
        },
        Err(f) => {
            panic!(f.to_string());
        }
    }
}

fn handle_client(stream: TcpStream) {
    let mut buf_stream = BufStream::new(stream);
    let mut read_buf = [0; 4096];
    let mut writer = LineBufferedWriter::new(stdio::stdout());
    loop {
        match(buf_stream.read(&mut read_buf)) {
            Ok(n) => {
                if n > 0 {
                    writer.write_all(&read_buf);
                }
                else {
                    return;
                }
            }
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<|endoftext|>