<commit_before>#[cfg(feature = "multipart")]
use super::multipart::Form;
/// dox
use bytes::Bytes;
use js_sys::{Uint8Array};
use std::fmt;
use wasm_bindgen::JsValue;

/// The body of a `Request`.
///
/// In most cases, this is not needed directly, as the
/// [`RequestBuilder.body`][builder] method uses `Into<Body>`, which allows
/// passing many things (like a string or vector of bytes).
///
/// [builder]: ./struct.RequestBuilder.html#method.body
pub struct Body {
    inner: Inner,
}

enum Inner {
    Bytes(Bytes),
    #[cfg(feature = "multipart")]
    Multipart(Form),
}

impl Body {
    /// Returns a reference to the internal data of the `Body`.
    ///
    /// `None` is returned, if the underlying data is a multipart form.
    #[inline]
    pub fn as_bytes(&self) -> Option<&[u8]> {
        match &self.inner {
            Inner::Bytes(bytes) => Some(bytes.as_ref()),
            #[cfg(feature = "multipart")]
            Inner::Multipart(_) => None,
        }
    }
    pub(crate) fn to_js_value(&self) -> crate::Result<JsValue> {
        match &self.inner {
            Inner::Bytes(body_bytes) => {
                let body_bytes: &[u8] = body_bytes.as_ref();
                let body_uint8_array: Uint8Array = body_bytes.into();
                let js_value: &JsValue = body_uint8_array.as_ref();
                Ok(js_value.to_owned())
            }
            #[cfg(feature = "multipart")]
            Inner::Multipart(form) => {
                let form_data = form.to_form_data()?;
                let js_value: &JsValue = form_data.as_ref();
                Ok(js_value.to_owned())
            }
        }
    }

    #[inline]
    #[cfg(feature = "multipart")]
    pub(crate) fn from_form(f: Form) -> Body {
        Self {
            inner: Inner::Multipart(f),
        }
    }

    pub(crate) fn is_empty(&self) -> bool {
        match &self.inner {
            Inner::Bytes(bytes) => bytes.is_empty(),
            #[cfg(feature = "multipart")]
            Inner::Multipart(form) => form.is_empty(),
        }
    }

    pub(crate) fn try_clone(&self) -> Option<Body> {
        match &self.inner {
            Inner::Bytes(bytes) => Some(Self {
                inner: Inner::Bytes(bytes.clone()),
            }),
            #[cfg(feature = "multipart")]
            Inner::Multipart(_) => None,
        }
    }
}

impl From<Bytes> for Body {
    #[inline]
    fn from(bytes: Bytes) -> Body {
        Body {
            inner: Inner::Bytes(bytes),
        }
    }
}

impl From<Vec<u8>> for Body {
    #[inline]
    fn from(vec: Vec<u8>) -> Body {
        Body {
            inner: Inner::Bytes(vec.into()),
        }
    }
}

impl From<&'static [u8]> for Body {
    #[inline]
    fn from(s: &'static [u8]) -> Body {
        Body {
            inner: Inner::Bytes(Bytes::from_static(s)),
        }
    }
}

impl From<String> for Body {
    #[inline]
    fn from(s: String) -> Body {
        Body {
            inner: Inner::Bytes(s.into()),
        }
    }
}

impl From<&'static str> for Body {
    #[inline]
    fn from(s: &'static str) -> Body {
        s.as_bytes().into()
    }
}

impl fmt::Debug for Body {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Body").finish()
    }
}

#[cfg(test)]
mod tests {
    // use js_sys::{Array, Uint8Array};
    use wasm_bindgen::{prelude::*};
    use wasm_bindgen_test::*;

    wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);

    #[wasm_bindgen]
    extern "C" {
        // Use `js_namespace` here to bind `console.log(..)` instead of just
        // `log(..)`
        #[wasm_bindgen(js_namespace = console)]
        fn log(s: String);
    }

    #[wasm_bindgen_test]
    async fn test_body() {
        use crate::Body;

        let body = Body::from("TEST");
        assert_eq!([84, 69, 83, 84], body.as_bytes().unwrap());
    }

    #[wasm_bindgen_test]
    async fn test_body_js() {
        use crate::Body;

        let body_value = "TEST";
        let body = Body::from(body_value);

        let mut init = web_sys::RequestInit::new();
        init.method("POST");
        init.body(Some(body.to_js_value().expect("could not convert body to JsValue").as_ref()));

        let js_req = web_sys::Request::new_with_str_and_init("", &init).expect("could not create JS request");
        let text_promise = js_req.text().expect("could not get text promise");
        let text = crate::wasm::promise::<JsValue>(text_promise).await.expect("could not get request body as text");

        assert_eq!(text.as_string().expect("text is not a string"), body_value);
    }
}
<commit_msg>fmt: wasm body (#1359)<commit_after>#[cfg(feature = "multipart")]
use super::multipart::Form;
/// dox
use bytes::Bytes;
use js_sys::Uint8Array;
use std::fmt;
use wasm_bindgen::JsValue;

/// The body of a `Request`.
///
/// In most cases, this is not needed directly, as the
/// [`RequestBuilder.body`][builder] method uses `Into<Body>`, which allows
/// passing many things (like a string or vector of bytes).
///
/// [builder]: ./struct.RequestBuilder.html#method.body
pub struct Body {
    inner: Inner,
}

enum Inner {
    Bytes(Bytes),
    #[cfg(feature = "multipart")]
    Multipart(Form),
}

impl Body {
    /// Returns a reference to the internal data of the `Body`.
    ///
    /// `None` is returned, if the underlying data is a multipart form.
    #[inline]
    pub fn as_bytes(&self) -> Option<&[u8]> {
        match &self.inner {
            Inner::Bytes(bytes) => Some(bytes.as_ref()),
            #[cfg(feature = "multipart")]
            Inner::Multipart(_) => None,
        }
    }
    pub(crate) fn to_js_value(&self) -> crate::Result<JsValue> {
        match &self.inner {
            Inner::Bytes(body_bytes) => {
                let body_bytes: &[u8] = body_bytes.as_ref();
                let body_uint8_array: Uint8Array = body_bytes.into();
                let js_value: &JsValue = body_uint8_array.as_ref();
                Ok(js_value.to_owned())
            }
            #[cfg(feature = "multipart")]
            Inner::Multipart(form) => {
                let form_data = form.to_form_data()?;
                let js_value: &JsValue = form_data.as_ref();
                Ok(js_value.to_owned())
            }
        }
    }

    #[inline]
    #[cfg(feature = "multipart")]
    pub(crate) fn from_form(f: Form) -> Body {
        Self {
            inner: Inner::Multipart(f),
        }
    }

    pub(crate) fn is_empty(&self) -> bool {
        match &self.inner {
            Inner::Bytes(bytes) => bytes.is_empty(),
            #[cfg(feature = "multipart")]
            Inner::Multipart(form) => form.is_empty(),
        }
    }

    pub(crate) fn try_clone(&self) -> Option<Body> {
        match &self.inner {
            Inner::Bytes(bytes) => Some(Self {
                inner: Inner::Bytes(bytes.clone()),
            }),
            #[cfg(feature = "multipart")]
            Inner::Multipart(_) => None,
        }
    }
}

impl From<Bytes> for Body {
    #[inline]
    fn from(bytes: Bytes) -> Body {
        Body {
            inner: Inner::Bytes(bytes),
        }
    }
}

impl From<Vec<u8>> for Body {
    #[inline]
    fn from(vec: Vec<u8>) -> Body {
        Body {
            inner: Inner::Bytes(vec.into()),
        }
    }
}

impl From<&'static [u8]> for Body {
    #[inline]
    fn from(s: &'static [u8]) -> Body {
        Body {
            inner: Inner::Bytes(Bytes::from_static(s)),
        }
    }
}

impl From<String> for Body {
    #[inline]
    fn from(s: String) -> Body {
        Body {
            inner: Inner::Bytes(s.into()),
        }
    }
}

impl From<&'static str> for Body {
    #[inline]
    fn from(s: &'static str) -> Body {
        s.as_bytes().into()
    }
}

impl fmt::Debug for Body {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Body").finish()
    }
}

#[cfg(test)]
mod tests {
    // use js_sys::{Array, Uint8Array};
    use wasm_bindgen::prelude::*;
    use wasm_bindgen_test::*;

    wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);

    #[wasm_bindgen]
    extern "C" {
        // Use `js_namespace` here to bind `console.log(..)` instead of just
        // `log(..)`
        #[wasm_bindgen(js_namespace = console)]
        fn log(s: String);
    }

    #[wasm_bindgen_test]
    async fn test_body() {
        use crate::Body;

        let body = Body::from("TEST");
        assert_eq!([84, 69, 83, 84], body.as_bytes().unwrap());
    }

    #[wasm_bindgen_test]
    async fn test_body_js() {
        use crate::Body;

        let body_value = "TEST";
        let body = Body::from(body_value);

        let mut init = web_sys::RequestInit::new();
        init.method("POST");
        init.body(Some(
            body.to_js_value()
                .expect("could not convert body to JsValue")
                .as_ref(),
        ));

        let js_req = web_sys::Request::new_with_str_and_init("", &init)
            .expect("could not create JS request");
        let text_promise = js_req.text().expect("could not get text promise");
        let text = crate::wasm::promise::<JsValue>(text_promise)
            .await
            .expect("could not get request body as text");

        assert_eq!(text.as_string().expect("text is not a string"), body_value);
    }
}
<|endoftext|>


<commit_before>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
#[cfg(test)]
extern crate serialize;
use libc::{c_ulonglong, c_int};
use std::intrinsics::volatile_set_memory;

#[link(name = "sodium")]
extern {
    fn crypto_sign_ed25519_keypair(pk: *mut u8,
                                   sk: *mut u8) -> c_int;
    fn crypto_sign_ed25519_seed_keypair(pk: *mut u8,
                                        sk: *mut u8,
                                        seed: *const u8) -> c_int;
    fn crypto_sign_ed25519(sm: *mut u8,
                           smlen: *mut c_ulonglong,
                           m: *const u8,
                           mlen: c_ulonglong,
                           sk: *const u8) -> c_int;
    fn crypto_sign_ed25519_open(m: *mut u8,
                                mlen: *mut c_ulonglong,
                                sm: *const u8,
                                smlen: c_ulonglong,
                                pk: *const u8) -> c_int;
}

