<commit_before>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [Postcard]: https://github.com/jamesmunns/postcard
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.101")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // not available in our oldest supported compiler
        checked_conversions,
        empty_enum,
        redundant_field_names,
        redundant_static_lifetimes,
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_sign_loss,
        // things are often more readable this way
        cast_lossless,
        module_name_repetitions,
        single_match_else,
        type_complexity,
        use_self,
        zero_prefixed_literal,
        // not practical
        needless_pass_by_value,
        similar_names,
        too_many_lines,
        // preference
        doc_markdown,
    )
)]
// Rustc lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::{String, ToString};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(all(feature = "std", collections_bound))]
    pub use std::collections::Bound;

    #[cfg(core_reverse)]
    pub use self::core::cmp::Reverse;

    #[cfg(ops_bound)]
    pub use self::core::ops::Bound;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;

    #[cfg(all(feature = "std", std_atomic))]
    pub use std::sync::atomic::{
        AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
        AtomicUsize, Ordering,
    };
    #[cfg(all(feature = "std", std_atomic64))]
    pub use std::sync::atomic::{AtomicI64, AtomicU64};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

#[cfg(not(feature = "std"))]
mod std_error;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<commit_msg>Ignore needless_doctest_main lint<commit_after>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [Postcard]: https://github.com/jamesmunns/postcard
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.101")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // not available in our oldest supported compiler
        checked_conversions,
        empty_enum,
        redundant_field_names,
        redundant_static_lifetimes,
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_sign_loss,
        // things are often more readable this way
        cast_lossless,
        module_name_repetitions,
        single_match_else,
        type_complexity,
        use_self,
        zero_prefixed_literal,
        // not practical
        needless_pass_by_value,
        similar_names,
        too_many_lines,
        // preference
        doc_markdown,
        // false positive
        needless_doctest_main,
    )
)]
// Rustc lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::{String, ToString};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(all(feature = "std", collections_bound))]
    pub use std::collections::Bound;

    #[cfg(core_reverse)]
    pub use self::core::cmp::Reverse;

    #[cfg(ops_bound)]
    pub use self::core::ops::Bound;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;

    #[cfg(all(feature = "std", std_atomic))]
    pub use std::sync::atomic::{
        AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
        AtomicUsize, Ordering,
    };
    #[cfg(all(feature = "std", std_atomic64))]
    pub use std::sync::atomic::{AtomicI64, AtomicU64};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

#[cfg(not(feature = "std"))]
mod std_error;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<|endoftext|>


<commit_before>use std::io;
use futures::{Future, Stream};
use futures::future::{err, ok};
use serde_json;
use model::{RegisterRequest, Instance};
use errors::EurekaClientError;
use hyper::{Client, Method, Request, Body, Uri, mime, Error as HyperError, StatusCode};
use hyper::header::{Accept, AcceptEncoding, Encoding, Headers, UserAgent, ContentType, ContentLength, qitem};
use tokio_core::reactor::Handle;

pub struct EurekaClient<'a> {
    handle: &'a Handle,
    client_name: String,
    eureka_cluster_url: String,
}

//
// A simple port of the example found at: https://github.com/Netflix/eureka/wiki/Example-Custom-ReadOnly-client
// Eureka REST API: https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
impl<'a> EurekaClient<'a> {
    pub fn new(handle: &'a Handle, client_name: &str, eureka_cluster_url: &str) -> EurekaClient<'a> {
        debug!("Creating new Eureka Client client_name:{:?}, eureka_client:{:?}", client_name, eureka_cluster_url);
        EurekaClient {
            handle: &handle,
            client_name: client_name.to_owned(),
            eureka_cluster_url: eureka_cluster_url.to_owned()
        }
    }

    pub fn register(&self, application_id: &str, register_request: &RegisterRequest) -> Box<Future<Item=(), Error=EurekaClientError>> {
        debug!("register: application_id={:?}, register_request:{:?}", application_id, register_request);
        let client = Client::new(self.handle);
        let path = "/v2/apps/".to_owned() + application_id;
        let mut req: Request<Body> = Request::new(Method::Post, self.build_uri(path.as_ref()));
        self.set_headers(req.headers_mut());

        let json = serde_json::to_string(register_request).unwrap();
        req.headers_mut().set(ContentLength(json.len() as u64));
        req.set_body(json);

        let result = client.request(req)
            .map_err(|e| {
                EurekaClientError::from(e)
            })
            .and_then(|res| {
                debug!("register: server response {:?}", res);

                let status = res.status();
                match status {
                    StatusCode::BadRequest => Err(EurekaClientError::BadRequest),
                    StatusCode::InternalServerError => Err(EurekaClientError::InternalServerError),
                    _ => Ok(())
                }
            });
        Box::new(result)
    }

    pub fn get_application_instances<'b>(&self, application_id: &str) -> Box<Future<Item=Vec<Instance>, Error=EurekaClientError>> {

        // Since it was hard to coerce the errot type into a EurekaClientError
        // I set the result in a holder then map result into an error or ok
        // There has to be a better way.. but this works.
        enum IntermediateResult {
            Ok(Vec<Instance>),
            Err(EurekaClientError)
        }
        impl IntermediateResult {
            fn ok(vec: Vec<Instance>) -> IntermediateResult {
                IntermediateResult::Ok(vec)
            }
            fn err(err: EurekaClientError) -> IntermediateResult {
                IntermediateResult::Err(err)
            }
        }

        let client = Client::new(self.handle);
        let path = "/v2/apps/".to_owned() + application_id;
        let mut req: Request<Body> = Request::new(Method::Get, self.build_uri(path.as_ref()));
        self.set_headers(req.headers_mut());

        let result = client.request(req).and_then(|res| {
            let status = res.status();
            debug!("get_application_instance: server response status: {}", status);
            res.body().concat2().and_then(move |body| {
                match status {
                    StatusCode::NotFound => Ok(IntermediateResult::err(EurekaClientError::NotFound)),
                    _ => {
                        serde_json::from_slice::<Vec<Instance>>(&body).map_err(|e| {
                            HyperError::Io(io::Error::new(io::ErrorKind::Other, e))
                        })
                        .map(|r| IntermediateResult::ok(r))
                    }
                }
            })
        })
        .map_err(|e| {
            EurekaClientError::from(e)
        })
        .and_then(|ir| {
            // now that we have changed the error to EurekaClientError
            // we can map our err back in
            match ir {
                IntermediateResult::Ok(vec) => Ok(vec),
                IntermediateResult::Err(err) => Err(err)
            }
        });
        Box::new(result)
    }

    fn build_uri(&self, path: &str) -> Uri {
        (self.eureka_cluster_url.to_owned() + path).parse().unwrap()
    }

    fn set_headers(&self, headers: &mut Headers) {
        headers.set(AcceptEncoding(vec![qitem(Encoding::Gzip)]));
        headers.set(Accept(vec![qitem(mime::APPLICATION_JSON)]));
        headers.set(ContentType(mime::APPLICATION_JSON));
        let user_agent = "Rust Hyper/".to_string() + self.client_name.as_ref();
        headers.set(UserAgent::new(user_agent));
    }
}
<commit_msg>A little bit of cleanup.<commit_after>use std::io;
use futures::{Future, Stream};
use serde_json;
use model::{RegisterRequest, Instance};
use errors::EurekaClientError;
use hyper::{Client, Method, Request, Body, Uri, mime, Error as HyperError, StatusCode};
use hyper::header::{Accept, AcceptEncoding, Encoding, Headers, UserAgent, ContentType, ContentLength, qitem};
use tokio_core::reactor::Handle;

pub struct EurekaClient<'a> {
    handle: &'a Handle,
    client_name: String,
    eureka_cluster_url: String,
}