pub const SEEDBYTES: uint = 32;
pub const SECRETKEYBYTES: uint = 64;
pub const PUBLICKEYBYTES: uint = 32;
pub const SIGNATUREBYTES: uint = 64;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed(pub [u8, ..SEEDBYTES]);

newtype_drop!(Seed)
newtype_clone!(Seed)

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey(pub [u8, ..SECRETKEYBYTES]);

newtype_drop!(SecretKey)
newtype_clone!(SecretKey)

/**
 * `PublicKey` for signatures
 */
pub struct PublicKey(pub [u8, ..PUBLICKEYBYTES]);

newtype_clone!(PublicKey)

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> Vec<u8> {
    unsafe {
        let mut sm = Vec::from_elem(m.len() + SIGNATUREBYTES, 0u8);
        let mut smlen = 0;
        crypto_sign_ed25519(sm.as_mut_ptr(),
                            &mut smlen,
                            m.as_ptr(),
                            m.len() as c_ulonglong,
                            sk.as_ptr());
        sm.truncate(smlen as uint);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<Vec<u8>> {
    unsafe {
        let mut m = Vec::from_elem(sm.len(), 0u8);
        let mut mlen = 0;
        if crypto_sign_ed25519_open(m.as_mut_ptr(),
                                    &mut mlen,
                                    sm.as_ptr(),
                                    sm.len() as c_ulonglong,
                                    pk.as_ptr()) == 0 {
            m.truncate(mlen as uint);
            Some(m)
        } else {
            None
        }
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in range(0, 256u) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32u) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 256u) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 32u) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // form the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.as_slice().split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8, ..SEEDBYTES];
        for (s, b) in seedbuf.iter_mut().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m.as_slice(), &sk);
        verify(sm.as_slice(), &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.as_slice().to_hex().as_slice());
        assert!(x3 == sm.as_slice().to_hex().as_slice());
    }
}
<commit_msg>Fixed spelling in comment<commit_after>/*!
`ed25519`, a signature scheme specified in
[Ed25519](http://ed25519.cr.yp.to/). This function is conjectured to meet the
standard notion of unforgeability for a public-key signature scheme under
chosen-message attacks.
*/
#[cfg(test)]
extern crate serialize;
use libc::{c_ulonglong, c_int};
use std::intrinsics::volatile_set_memory;

#[link(name = "sodium")]
extern {
    fn crypto_sign_ed25519_keypair(pk: *mut u8,
                                   sk: *mut u8) -> c_int;
    fn crypto_sign_ed25519_seed_keypair(pk: *mut u8,
                                        sk: *mut u8,
                                        seed: *const u8) -> c_int;
    fn crypto_sign_ed25519(sm: *mut u8,
                           smlen: *mut c_ulonglong,
                           m: *const u8,
                           mlen: c_ulonglong,
                           sk: *const u8) -> c_int;
    fn crypto_sign_ed25519_open(m: *mut u8,
                                mlen: *mut c_ulonglong,
                                sm: *const u8,
                                smlen: c_ulonglong,
                                pk: *const u8) -> c_int;
}

pub const SEEDBYTES: uint = 32;
pub const SECRETKEYBYTES: uint = 64;
pub const PUBLICKEYBYTES: uint = 32;
pub const SIGNATUREBYTES: uint = 64;

/**
 * `Seed` that can be used for keypair generation
 *
 * The `Seed` is used by `keypair_from_seed()` to generate
 * a secret and public signature key.
 *
 * When a `Seed` goes out of scope its contents
 * will be zeroed out
 */
pub struct Seed(pub [u8, ..SEEDBYTES]);

newtype_drop!(Seed)
newtype_clone!(Seed)

/**
 * `SecretKey` for signatures
 *
 * When a `SecretKey` goes out of scope its contents
 * will be zeroed out
 */
pub struct SecretKey(pub [u8, ..SECRETKEYBYTES]);

newtype_drop!(SecretKey)
newtype_clone!(SecretKey)

/**
 * `PublicKey` for signatures
 */
pub struct PublicKey(pub [u8, ..PUBLICKEYBYTES]);

newtype_clone!(PublicKey)

/**
 * `gen_keypair()` randomly generates a secret key and a corresponding public
 * key.
 *
 * THREAD SAFETY: `gen_keypair()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_keypair() -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_keypair(pk.as_mut_ptr(), sk.as_mut_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `keypair_from_seed()` computes a secret key and a corresponding public key
 * from a `Seed`.
 */
pub fn keypair_from_seed(&Seed(seed): &Seed) -> (PublicKey, SecretKey) {
    unsafe {
        let mut pk = [0u8, ..PUBLICKEYBYTES];
        let mut sk = [0u8, ..SECRETKEYBYTES];
        crypto_sign_ed25519_seed_keypair(pk.as_mut_ptr(),
                                         sk.as_mut_ptr(),
                                         seed.as_ptr());
        (PublicKey(pk), SecretKey(sk))
    }
}

/**
 * `sign()` signs a message `m` using the signer's secret key `sk`.
 * `sign()` returns the resulting signed message `sm`.
 */
pub fn sign(m: &[u8],
            &SecretKey(sk): &SecretKey) -> Vec<u8> {
    unsafe {
        let mut sm = Vec::from_elem(m.len() + SIGNATUREBYTES, 0u8);
        let mut smlen = 0;
        crypto_sign_ed25519(sm.as_mut_ptr(),
                            &mut smlen,
                            m.as_ptr(),
                            m.len() as c_ulonglong,
                            sk.as_ptr());
        sm.truncate(smlen as uint);
        sm
    }
}

/**
 * `verify()` verifies the signature in `sm` using the signer's public key `pk`.
 * `verify()` returns the message `Some(m)`.
 * If the signature fails verification, `verify()` returns `None`.
 */
pub fn verify(sm: &[u8],
              &PublicKey(pk): &PublicKey) -> Option<Vec<u8>> {
    unsafe {
        let mut m = Vec::from_elem(sm.len(), 0u8);
        let mut mlen = 0;
        if crypto_sign_ed25519_open(m.as_mut_ptr(),
                                    &mut mlen,
                                    sm.as_ptr(),
                                    sm.len() as c_ulonglong,
                                    pk.as_ptr()) == 0 {
            m.truncate(mlen as uint);
            Some(m)
        } else {
            None
        }
    }
}

#[test]
fn test_sign_verify() {
    use randombytes::randombytes;
    for i in range(0, 256u) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper() {
    use randombytes::randombytes;
    for i in range(0, 32u) {
        let (pk, sk) = gen_keypair();
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_sign_verify_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 256u) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let sm = sign(m.as_slice(), &sk);
        let m2 = verify(sm.as_slice(), &pk);
        assert!(Some(m) == m2);
    }
}

#[test]
fn test_sign_verify_tamper_seed() {
    use randombytes::{randombytes, randombytes_into};
    for i in range(0, 32u) {
        let mut seedbuf = [0, ..32];
        randombytes_into(seedbuf);
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = randombytes(i);
        let mut smv = sign(m.as_slice(), &sk);
        let sm = smv.as_mut_slice();
        for j in range(0, sm.len()) {
            sm[j] ^= 0x20;
            assert!(None == verify(sm, &pk));
            sm[j] ^= 0x20;
        }
    }
}

#[test]
fn test_vectors() {
    // test vectors from the Python implementation
    // from the [Ed25519 Homepage](http://ed25519.cr.yp.to/software.html)
    use self::serialize::hex::{FromHex, ToHex};
    use std::io::BufferedReader;
    use std::io::File;
    use std::path::Path;

    let p = &Path::new("testvectors/ed25519.input");
    let mut r = BufferedReader::new(File::open(p).unwrap());
    loop {
        let line = match r.read_line() {
            Err(_) => break,
            Ok(line) => line
        };
        let mut x = line.as_slice().split(':');
        let x0 = x.next().unwrap();
        let x1 = x.next().unwrap();
        let x2 = x.next().unwrap();
        let x3 = x.next().unwrap();
        let seed_bytes = x0.slice(0, 64).from_hex().unwrap();
        assert!(seed_bytes.len() == SEEDBYTES);
        let mut seedbuf = [0u8, ..SEEDBYTES];
        for (s, b) in seedbuf.iter_mut().zip(seed_bytes.iter()) {
            *s = *b
        }
        let seed = Seed(seedbuf);
        let (pk, sk) = keypair_from_seed(&seed);
        let m = x2.from_hex().unwrap();
        let sm = sign(m.as_slice(), &sk);
        verify(sm.as_slice(), &pk).unwrap();
        let PublicKey(pkbuf) = pk;
        assert!(x1 == pkbuf.as_slice().to_hex().as_slice());
        assert!(x3 == sm.as_slice().to_hex().as_slice());
    }
}
<|endoftext|>


<commit_before>use bitmap_font::BitmapFont;
use line_renderer::LineRenderer;
use text_renderer::TextRenderer;

use gfx;
use gfx::traits::*;
use gfx_texture;
use image;

pub enum DebugRendererError {
    ShaderProgramError(gfx::ProgramError),
    BitmapFontTextureError,
}

impl From<gfx::ProgramError> for DebugRendererError {
    fn from(err: gfx::ProgramError) -> DebugRendererError {
        DebugRendererError::ShaderProgramError(err)
    }
}

pub struct DebugRenderer<R: gfx::Resources> {
    line_renderer: LineRenderer<R>,
    text_renderer: TextRenderer<R>,
}

impl<R: gfx::Resources> DebugRenderer<R> {

    pub fn from_canvas<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        O: gfx::render::target::Output<R>,
        D: Device<Resources = R, CommandBuffer = C>,
    > (
        canvas: &mut gfx::Canvas<O, D, F>,
        initial_buffer_size: usize,
        bitmap_font: Option<BitmapFont>,
        bitmap_font_texture: Option<gfx::TextureHandle<R>>,
    ) -> Result<DebugRenderer<R>, DebugRendererError> {
        let (w, h) = canvas.output.get_size();
        DebugRenderer::new(&canvas.device, &mut canvas.factory,
                           [w as u32, h as u32], initial_buffer_size,
                           bitmap_font, bitmap_font_texture)
    }