//
// A simple port of the example found at: https://github.com/Netflix/eureka/wiki/Example-Custom-ReadOnly-client
// Eureka REST API: https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
impl<'a> EurekaClient<'a> {
    pub fn new(handle: &'a Handle, client_name: &str, eureka_cluster_url: &str) -> EurekaClient<'a> {
        debug!("Creating new Eureka Client client_name:{:?}, eureka_client:{:?}", client_name, eureka_cluster_url);
        EurekaClient {
            handle: &handle,
            client_name: client_name.to_owned(),
            eureka_cluster_url: eureka_cluster_url.to_owned()
        }
    }

    pub fn register(&self, application_id: &str, register_request: &RegisterRequest) -> Box<Future<Item=(), Error=EurekaClientError>> {
        debug!("register: application_id={:?}, register_request:{:?}", application_id, register_request);
        let client = Client::new(self.handle);
        let path = "/v2/apps/".to_owned() + application_id;
        let mut req: Request<Body> = Request::new(Method::Post, self.build_uri(path.as_ref()));
        self.set_headers(req.headers_mut());

        let json = serde_json::to_string(register_request).unwrap();
        req.headers_mut().set(ContentLength(json.len() as u64));
        req.set_body(json);

        let result = client.request(req)
            .map_err(|e| {
                EurekaClientError::from(e)
            })
            .and_then(|res| {
                debug!("register: server response {:?}", res);

                let status = res.status();
                match status {
                    StatusCode::BadRequest => Err(EurekaClientError::BadRequest),
                    StatusCode::InternalServerError => Err(EurekaClientError::InternalServerError),
                    _ => Ok(())
                }
            });
        Box::new(result)
    }

    pub fn get_application_instances<'b>(&self, application_id: &str) -> Box<Future<Item=Vec<Instance>, Error=EurekaClientError>> {

        // Since it was hard to coerce the errot type into a EurekaClientError
        // I set the result in a holder then map result into an error or ok
        // There has to be a better way.. but this works.
        enum IntermediateResult {
            Ok(Vec<Instance>),
            Err(EurekaClientError)
        }

        let client = Client::new(self.handle);
        let path = "/v2/apps/".to_owned() + application_id;
        let mut req: Request<Body> = Request::new(Method::Get, self.build_uri(path.as_ref()));
        self.set_headers(req.headers_mut());

        let result = client.request(req).and_then(|res| {
            let status = res.status();
            debug!("get_application_instance: server response status: {}", status);
            res.body().concat2().and_then(move |body| {
                match status {
                    StatusCode::NotFound => Ok(IntermediateResult::Err(EurekaClientError::NotFound)),
                    _ => {
                        serde_json::from_slice::<Vec<Instance>>(&body).map_err(|e| {
                            HyperError::Io(io::Error::new(io::ErrorKind::Other, e))
                        })
                        .map(|r| IntermediateResult::Ok(r))
                    }
                }
            })
        })
        .map_err(|e| {
            EurekaClientError::from(e)
        })
        .and_then(|ir| {
            // now that we have changed the error to EurekaClientError
            // we can map our err back in
            match ir {
                IntermediateResult::Ok(vec) => Ok(vec),
                IntermediateResult::Err(err) => Err(err)
            }
        });
        Box::new(result)
    }

    fn build_uri(&self, path: &str) -> Uri {
        (self.eureka_cluster_url.to_owned() + path).parse().unwrap()
    }

    fn set_headers(&self, headers: &mut Headers) {
        headers.set(AcceptEncoding(vec![qitem(Encoding::Gzip)]));
        headers.set(Accept(vec![qitem(mime::APPLICATION_JSON)]));
        headers.set(ContentType(mime::APPLICATION_JSON));
        let user_agent = "Rust Hyper/".to_string() + self.client_name.as_ref();
        headers.set(UserAgent::new(user_agent));
    }
}
<|endoftext|>


<commit_before>use crate::convert::*;
use crate::operations::folded_multiply;
#[cfg(feature = "specialize")]
use crate::HasherExt;
use core::hash::Hasher;
use crate::RandomState;
use crate::random_state::PI;

///This constant come from Kunth's prng (Empirically it works better than those from splitmix32).
pub(crate) const MULTIPLE: u64 = 6364136223846793005;
const ROT: u32 = 23; //17

/// A `Hasher` for hashing an arbitrary stream of bytes.
///
/// Instances of [`AHasher`] represent state that is updated while hashing data.
///
/// Each method updates the internal state based on the new data provided. Once
/// all of the data has been provided, the resulting hash can be obtained by calling
/// `finish()`
///
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
/// start with the same data.
///
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: u64,
    pad: u64,
    extra_keys: [u64; 2],
}

impl AHasher {
    /// Creates a new hasher keyed to the provided key.
    #[inline]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub fn new_with_keys(key1: u128, key2: u128) -> AHasher {
        let pi: [u128; 2] = PI.convert();
        let key1: [u64; 2] = (key1 ^ pi[0]).convert();
        let key2: [u64; 2] = (key2 ^ pi[1]).convert();
        AHasher {
            buffer: key1[0],
            pad: key1[1],
            extra_keys: key2,
        }
    }

    #[inline]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub(crate) fn from_random_state(rand_state: &RandomState) -> AHasher  {
        AHasher {
            buffer: rand_state.k0,
            pad: rand_state.k1,
            extra_keys: [rand_state.k2, rand_state.k3],
        }
    }

    /// This update function has the goal of updating the buffer with a single multiply
    /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an
    /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable
    /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily
    /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the
    /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a
    /// subsequent update that also differed in this bit could result in a predictable collision.
    ///
    /// This version avoids this vulnerability while still only using a single multiply. It takes advantage
    /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown
    /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them.
    /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly)
    /// Then the upper bits are xored with the lower bits to produce a single 64 bit result.
    ///
    /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs:
    /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator
    /// If the multiple is chosen well, this creates a long period, decent quality PRNG.
    /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each
    /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG.
    ///
    /// This is impervious to attack because every bit buffer at the end is dependent on every bit in
    /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the
    /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by
    /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the
    /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in
    /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every
    /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an
    /// attacker somehow knew part of (but not all) the contents of the buffer before hand,
    /// they would not be able to predict any of the bits in the buffer at the end.
    #[inline(always)]
    fn update(&mut self, new_data: u64) {
        self.buffer = folded_multiply(new_data ^ self.buffer, MULTIPLE);
    }

    /// Similar to the above this function performs an update using a "folded multiply".
    /// However it takes in 128 bits of data instead of 64. Both halves must be masked.
    ///
    /// This makes it impossible for an attacker to place a single bit difference between
    /// two blocks so as to cancel each other.
    ///
    /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must
    /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used.
    /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits
    /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require
    /// knowing the keys.
    #[inline(always)]
    fn large_update(&mut self, new_data: u128) {
        let block: [u64; 2] = new_data.convert();
        let combined = folded_multiply(block[0] ^ self.extra_keys[0], block[1] ^ self.extra_keys[1]);
        self.buffer = (combined.wrapping_add(self.buffer) ^ self.pad).rotate_left(ROT);
    }
}

#[cfg(feature = "specialize")]
impl HasherExt for AHasher {
    #[inline]
    fn hash_u64(self, value: u64) -> u64 {
        let rot = (self.pad & 64) as u32;
        folded_multiply(value ^ self.buffer, MULTIPLE).rotate_left(rot)
    }

    #[inline]
    fn short_finish(&self) -> u64 {
        self.buffer.wrapping_add(self.pad)
    }
}

/// Provides [Hasher] methods to hash all of the primitive types.
///
/// [Hasher]: core::hash::Hasher
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        self.large_update(i);
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    #[allow(clippy::collapsible_if)]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let length = data.len() as u64;
        //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input.
        self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE);
        //A 'binary search' on sizes reduces the number of comparisons.
        if data.len() > 8 {
            if data.len() > 16 {
                let tail = data.read_last_u128();
                self.large_update(tail);
                while data.len() > 16 {
                    let (block, rest) = data.read_u128();
                    self.large_update(block);
                    data = rest;
                }
            } else {
                self.large_update([data.read_u64().0, data.read_last_u64()].convert());
            }
        } else {
            if data.len() >= 2 {
                if data.len() >= 4 {
                    let block = [data.read_u32().0 as u64, data.read_last_u32() as u64];
                    self.large_update(block.convert());
                } else {
                    let value = [data.read_u16().0 as u32, data[data.len() - 1] as u32];
                    self.update(value.convert());
                }
            } else {
                if data.len() > 0 {
                    self.update(data[0] as u64);
                }
            }
        }
    }
    #[inline]
    fn finish(&self) -> u64 {
        let rot = (self.buffer & 63) as u32;
        folded_multiply(self.buffer ^ self.pad, MULTIPLE).rotate_left(rot)
    }
}

#[cfg(test)]
mod tests {
    use crate::convert::Convert;
    use crate::fallback_hash::*;

    #[test]
    fn test_hash() {
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value: u64 = 1 << 32;
        hasher.update(value);
        let result = hasher.buffer;
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value2: u64 = 1;
        hasher.update(value2);
        let result2 = hasher.buffer;
        let result: [u8; 8] = result.convert();
        let result2: [u8; 8] = result2.convert();
        assert_ne!(hex::encode(result), hex::encode(result2));
    }

    #[test]
    fn test_conversion() {
        let input: &[u8] = "dddddddd".as_bytes();
        let bytes: u64 = as_array!(input, 8).convert();
        assert_eq!(bytes, 0x6464646464646464);
    }
}
<commit_msg>Restore faster finish<commit_after>use crate::convert::*;
use crate::operations::folded_multiply;
#[cfg(feature = "specialize")]
use crate::HasherExt;
use core::hash::Hasher;
use crate::RandomState;
use crate::random_state::PI;

///This constant come from Kunth's prng (Empirically it works better than those from splitmix32).
pub(crate) const MULTIPLE: u64 = 6364136223846793005;
const ROT: u32 = 23; //17

/// A `Hasher` for hashing an arbitrary stream of bytes.
///
/// Instances of [`AHasher`] represent state that is updated while hashing data.
///
/// Each method updates the internal state based on the new data provided. Once
/// all of the data has been provided, the resulting hash can be obtained by calling
/// `finish()`
///
/// [Clone] is also provided in case you wish to calculate hashes for two different items that
/// start with the same data.
///
#[derive(Debug, Clone)]
pub struct AHasher {
    buffer: u64,
    pad: u64,
    extra_keys: [u64; 2],
}

impl AHasher {
    /// Creates a new hasher keyed to the provided key.
    #[inline]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub fn new_with_keys(key1: u128, key2: u128) -> AHasher {
        let pi: [u128; 2] = PI.convert();
        let key1: [u64; 2] = (key1 ^ pi[0]).convert();
        let key2: [u64; 2] = (key2 ^ pi[1]).convert();
        AHasher {
            buffer: key1[0],
            pad: key1[1],
            extra_keys: key2,
        }
    }

    #[inline]
    #[allow(dead_code)] // Is not called if non-fallback hash is used.
    pub(crate) fn from_random_state(rand_state: &RandomState) -> AHasher  {
        AHasher {
            buffer: rand_state.k0,
            pad: rand_state.k1,
            extra_keys: [rand_state.k2, rand_state.k3],
        }
    }

    /// This update function has the goal of updating the buffer with a single multiply
    /// FxHash does this but is vulnerable to attack. To avoid this input needs to be masked to with an
    /// unpredictable value. Other hashes such as murmurhash have taken this approach but were found vulnerable
    /// to attack. The attack was based on the idea of reversing the pre-mixing (Which is necessarily
    /// reversible otherwise bits would be lost) then placing a difference in the highest bit before the
    /// multiply used to mix the data. Because a multiply can never affect the bits to the right of it, a
    /// subsequent update that also differed in this bit could result in a predictable collision.
    ///
    /// This version avoids this vulnerability while still only using a single multiply. It takes advantage
    /// of the fact that when a 64 bit multiply is performed the upper 64 bits are usually computed and thrown
    /// away. Instead it creates two 128 bit values where the upper 64 bits are zeros and multiplies them.
    /// (The compiler is smart enough to turn this into a 64 bit multiplication in the assembly)
    /// Then the upper bits are xored with the lower bits to produce a single 64 bit result.
    ///
    /// To understand why this is a good scrambling function it helps to understand multiply-with-carry PRNGs:
    /// https://en.wikipedia.org/wiki/Multiply-with-carry_pseudorandom_number_generator
    /// If the multiple is chosen well, this creates a long period, decent quality PRNG.
    /// Notice that this function is equivalent to this except the `buffer`/`state` is being xored with each
    /// new block of data. In the event that data is all zeros, it is exactly equivalent to a MWC PRNG.
    ///
    /// This is impervious to attack because every bit buffer at the end is dependent on every bit in
    /// `new_data ^ buffer`. For example suppose two inputs differed in only the 5th bit. Then when the
    /// multiplication is performed the `result` will differ in bits 5-69. More specifically it will differ by
    /// 2^5 * MULTIPLE. However in the next step bits 65-128 are turned into a separate 64 bit value. So the
    /// differing bits will be in the lower 6 bits of this value. The two intermediate values that differ in
    /// bits 5-63 and in bits 0-5 respectively get added together. Producing an output that differs in every
    /// bit. The addition carries in the multiplication and at the end additionally mean that the even if an
    /// attacker somehow knew part of (but not all) the contents of the buffer before hand,
    /// they would not be able to predict any of the bits in the buffer at the end.
    #[inline(always)]
    fn update(&mut self, new_data: u64) {
        self.buffer = folded_multiply(new_data ^ self.buffer, MULTIPLE);
    }

    /// Similar to the above this function performs an update using a "folded multiply".
    /// However it takes in 128 bits of data instead of 64. Both halves must be masked.
    ///
    /// This makes it impossible for an attacker to place a single bit difference between
    /// two blocks so as to cancel each other.
    ///
    /// However this is not sufficient. to prevent (a,b) from hashing the same as (b,a) the buffer itself must
    /// be updated between calls in a way that does not commute. To achieve this XOR and Rotate are used.
    /// Add followed by xor is not the same as xor followed by add, and rotate ensures that the same out bits
    /// can't be changed by the same set of input bits. To cancel this sequence with subsequent input would require
    /// knowing the keys.
    #[inline(always)]
    fn large_update(&mut self, new_data: u128) {
        let block: [u64; 2] = new_data.convert();
        let combined = folded_multiply(block[0] ^ self.extra_keys[0], block[1] ^ self.extra_keys[1]);
        self.buffer = (combined.wrapping_add(self.buffer) ^ self.pad).rotate_left(ROT);
    }
}

#[cfg(feature = "specialize")]
impl HasherExt for AHasher {
    #[inline]
    fn hash_u64(self, value: u64) -> u64 {
        let rot = (self.pad & 64) as u32;
        folded_multiply(value ^ self.buffer, MULTIPLE).rotate_left(rot)
    }

    #[inline]
    fn short_finish(&self) -> u64 {
        self.buffer.wrapping_add(self.pad)
    }
}

/// Provides [Hasher] methods to hash all of the primitive types.
///
/// [Hasher]: core::hash::Hasher
impl Hasher for AHasher {
    #[inline]
    fn write_u8(&mut self, i: u8) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u16(&mut self, i: u16) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u32(&mut self, i: u32) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u64(&mut self, i: u64) {
        self.update(i as u64);
    }

    #[inline]
    fn write_u128(&mut self, i: u128) {
        self.large_update(i);
    }

    #[inline]
    fn write_usize(&mut self, i: usize) {
        self.write_u64(i as u64);
    }

    #[inline]
    #[allow(clippy::collapsible_if)]
    fn write(&mut self, input: &[u8]) {
        let mut data = input;
        let length = data.len() as u64;
        //Needs to be an add rather than an xor because otherwise it could be canceled with carefully formed input.
        self.buffer = self.buffer.wrapping_add(length).wrapping_mul(MULTIPLE);
        //A 'binary search' on sizes reduces the number of comparisons.
        if data.len() > 8 {
            if data.len() > 16 {
                let tail = data.read_last_u128();
                self.large_update(tail);
                while data.len() > 16 {
                    let (block, rest) = data.read_u128();
                    self.large_update(block);
                    data = rest;
                }
            } else {
                self.large_update([data.read_u64().0, data.read_last_u64()].convert());
            }
        } else {
            if data.len() >= 2 {
                if data.len() >= 4 {
                    let block = [data.read_u32().0 as u64, data.read_last_u32() as u64];
                    self.large_update(block.convert());
                } else {
                    let value = [data.read_u16().0 as u32, data[data.len() - 1] as u32];
                    self.update(value.convert());
                }
            } else {
                if data.len() > 0 {
                    self.update(data[0] as u64);
                }
            }
        }
    }
    #[inline]
    fn finish(&self) -> u64 {
        let rot = (self.buffer & 63) as u32;
        folded_multiply(self.buffer, self.pad).rotate_left(rot)
    }
}

#[cfg(test)]
mod tests {
    use crate::convert::Convert;
    use crate::fallback_hash::*;

    #[test]
    fn test_hash() {
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value: u64 = 1 << 32;
        hasher.update(value);
        let result = hasher.buffer;
        let mut hasher = AHasher::new_with_keys(0, 0);
        let value2: u64 = 1;
        hasher.update(value2);
        let result2 = hasher.buffer;
        let result: [u8; 8] = result.convert();
        let result2: [u8; 8] = result2.convert();
        assert_ne!(hex::encode(result), hex::encode(result2));
    }

    #[test]
    fn test_conversion() {
        let input: &[u8] = "dddddddd".as_bytes();
        let bytes: u64 = as_array!(input, 8).convert();
        assert_eq!(bytes, 0x6464646464646464);
    }
}
<|endoftext|>


<commit_before>use frame::ChannelAssignment;
use utility::Sample;

// Decode left and side channels to left and right channels.
//
// Two channels, left and side (difference) that transforms the difference
// into the right channel.
pub fn decode_left_side<S: Sample>(buffer: &mut [S]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    unsafe {
      let left = *buffer.get_unchecked(i);
      let side = *buffer.get_unchecked(i + block_size);

      // right channel
      buffer[i + block_size] = left - side;
    }
  }
}

// Decode side and right channels to left and right channels.
//
// Two channels, side (difference) and right that transforms the difference
// into the left channel.
pub fn decode_right_side<S: Sample>(buffer: &mut [S]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    unsafe {
      let side  = *buffer.get_unchecked(i);
      let right = *buffer.get_unchecked(i + block_size);

      // left channel
      buffer[i] = side + right;
    }
  }
}