    pub fn new<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        D: Device<Resources = R, CommandBuffer = C>,
    > (
        device: &D,
        factory: &mut F,
        frame_size: [u32; 2],
        initial_buffer_size: usize,
        bitmap_font: Option<BitmapFont>,
        bitmap_font_texture: Option<gfx::TextureHandle<R>>,
    ) -> Result<DebugRenderer<R>, DebugRendererError> {

        let device_capabilities = device.get_capabilities();

        let bitmap_font = match bitmap_font {
            Some(f) => f,
            None => BitmapFont::from_string(include_str!("../assets/notosans.fnt")).unwrap()
        };

        let bitmap_font_texture = match bitmap_font_texture {
            Some(t) => t,
            None => {
                if let image::DynamicImage::ImageRgba8(rgba_image) = image::load_from_memory_with_format(include_bytes!("../assets/notosans.png"), image::ImageFormat::PNG).unwrap() {
                    gfx_texture::Texture::from_image(factory, &rgba_image, false, false, false).handle
                } else {
                    return Err(DebugRendererError::BitmapFontTextureError)
                }
            }
        };

        let line_renderer = try!(LineRenderer::new(*device_capabilities, factory, initial_buffer_size));
        let text_renderer = try!(TextRenderer::new(*device_capabilities, factory, frame_size, initial_buffer_size, bitmap_font, bitmap_font_texture));

        Ok(DebugRenderer {
            line_renderer: line_renderer,
            text_renderer: text_renderer,
        })
    }

    pub fn draw_line(&mut self, start: [f32; 3], end: [f32; 3], color: [f32; 4]) {
        self.line_renderer.draw_line(start, end, color);
    }

    pub fn draw_text_on_screen (
        &mut self,
        text: &str,
        screen_position: [i32; 2],
        color: [f32; 4],
    ) {
        self.text_renderer.draw_text_on_screen(text, screen_position, color);
    }

    pub fn draw_text_at_position (
        &mut self,
        text: &str,
        world_position: [f32; 3],
        color: [f32; 4],
    ) {
        self.text_renderer.draw_text_at_position(text, world_position, color);
    }

    pub fn render_canvas<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        O: gfx::render::target::Output<R>,
        D: Device<Resources = R, CommandBuffer = C>,
    > (
        &mut self,
        canvas: &mut gfx::Canvas<O, D, F>,
        projection: [[f32; 4]; 4],
    ) {
        self.render(&mut canvas.renderer, &mut canvas.factory, &canvas.output, projection);
    }

    pub fn render<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        O: gfx::render::target::Output<R>,
    > (
        &mut self,
        renderer: &mut gfx::Renderer<R, C>,
        factory: &mut F,
        output: &O,
        projection: [[f32; 4]; 4],
    ) {
        self.line_renderer.render(renderer, factory, output, projection);
        self.text_renderer.render(renderer, factory, output, projection);
    }
}
<commit_msg>Update to latest gfx_texture<commit_after>use bitmap_font::BitmapFont;
use line_renderer::LineRenderer;
use text_renderer::TextRenderer;

use gfx;
use gfx::traits::*;
use gfx_texture;
use image;

pub enum DebugRendererError {
    ShaderProgramError(gfx::ProgramError),
    BitmapFontTextureError,
}

impl From<gfx::ProgramError> for DebugRendererError {
    fn from(err: gfx::ProgramError) -> DebugRendererError {
        DebugRendererError::ShaderProgramError(err)
    }
}

pub struct DebugRenderer<R: gfx::Resources> {
    line_renderer: LineRenderer<R>,
    text_renderer: TextRenderer<R>,
}

impl<R: gfx::Resources> DebugRenderer<R> {

    pub fn from_canvas<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        O: gfx::render::target::Output<R>,
        D: Device<Resources = R, CommandBuffer = C>,
    > (
        canvas: &mut gfx::Canvas<O, D, F>,
        initial_buffer_size: usize,
        bitmap_font: Option<BitmapFont>,
        bitmap_font_texture: Option<gfx::TextureHandle<R>>,
    ) -> Result<DebugRenderer<R>, DebugRendererError> {
        let (w, h) = canvas.output.get_size();
        DebugRenderer::new(&canvas.device, &mut canvas.factory,
                           [w as u32, h as u32], initial_buffer_size,
                           bitmap_font, bitmap_font_texture)
    }

    pub fn new<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        D: Device<Resources = R, CommandBuffer = C>,
    > (
        device: &D,
        factory: &mut F,
        frame_size: [u32; 2],
        initial_buffer_size: usize,
        bitmap_font: Option<BitmapFont>,
        bitmap_font_texture: Option<gfx::TextureHandle<R>>,
    ) -> Result<DebugRenderer<R>, DebugRendererError> {

        let device_capabilities = device.get_capabilities();

        let bitmap_font = match bitmap_font {
            Some(f) => f,
            None => BitmapFont::from_string(include_str!("../assets/notosans.fnt")).unwrap()
        };

        let bitmap_font_texture = match bitmap_font_texture {
            Some(t) => t,
            None => {
                if let image::DynamicImage::ImageRgba8(rgba_image) = image::load_from_memory_with_format(include_bytes!("../assets/notosans.png"), image::ImageFormat::PNG).unwrap() {
                    gfx_texture::Texture::from_image(factory, &rgba_image, false, false, false).handle()
                } else {
                    return Err(DebugRendererError::BitmapFontTextureError)
                }
            }
        };

        let line_renderer = try!(LineRenderer::new(*device_capabilities, factory, initial_buffer_size));
        let text_renderer = try!(TextRenderer::new(*device_capabilities, factory, frame_size, initial_buffer_size, bitmap_font, bitmap_font_texture));

        Ok(DebugRenderer {
            line_renderer: line_renderer,
            text_renderer: text_renderer,
        })
    }

    pub fn draw_line(&mut self, start: [f32; 3], end: [f32; 3], color: [f32; 4]) {
        self.line_renderer.draw_line(start, end, color);
    }

    pub fn draw_text_on_screen (
        &mut self,
        text: &str,
        screen_position: [i32; 2],
        color: [f32; 4],
    ) {
        self.text_renderer.draw_text_on_screen(text, screen_position, color);
    }

    pub fn draw_text_at_position (
        &mut self,
        text: &str,
        world_position: [f32; 3],
        color: [f32; 4],
    ) {
        self.text_renderer.draw_text_at_position(text, world_position, color);
    }

    pub fn render_canvas<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        O: gfx::render::target::Output<R>,
        D: Device<Resources = R, CommandBuffer = C>,
    > (
        &mut self,
        canvas: &mut gfx::Canvas<O, D, F>,
        projection: [[f32; 4]; 4],
    ) {
        self.render(&mut canvas.renderer, &mut canvas.factory, &canvas.output, projection);
    }

    pub fn render<
        C: gfx::CommandBuffer<R>,
        F: Factory<R>,
        O: gfx::render::target::Output<R>,
    > (
        &mut self,
        renderer: &mut gfx::Renderer<R, C>,
        factory: &mut F,
        output: &O,
        projection: [[f32; 4]; 4],
    ) {
        self.line_renderer.render(renderer, factory, output, projection);
        self.text_renderer.render(renderer, factory, output, projection);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Fedor Gogolev <knsd@knsd.net>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io::{Read, BufRead, Error as IoError, ErrorKind};
use std::string::{FromUtf8Error};
use std::collections::{HashMap};
use std::cell::{RefCell};
use std::rc::{Rc};

use num::{Zero};
use num::bigint::{BigInt, ToBigInt, Sign};
use byteorder::{ReadBytesExt, LittleEndian, BigEndian, Error as ByteorderError};
use from_ascii::{FromAscii, ParseIntError, ParseFloatError};

use string::{unescape, Error as UnescapeError};
use value::{Value};

use opcodes::*;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        EmptyMarker
        StackTooSmall
        EmptyStack
        InvalidValueOnStack
        InvalidGetValue
        InvalidPutValue
        NotImplemented

        Read(err: ByteorderError) {
            from()
        }
        Io(err: IoError) {
            from()
        }
        UnknownOpcode(opcode: u8) {}

        InvalidInt {
            from(ParseIntError)
        }
        InvalidLong
        InvalidFloat {
            from(ParseFloatError)
        }

        InvalidString {
            from(FromUtf8Error)
        }
        UnescapeError(err: UnescapeError) {
            from()
        }

        InvalidProto(proto: u8)
        NegativeLength {}

        #[doc(hidden)]
        __Nonexhaustive
    }
}

#[derive(Debug, PartialEq)]
pub enum BooleanOrInt {
    Boolean(bool),
    Int(i64),
}

macro_rules! rc {
    ($term: expr) => (Rc::new(RefCell::new($term)))
}

fn read_exact<R>(rd: &mut R, mut buf: &mut [u8]) -> Result<(), IoError> where R: Read {
    while !buf.is_empty() {
        match rd.read(buf) {
            Ok(0) => break,
            Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    if !buf.is_empty() {
        Err(IoError::new(ErrorKind::Other,
                       "failed to fill whole buffer"))
    } else {
        Ok(())
    }
}

fn read_until_newline<R>(rd: &mut R) -> Result<Vec<u8>, Error> where R: Read + BufRead {
    let mut buf = Vec::new();
    try!(rd.read_until('\n' as u8, &mut buf));

    // Skip last symbol — \n
    match buf.split_last() {
        Some((&b'\n', init)) => Ok(init.to_vec()),
        _ => return Err(Error::InvalidString),
    }
}

fn read_decimal_int<R>(rd: &mut R) -> Result<BooleanOrInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let val = match &s[..] {
        b"00" => BooleanOrInt::Boolean(false),
        b"01" => BooleanOrInt::Boolean(true),
        _ => BooleanOrInt::Int(try!(i64::from_ascii(&s)))
    };
    Ok(val)
}

fn read_decimal_long<R>(rd: &mut R) -> Result<BigInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let init = match s.split_last() {
        None => return Err(Error::InvalidString),
        Some((&b'L', init)) => init,
        Some(_) => &s[..],
    };

    match BigInt::parse_bytes(&init, 10) {
        Some(i) => Ok(i),
        None => Err(Error::InvalidLong)
    }
}

fn read_long<R>(rd: &mut R, length: usize) -> Result<BigInt, Error> where R: Read + BufRead {
    let mut buf = vec![0; length];
    try!(read_exact(rd, buf.as_mut()));

    let mut n = BigInt::from_bytes_le(Sign::Plus, &buf);

    let last = match buf.last_mut() {
        None => return Err(Error::InvalidLong),
        Some(last) => last,
    };

    if *last > 127 {
        n = n - (1.to_bigint().unwrap() << (length * 8))
    }

    Ok(n)
}

pub struct Machine {
    stack: Vec<Value>,
    memo: HashMap<usize, Value>,
    marker: Option<usize>,
}

impl Machine {
    pub fn new() -> Self {
        Machine {
            stack: Vec::new(),
            memo: HashMap::new(),
            marker: None,
        }
    }

    fn split_off(&mut self) -> Result<Vec<Value>, Error> {
        let at = match self.marker {
            None => return Err(Error::EmptyMarker),
            Some(marker) => marker,
        };

        if at > self.stack.len() {
            return Err(Error::StackTooSmall);
        }

        Ok(self.stack.split_off(at))
    }

    fn pop(&mut self) -> Result<Value, Error> {
        match self.stack.pop() {
            None => return Err(Error::EmptyStack),
            Some(value) => Ok(value),
        }
    }

    fn handle_get(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.memo.get(&i) {
            None => return Err(Error::InvalidGetValue),
            Some(ref v) => (*v).clone(),
        };
        self.stack.push(value);
        Ok(())
    }

    fn handle_put(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.stack.last() {
            None => return Err(Error::EmptyStack),
            Some(ref v) => (*v).clone(),
        };
        self.memo.insert(i, value);
        Ok(())
    }

    pub fn execute<R>(&mut self, rd: &mut R) -> Result<bool, Error> where R: Read + BufRead {
        macro_rules! ensure_not_negative {
            ($n: expr) => ({
                if $n < Zero::zero() {
                    return Err(Error::NegativeLength)
                }
            })
        }

        let marker = try!(rd.read_u8());
        match marker {
            PROTO => {
                let version = try!(rd.read_u8());
                if version < 2 {
                    return Err(Error::InvalidProto(version))
                }
            },
            STOP => return Ok(true),

            INT => {
                self.stack.push(match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Boolean(v) => Value::Bool(v),
                    BooleanOrInt::Int(v) => Value::Long(BigInt::from(v)),
                })
            },
            BININT => self.stack.push(Value::Int(try!(rd.read_i32::<LittleEndian>()) as isize)),
            BININT1 => self.stack.push(Value::Int(try!(rd.read_u8()) as isize)),
            BININT2 => self.stack.push(Value::Int(try!(rd.read_u16::<LittleEndian>()) as isize)),
            LONG => self.stack.push(Value::Long(BigInt::from(try!(read_decimal_long(rd))))),
            LONG1 => {
                let length = try!(rd.read_u8());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }
            LONG4 => {
                let length = try!(rd.read_i32::<LittleEndian>());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }

            STRING => self.stack.push(Value::String(try!(unescape(&try!(read_until_newline(rd)), false)))),
            BINSTRING => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);

                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },
            SHORT_BINSTRING => {
                let length = try!(rd.read_u8());
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },

            NONE => self.stack.push(Value::None),
            NEWTRUE => self.stack.push(Value::Bool(true)),
            NEWFALSE => self.stack.push(Value::Bool(false)),

            UNICODE => {
                let buf = try!(unescape(&try!(read_until_newline(rd)), true));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },
            BINUNICODE => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, buf.as_mut()));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },

            FLOAT => {
                let s = try!(read_until_newline(rd));
                self.stack.push(Value::Float(try!(f64::from_ascii(&s))))
            },
            BINFLOAT => {
                self.stack.push(Value::Float(try!(rd.read_f64::<BigEndian>())))
            },

            EMPTY_LIST => {
                self.stack.push(Value::List(rc!(Vec::new())))
            },
            APPEND => {
                let v = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => (*list.borrow_mut()).push(v),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            APPENDS => {
                let values = try!(self.split_off());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => (*list.borrow_mut()).extend(values),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            LIST => {
                let values = try!(self.split_off());
                self.stack.push(Value::List(rc!(values)));
            },

            EMPTY_TUPLE => self.stack.push(Value::Tuple(rc!(Vec::new()))),
            TUPLE => {
                let values = try!(self.split_off());
                self.stack.push(Value::Tuple(rc!(values)));
            },
            TUPLE1 => {
                let v1 = try!(self.pop());
                self.stack.push(Value::Tuple(rc!(vec![v1])))
            },
            TUPLE2 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                self.stack.push(Value::Tuple(rc!(vec![v1, v2])))
            },
            TUPLE3 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                let v3 = try!(self.pop());
                self.stack.push(Value::Tuple(rc!(vec![v1, v2, v3])))
            }

            EMPTY_DICT => self.stack.push(Value::Dict(rc!(Vec::new()))),
            DICT => {
                let mut values = try!(self.split_off());
                let mut dict = Vec::new();

                for i in 0 .. values.len() / 2 { // TODO: Check panic
                    let key = values.remove(2 * i);
                    let value = values.remove(2 * i + 1);
                    dict.push((key, value));
                }
                self.stack.push(Value::Dict(rc!(dict)));
            },
            SETITEM => {
                let value = try!(self.pop());
                let key = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict)) => (*dict.borrow_mut()).push((key, value)),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            SETITEMS => {
                let mut values = try!(self.split_off());

                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict_ref)) => {
                        for i in 0 .. values.len() / 2 { // TODO: Check panic
                                let key = values.remove(2 * i);
                                let value = values.remove(2 * i + 1);
                                (*dict_ref.borrow_mut()).push((key, value));
                            }
                    },
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },

            POP => {
                try!(self.pop());
            },
            DUP => {
                let value = match self.stack.last() {
                    None => return Err(Error::EmptyStack),
                    Some(ref v) => (*v).clone(),
                };
                self.stack.push(value)
            },
            MARK => {
                self.marker = Some(self.stack.len())
            },
            POP_MARK => {
                try!(self.split_off());
            },

            GET => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }
            BINGET => {
                try!(self.handle_get(try!(rd.read_u8()) as usize))
            }
            LONG_BINGET => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }

            PUT => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }
            BINPUT => {
                try!(self.handle_put(try!(rd.read_u8()) as usize))
            }
            LONG_BINPUT => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }

            c => return Err(Error::UnknownOpcode(c)),
        }
        Ok(false)
    }
}

pub fn unpickle<R>(rd: &mut R) -> Result<Value, Error> where R: Read + BufRead {
    let mut machine = Machine::new();
    loop {
        if try!(machine.execute(rd)) {
            break
        }
    }
    Ok(try!(machine.pop()))
}
<commit_msg>Remove unneeded return statement<commit_after>// Copyright (c) 2016 Fedor Gogolev <knsd@knsd.net>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io::{Read, BufRead, Error as IoError, ErrorKind};
use std::string::{FromUtf8Error};
use std::collections::{HashMap};
use std::cell::{RefCell};
use std::rc::{Rc};

use num::{Zero};
use num::bigint::{BigInt, ToBigInt, Sign};
use byteorder::{ReadBytesExt, LittleEndian, BigEndian, Error as ByteorderError};
use from_ascii::{FromAscii, ParseIntError, ParseFloatError};

use string::{unescape, Error as UnescapeError};
use value::{Value};

use opcodes::*;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        EmptyMarker
        StackTooSmall
        EmptyStack
        InvalidValueOnStack
        InvalidGetValue
        InvalidPutValue
        NotImplemented

        Read(err: ByteorderError) {
            from()
        }
        Io(err: IoError) {
            from()
        }
        UnknownOpcode(opcode: u8) {}

        InvalidInt {
            from(ParseIntError)
        }
        InvalidLong
        InvalidFloat {
            from(ParseFloatError)
        }

        InvalidString {
            from(FromUtf8Error)
        }
        UnescapeError(err: UnescapeError) {
            from()
        }

        InvalidProto(proto: u8)
        NegativeLength {}

        #[doc(hidden)]
        __Nonexhaustive
    }
}

#[derive(Debug, PartialEq)]
pub enum BooleanOrInt {
    Boolean(bool),
    Int(i64),
}

macro_rules! rc {
    ($term: expr) => (Rc::new(RefCell::new($term)))
}

fn read_exact<R>(rd: &mut R, mut buf: &mut [u8]) -> Result<(), IoError> where R: Read {
    while !buf.is_empty() {
        match rd.read(buf) {
            Ok(0) => break,
            Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    if !buf.is_empty() {
        Err(IoError::new(ErrorKind::Other,
                       "failed to fill whole buffer"))
    } else {
        Ok(())
    }
}

fn read_until_newline<R>(rd: &mut R) -> Result<Vec<u8>, Error> where R: Read + BufRead {
    let mut buf = Vec::new();
    try!(rd.read_until('\n' as u8, &mut buf));

    // Skip last symbol — \n
    match buf.split_last() {
        Some((&b'\n', init)) => Ok(init.to_vec()),
        _ => Err(Error::InvalidString),
    }
}

fn read_decimal_int<R>(rd: &mut R) -> Result<BooleanOrInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let val = match &s[..] {
        b"00" => BooleanOrInt::Boolean(false),
        b"01" => BooleanOrInt::Boolean(true),
        _ => BooleanOrInt::Int(try!(i64::from_ascii(&s)))
    };
    Ok(val)
}

fn read_decimal_long<R>(rd: &mut R) -> Result<BigInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let init = match s.split_last() {
        None => return Err(Error::InvalidString),
        Some((&b'L', init)) => init,
        Some(_) => &s[..],
    };

    match BigInt::parse_bytes(&init, 10) {
        Some(i) => Ok(i),
        None => Err(Error::InvalidLong)
    }
}