// Decode midpoint and side channels to left and right channels.
//
// Two channels, midpoint (average) and side (difference) that transforms
// the average and difference into the left and right channels.
pub fn decode_midpoint_side<S: Sample>(buffer: &mut [S]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    let mut midpoint = buffer[i];
    let side         = buffer[i + block_size];

    midpoint = (midpoint << 1) | (side & S::from_i8(1));

    // left and right channel
    buffer[i]              = (midpoint + side) >> 1;
    buffer[i + block_size] = (midpoint - side) >> 1;
  }
}

/// Decode the current frame buffer
///
/// * `Independent` - does nothing to buffer because this channel assignment
///   is already correct.
/// * `LeftSide` - decode left and side channels to left and right channels.
/// * `RightSide` - decode side and right channels to left and right
///   channels.
/// * `MidpointSide` - decode midpoint and side channels to left and right
///   channels.
pub fn decode<S>(channel_assignment: ChannelAssignment, buffer: &mut [S])
 where S: Sample {
  match channel_assignment {
    ChannelAssignment::Independent  => return,
    ChannelAssignment::LeftSide     => decode_left_side(buffer),
    ChannelAssignment::RightSide    => decode_right_side(buffer),
    ChannelAssignment::MidpointSide => decode_midpoint_side(buffer),
  }
}

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

  #[test]
  fn test_decode_left_side() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let result       = [-5, -33, -59, -125, 127, 89, 7, 3];

    decode_left_side(&mut channels);

    assert_eq!(&channels[8..16], &result);
  }

  #[test]
  fn test_decode_right_side() {
    let mut channels = [ 7, 38, 142, 238, 0, -152, -52, -18
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];
    let result       = [2, 5, 83, 113, 127, -63, -45, -15];

    decode_right_side(&mut channels);

    assert_eq!(&channels[0..8], &result);
  }

  #[test]
  fn test_decode_midpoint_side() {
    let mut channels = [ -2, -14, 12, -6, 127, 13, -19, -6
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let results      = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];

    decode_midpoint_side(&mut channels);

    assert_eq!(&channels, &results);
  }

  #[test]
  fn test_decode() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];

    let results = [ [ 2, 5, 83, 113, 127, -63, -45, -15
                    , 7, 38, 142, 238, 0, -152, -52, -18
                    ],
                    [ 2, 5, 83, 113, 127, -63, -45, -15
                    ,-5, -33, -59, -125, 127, 89, 7, 3
                    ]
                  ];

    decode(ChannelAssignment::Independent, &mut channels);
    assert_eq!(&channels, &results[0]);

    channels = [ 2, 5, 83, 113, 127, -63, -45, -15
               , 7, 38, 142, 238, 0, -152, -52, -18
               ];

    decode(ChannelAssignment::LeftSide, &mut channels);
    assert_eq!(&channels, &results[1]);

    channels = [ 7, 38, 142, 238, 0, -152, -52, -18
               , -5, -33, -59, -125, 127, 89, 7, 3
               ];

    decode(ChannelAssignment::RightSide, &mut channels);
    assert_eq!(&channels, &results[1]);

    channels = [ -2, -14, 12, -6, 127, 13, -19, -6
               , 7, 38, 142, 238, 0, -152, -52, -18
               ];

    decode(ChannelAssignment::MidpointSide, &mut channels);
    assert_eq!(&channels, &results[1]);
  }
}
<commit_msg>Add unchecked array for `decode_midpoint_side`<commit_after>use frame::ChannelAssignment;
use utility::Sample;

// Decode left and side channels to left and right channels.
//
// Two channels, left and side (difference) that transforms the difference
// into the right channel.
pub fn decode_left_side<S: Sample>(buffer: &mut [S]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    unsafe {
      let left = *buffer.get_unchecked(i);
      let side = *buffer.get_unchecked(i + block_size);

      // right channel
      buffer[i + block_size] = left - side;
    }
  }
}

// Decode side and right channels to left and right channels.
//
// Two channels, side (difference) and right that transforms the difference
// into the left channel.
pub fn decode_right_side<S: Sample>(buffer: &mut [S]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    unsafe {
      let side  = *buffer.get_unchecked(i);
      let right = *buffer.get_unchecked(i + block_size);

      // left channel
      buffer[i] = side + right;
    }
  }
}

// Decode midpoint and side channels to left and right channels.
//
// Two channels, midpoint (average) and side (difference) that transforms
// the average and difference into the left and right channels.
pub fn decode_midpoint_side<S: Sample>(buffer: &mut [S]) {
  let block_size = buffer.len() / 2;

  for i in 0..block_size {
    unsafe {
      let mut midpoint = *buffer.get_unchecked(i);
      let side         = *buffer.get_unchecked(i + block_size);

      midpoint = (midpoint << 1) | (side & S::from_i8(1));

      // left and right channel
      buffer[i]              = (midpoint + side) >> 1;
      buffer[i + block_size] = (midpoint - side) >> 1;
    }
  }
}

/// Decode the current frame buffer
///
/// * `Independent` - does nothing to buffer because this channel assignment
///   is already correct.
/// * `LeftSide` - decode left and side channels to left and right channels.
/// * `RightSide` - decode side and right channels to left and right
///   channels.
/// * `MidpointSide` - decode midpoint and side channels to left and right
///   channels.
pub fn decode<S>(channel_assignment: ChannelAssignment, buffer: &mut [S])
 where S: Sample {
  match channel_assignment {
    ChannelAssignment::Independent  => return,
    ChannelAssignment::LeftSide     => decode_left_side(buffer),
    ChannelAssignment::RightSide    => decode_right_side(buffer),
    ChannelAssignment::MidpointSide => decode_midpoint_side(buffer),
  }
}

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

  #[test]
  fn test_decode_left_side() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let result       = [-5, -33, -59, -125, 127, 89, 7, 3];

    decode_left_side(&mut channels);

    assert_eq!(&channels[8..16], &result);
  }

  #[test]
  fn test_decode_right_side() {
    let mut channels = [ 7, 38, 142, 238, 0, -152, -52, -18
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];
    let result       = [2, 5, 83, 113, 127, -63, -45, -15];

    decode_right_side(&mut channels);

    assert_eq!(&channels[0..8], &result);
  }

  #[test]
  fn test_decode_midpoint_side() {
    let mut channels = [ -2, -14, 12, -6, 127, 13, -19, -6
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];
    let results      = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , -5, -33, -59, -125, 127, 89, 7, 3
                       ];

    decode_midpoint_side(&mut channels);

    assert_eq!(&channels, &results);
  }

  #[test]
  fn test_decode() {
    let mut channels = [ 2, 5, 83, 113, 127, -63, -45, -15
                       , 7, 38, 142, 238, 0, -152, -52, -18
                       ];

    let results = [ [ 2, 5, 83, 113, 127, -63, -45, -15
                    , 7, 38, 142, 238, 0, -152, -52, -18
                    ],
                    [ 2, 5, 83, 113, 127, -63, -45, -15
                    ,-5, -33, -59, -125, 127, 89, 7, 3
                    ]
                  ];

    decode(ChannelAssignment::Independent, &mut channels);
    assert_eq!(&channels, &results[0]);

    channels = [ 2, 5, 83, 113, 127, -63, -45, -15
               , 7, 38, 142, 238, 0, -152, -52, -18
               ];

    decode(ChannelAssignment::LeftSide, &mut channels);
    assert_eq!(&channels, &results[1]);

    channels = [ 7, 38, 142, 238, 0, -152, -52, -18
               , -5, -33, -59, -125, 127, 89, 7, 3
               ];

    decode(ChannelAssignment::RightSide, &mut channels);
    assert_eq!(&channels, &results[1]);

    channels = [ -2, -14, 12, -6, 127, 13, -19, -6
               , 7, 38, 142, 238, 0, -152, -52, -18
               ];

    decode(ChannelAssignment::MidpointSide, &mut channels);
    assert_eq!(&channels, &results[1]);
  }
}
<|endoftext|>


<commit_before>
extern mod core;
extern mod cortex;
extern mod rustusb = "usb";

use core::fail::abort;
use core::option::{Option, Some, None};
use cortex::regs::{store, load, set, wait_for};
use sim::{enable_clock, USBOTG};
use sim::{select_usb_source};
use rustusb::usb::{Usb_Peripheral, Usb_Module};
use rustusb::usb::{Endpoint_Type};
use rustusb::stream::Stream_Handler;

mod sim;

static mut USB_PERIPHERAL: Option<Freescale_Usb> = None;

static BASE_USB: u32        = 0x4007_2000;
static USB_USBTRC0: u32     = BASE_USB + 0x010C;
static USB_USBCTRL: u32     = BASE_USB + 0x0100;
static USB_CTL: u32         = BASE_USB + 0x0094;
static USB_ADDR: u32        = BASE_USB + 0x0098;
static USB_CONTROL: u32     = BASE_USB + 0x0108;
static USB_INTEN: u32       = BASE_USB + 0x0084;