fn read_long<R>(rd: &mut R, length: usize) -> Result<BigInt, Error> where R: Read + BufRead {
    let mut buf = vec![0; length];
    try!(read_exact(rd, buf.as_mut()));

    let mut n = BigInt::from_bytes_le(Sign::Plus, &buf);

    let last = match buf.last_mut() {
        None => return Err(Error::InvalidLong),
        Some(last) => last,
    };

    if *last > 127 {
        n = n - (1.to_bigint().unwrap() << (length * 8))
    }

    Ok(n)
}

pub struct Machine {
    stack: Vec<Value>,
    memo: HashMap<usize, Value>,
    marker: Option<usize>,
}

impl Machine {
    pub fn new() -> Self {
        Machine {
            stack: Vec::new(),
            memo: HashMap::new(),
            marker: None,
        }
    }

    fn split_off(&mut self) -> Result<Vec<Value>, Error> {
        let at = match self.marker {
            None => return Err(Error::EmptyMarker),
            Some(marker) => marker,
        };

        if at > self.stack.len() {
            return Err(Error::StackTooSmall);
        }

        Ok(self.stack.split_off(at))
    }

    fn pop(&mut self) -> Result<Value, Error> {
        match self.stack.pop() {
            None => return Err(Error::EmptyStack),
            Some(value) => Ok(value),
        }
    }

    fn handle_get(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.memo.get(&i) {
            None => return Err(Error::InvalidGetValue),
            Some(ref v) => (*v).clone(),
        };
        self.stack.push(value);
        Ok(())
    }

    fn handle_put(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.stack.last() {
            None => return Err(Error::EmptyStack),
            Some(ref v) => (*v).clone(),
        };
        self.memo.insert(i, value);
        Ok(())
    }

    pub fn execute<R>(&mut self, rd: &mut R) -> Result<bool, Error> where R: Read + BufRead {
        macro_rules! ensure_not_negative {
            ($n: expr) => ({
                if $n < Zero::zero() {
                    return Err(Error::NegativeLength)
                }
            })
        }

        let marker = try!(rd.read_u8());
        match marker {
            PROTO => {
                let version = try!(rd.read_u8());
                if version < 2 {
                    return Err(Error::InvalidProto(version))
                }
            },
            STOP => return Ok(true),

            INT => {
                self.stack.push(match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Boolean(v) => Value::Bool(v),
                    BooleanOrInt::Int(v) => Value::Long(BigInt::from(v)),
                })
            },
            BININT => self.stack.push(Value::Int(try!(rd.read_i32::<LittleEndian>()) as isize)),
            BININT1 => self.stack.push(Value::Int(try!(rd.read_u8()) as isize)),
            BININT2 => self.stack.push(Value::Int(try!(rd.read_u16::<LittleEndian>()) as isize)),
            LONG => self.stack.push(Value::Long(BigInt::from(try!(read_decimal_long(rd))))),
            LONG1 => {
                let length = try!(rd.read_u8());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }
            LONG4 => {
                let length = try!(rd.read_i32::<LittleEndian>());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }

            STRING => self.stack.push(Value::String(try!(unescape(&try!(read_until_newline(rd)), false)))),
            BINSTRING => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);

                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },
            SHORT_BINSTRING => {
                let length = try!(rd.read_u8());
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },

            NONE => self.stack.push(Value::None),
            NEWTRUE => self.stack.push(Value::Bool(true)),
            NEWFALSE => self.stack.push(Value::Bool(false)),

            UNICODE => {
                let buf = try!(unescape(&try!(read_until_newline(rd)), true));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },
            BINUNICODE => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, buf.as_mut()));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },

            FLOAT => {
                let s = try!(read_until_newline(rd));
                self.stack.push(Value::Float(try!(f64::from_ascii(&s))))
            },
            BINFLOAT => {
                self.stack.push(Value::Float(try!(rd.read_f64::<BigEndian>())))
            },

            EMPTY_LIST => {
                self.stack.push(Value::List(rc!(Vec::new())))
            },
            APPEND => {
                let v = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => (*list.borrow_mut()).push(v),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            APPENDS => {
                let values = try!(self.split_off());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => (*list.borrow_mut()).extend(values),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            LIST => {
                let values = try!(self.split_off());
                self.stack.push(Value::List(rc!(values)));
            },

            EMPTY_TUPLE => self.stack.push(Value::Tuple(rc!(Vec::new()))),
            TUPLE => {
                let values = try!(self.split_off());
                self.stack.push(Value::Tuple(rc!(values)));
            },
            TUPLE1 => {
                let v1 = try!(self.pop());
                self.stack.push(Value::Tuple(rc!(vec![v1])))
            },
            TUPLE2 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                self.stack.push(Value::Tuple(rc!(vec![v1, v2])))
            },
            TUPLE3 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                let v3 = try!(self.pop());
                self.stack.push(Value::Tuple(rc!(vec![v1, v2, v3])))
            }

            EMPTY_DICT => self.stack.push(Value::Dict(rc!(Vec::new()))),
            DICT => {
                let mut values = try!(self.split_off());
                let mut dict = Vec::new();

                for i in 0 .. values.len() / 2 { // TODO: Check panic
                    let key = values.remove(2 * i);
                    let value = values.remove(2 * i + 1);
                    dict.push((key, value));
                }
                self.stack.push(Value::Dict(rc!(dict)));
            },
            SETITEM => {
                let value = try!(self.pop());
                let key = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict)) => (*dict.borrow_mut()).push((key, value)),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            SETITEMS => {
                let mut values = try!(self.split_off());

                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict_ref)) => {
                        for i in 0 .. values.len() / 2 { // TODO: Check panic
                                let key = values.remove(2 * i);
                                let value = values.remove(2 * i + 1);
                                (*dict_ref.borrow_mut()).push((key, value));
                            }
                    },
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },

            POP => {
                try!(self.pop());
            },
            DUP => {
                let value = match self.stack.last() {
                    None => return Err(Error::EmptyStack),
                    Some(ref v) => (*v).clone(),
                };
                self.stack.push(value)
            },
            MARK => {
                self.marker = Some(self.stack.len())
            },
            POP_MARK => {
                try!(self.split_off());
            },

            GET => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }
            BINGET => {
                try!(self.handle_get(try!(rd.read_u8()) as usize))
            }
            LONG_BINGET => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }

            PUT => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }
            BINPUT => {
                try!(self.handle_put(try!(rd.read_u8()) as usize))
            }
            LONG_BINPUT => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }

            c => return Err(Error::UnknownOpcode(c)),
        }
        Ok(false)
    }
}

pub fn unpickle<R>(rd: &mut R) -> Result<Value, Error> where R: Read + BufRead {
    let mut machine = Machine::new();
    loop {
        if try!(machine.execute(rd)) {
            break
        }
    }
    Ok(try!(machine.pop()))
}
<|endoftext|>


<commit_before>use std::any::{Any, TypeId};
use std::fmt::Debug;
use std::io::{
    Read,
    Result,
    Write,
};

/// A protobuf message.
pub trait Message: Any + Debug + Default + Send + Sync {

    /// Encode the message and write it to the provided `Write`.
    fn write_to(&self, w: &mut Write) -> Result<()>;

    /// Encode the message and its length and write them to the provided `Write`.
    fn write_length_delimited_to(&self, w: &mut Write) -> Result<()>;

    fn merge_from(&mut self, r: &mut Read) -> Result<()>;

    fn merge_delimited_from(&mut self, r: &mut Read) -> Result<()>;

    fn type_id(&self) -> TypeId;

    fn as_any(&self) -> &Any;

    fn as_any_mut(&mut self) -> &mut Any;

    fn into_any(self: Box<Self>) -> Box<Any>;
}
<commit_msg>tweak Message trait<commit_after>use std::any::{Any, TypeId};
use std::fmt::Debug;
use std::io::{
    Read,
    Result,
    Write,
};

/// A protobuf message.
pub trait Message: Any + Debug + Send + Sync {

    /// Encode the message and its length and write them to the provided `Write`.
    fn write_length_delimited_to<W>(&self, w: &mut W) -> Result<()> where W: Write, Self: Sized;

    /// Merge a length-delimited message into `self`.
    fn merge_length_delimited_from<R>(&self, r: &mut R) -> Result<()> where R: Read, Self: Sized;

    /// Like `write_length_delimited_to`, but allows generic `Message` instances
    /// (e.g. `&Message`) to be written.
    fn write_length_delimited_to_dynamic(&self, w: &mut Write) -> Result<()>;

    /// Like `merge_length_delimited_from`, but allows generic `Message` instances
    /// (e.g. `&mut Message`) to be merged.
    fn merge_length_delimited_from_dynamic(&mut self, r: &mut Read) -> Result<()>;

    fn type_id(&self) -> TypeId;

    fn as_any(&self) -> &Any;

    fn as_any_mut(&mut self) -> &mut Any;

    fn into_any(self: Box<Self>) -> Box<Any>;
}

/// Test that the `Message` trait is object-safe.
#[allow(unused)]
fn test_message_is_object_safe(message: &Message) {}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::thread;

use parking_lot::Mutex;

use select::CaseId;
use select::handle::{self, Handle};

/// A selection case, identified by a `Handle` and a `CaseId`.
///
/// Note that multiple threads could be operating on a single channel end, as well as a single
/// thread on multiple different channel ends.
struct Case {
    /// A handle associated with the thread owning this case.
    handle: Handle,

    /// The case ID.
    case_id: CaseId,
}

/// A simple wait queue for list-based and array-based channels.
///
/// This data structure is used sfor registeroing selection cases before blocking and waking them
/// up when the channel receives a message, sends one, or gets closed.
pub struct Monitor {
    /// The list of registered selection cases.
    cases: Mutex<VecDeque<Case>>,

    /// Number of cases in the list.
    len: AtomicUsize,
}

impl Monitor {
    /// Creates a new `Monitor`.
    #[inline]
    pub fn new() -> Self {
        Monitor {
            cases: Mutex::new(VecDeque::new()),
            len: AtomicUsize::new(0),
        }
    }

    /// Registers the current thread with `case_id`.
    pub fn register(&self, case_id: CaseId) {
        let mut cases = self.cases.lock();
        cases.push_back(Case {
            handle: handle::current(),
            case_id,
        });
        self.len.store(cases.len(), SeqCst);
    }

    /// Unregisters the current thread with `case_id`.
    pub fn unregister(&self, case_id: CaseId) {
        let thread_id = thread::current().id();
        let mut cases = self.cases.lock();

        if let Some((i, _)) = cases.iter().enumerate().find(|&(_, case)| {
            case.case_id == case_id && case.handle.thread_id() == thread_id
        }) {
            cases.remove(i);
            self.len.store(cases.len(), SeqCst);
            Self::maybe_shrink(&mut cases);
        }
    }

    /// Attempts to fire one case which is owned by another thread.
    pub fn notify_one(&self) {
        if self.len.load(SeqCst) > 0 {
            let thread_id = thread::current().id();
            let mut cases = self.cases.lock();

            for i in 0..cases.len() {
                if cases[i].handle.thread_id() != thread_id {
                    if cases[i].handle.try_select(cases[i].case_id) {
                        let case = cases.remove(i).unwrap();
                        self.len.store(cases.len(), SeqCst);
                        Self::maybe_shrink(&mut cases);

                        case.handle.unpark();
                        break;
                    }
                }
            }
        }
    }

    /// Aborts all currently registered selection cases.
    pub fn abort_all(&self) {
        if self.len.load(SeqCst) > 0 {
            let mut cases = self.cases.lock();

            self.len.store(0, SeqCst);
            for case in cases.drain(..) {
                if case.handle.try_select(CaseId::abort()) {
                    case.handle.unpark();
                }
            }

            Self::maybe_shrink(&mut cases);
        }
    }

    /// Shrinks the internal deque if it's capacity is much larger than length.
    fn maybe_shrink(cases: &mut VecDeque<Case>) {
        if cases.capacity() > 32 && cases.len() < cases.capacity() / 4 {
            let mut v = VecDeque::with_capacity(cases.capacity() / 2);
            v.extend(cases.drain(..));
            *cases = v;
        }
    }
}

impl Drop for Monitor {
    fn drop(&mut self) {
        debug_assert!(self.cases.lock().is_empty());
        debug_assert_eq!(self.len.load(SeqCst), 0);
    }
}
<commit_msg>Fix a typo<commit_after>use std::collections::VecDeque;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::thread;

use parking_lot::Mutex;

use select::CaseId;
use select::handle::{self, Handle};

/// A selection case, identified by a `Handle` and a `CaseId`.
///
/// Note that multiple threads could be operating on a single channel end, as well as a single
/// thread on multiple different channel ends.
struct Case {
    /// A handle associated with the thread owning this case.
    handle: Handle,

    /// The case ID.
    case_id: CaseId,
}

/// A simple wait queue for list-based and array-based channels.
///
/// This data structure is used for registering selection cases before blocking and waking them
/// up when the channel receives a message, sends one, or gets closed.
pub struct Monitor {
    /// The list of registered selection cases.
    cases: Mutex<VecDeque<Case>>,

    /// Number of cases in the list.
    len: AtomicUsize,
}

impl Monitor {
    /// Creates a new `Monitor`.
    #[inline]
    pub fn new() -> Self {
        Monitor {
            cases: Mutex::new(VecDeque::new()),
            len: AtomicUsize::new(0),
        }
    }

    /// Registers the current thread with `case_id`.
    pub fn register(&self, case_id: CaseId) {
        let mut cases = self.cases.lock();
        cases.push_back(Case {
            handle: handle::current(),
            case_id,
        });
        self.len.store(cases.len(), SeqCst);
    }

    /// Unregisters the current thread with `case_id`.
    pub fn unregister(&self, case_id: CaseId) {
        let thread_id = thread::current().id();
        let mut cases = self.cases.lock();

        if let Some((i, _)) = cases.iter().enumerate().find(|&(_, case)| {
            case.case_id == case_id && case.handle.thread_id() == thread_id
        }) {
            cases.remove(i);
            self.len.store(cases.len(), SeqCst);
            Self::maybe_shrink(&mut cases);
        }
    }

    /// Attempts to fire one case which is owned by another thread.
    pub fn notify_one(&self) {
        if self.len.load(SeqCst) > 0 {
            let thread_id = thread::current().id();
            let mut cases = self.cases.lock();

            for i in 0..cases.len() {
                if cases[i].handle.thread_id() != thread_id {
                    if cases[i].handle.try_select(cases[i].case_id) {
                        let case = cases.remove(i).unwrap();
                        self.len.store(cases.len(), SeqCst);
                        Self::maybe_shrink(&mut cases);

                        case.handle.unpark();
                        break;
                    }
                }
            }
        }
    }

    /// Aborts all currently registered selection cases.
    pub fn abort_all(&self) {
        if self.len.load(SeqCst) > 0 {
            let mut cases = self.cases.lock();

            self.len.store(0, SeqCst);
            for case in cases.drain(..) {
                if case.handle.try_select(CaseId::abort()) {
                    case.handle.unpark();
                }
            }

            Self::maybe_shrink(&mut cases);
        }
    }

    /// Shrinks the internal deque if it's capacity is much larger than length.
    fn maybe_shrink(cases: &mut VecDeque<Case>) {
        if cases.capacity() > 32 && cases.len() < cases.capacity() / 4 {
            let mut v = VecDeque::with_capacity(cases.capacity() / 2);
            v.extend(cases.drain(..));
            *cases = v;
        }
    }
}

impl Drop for Monitor {
    fn drop(&mut self) {
        debug_assert!(self.cases.lock().is_empty());
        debug_assert_eq!(self.len.load(SeqCst), 0);
    }
}
<|endoftext|>


<commit_before>// Copyright(C) 2016 Chris Liebert
extern crate glium;
extern crate nalgebra;

use common::Vertex8f32;
implement_vertex!(Vertex8f32, position, normal, texcoord);

// use self::glium::{Surface, Display, IndexBuffer, Program, VertexBuffer};
// use glium::uniforms::UniformsStorage;

// use self::nalgebra::{Matrix4, PerspectiveMatrix3};

// ::VertexBuffer;
// use glium::IndexBuffer;

// trait Renderer {
// fn new(display: Display) -> Renderer;
// fn buffer_to_gpu();
// fn render();
// }
//
// pub struct SceneRenderer {
// display: Display,
// vertexBuffer: VertexBuffer,
// indices: raw,
// program: raw,
// }
//
//
// pub fn new(display: Display) -> Renderer {
// Renderer { display: display }
// Set up camera
//    let perspective = PerspectiveMatrix3::new(screen_width as f32 / screen_height as f32,
//                                              45.0,
//                                              0.1,
//                                              1000.0);
//    let perspective_matrix: Matrix4<f32> = perspective.to_matrix();
//
//
//    let modelview_matrix_array = [[1.0f32, -0.0f32, -0.0f32, 0.0f32],
//                                  [0.0f32, 1.0f32, -0.0f32, 0.0f32],
//                                  [0.0f32, 0.0f32, 1.0f32, 0.0f32],
//                                  [-5.0f32, -3.0f32, -12.0f32, 1.0f32]];
//
//    let uniforms = uniform! {
// 	        projection: *perspective_matrix.as_ref(),
// 	        modelview: modelview_matrix_array,
// 	        light_position_worldspace: [2.0, 10.0, 1.0f32],
// 	        diffuse: [0.5f32, 0.5, 0.5]
// 	    };
// }
//

// pub fn render(display: Display,
// let mut target = display.draw();
//        target.clear_color(0.0, 0.0, 0.0, 1.0);
//        target.draw(&vertex_buffer,
//                  &index_buffer,
//                  &program,
//                  &uniforms,
//                  &Default::default())
//            .unwrap();
//        target.finish().unwrap();
// }
//

// Uniform buffers
	/* camera modelview matrix used for testing

	let projection_matrix_array = [
		[1.19506f32, 0.0f32, 0.0f32, 0.0f32],
        [0.0f32, 1.79259, 0.0f32, 0.0f32],
        [ 0.0f32, 0.0f32,-1.0f32,-1.0f32],
        [0.0f32, 0.0f32, -0.2f32, 0.0f32]
   ];
    */

	/*
	//#[derive(Copy, Clone)]
    struct ViewMatrixBlockData {
        projection: [[f32; 4]; 4],
        modelview: [[f32; 4]; 4],
    }

    //implement_buffer_content!(ViewMatrixBlockData);
   //implement_uniform_block!(ViewMatrixBlockData, projection, modelview);

	let mut view_matrix_block_buffer = glium::uniforms::UniformBuffer::<ViewMatrixBlockData>::dynamic(&display,
	//let mut view_matrix_block_buffer = glium::uniforms::UniformBuffer::<ViewMatrixBlockData>::empty_unsized(&display,
	//	32
		ViewMatrixBlockData {
			projection: projection_matrix_array,
			modelview: modelview_matrix_array,
		}
	).unwrap();
	*/
	/*
	// How to map the buffer to local memory
	let mut mapping = view_matrix_block_buffer.map();
	for val in mapping.projection.iter_mut() {
		*val =
			[1.19506f32, 0.00f32, 0.0f32, 0.0f32];

	}

	//#[derive(Debug)]
	#[derive(Copy, Clone)]
	struct ViewMatrixBlockData {
	    projection: [[f32; 4]; 4],
        modelview: [[f32; 4]; 4],
    } */

	//implement_buffer_content!(ViewMatrixBlockData);    // without this, you can't put `Data` in a glium buffer
	//implement_uniform_block!(ViewMatrixBlockData, projection, modelview);

	/*let view_matrix_block_data: ViewMatrixBlockData = ViewMatrixBlockData {
		projection: projection_matrix_array,
		modelview: modelview_matrix_array,
	};*/
	// creates a buffer of 64 bytes, which thus holds 8 f32s
	//let mut buffer = glium::buffer::Buffer::<ViewMatrixBlockData>::empty_unsized(&display, BufferType::UniformBuffer,
	//                                                              4 * 32, BufferMode::Dynamic).unwrap();
	//let buffer = UniformBuffer::new(&display, view_matrix_block_data).unwrap();
	/*
	let mut buffer: glium::uniforms::UniformBuffer<ViewMatrixBlockData> =
              glium::uniforms::UniformBuffer::empty_unsized(&display, 32).unwrap();
              */
	// you can then write to it like you normally would
	//buffer.map().projection[0] = projection_matrix_array[0];
	//let mut buffer = glium::uniforms::UniformBuffer::new(&display, 4 * 32).unwrap();

	/*
	let mut buffer: glium::uniforms::UniformBuffer::<ViewMatrixBlockData> =
              glium::uniforms::UniformBuffer::new(&display, ViewMatrixBlockData {
		projection: projection_matrix_array,
		modelview: modelview_matrix_array,
	}).unwrap();
	*/

	/*
	let buffer = match glium::uniforms::UniformBuffer::new(&display,
		ViewMatrixBlockData {
				projection: projection_matrix_array,
				modelview: modelview_matrix_array,
			}
		) {
        Err(_) => return,
        Ok(b) => b
    };
    */
    /*
	    let mut buffer = match glium::uniforms::UniformBuffer::<ViewMatrixBlockData>::empty_unsized(&display, 4 * 32) {
        Err(_) => return,
        Ok(b) => b
    }; */

	// 2nd way to map uniform buffer data to local memory
	//let mut mapping = buffer.map();
     //   mapping.projection = projection_matrix_array;
	//*mapping.modelview[0] = modelview_matrix_array[0]<commit_msg>removed commented efforts that were not working correctly from renderer.rs<commit_after>// Copyright(C) 2016 Chris Liebert