static USB_STAT: u32        = BASE_USB + 0x0090;
static USB_ISTAT: *mut u8   = (BASE_USB + 0x0080) as *mut u8;
static USB_ERRSTAT: u32     = BASE_USB + 0x0088;
static USB_OTGISTAT: u32    = BASE_USB + 0x0010;

static USB_BDTPAGE1: u32    = BASE_USB + 0x009C;
static USB_BDTPAGE2: u32    = BASE_USB + 0x00B0;
static USB_BDTPAGE3: u32    = BASE_USB + 0x00B4;

static USB_ENDPT0: u32      = BASE_USB + 0x00C0;

pub enum Usb_Int {
    USBRSTEN = 0x01,
    ERROREN  = 0x02,
    SOFTOKEN = 0x04,
    TOKDNEEN = 0x08,
    SLEEPEN  = 0x10,
    RESUMEEN = 0x20,
    ATTACHEN = 0x40,
    STALLEN  = 0x80
}

// fn zero_bdt() {
// }
//
// fn set_bdt() {
//     // Need a 512 byte aligned memory
//     let addr: u32 = 0x00; // This should be a pointer to the BDT
//     unsafe {
//         store(USB_BDTPAGE1 as *mut u8, (addr << 8) as u8);
//         store(USB_BDTPAGE2 as *mut u8, (addr << 16) as u8);
//         store(USB_BDTPAGE3 as *mut u8, (addr << 24) as u8);
//     }
// }
//
//
// /// Read PID from BDT
// pub fn get_pid(ep: u8) {
//
// }
//
// /// Sets the STALL flag for ENDPTx register
// pub fn stall_ep(ep: u32) {
//     if ep <= 15 {
//         let addr = USB_ENDPT0 + ep*4;
//         unsafe {
//             set(addr as *mut u8, 0x02);
//         }
//     }
// }
//
// /// Clears the STALL flag for ENDPTx register
// pub fn unstall_ep(ep: u32) {
//     if ep <= 15 {
//         let addr = USB_ENDPT0 + ep*4;
//         unsafe {
//             clear(addr as *mut u8, 0x02);
//         }
//     }
// }
//
// /// Enables the endpoint (also unstalls)
// pub fn enable_ep(ep: u32, control: bool, handshake: bool) {
//     if ep <= 15 {
//         let addr = USB_ENDPT0 + ep*4;
//         let val = 0x0c; // |
//         //    (if !control 0x10 else 0) |
//         //    (if handshake 0x01 else 0)
//         unsafe {
//             store(addr as *mut u8, val as u8);
//         }
//     }
// }
//
// /// Resume token processing
// pub fn resume() {
//     unsafe {
//         clear(USB_CTL as *mut u8, 0x20);
//     }
// }
//
// pub fn set_interrupt(val: Usb_Int) {
//     unsafe {
//         set(USB_INTEN as *mut u8, val as u8);
//     }
// }
//

pub struct Freescale_Usb {
    bdt: *mut u32,
    max_ep: uint,
    ping: [bool, ..32],
}

impl Freescale_Usb {
    /// Create a new instance
    /// Specify number of endpoints including EP0
    pub fn new(max_endpoint: uint) -> &'static mut Freescale_Usb {
        let size = if max_endpoint > 15 {
            512
        } else {
            max_endpoint * 32
        };

        // Need 512byte aligned memory for BDT
        let ptr = unsafe { core::heap::aligned_alloc_raw(512, size) };
        let this =Freescale_Usb {
            bdt: ptr as *mut u32,
            max_ep: max_endpoint,
            ping: [false, ..32],
        };
        unsafe { USB_PERIPHERAL = Some(this); }
        Freescale_Usb::get()
    }

    pub fn get() -> &'static mut Freescale_Usb {
        unsafe {
            match USB_PERIPHERAL {
                Some(ref mut module) => module,
                None => abort()
            }
        }
    }

    fn get_bdt_offset(ep: uint, is_tx: bool, is_odd: bool) -> uint {
        32*ep + (if is_tx { 16 } else { 0 } ) +
            (if is_odd { 8 } else { 0 } )
    }

    pub fn get_bdt_setting(&self, ep: uint, is_tx: bool, is_odd: bool) -> u32 {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd);
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            load(addr)
        }
    }

    pub fn set_bdt_setting(&self, ep: uint, is_tx: bool, is_odd: bool, val: u32) {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd);
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            store(addr, val);
        }
    }

    pub fn get_bdt_address(&self, ep: uint, is_tx: bool, is_odd: bool) -> u32 {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd) + 4;
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            load(addr)
        }
    }

    pub fn set_bdt_address(&self, ep: uint, is_tx: bool, is_odd: bool, val: u32) {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd) + 4;
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            store(addr, val);
        }
    }

    fn usb_reset_hard(&self) {
        unsafe {
            let addr: *mut u8 = (BASE_USB + 0x010C) as *mut u8;
            store(addr, 0x80);
            wait_for(addr as *u8, 0x80, 0x00);
        }
    }

    fn set_interrupts(&self, val: u8) {
        unsafe {
            store(USB_INTEN as *mut u8, val as u8);
        }
    }
}

// TODO: Implement Drop trait to free the bdt

impl Usb_Peripheral for Freescale_Usb {
    /// Enables the USB peripheral
    /// Selects clock source, resets peripheral hardware,
    /// allocates needed memory, runs software usb reset
    fn init(&self) {
        // Enable the SIM clock for USB
        enable_clock(USBOTG);

        // Set the USB clock source to internal
        select_usb_source(true);

        // Cycle the USB module through a hard reset
        self.usb_reset_hard();

        // Load the address of the BDT
        unsafe {
            let addr = self.bdt as u32;
            store(USB_BDTPAGE1 as *mut u8, (addr << 8) as u8);
            store(USB_BDTPAGE2 as *mut u8, (addr << 16) as u8);
            store(USB_BDTPAGE3 as *mut u8, (addr << 24) as u8);
        }

        // Enable the transceiver and disable pulldowns
        unsafe { store(USB_USBCTRL as *mut u8, 0x00); }

        // Run the software USB reset
        self.reset();

        // Enable interrupts for USBRST, TOKDNE and STALL
        self.set_interrupts(STALLEN as u8 |
                      TOKDNEEN as u8 |
                      USBRSTEN as u8);
    }

    /// Attaches the device to the bus
    /// Enables relevant pullup
    fn attach(&self) {
        // Enable the DP pullup
        unsafe { set(USB_CONTROL as *mut u8, 0x10); }
    }

    /// Moves peripheral to default state
    /// Reset address, reset all endpoints,
    /// clear any status flags
    fn reset(&self) {
        unsafe {
            // Disable and suspend USB module
            set(USB_CTL as *mut u8, 0x22);

            // TODO: Reset pingpong register

            // Clear any remaining status flags
            store(USB_ISTAT as *mut u8, 0xFF);
            store(USB_ERRSTAT as *mut u8, 0xFF);
            store(USB_OTGISTAT as *mut u8, 0xFF);

            // Zero out BDT
            core::ptr::set_memory(self.bdt as *mut u8, 0, self.max_ep*32);

            // Reset address
            self.set_address(0x00);

            // Enable USB module
            store(USB_CTL as *mut u8, 0x01);
        }
    }

    fn poll(&self) {
        USB0_Handler();
    }

    fn max_endpoints(&self) -> uint {
        16
    }

    fn queue_next(&mut self, ep: uint, is_tx: bool, stream: &Stream_Handler) {
        // Get pingpong status
        // TODO: Need to offset address for when is_tx=true
        let odd = self.ping[ep*2];

        // Check BDT is free
        let stat = self.get_bdt_setting(ep, is_tx, odd);
        if stat & 0x80 > 0 {
            abort();
        }

        // Transfer Stream_Handler into BDT
        let addr = stream.address() as u32;
        self.set_bdt_address(ep, is_tx, odd, addr);

        let len = stream.len();
        let data1 = if stream.data1() { 1 } else { 0 };

        // Activate BDT
        let val = ((len & 0x3FF) << 16) |
            0x88 | (data1 << 6);
        let stat = self.set_bdt_setting(ep, is_tx, odd, val as u32);

        // Swap pingpong
        self.ping[ep*2] = !odd;
    }

    fn set_address(&self, addr: u8) {
        unsafe {
            store(USB_ADDR as *mut u8, addr);
        }
    }

    fn ep_enable(&self, ep: uint, typ: Endpoint_Type) {
        // Make sure ep is in range
        if ep > 15 {
            abort();
        }

        // Work out flags required for type
        let val = match typ {
            rustusb::usb::Control         => 0x0D,
            rustusb::usb::Tx_Only         => 0x15,
            rustusb::usb::Rx_Only         => 0x19,
            rustusb::usb::Tx_Rx           => 0x1D,
            rustusb::usb::Isochronous_Tx  => 0x14,
            rustusb::usb::Isochronous_Rx  => 0x18
        };

        // Set enpoint
        let addr = USB_ENDPT0 + (ep as u32)*4;
        unsafe {
            store(addr as *mut u8, val as u8);
        }
    }

    fn ep_stall(&self, ep: uint) {

    }

    fn ep_unstall(&self, ep: uint) {

    }
}

/// Handler for usb interrupts
/// Uses following regs
///   ISTAT - To see which flasg are set and clear them after
///   STAT - To get info on completed transaction
/// Also reads from the BDT specified by STAT register
#[no_mangle]
pub extern "C" fn USB0_Handler() {
    // Check module has been initialised (needed?)
    if !Usb_Module::is_ready() {
        return;
    }

    // Get interrupt status
    let istat = unsafe { load(USB_ISTAT) };

    // Get module
    let module = Usb_Module::get();

    // On usbrst call reset and return
    if istat & 1 > 0 {
        module.on_reset();
        return;
    }

    // On stall call stall
    if istat & 0x80 > 0 {
        module.on_stall();
    }

    // On tokdne call out to handle_transaction
    // TODO: Will probably need to work differently for isochronous stuff
    if istat & 0x08 > 0 {
        // Get token info
        let stat = unsafe { load(USB_STAT as *mut u8) as uint };
        let ep = stat >> 4;
        let tx = (stat & 0x08) > 0;
        let odd = (stat & 0x04) > 0;

        let this = Freescale_Usb::get();
        let bdt_info = this.get_bdt_setting(ep, tx, odd);
        let pid = (bdt_info >> 2) & 0x0F;
        let len = (bdt_info >> 16) & 0x3FF;

        module.on_token(ep, tx, pid as uint, len as uint);

        // Update CTL after processing a SETUP token (will have been paused)
        if pid == 0x0D {
            unsafe { store(USB_CTL as *mut u8, 0x01); }
        }
    }

    // Clear flags
    // TODO: Does this need to be more complicated?
    unsafe { store(USB_ISTAT, istat); }
}
<commit_msg>Finish queue_next function<commit_after>
extern mod core;
extern mod cortex;
extern mod rustusb = "usb";

use core::fail::abort;
use core::option::{Option, Some, None};
use cortex::regs::{store, load, set, wait_for};
use sim::{enable_clock, USBOTG};
use sim::{select_usb_source};
use rustusb::usb::{Usb_Peripheral, Usb_Module};
use rustusb::usb::{Endpoint_Type};
use rustusb::stream::Stream_Handler;

mod sim;

static mut USB_PERIPHERAL: Option<Freescale_Usb> = None;

static BASE_USB: u32        = 0x4007_2000;
static USB_USBTRC0: u32     = BASE_USB + 0x010C;
static USB_USBCTRL: u32     = BASE_USB + 0x0100;
static USB_CTL: u32         = BASE_USB + 0x0094;
static USB_ADDR: u32        = BASE_USB + 0x0098;
static USB_CONTROL: u32     = BASE_USB + 0x0108;
static USB_INTEN: u32       = BASE_USB + 0x0084;

static USB_STAT: u32        = BASE_USB + 0x0090;
static USB_ISTAT: *mut u8   = (BASE_USB + 0x0080) as *mut u8;
static USB_ERRSTAT: u32     = BASE_USB + 0x0088;
static USB_OTGISTAT: u32    = BASE_USB + 0x0010;

static USB_BDTPAGE1: u32    = BASE_USB + 0x009C;
static USB_BDTPAGE2: u32    = BASE_USB + 0x00B0;
static USB_BDTPAGE3: u32    = BASE_USB + 0x00B4;

static USB_ENDPT0: u32      = BASE_USB + 0x00C0;

pub enum Usb_Int {
    USBRSTEN = 0x01,
    ERROREN  = 0x02,
    SOFTOKEN = 0x04,
    TOKDNEEN = 0x08,
    SLEEPEN  = 0x10,
    RESUMEEN = 0x20,
    ATTACHEN = 0x40,
    STALLEN  = 0x80
}

// fn zero_bdt() {
// }
//
// fn set_bdt() {
//     // Need a 512 byte aligned memory
//     let addr: u32 = 0x00; // This should be a pointer to the BDT
//     unsafe {
//         store(USB_BDTPAGE1 as *mut u8, (addr << 8) as u8);
//         store(USB_BDTPAGE2 as *mut u8, (addr << 16) as u8);
//         store(USB_BDTPAGE3 as *mut u8, (addr << 24) as u8);
//     }
// }
//
//
// /// Read PID from BDT
// pub fn get_pid(ep: u8) {
//
// }
//
// /// Sets the STALL flag for ENDPTx register
// pub fn stall_ep(ep: u32) {
//     if ep <= 15 {
//         let addr = USB_ENDPT0 + ep*4;
//         unsafe {
//             set(addr as *mut u8, 0x02);
//         }
//     }
// }
//
// /// Clears the STALL flag for ENDPTx register
// pub fn unstall_ep(ep: u32) {
//     if ep <= 15 {
//         let addr = USB_ENDPT0 + ep*4;
//         unsafe {
//             clear(addr as *mut u8, 0x02);
//         }
//     }
// }
//
// /// Enables the endpoint (also unstalls)
// pub fn enable_ep(ep: u32, control: bool, handshake: bool) {
//     if ep <= 15 {
//         let addr = USB_ENDPT0 + ep*4;
//         let val = 0x0c; // |
//         //    (if !control 0x10 else 0) |
//         //    (if handshake 0x01 else 0)
//         unsafe {
//             store(addr as *mut u8, val as u8);
//         }
//     }
// }
//
// /// Resume token processing
// pub fn resume() {
//     unsafe {
//         clear(USB_CTL as *mut u8, 0x20);
//     }
// }
//
// pub fn set_interrupt(val: Usb_Int) {
//     unsafe {
//         set(USB_INTEN as *mut u8, val as u8);
//     }
// }
//

pub struct Freescale_Usb {
    bdt: *mut u32,
    max_ep: uint,
    ping: [bool, ..32],
}

impl Freescale_Usb {
    /// Create a new instance
    /// Specify number of endpoints including EP0
    pub fn new(max_endpoint: uint) -> &'static mut Freescale_Usb {
        let size = if max_endpoint > 15 {
            512
        } else {
            max_endpoint * 32
        };

        // Need 512byte aligned memory for BDT
        let ptr = unsafe { core::heap::aligned_alloc_raw(512, size) };
        let this =Freescale_Usb {
            bdt: ptr as *mut u32,
            max_ep: max_endpoint,
            ping: [false, ..32],
        };
        unsafe { USB_PERIPHERAL = Some(this); }
        Freescale_Usb::get()
    }

    pub fn get() -> &'static mut Freescale_Usb {
        unsafe {
            match USB_PERIPHERAL {
                Some(ref mut module) => module,
                None => abort()
            }
        }
    }

    fn get_bdt_offset(ep: uint, is_tx: bool, is_odd: bool) -> uint {
        32*ep + (if is_tx { 16 } else { 0 } ) +
            (if is_odd { 8 } else { 0 } )
    }

    pub fn get_bdt_setting(&self, ep: uint, is_tx: bool, is_odd: bool) -> u32 {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd);
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            load(addr)
        }
    }

    pub fn set_bdt_setting(&self, ep: uint, is_tx: bool, is_odd: bool, val: u32) {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd);
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            store(addr, val);
        }
    }

    pub fn get_bdt_address(&self, ep: uint, is_tx: bool, is_odd: bool) -> u32 {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd) + 4;
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            load(addr)
        }
    }

    pub fn set_bdt_address(&self, ep: uint, is_tx: bool, is_odd: bool, val: u32) {
        let offset = Freescale_Usb::get_bdt_offset(ep, is_tx, is_odd) + 4;
        let addr = ((self.bdt as u32) + offset as u32) as *mut u32;
        unsafe {
            store(addr, val);
        }
    }

    fn usb_reset_hard(&self) {
        unsafe {
            let addr: *mut u8 = (BASE_USB + 0x010C) as *mut u8;
            store(addr, 0x80);
            wait_for(addr as *u8, 0x80, 0x00);
        }
    }

    fn set_interrupts(&self, val: u8) {
        unsafe {
            store(USB_INTEN as *mut u8, val as u8);
        }
    }
}

// TODO: Implement Drop trait to free the bdt