extern crate glium;
extern crate nalgebra;

use common::Vertex8f32;
implement_vertex!(Vertex8f32, position, normal, texcoord);
<|endoftext|>


<commit_before>use bullet;
use character;
use critter::CharacterSprite;
use gfx;
use gfx_app::{ColorFormat, DepthFormat};
use gfx_app::renderer::EncoderQueue;
use graphics::{DeltaTime, orientation::Stance};
use graphics::Drawables;
use hud;
use hud::TextDrawable;
use specs;
use specs::prelude::{ReadStorage, Read, WriteStorage};
use std::time::Instant;
use terrain;
use terrain_object;
use terrain_object::TerrainTexture;
use zombie;

pub struct DrawSystem<D: gfx::Device> {
  render_target_view: gfx::handle::RenderTargetView<D::Resources, ColorFormat>,
  depth_stencil_view: gfx::handle::DepthStencilView<D::Resources, DepthFormat>,
  terrain_system: terrain::TerrainDrawSystem<D::Resources>,
  character_system: character::CharacterDrawSystem<D::Resources>,
  zombie_system: zombie::ZombieDrawSystem<D::Resources>,
  bullet_system: bullet::BulletDrawSystem<D::Resources>,
  terrain_object_system: [terrain_object::TerrainObjectDrawSystem<D::Resources>; 2],
  text_system: hud::TextDrawSystem<D::Resources>,
  encoder_queue: EncoderQueue<D>,
  game_time: Instant,
  frames: u32,
  cool_down: f64,
  fire_cool_down: f64,
}

impl<D: gfx::Device> DrawSystem<D> {
  pub fn new<F>(factory: &mut F,
                rtv: &gfx::handle::RenderTargetView<D::Resources, ColorFormat>,
                dsv: &gfx::handle::DepthStencilView<D::Resources, DepthFormat>,
                encoder_queue: EncoderQueue<D>)
                -> DrawSystem<D>
                where F: gfx::Factory<D::Resources> {
    DrawSystem {
      render_target_view: rtv.clone(),
      depth_stencil_view: dsv.clone(),
      terrain_system: terrain::TerrainDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      character_system: character::CharacterDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      zombie_system: zombie::ZombieDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      bullet_system: bullet::BulletDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      terrain_object_system: [
        terrain_object::TerrainObjectDrawSystem::new(factory, rtv.clone(), dsv.clone(), TerrainTexture::House),
        terrain_object::TerrainObjectDrawSystem::new(factory, rtv.clone(), dsv.clone(), TerrainTexture::Tree)
      ],
      text_system: hud::TextDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      encoder_queue,
      game_time: Instant::now(),
      frames: 0,
      cool_down: 1.0,
      fire_cool_down: 1.0,
    }
  }
}