impl Usb_Peripheral for Freescale_Usb {
    /// Enables the USB peripheral
    /// Selects clock source, resets peripheral hardware,
    /// allocates needed memory, runs software usb reset
    fn init(&self) {
        // Enable the SIM clock for USB
        enable_clock(USBOTG);

        // Set the USB clock source to internal
        select_usb_source(true);

        // Cycle the USB module through a hard reset
        self.usb_reset_hard();

        // Load the address of the BDT
        unsafe {
            let addr = self.bdt as u32;
            store(USB_BDTPAGE1 as *mut u8, (addr << 8) as u8);
            store(USB_BDTPAGE2 as *mut u8, (addr << 16) as u8);
            store(USB_BDTPAGE3 as *mut u8, (addr << 24) as u8);
        }

        // Enable the transceiver and disable pulldowns
        unsafe { store(USB_USBCTRL as *mut u8, 0x00); }

        // Run the software USB reset
        self.reset();

        // Enable interrupts for USBRST, TOKDNE and STALL
        self.set_interrupts(STALLEN as u8 |
                      TOKDNEEN as u8 |
                      USBRSTEN as u8);
    }

    /// Attaches the device to the bus
    /// Enables relevant pullup
    fn attach(&self) {
        // Enable the DP pullup
        unsafe { set(USB_CONTROL as *mut u8, 0x10); }
    }

    /// Moves peripheral to default state
    /// Reset address, reset all endpoints,
    /// clear any status flags
    fn reset(&self) {
        unsafe {
            // Disable and suspend USB module
            set(USB_CTL as *mut u8, 0x22);

            // TODO: Reset pingpong register

            // Clear any remaining status flags
            store(USB_ISTAT as *mut u8, 0xFF);
            store(USB_ERRSTAT as *mut u8, 0xFF);
            store(USB_OTGISTAT as *mut u8, 0xFF);

            // Zero out BDT
            core::ptr::set_memory(self.bdt as *mut u8, 0, self.max_ep*32);

            // Reset address
            self.set_address(0x00);

            // Enable USB module
            store(USB_CTL as *mut u8, 0x01);
        }
    }

    fn poll(&self) {
        USB0_Handler();
    }

    fn max_endpoints(&self) -> uint {
        16
    }

    fn queue_next(&mut self, ep: uint, is_tx: bool, stream: &Stream_Handler) {
        // Get pingpong status
        let ping_index = ep*2 + if is_tx { 1 } else { 0 };
        let odd = self.ping[ping_index];

        // Check BDT is free
        let stat = self.get_bdt_setting(ep, is_tx, odd);
        if stat & 0x80 > 0 {
            abort();
        }

        // Transfer Stream_Handler into BDT
        let addr = stream.address() as u32;
        self.set_bdt_address(ep, is_tx, odd, addr);

        let len = stream.len();
        let data1 = if stream.data1() { 1 } else { 0 };

        // Activate BDT
        let val = ((len & 0x3FF) << 16) |
            0x88 | (data1 << 6);
        let stat = self.set_bdt_setting(ep, is_tx, odd, val as u32);

        // Swap pingpong
        self.ping[ping_index] = !odd;
    }

    fn set_address(&self, addr: u8) {
        unsafe {
            store(USB_ADDR as *mut u8, addr);
        }
    }

    fn ep_enable(&self, ep: uint, typ: Endpoint_Type) {
        // Make sure ep is in range
        if ep > 15 {
            abort();
        }

        // Work out flags required for type
        let val = match typ {
            rustusb::usb::Control         => 0x0D,
            rustusb::usb::Tx_Only         => 0x15,
            rustusb::usb::Rx_Only         => 0x19,
            rustusb::usb::Tx_Rx           => 0x1D,
            rustusb::usb::Isochronous_Tx  => 0x14,
            rustusb::usb::Isochronous_Rx  => 0x18
        };

        // Set enpoint
        let addr = USB_ENDPT0 + (ep as u32)*4;
        unsafe {
            store(addr as *mut u8, val as u8);
        }
    }

    fn ep_stall(&self, ep: uint) {

    }

    fn ep_unstall(&self, ep: uint) {

    }
}

/// Handler for usb interrupts
/// Uses following regs
///   ISTAT - To see which flasg are set and clear them after
///   STAT - To get info on completed transaction
/// Also reads from the BDT specified by STAT register
#[no_mangle]
pub extern "C" fn USB0_Handler() {
    // Check module has been initialised (needed?)
    if !Usb_Module::is_ready() {
        return;
    }

    // Get interrupt status
    let istat = unsafe { load(USB_ISTAT) };

    // Get module
    let module = Usb_Module::get();

    // On usbrst call reset and return
    if istat & 1 > 0 {
        module.on_reset();
        return;
    }

    // On stall call stall
    if istat & 0x80 > 0 {
        module.on_stall();
    }

    // On tokdne call out to handle_transaction
    // TODO: Will probably need to work differently for isochronous stuff
    if istat & 0x08 > 0 {
        // Get token info
        let stat = unsafe { load(USB_STAT as *mut u8) as uint };
        let ep = stat >> 4;
        let tx = (stat & 0x08) > 0;
        let odd = (stat & 0x04) > 0;

        let this = Freescale_Usb::get();
        let bdt_info = this.get_bdt_setting(ep, tx, odd);
        let pid = (bdt_info >> 2) & 0x0F;
        let len = (bdt_info >> 16) & 0x3FF;

        module.on_token(ep, tx, pid as uint, len as uint);

        // Update CTL after processing a SETUP token (will have been paused)
        if pid == 0x0D {
            unsafe { store(USB_CTL as *mut u8, 0x01); }
        }
    }

    // Clear flags
    // TODO: Does this need to be more complicated?
    unsafe { store(USB_ISTAT, istat); }
}
<|endoftext|>


<commit_before>use std::marker::ContravariantLifetime;
use std::mem;
use std::ptr;
use libc::c_ulong;

use objc::Id;
use objc::runtime::Object;

use INSObject;

pub struct NSEnumerator<'a, T> {
    id: Id<Object>,
    marker: ContravariantLifetime<'a>,
}

impl<'a, T> NSEnumerator<'a, T> where T: INSObject {
    pub unsafe fn from_ptr(ptr: *mut Object) -> NSEnumerator<'a, T> {
        NSEnumerator { id: Id::from_ptr(ptr), marker: ContravariantLifetime }
    }
}

impl<'a, T> Iterator for NSEnumerator<'a, T> where T: INSObject {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        unsafe {
            let obj: *mut T = msg_send![self.id, nextObject];
            obj.as_ref()
        }
    }
}

pub trait INSFastEnumeration: INSObject {
    type Item: INSObject;

    fn enumerator(&self) -> NSFastEnumerator<Self::Item> {
        NSFastEnumerator::<Self::Item>::new(self)
    }
}

#[repr(C)]
struct NSFastEnumerationState<T> {
    state: c_ulong,
    items_ptr: *const *const T,
    mutations_ptr: *mut c_ulong,
    extra: [c_ulong; 5],
}

const FAST_ENUM_BUF_SIZE: usize = 16;

pub struct NSFastEnumerator<'a, T> {
    object: &'a Object,

    ptr: *const *const T,
    end: *const *const T,

    state: NSFastEnumerationState<T>,
    buf: [*const T; FAST_ENUM_BUF_SIZE],
}

impl<'a, T> NSFastEnumerator<'a, T> where T: INSObject {
    fn new<C: INSFastEnumeration>(object: &C) -> NSFastEnumerator<C::Item> {
        NSFastEnumerator {
            object: unsafe { &*(object as *const C as *const Object) },

            ptr: ptr::null(),
            end: ptr::null(),

            state: unsafe { mem::zeroed() },
            buf: [ptr::null(); FAST_ENUM_BUF_SIZE],
        }
    }

    fn update_buf(&mut self) -> bool {
        // If this isn't our first time enumerating, record the previous value
        // from the mutations pointer.
        let mutations = if !self.ptr.is_null() {
            Some(unsafe { *self.state.mutations_ptr })
        } else {
            None
        };

        let count: usize = unsafe {
            msg_send![self.object, countByEnumeratingWithState:&mut self.state
                                                       objects:self.buf.as_mut_ptr()
                                                         count:self.buf.len()]
        };

        if count > 0 {
            // Check if the collection was mutated
            if let Some(mutations) = mutations {
                assert!(mutations == unsafe { *self.state.mutations_ptr },
                    "Mutation detected during enumeration of object {:?}",
                    self.object);
            }

            self.ptr = self.state.items_ptr;
            self.end = unsafe { self.ptr.offset(count as isize) };
            true
        } else {
            self.ptr = ptr::null();
            self.end = ptr::null();
            false
        }
    }
}