impl<'a, D> specs::prelude::System<'a> for DrawSystem<D>
  where D: gfx::Device,
        D::CommandBuffer: Send {
  #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
  type SystemData = (WriteStorage<'a, terrain::TerrainDrawable>,
                     WriteStorage<'a, character::CharacterDrawable>,
                     WriteStorage<'a, CharacterSprite>,
                     ReadStorage<'a, TextDrawable>,
                     WriteStorage<'a, zombie::zombies::Zombies>,
                     WriteStorage<'a, bullet::bullets::Bullets>,
                     WriteStorage<'a, terrain_object::terrain_objects::TerrainObjects>,
                     Read<'a, DeltaTime>);

  fn run(&mut self, (mut terrain, mut character, mut character_sprite, text, mut zombies, mut bullets, mut terrain_objects, d): Self::SystemData) {
    use specs::join::Join;
    let mut encoder = self.encoder_queue.receiver.recv().unwrap();

    let delta = d.0;

    if self.cool_down == 0.0 {
      self.cool_down += 0.1;
    }
    if self.fire_cool_down == 0.0 {
      self.fire_cool_down += 0.2;
    }
    self.cool_down = (self.cool_down - delta).max(0.0);
    self.fire_cool_down = (self.fire_cool_down - delta).max(0.0);

    let current_time = Instant::now();
    self.frames += 1;
    if cfg!(feature = "framerate") && (current_time.duration_since(self.game_time).as_secs()) >= 1 {
      println!("{:?} ms/frames", 1000.0 / f64::from(self.frames));
      self.frames = 0;
      self.game_time = Instant::now();
    }

    encoder.clear(&self.render_target_view, [16.0 / 256.0, 16.0 / 256.0, 20.0 / 256.0, 1.0]);
    encoder.clear_depth(&self.depth_stencil_view, 1.0);

    for (t, c, cs, tx, zs, bs, obj) in (&mut terrain, &mut character, &mut character_sprite, &text, &mut zombies, &mut bullets, &mut terrain_objects).join() {
      self.terrain_system.draw(t, &mut encoder);

      self.text_system.draw(tx, &mut encoder);

      if self.cool_down == 0.0 {
        if c.stance == Stance::Walking {
          cs.update_run();
        }
        for mut z in &mut zs.zombies {
          match z.stance {
            Stance::NormalDeath => z.update_death_idx(5),
            Stance::CriticalDeath => z.update_death_idx(7),
            Stance::Walking => z.update_alive_idx(7),
            Stance::Still => z.update_alive_idx(3),
            _ => ()
          };
        }
      } else if self.fire_cool_down == 0.0 && c.stance == Stance::Firing {
        cs.update_fire();
      }
      let mut drawables: Vec<Drawables> = vec![];
      drawables.append(&mut bs.bullets.iter().map(|b| Drawables::Bullet(b.clone())).collect());
      drawables.append(&mut zs.zombies.iter().map(|z| Drawables::Zombie(z.clone())).collect());

      for (idx, o) in obj.objects.iter().enumerate() {
        if idx < 2 {
          drawables.push(Drawables::TerrainHouse(o.clone()));
        } else {
          drawables.push(Drawables::TerrainTree(o.clone()));
        }
      }

      drawables.push(Drawables::Character(c.clone()));

      drawables.sort_by(|a, b| {
        let a_val = match *a {
          Drawables::Bullet(ref e) => e.position.position[1],
          Drawables::Zombie(ref e) => e.position.position[1],
          Drawables::TerrainHouse(ref e) => e.position.position[1],
          Drawables::TerrainTree(ref e) => e.position.position[1],
          Drawables::Character(ref e) => e.position.position[1],
        };

        let b_val = match *b {
          Drawables::Bullet(ref e) => e.position.position[1],
          Drawables::Zombie(ref e) => e.position.position[1],
          Drawables::TerrainHouse(ref e) => e.position.position[1],
          Drawables::TerrainTree(ref e) => e.position.position[1],
          Drawables::Character(ref e) => e.position.position[1],
        };

        b_val.partial_cmp(&a_val).unwrap()
      });

      for mut e in &mut drawables {
        match *e {
          Drawables::Bullet(ref e) => { self.bullet_system.draw(e, &mut encoder) },
          Drawables::Zombie(ref mut e) => { self.zombie_system.draw(e, &mut encoder) },
          Drawables::TerrainHouse(ref mut e) => { self.terrain_object_system[0].draw(e, &mut encoder) },
          Drawables::TerrainTree(ref mut e) => { self.terrain_object_system[1].draw(e, &mut encoder) },
          Drawables::Character(ref mut e) => { self.character_system.draw(e, cs, &mut encoder) },
        }
      }
    }

    if let Err(e) = self.encoder_queue.sender.send(encoder) {
      panic!("Disconnected, cannot return encoder to mpsc: {}", e);
    };
  }
}
<commit_msg>Refactor render order code<commit_after>use bullet;
use character;
use critter::CharacterSprite;
use gfx;
use gfx_app::{ColorFormat, DepthFormat};
use gfx_app::renderer::EncoderQueue;
use graphics::{DeltaTime, orientation::Stance};
use graphics::Drawables;
use hud;
use hud::TextDrawable;
use specs;
use specs::prelude::{ReadStorage, Read, WriteStorage};
use std::time::Instant;
use terrain;
use terrain_object;
use terrain_object::TerrainTexture;
use zombie;

pub struct DrawSystem<D: gfx::Device> {
  render_target_view: gfx::handle::RenderTargetView<D::Resources, ColorFormat>,
  depth_stencil_view: gfx::handle::DepthStencilView<D::Resources, DepthFormat>,
  terrain_system: terrain::TerrainDrawSystem<D::Resources>,
  character_system: character::CharacterDrawSystem<D::Resources>,
  zombie_system: zombie::ZombieDrawSystem<D::Resources>,
  bullet_system: bullet::BulletDrawSystem<D::Resources>,
  terrain_object_system: [terrain_object::TerrainObjectDrawSystem<D::Resources>; 2],
  text_system: hud::TextDrawSystem<D::Resources>,
  encoder_queue: EncoderQueue<D>,
  game_time: Instant,
  frames: u32,
  cool_down: f64,
  fire_cool_down: f64,
}

impl<D: gfx::Device> DrawSystem<D> {
  pub fn new<F>(factory: &mut F,
                rtv: &gfx::handle::RenderTargetView<D::Resources, ColorFormat>,
                dsv: &gfx::handle::DepthStencilView<D::Resources, DepthFormat>,
                encoder_queue: EncoderQueue<D>)
                -> DrawSystem<D>
                where F: gfx::Factory<D::Resources> {
    DrawSystem {
      render_target_view: rtv.clone(),
      depth_stencil_view: dsv.clone(),
      terrain_system: terrain::TerrainDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      character_system: character::CharacterDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      zombie_system: zombie::ZombieDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      bullet_system: bullet::BulletDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      terrain_object_system: [
        terrain_object::TerrainObjectDrawSystem::new(factory, rtv.clone(), dsv.clone(), TerrainTexture::House),
        terrain_object::TerrainObjectDrawSystem::new(factory, rtv.clone(), dsv.clone(), TerrainTexture::Tree)
      ],
      text_system: hud::TextDrawSystem::new(factory, rtv.clone(), dsv.clone()),
      encoder_queue,
      game_time: Instant::now(),
      frames: 0,
      cool_down: 1.0,
      fire_cool_down: 1.0,
    }
  }
}

impl<'a, D> specs::prelude::System<'a> for DrawSystem<D>
  where D: gfx::Device,
        D::CommandBuffer: Send {
  #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
  type SystemData = (WriteStorage<'a, terrain::TerrainDrawable>,
                     WriteStorage<'a, character::CharacterDrawable>,
                     WriteStorage<'a, CharacterSprite>,
                     ReadStorage<'a, TextDrawable>,
                     WriteStorage<'a, zombie::zombies::Zombies>,
                     WriteStorage<'a, bullet::bullets::Bullets>,
                     WriteStorage<'a, terrain_object::terrain_objects::TerrainObjects>,
                     Read<'a, DeltaTime>);

  fn run(&mut self, (mut terrain, mut character, mut character_sprite, text, mut zombies, mut bullets, mut terrain_objects, d): Self::SystemData) {
    use specs::join::Join;
    let mut encoder = self.encoder_queue.receiver.recv().unwrap();

    let delta = d.0;

    if self.cool_down == 0.0 {
      self.cool_down += 0.1;
    }
    if self.fire_cool_down == 0.0 {
      self.fire_cool_down += 0.2;
    }
    self.cool_down = (self.cool_down - delta).max(0.0);
    self.fire_cool_down = (self.fire_cool_down - delta).max(0.0);

    let current_time = Instant::now();
    self.frames += 1;
    if cfg!(feature = "framerate") && (current_time.duration_since(self.game_time).as_secs()) >= 1 {
      println!("{:?} ms/frames", 1000.0 / f64::from(self.frames));
      self.frames = 0;
      self.game_time = Instant::now();
    }

    encoder.clear(&self.render_target_view, [16.0 / 256.0, 16.0 / 256.0, 20.0 / 256.0, 1.0]);
    encoder.clear_depth(&self.depth_stencil_view, 1.0);

    for (t, c, cs, tx, zs, bs, obj) in (&mut terrain, &mut character, &mut character_sprite, &text, &mut zombies, &mut bullets, &mut terrain_objects).join() {
      self.terrain_system.draw(t, &mut encoder);

      self.text_system.draw(tx, &mut encoder);

      if self.cool_down == 0.0 {
        if c.stance == Stance::Walking {
          cs.update_run();
        }
        for mut z in &mut zs.zombies {
          match z.stance {
            Stance::NormalDeath => z.update_death_idx(5),
            Stance::CriticalDeath => z.update_death_idx(7),
            Stance::Walking => z.update_alive_idx(7),
            Stance::Still => z.update_alive_idx(3),
            _ => ()
          };
        }
      } else if self.fire_cool_down == 0.0 && c.stance == Stance::Firing {
        cs.update_fire();
      }
      let mut drawables: Vec<Drawables> = vec![];
      drawables.append(&mut bs.bullets.iter().map(|b| Drawables::Bullet(b.clone())).collect());
      drawables.append(&mut zs.zombies.iter().map(|z| Drawables::Zombie(z.clone())).collect());

      for (idx, o) in obj.objects.iter().enumerate() {
        if idx < 2 {
          drawables.push(Drawables::TerrainHouse(o.clone()));
        } else {
          drawables.push(Drawables::TerrainTree(o.clone()));
        }
      }

      drawables.push(Drawables::Character(c.clone()));

      drawables.sort_by(|a, b| {
        let a_val = match a {
          Drawables::Bullet(e) => e.position.position[1],
          Drawables::Zombie(e) => e.position.position[1],
          Drawables::TerrainHouse(e) => e.position.position[1],
          Drawables::TerrainTree(e) => e.position.position[1],
          Drawables::Character(e) => e.position.position[1],
        };

        let b_val = match b {
          Drawables::Bullet(e) => e.position.position[1],
          Drawables::Zombie(e) => e.position.position[1],
          Drawables::TerrainHouse(e) => e.position.position[1],
          Drawables::TerrainTree(e) => e.position.position[1],
          Drawables::Character(e) => e.position.position[1],
        };

        b_val.partial_cmp(&a_val).unwrap()
      });

      for mut e in &mut drawables {
        match *e {
          Drawables::Bullet(ref e) => { self.bullet_system.draw(e, &mut encoder) },
          Drawables::Zombie(ref mut e) => { self.zombie_system.draw(e, &mut encoder) },
          Drawables::TerrainHouse(ref mut e) => { self.terrain_object_system[0].draw(e, &mut encoder) },
          Drawables::TerrainTree(ref mut e) => { self.terrain_object_system[1].draw(e, &mut encoder) },
          Drawables::Character(ref mut e) => { self.character_system.draw(e, cs, &mut encoder) },
        }
      }
    }

    if let Err(e) = self.encoder_queue.sender.send(encoder) {
      panic!("Disconnected, cannot return encoder to mpsc: {}", e);
    };
  }
}
<|endoftext|>


<commit_before>#[derive(Clone, Debug)]
pub struct URIBase {
    base_uri: String,
    port: u16,
}

impl Default for URIBase {
    fn default() -> URIBase {
        URIBase {
            base_uri: "localhost".to_string(),
            port: 10041,
        }
    }
}

impl URIBase {
    ///
    /// Create URIBase struct.
    ///
    /// Default values are:
    ///
    ///   base_uri: "localhost"
    ///
    ///   port: 10041
    ///
    pub fn new() -> URIBase {
        let default: URIBase = Default::default();
        default
    }

    /// Set base to replace default value with specified value.
    pub fn base_uri(mut self, base_uri: String) -> URIBase {
        self.base_uri = base_uri;
        self
    }

    /// Set port number to replace default value with specified value.
    pub fn port(mut self, port: u16) -> URIBase {
        self.port = port;
        self
    }

    /// Build and get base uri.
    pub fn build(self) -> String {
        format!("http://{}:{}", self.base_uri, self.port)
    }
}

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

    #[test]
    fn construct_uri_default() {
        let uri_base = URIBase::new().build();
        assert_eq!("http://localhost:10041", uri_base)
    }

    #[test]
    fn build_only_uri_base() {
        let uri_base = URIBase::new()
            .base_uri("127.0.0.1".to_string())
            .build();
        assert_eq!("http://127.0.0.1:10041", uri_base);
    }

    #[test]
    fn build_only_port() {
        let uri_base = URIBase::new().port(10042).build();
        assert_eq!("http://localhost:10042", uri_base);
    }

    #[test]
    fn uri_with_builder() {
        let uri_base = URIBase::new()
            .base_uri("127.0.1.1".to_string())
            .port(10043)
            .build();
        assert_eq!("http://127.0.1.1:10043", uri_base)
    }

}
<commit_msg>uri_base: Use Cow to reduce allocation<commit_after>use std::borrow::Cow;

#[derive(Clone, Debug)]
pub struct URIBase<'a> {
    base_uri: Cow<'a, str>,
    port: u16,
}

impl<'a> Default for URIBase<'a> {
    fn default() -> URIBase<'a> {
        URIBase {
            base_uri: "localhost".into(),
            port: 10041,
        }
    }
}

impl<'a> URIBase<'a> {
    ///
    /// Create URIBase struct.
    ///
    /// Default values are:
    ///
    ///   base_uri: "localhost"
    ///
    ///   port: 10041
    ///
    pub fn new() -> URIBase<'a> {
        URIBase::default()
    }

    /// Set base to replace default value with specified value.
    pub fn base_uri<T>(mut self, base_uri: T) -> URIBase<'a>
        where T: Into<Cow<'a, str>>
    {
        self.base_uri = base_uri.into();
        self
    }

    /// Set port number to replace default value with specified value.
    pub fn port(mut self, port: u16) -> URIBase<'a> {
        self.port = port;
        self
    }

    /// Build and get base uri.
    pub fn build(self) -> String {
        format!("http://{}:{}", self.base_uri.into_owned(), self.port)
    }
}

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

    #[test]
    fn construct_uri_default() {
        let uri_base = URIBase::new().build();
        assert_eq!("http://localhost:10041", uri_base)
    }

    #[test]
    fn build_only_uri_base() {
        let uri_base = URIBase::new()
            .base_uri("127.0.0.1")
            .build();
        assert_eq!("http://127.0.0.1:10041", uri_base);
    }

    #[test]
    fn build_only_uri_base_with_owned_str() {
        let uri_base = URIBase::new()
            .base_uri("127.0.0.1".to_owned())
            .build();
        assert_eq!("http://127.0.0.1:10041", uri_base);
    }

    #[test]
    fn build_only_port() {
        let uri_base = URIBase::new().port(10042).build();
        assert_eq!("http://localhost:10042", uri_base);
    }

    #[test]
    fn uri_with_builder() {
        let uri_base = URIBase::new()
            .base_uri("127.0.1.1".to_string())
            .port(10043)
            .build();
        assert_eq!("http://127.0.1.1:10043", uri_base)
    }

}
<|endoftext|>