impl<'a, T> Iterator for NSFastEnumerator<'a, T> where T: INSObject {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        if self.ptr == self.end && !self.update_buf() {
            None
        } else {
            unsafe {
                let obj = *self.ptr;
                self.ptr = self.ptr.offset(1);
                Some(&*obj)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use objc::Id;
    use {INSArray, INSValue, NSArray, NSValue};
    use super::INSFastEnumeration;

    #[test]
    fn test_enumerator() {
        let vec: Vec<Id<NSValue<u32>>> = (0..4).map(INSValue::from_value).collect();
        let array: Id<NSArray<_>> = INSArray::from_vec(vec);

        let enumerator = array.object_enumerator();
        assert!(enumerator.count() == 4);

        let enumerator = array.object_enumerator();
        assert!(enumerator.enumerate().all(|(i, obj)| obj.value() == i as u32));
    }

    #[test]
    fn test_fast_enumerator() {
        let vec: Vec<Id<NSValue<u32>>> = (0..4).map(INSValue::from_value).collect();
        let array: Id<NSArray<_>> = INSArray::from_vec(vec);

        let enumerator = array.enumerator();
        assert!(enumerator.count() == 4);

        let enumerator = array.enumerator();
        assert!(enumerator.enumerate().all(|(i, obj)| obj.value() == i as u32));
    }
}
<commit_msg>Changed NSFastEnumerator's bound to be on the collection.<commit_after>use std::marker::ContravariantLifetime;
use std::mem;
use std::ptr;
use libc::c_ulong;

use objc::Id;
use objc::runtime::Object;

use INSObject;

pub struct NSEnumerator<'a, T> {
    id: Id<Object>,
    marker: ContravariantLifetime<'a>,
}

impl<'a, T> NSEnumerator<'a, T> where T: INSObject {
    pub unsafe fn from_ptr(ptr: *mut Object) -> NSEnumerator<'a, T> {
        NSEnumerator { id: Id::from_ptr(ptr), marker: ContravariantLifetime }
    }
}

impl<'a, T> Iterator for NSEnumerator<'a, T> where T: INSObject {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        unsafe {
            let obj: *mut T = msg_send![self.id, nextObject];
            obj.as_ref()
        }
    }
}

pub trait INSFastEnumeration: INSObject {
    type Item: INSObject;

    fn enumerator(&self) -> NSFastEnumerator<Self> {
        NSFastEnumerator::new(self)
    }
}

#[repr(C)]
struct NSFastEnumerationState<T> {
    state: c_ulong,
    items_ptr: *const *const T,
    mutations_ptr: *mut c_ulong,
    extra: [c_ulong; 5],
}

const FAST_ENUM_BUF_SIZE: usize = 16;

pub struct NSFastEnumerator<'a, C: 'a + INSFastEnumeration> {
    object: &'a C,

    ptr: *const *const C::Item,
    end: *const *const C::Item,

    state: NSFastEnumerationState<C::Item>,
    buf: [*const C::Item; FAST_ENUM_BUF_SIZE],
}

impl<'a, C: INSFastEnumeration> NSFastEnumerator<'a, C> {
    fn new(object: &C) -> NSFastEnumerator<C> {
        NSFastEnumerator {
            object: object,

            ptr: ptr::null(),
            end: ptr::null(),

            state: unsafe { mem::zeroed() },
            buf: [ptr::null(); FAST_ENUM_BUF_SIZE],
        }
    }

    fn update_buf(&mut self) -> bool {
        // If this isn't our first time enumerating, record the previous value
        // from the mutations pointer.
        let mutations = if !self.ptr.is_null() {
            Some(unsafe { *self.state.mutations_ptr })
        } else {
            None
        };

        let count: usize = unsafe {
            msg_send![self.object, countByEnumeratingWithState:&mut self.state
                                                       objects:self.buf.as_mut_ptr()
                                                         count:self.buf.len()]
        };

        if count > 0 {
            // Check if the collection was mutated
            if let Some(mutations) = mutations {
                assert!(mutations == unsafe { *self.state.mutations_ptr },
                    "Mutation detected during enumeration of object {:?}",
                    self.object as *const C);
            }

            self.ptr = self.state.items_ptr;
            self.end = unsafe { self.ptr.offset(count as isize) };
            true
        } else {
            self.ptr = ptr::null();
            self.end = ptr::null();
            false
        }
    }
}

impl<'a, C: INSFastEnumeration> Iterator for NSFastEnumerator<'a, C> {
    type Item = &'a C::Item;

    fn next(&mut self) -> Option<&'a C::Item> {
        if self.ptr == self.end && !self.update_buf() {
            None
        } else {
            unsafe {
                let obj = *self.ptr;
                self.ptr = self.ptr.offset(1);
                Some(&*obj)
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use objc::Id;
    use {INSArray, INSValue, NSArray, NSValue};
    use super::INSFastEnumeration;

    #[test]
    fn test_enumerator() {
        let vec: Vec<Id<NSValue<u32>>> = (0..4).map(INSValue::from_value).collect();
        let array: Id<NSArray<_>> = INSArray::from_vec(vec);

        let enumerator = array.object_enumerator();
        assert!(enumerator.count() == 4);

        let enumerator = array.object_enumerator();
        assert!(enumerator.enumerate().all(|(i, obj)| obj.value() == i as u32));
    }

    #[test]
    fn test_fast_enumerator() {
        let vec: Vec<Id<NSValue<u32>>> = (0..4).map(INSValue::from_value).collect();
        let array: Id<NSArray<_>> = INSArray::from_vec(vec);

        let enumerator = array.enumerator();
        assert!(enumerator.count() == 4);

        let enumerator = array.enumerator();
        assert!(enumerator.enumerate().all(|(i, obj)| obj.value() == i as u32));
    }
}
<|endoftext|>


<commit_before>fn is_prime(n: int) -> bool {
    if n <= 2 {
        return n == 2;
    }
    let mut primes = ~[2];
    let mut i = 1;
    while std::num::pow(i, 2) < n {
        let &p = primes.last().unwrap();
        if n % p == 0 {
            return false;
        }
        i += 2;
        if primes.iter().all(|&x| i%x != 0) {
            primes.push(i);
        }
    }
    true
}

fn main() {
    for n in range(0, 100) {
        if is_prime(n) {
            println!("{}", n);
        }
    }
}

<commit_msg>Make Problem 31 faster<commit_after>fn is_prime(n: int) -> bool {
    if n <= 2 {
        return n == 2;
    }
    let mut primes = ~[2];
    let mut i = 3;
    while std::num::pow(i, 2) < n {
        let &p = primes.last().unwrap();
        if n % p == 0 {
            return false;
        }
        while primes.iter().any(|&x| i%x == 0) {
            i += 2;
        }
        primes.push(i);
    }
    true
}

fn main() {
    for n in range(0, 100) {
        if is_prime(n) {
            println!("{}", n);
        }
    }
}

<|endoftext|>


<commit_before>// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength

// min-system-llvm-version: 9.0
// ignore-arm
// ignore-mips
// ignore-mips64
// ignore-powerpc
// ignore-powerpc64
// ignore-riscv64 see codegen/riscv-abi
// ignore-windows
// See repr-transparent.rs

#![feature(transparent_unions)]

#![crate_type="lib"]

#[derive(Clone, Copy)]
#[repr(C)]
pub struct BigS([u32; 16]);

#[repr(transparent)]
pub struct TsBigS(BigS);

#[repr(transparent)]
pub union TuBigS {
    field: BigS,
}

#[repr(transparent)]
pub enum TeBigS {
    Variant(BigS),
}

// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }

// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }

// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }

// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }

#[derive(Clone, Copy)]
#[repr(C)]
pub union BigU {
    foo: [u32; 16],
}

#[repr(transparent)]
pub struct TsBigU(BigU);

#[repr(transparent)]
pub union TuBigU {
    field: BigU,
}

#[repr(transparent)]
pub enum TeBigU {
    Variant(BigU),
}

// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }

// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }

// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }

// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
<commit_msg>Ignoring test case: [codegen] repr-transparent-aggregates-1.rs for aarch64<commit_after>// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength

// min-system-llvm-version: 9.0
// ignore-arm
// ignore-aarch64
// ignore-mips
// ignore-mips64
// ignore-powerpc
// ignore-powerpc64
// ignore-riscv64 see codegen/riscv-abi
// ignore-windows
// See repr-transparent.rs

#![feature(transparent_unions)]

#![crate_type="lib"]

#[derive(Clone, Copy)]
#[repr(C)]
pub struct BigS([u32; 16]);

#[repr(transparent)]
pub struct TsBigS(BigS);

#[repr(transparent)]
pub union TuBigS {
    field: BigS,
}

#[repr(transparent)]
pub enum TeBigS {
    Variant(BigS),
}

// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }

// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }

// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }

// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }

#[derive(Clone, Copy)]
#[repr(C)]
pub union BigU {
    foo: [u32; 16],
}

#[repr(transparent)]
pub struct TsBigU(BigU);

#[repr(transparent)]
pub union TuBigU {
    field: BigU,
}

#[repr(transparent)]
pub enum TeBigU {
    Variant(BigU),
}

// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
#[no_mangle]
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }

// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }

// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }

// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
#[no_mangle]
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
<|endoftext|>