<commit_before>//! Rustdoc's JSON backend
//!
//! This module contains the logic for rendering a crate as JSON rather than the normal static HTML
//! output. See [the RFC](https://github.com/rust-lang/rfcs/pull/2963) and the [`types`] module
//! docs for usage and details.

mod conversions;

use std::cell::RefCell;
use std::fs::File;
use std::path::PathBuf;
use std::rc::Rc;

use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::edition::Edition;

use json_types as types;

use crate::clean;
use crate::config::{RenderInfo, RenderOptions};
use crate::error::Error;
use crate::formats::cache::Cache;
use crate::formats::FormatRenderer;
use crate::html::render::cache::ExternalLocation;
use crate::json::conversions::from_def_id;

#[derive(Clone)]
crate struct JsonRenderer<'tcx> {
    tcx: TyCtxt<'tcx>,
    /// A mapping of IDs that contains all local items for this crate which gets output as a top
    /// level field of the JSON blob.
    index: Rc<RefCell<FxHashMap<types::Id, types::Item>>>,
    /// The directory where the blob will be written to.
    out_path: PathBuf,
    cache: Rc<Cache>,
}

impl JsonRenderer<'_> {
    fn sess(&self) -> &Session {
        self.tcx.sess
    }

    fn get_trait_implementors(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
        Rc::clone(&self.cache)
            .implementors
            .get(&id)
            .map(|implementors| {
                implementors
                    .iter()
                    .map(|i| {
                        let item = &i.impl_item;
                        self.item(item.clone()).unwrap();
                        from_def_id(item.def_id)
                    })
                    .collect()
            })
            .unwrap_or_default()
    }

    fn get_impls(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
        Rc::clone(&self.cache)
            .impls
            .get(&id)
            .map(|impls| {
                impls
                    .iter()
                    .filter_map(|i| {
                        let item = &i.impl_item;
                        if item.def_id.is_local() {
                            self.item(item.clone()).unwrap();
                            Some(from_def_id(item.def_id))
                        } else {
                            None
                        }
                    })
                    .collect()
            })
            .unwrap_or_default()
    }

    fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
        Rc::clone(&self.cache)
            .traits
            .iter()
            .filter_map(|(&id, trait_item)| {
                // only need to synthesize items for external traits
                if !id.is_local() {
                    trait_item.items.clone().into_iter().for_each(|i| self.item(i).unwrap());
                    Some((
                        from_def_id(id),
                        types::Item {
                            id: from_def_id(id),
                            crate_id: id.krate.as_u32(),
                            name: self
                                .cache
                                .paths
                                .get(&id)
                                .unwrap_or_else(|| {
                                    self.cache
                                        .external_paths
                                        .get(&id)
                                        .expect("Trait should either be in local or external paths")
                                })
                                .0
                                .last()
                                .map(Clone::clone),
                            visibility: types::Visibility::Public,
                            kind: types::ItemKind::Trait,
                            inner: types::ItemEnum::TraitItem(trait_item.clone().into()),
                            source: None,
                            docs: Default::default(),
                            links: Default::default(),
                            attrs: Default::default(),
                            deprecation: Default::default(),
                        },
                    ))
                } else {
                    None
                }
            })
            .collect()
    }
}

impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
    fn descr() -> &'static str {
        "json"
    }

    fn init(
        krate: clean::Crate,
        options: RenderOptions,
        _render_info: RenderInfo,
        _edition: Edition,
        cache: Cache,
        tcx: TyCtxt<'tcx>,
    ) -> Result<(Self, clean::Crate), Error> {
        debug!("Initializing json renderer");
        Ok((
            JsonRenderer {
                tcx,
                index: Rc::new(RefCell::new(FxHashMap::default())),
                out_path: options.output,
                cache: Rc::new(cache),
            },
            krate,
        ))
    }

    /// Inserts an item into the index. This should be used rather than directly calling insert on
    /// the hashmap because certain items (traits and types) need to have their mappings for trait
    /// implementations filled out before they're inserted.
    fn item(&mut self, item: clean::Item) -> Result<(), Error> {
        // Flatten items that recursively store other items
        item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());

        let id = item.def_id;
        if let Some(mut new_item) = self.convert_item(item) {
            if let types::ItemEnum::TraitItem(ref mut t) = new_item.inner {
                t.implementors = self.get_trait_implementors(id)
            } else if let types::ItemEnum::StructItem(ref mut s) = new_item.inner {
                s.impls = self.get_impls(id)
            } else if let types::ItemEnum::EnumItem(ref mut e) = new_item.inner {
                e.impls = self.get_impls(id)
            }
            let removed = self.index.borrow_mut().insert(from_def_id(id), new_item.clone());
            // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
            // to make sure the items are unique.
            if let Some(old_item) = removed {
                assert_eq!(old_item, new_item);
            }
        }

        Ok(())
    }

    fn mod_item_in(&mut self, item: &clean::Item, _module_name: &str) -> Result<(), Error> {
        use clean::types::ItemKind::*;
        if let ModuleItem(m) = &*item.kind {
            for item in &m.items {
                match &*item.kind {
                    // These don't have names so they don't get added to the output by default
                    ImportItem(_) => self.item(item.clone()).unwrap(),
                    ExternCrateItem(_, _) => self.item(item.clone()).unwrap(),
                    ImplItem(i) => i.items.iter().for_each(|i| self.item(i.clone()).unwrap()),
                    _ => {}
                }
            }
        }
        self.item(item.clone()).unwrap();
        Ok(())
    }

    fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> {
        Ok(())
    }

    fn after_krate(
        &mut self,
        krate: &clean::Crate,
        _diag: &rustc_errors::Handler,
    ) -> Result<(), Error> {
        debug!("Done with crate");
        let mut index = (*self.index).clone().into_inner();
        index.extend(self.get_trait_items());
        let len = index.len();
        let output = types::Crate {
            root: types::Id(String::from("0:0")),
            crate_version: krate.version.clone(),
            includes_private: self.cache.document_private,
            index: index.into_iter().fold(
                std::collections::HashMap::with_capacity(len),
                |mut acc, (key, val)| {
                    acc.insert(key, val);
                    acc
                },
            ),
            paths: self
                .cache
                .paths
                .clone()
                .into_iter()
                .chain(self.cache.external_paths.clone().into_iter())
                .map(|(k, (path, kind))| {
                    (
                        from_def_id(k),
                        types::ItemSummary { crate_id: k.krate.as_u32(), path, kind: kind.into() },
                    )
                })
                .collect(),
            external_crates: self
                .cache
                .extern_locations
                .iter()
                .map(|(k, v)| {
                    (
                        k.as_u32(),
                        types::ExternalCrate {
                            name: v.0.to_string(),
                            html_root_url: match &v.2 {
                                ExternalLocation::Remote(s) => Some(s.clone()),
                                _ => None,
                            },
                        },
                    )
                })
                .collect(),
            format_version: 2,
        };
        let mut p = self.out_path.clone();
        p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
        p.set_extension("json");
        let file = File::create(&p).map_err(|error| Error { error: error.to_string(), file: p })?;
        serde_json::ser::to_writer(&file, &output).unwrap();
        Ok(())
    }

    fn cache(&self) -> &Cache {
        &self.cache
    }
}
<commit_msg>Allow rustc::default_hash_types in the offending statement<commit_after>//! Rustdoc's JSON backend
//!
//! This module contains the logic for rendering a crate as JSON rather than the normal static HTML
//! output. See [the RFC](https://github.com/rust-lang/rfcs/pull/2963) and the [`types`] module
//! docs for usage and details.

mod conversions;

use std::cell::RefCell;
use std::fs::File;
use std::path::PathBuf;
use std::rc::Rc;

use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::edition::Edition;

use json_types as types;

use crate::clean;
use crate::config::{RenderInfo, RenderOptions};
use crate::error::Error;
use crate::formats::cache::Cache;
use crate::formats::FormatRenderer;
use crate::html::render::cache::ExternalLocation;
use crate::json::conversions::from_def_id;

#[derive(Clone)]
crate struct JsonRenderer<'tcx> {
    tcx: TyCtxt<'tcx>,
    /// A mapping of IDs that contains all local items for this crate which gets output as a top
    /// level field of the JSON blob.
    index: Rc<RefCell<FxHashMap<types::Id, types::Item>>>,
    /// The directory where the blob will be written to.
    out_path: PathBuf,
    cache: Rc<Cache>,
}

impl JsonRenderer<'_> {
    fn sess(&self) -> &Session {
        self.tcx.sess
    }

    fn get_trait_implementors(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
        Rc::clone(&self.cache)
            .implementors
            .get(&id)
            .map(|implementors| {
                implementors
                    .iter()
                    .map(|i| {
                        let item = &i.impl_item;
                        self.item(item.clone()).unwrap();
                        from_def_id(item.def_id)
                    })
                    .collect()
            })
            .unwrap_or_default()
    }

    fn get_impls(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
        Rc::clone(&self.cache)
            .impls
            .get(&id)
            .map(|impls| {
                impls
                    .iter()
                    .filter_map(|i| {
                        let item = &i.impl_item;
                        if item.def_id.is_local() {
                            self.item(item.clone()).unwrap();
                            Some(from_def_id(item.def_id))
                        } else {
                            None
                        }
                    })
                    .collect()
            })
            .unwrap_or_default()
    }

    fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
        Rc::clone(&self.cache)
            .traits
            .iter()
            .filter_map(|(&id, trait_item)| {
                // only need to synthesize items for external traits
                if !id.is_local() {
                    trait_item.items.clone().into_iter().for_each(|i| self.item(i).unwrap());
                    Some((
                        from_def_id(id),
                        types::Item {
                            id: from_def_id(id),
                            crate_id: id.krate.as_u32(),
                            name: self
                                .cache
                                .paths
                                .get(&id)
                                .unwrap_or_else(|| {
                                    self.cache
                                        .external_paths
                                        .get(&id)
                                        .expect("Trait should either be in local or external paths")
                                })
                                .0
                                .last()
                                .map(Clone::clone),
                            visibility: types::Visibility::Public,
                            kind: types::ItemKind::Trait,
                            inner: types::ItemEnum::TraitItem(trait_item.clone().into()),
                            source: None,
                            docs: Default::default(),
                            links: Default::default(),
                            attrs: Default::default(),
                            deprecation: Default::default(),
                        },
                    ))
                } else {
                    None
                }
            })
            .collect()
    }
}

impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
    fn descr() -> &'static str {
        "json"
    }

    fn init(
        krate: clean::Crate,
        options: RenderOptions,
        _render_info: RenderInfo,
        _edition: Edition,
        cache: Cache,
        tcx: TyCtxt<'tcx>,
    ) -> Result<(Self, clean::Crate), Error> {
        debug!("Initializing json renderer");
        Ok((
            JsonRenderer {
                tcx,
                index: Rc::new(RefCell::new(FxHashMap::default())),
                out_path: options.output,
                cache: Rc::new(cache),
            },
            krate,
        ))
    }

    /// Inserts an item into the index. This should be used rather than directly calling insert on
    /// the hashmap because certain items (traits and types) need to have their mappings for trait
    /// implementations filled out before they're inserted.
    fn item(&mut self, item: clean::Item) -> Result<(), Error> {
        // Flatten items that recursively store other items
        item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());

        let id = item.def_id;
        if let Some(mut new_item) = self.convert_item(item) {
            if let types::ItemEnum::TraitItem(ref mut t) = new_item.inner {
                t.implementors = self.get_trait_implementors(id)
            } else if let types::ItemEnum::StructItem(ref mut s) = new_item.inner {
                s.impls = self.get_impls(id)
            } else if let types::ItemEnum::EnumItem(ref mut e) = new_item.inner {
                e.impls = self.get_impls(id)
            }
            let removed = self.index.borrow_mut().insert(from_def_id(id), new_item.clone());
            // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
            // to make sure the items are unique.
            if let Some(old_item) = removed {
                assert_eq!(old_item, new_item);
            }
        }

        Ok(())
    }

    fn mod_item_in(&mut self, item: &clean::Item, _module_name: &str) -> Result<(), Error> {
        use clean::types::ItemKind::*;
        if let ModuleItem(m) = &*item.kind {
            for item in &m.items {
                match &*item.kind {
                    // These don't have names so they don't get added to the output by default
                    ImportItem(_) => self.item(item.clone()).unwrap(),
                    ExternCrateItem(_, _) => self.item(item.clone()).unwrap(),
                    ImplItem(i) => i.items.iter().for_each(|i| self.item(i.clone()).unwrap()),
                    _ => {}
                }
            }
        }
        self.item(item.clone()).unwrap();
        Ok(())
    }

    fn mod_item_out(&mut self, _item_name: &str) -> Result<(), Error> {
        Ok(())
    }

    fn after_krate(
        &mut self,
        krate: &clean::Crate,
        _diag: &rustc_errors::Handler,
    ) -> Result<(), Error> {
        debug!("Done with crate");
        let mut index = (*self.index).clone().into_inner();
        index.extend(self.get_trait_items());
        let len = index.len();
        // This needs to be the default HashMap for compatibility with the public interface for
        // rustdoc-json
        #[allow(rustc::default_hash_types)]
        let output = types::Crate {
            root: types::Id(String::from("0:0")),
            crate_version: krate.version.clone(),
            includes_private: self.cache.document_private,
            index: index.into_iter().fold(
                std::collections::HashMap::with_capacity(len),
                |mut acc, (key, val)| {
                    acc.insert(key, val);
                    acc
                },
            ),
            paths: self
                .cache
                .paths
                .clone()
                .into_iter()
                .chain(self.cache.external_paths.clone().into_iter())
                .map(|(k, (path, kind))| {
                    (
                        from_def_id(k),
                        types::ItemSummary { crate_id: k.krate.as_u32(), path, kind: kind.into() },
                    )
                })
                .collect(),
            external_crates: self
                .cache
                .extern_locations
                .iter()
                .map(|(k, v)| {
                    (
                        k.as_u32(),
                        types::ExternalCrate {
                            name: v.0.to_string(),
                            html_root_url: match &v.2 {
                                ExternalLocation::Remote(s) => Some(s.clone()),
                                _ => None,
                            },
                        },
                    )
                })
                .collect(),
            format_version: 2,
        };
        let mut p = self.out_path.clone();
        p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
        p.set_extension("json");
        let file = File::create(&p).map_err(|error| Error { error: error.to_string(), file: p })?;
        serde_json::ser::to_writer(&file, &output).unwrap();
        Ok(())
    }

    fn cache(&self) -> &Cache {
        &self.cache
    }
}
<|endoftext|>


<commit_before>//! This example uses [hyper][] to create a http server which handles requests asynchronously in
//! gluon. To do this we define a few types and functions in Rust with which we register in gluon
//! so that we can communicate with `hyper`. The rest of the implementation is done in gluon,
//! routing the requests and constructing the responses.
//!
//! [hyper]:https://hyper.rs

extern crate gluon;
extern crate gluon_base as base;
#[macro_use]
extern crate gluon_vm as vm;

#[macro_use]
extern crate collect_mac;
extern crate env_logger;
extern crate futures;
extern crate http;
extern crate hyper;
extern crate tokio;
#[macro_use]
extern crate log;

use std::env;
use std::error::Error as StdError;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::marker::PhantomData;
use std::sync::{Arc, Mutex};

use hyper::service::Service;
use hyper::Chunk;
use hyper::Server;

use http::StatusCode;

use futures::future::Either;
use futures::stream::Stream;
use futures::sync::oneshot;
use futures::{future, Async, Future};

use base::types::{ArcType, Type};

use vm::{Error as VmError, ExternModule, Result as VmResult};

use gluon::import::add_extern_module;
use vm::api::{
    Function, FutureResult, OpaqueValue, OwnedFunction, PushAsRef, Userdata, VmType, WithVM, IO,
};
use vm::future::FutureValue;
use vm::gc::{Gc, Traverseable};
use vm::thread::{RootedThread, Thread};

use gluon::{new_vm, Compiler};

// `Handler` is a type defined in http.glu but since we need to refer to it in the signature of
// listen we define a phantom type which we can use with `OpaqueValue` to store a `Handler` in Rust
struct Handler<T>(PhantomData<T>);

impl<T: VmType + 'static> VmType for Handler<T> {
    type Type = Self;
    fn make_type(vm: &Thread) -> ArcType {
        let typ = vm
            .find_type_info("examples.http.types.Handler")
            .unwrap_or_else(|err| panic!("{}", err))
            .into_type();
        Type::app(typ, collect![T::make_type(vm)])
    }
}

// Representation of a http body that is in the prograss of being read
pub struct Body(Arc<Mutex<Box<Stream<Item = PushAsRef<Chunk, [u8]>, Error = VmError> + Send>>>);

// By implementing `Userdata` on `Body` it can be automatically pushed and retrieved from gluon
// threads
impl Userdata for Body {}

// Types implementing `Userdata` requires a `std::fmt::Debug` implementation so it can be displayed
impl fmt::Debug for Body {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hyper::Body")
    }
}

// `Traverseable` is required by `Userdata` so that the garbage collector knows how to scan the
// value for garbage collected references. Normally objects do not contain any references so this
// can be empty
impl Traverseable for Body {
    fn traverse(&self, _: &mut Gc) {}
}

// `VmType` is the last trait required for a type to implement `Userdata` and defines the type used
// in gluon for this Rust type. For opaque `Userdata` values this minimal implementation is enough
// as the default implementation of `make_type` will lookup `VmType::Type` from the virtual machine
// which should have been registered earlier with `Thread::register_type`
impl VmType for Body {
    type Type = Self;
}

// Since `Body` implements `Userdata` gluon will automatically marshal the gluon representation
// into `&Body` argument
fn read_chunk(
    body: &Body,
) -> FutureResult<impl Future<Item = IO<Option<PushAsRef<Chunk, [u8]>>>, Error = VmError>> {
    use futures::future::poll_fn;

    let body = body.0.clone();
    // `FutureResult` is a wrapper type around `Future` which when returned to the interpreter is
    // polled until completion. After `poll` returns `Ready` the value is then returned to the
    // gluon function which called `read_chunk`
    FutureResult(poll_fn(move || {
        let mut stream = body.lock().unwrap();
        stream.poll().map(|async| async.map(IO::Value))
    }))
}

// A http body that is being written
pub struct ResponseBody(Arc<Mutex<Option<hyper::body::Sender>>>);

impl fmt::Debug for ResponseBody {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hyper::Response")
    }
}

impl Userdata for ResponseBody {}

impl Traverseable for ResponseBody {
    fn traverse(&self, _: &mut Gc) {}
}

impl VmType for ResponseBody {
    type Type = Self;
}

fn write_response(
    response: &ResponseBody,
    bytes: &[u8],
) -> FutureResult<impl Future<Item = IO<()>, Error = VmError>> {
    use futures::future::poll_fn;

    // Turn `bytes´ into a `Chunk` which can be sent to the http body
    let mut unsent_chunk = Some(bytes.to_owned().into());
    let response = response.0.clone();
    FutureResult(poll_fn(move || {
        info!("Starting response send");
        let mut sender = response.lock().unwrap();
        let sender = sender
            .as_mut()
            .expect("Sender has been dropped while still in use");
        let chunk = unsent_chunk
            .take()
            .expect("Attempt to poll after chunk is sent");
        match sender.poll_ready() {
            Ok(Async::NotReady) => {
                unsent_chunk = Some(chunk);
                return Ok(Async::NotReady);
            }
            Ok(Async::Ready(_)) => (),
            Err(_) => {
                info!("Could not send http response");
                return Ok(Async::Ready(IO::Value(())));
            }
        }
        match sender.send_data(chunk) {
            Ok(()) => Ok(Async::Ready(IO::Value(()))),
            Err(chunk) => {
                info!("Could not send http response");
                unsent_chunk = Some(chunk);
                Ok(Async::NotReady)
            }
        }
    }))
}

// Next we define some record types which are marshalled to and from gluon. These have equivalent
// definitions in http_types.glu
field_decl! { method, uri, status, body, request, response }

type Request = record_type!{
    method => String,
    uri => String,
    body => Body
};

type Response = record_type!{
    status => u16
};

type HttpState = record_type!{
    request => Request,
    response => ResponseBody
};

fn listen(
    port: i32,
    value: WithVM<OpaqueValue<RootedThread, Handler<Response>>>,
) -> FutureResult<impl Future<Item = IO<()>, Error = vm::Error> + Send + 'static> {
    let WithVM {
        value: handler,
        vm: thread,
    } = value;

    let thread = match thread.new_thread() {
        Ok(thread) => thread,
        Err(err) => return FutureResult(Either::A(future::err(err))),
    };

    // Retrieve the `handle` function from the http module which we use to evaluate values of type
    // `Handler Response`
    type ListenFn = fn(OpaqueValue<RootedThread, Handler<Response>>, HttpState) -> IO<Response>;
    let handle: Function<RootedThread, ListenFn> = thread
        .get_global("examples.http.http.handle")
        .unwrap_or_else(|err| panic!("{}", err));

    struct Listen {
        handle: Function<RootedThread, ListenFn>,
        handler: OpaqueValue<RootedThread, Handler<Response>>,
    }

    impl Service for Listen {
        type ReqBody = hyper::Body;
        type ResBody = hyper::Body;
        type Error = hyper::Error;
        type Future =
            Box<Future<Item = http::Response<hyper::Body>, Error = hyper::Error> + Send + 'static>;

        fn call(&mut self, request: http::Request<hyper::Body>) -> Self::Future {
            let gluon_request = record_no_decl! {
                method => request.method().as_str().to_owned(),
                uri => request.uri().to_string(),
                // Since `Body` implements `Userdata` it can be directly pushed to gluon
                body => Body(Arc::new(Mutex::new(Box::new(request.into_body()
                    .map_err(|err| VmError::Message(format!("{}", err)))
                    // `PushAsRef` makes the `body` parameter act as a `&[u8]` which means it is
                    // marshalled to `Array Byte` in gluon
                    .map(PushAsRef::<_, [u8]>::new)))))
            };
            let (response_sender, response_body) = hyper::Body::channel();
            let response_sender = Arc::new(Mutex::new(Some(response_sender)));
            let http_state = record_no_decl!{
                request => gluon_request,
                response => ResponseBody(response_sender.clone())
            };

            Box::new(
                self.handle
                    .clone()
                    .call_async(self.handler.clone(), http_state)
                    .then(move |result| match result {
                        Ok(value) => {
                            match value {
                                IO::Value(record_p!{ status }) => {
                                    // Drop the sender to so that it the receiver stops waiting for
                                    // more chunks
                                    *response_sender.lock().unwrap() = None;

                                    let status = StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
                                    Ok(
                                        http::Response::builder()
                                            .status(status)
                                            .body(response_body).unwrap(),
                                    )
                                }
                                IO::Exception(err) => {
                                    eprintln!("{}", err);
                                    Ok(
                                        http::Response::builder()
                                            .status(StatusCode::INTERNAL_SERVER_ERROR).body("".into()).unwrap()
                                    )
                                }
                            }
                        }
                        Err(err) => {
                            eprintln!("{}", err);
                            Ok(http::Response::builder()
                                .status(StatusCode::INTERNAL_SERVER_ERROR)
                                .body("".into())
                                .unwrap())
                        }
                    }),
            )
        }
    }

    let addr = format!("127.0.0.1:{}", port).parse().unwrap();

    let (sender, receiver) = oneshot::channel();
    tokio::spawn(
        Server::bind(&addr)
            .serve(move || -> Result<_, hyper::Error> {
                Ok(Listen {
                    handle: handle.clone(),
                    handler: handler.clone(),
                })
            })
            .map_err(|err| {
                error!("{}", err);
            })
            .and_then(|_| sender.send(IO::Value(())).map_err(|_| ())),
    );
    FutureResult(Either::B(
        receiver.map_err(|err| vm::Error::from(format!("Server error: {}", err))),
    ))
}

// To let the `http_types` module refer to `Body` and `ResponseBody` we register these types in a
// separate function which is called before loading `http_types`
pub fn load_types(vm: &Thread) -> VmResult<ExternModule> {
    vm.register_type::<Body>("Body", &[])?;
    vm.register_type::<ResponseBody>("ResponseBody", &[])?;

    ExternModule::new(
        vm,
        record! {
            // Define the types so that they can be used from gluon
            type Body => Body,
            type ResponseBody => ResponseBody,
            type Method => String,
            type StatusCode => u16,
            type Request => Request,
            type Response => Response,
            type HttpState => HttpState
        },
    )
}

pub fn load(vm: &Thread) -> VmResult<ExternModule> {
    ExternModule::new(
        vm,
        record! {
            listen => primitive!(2 listen),
            read_chunk => primitive!(1 read_chunk),
            write_response => primitive!(2 write_response)
        },
    )
}

fn main() {
    env_logger::init();

    let port = env::args()
        .nth(1)
        .map(|port| port.parse::<u16>().expect("port"))
        .unwrap_or(80);

    let thread = new_vm();
    tokio::run(start(&thread, port).map_err(|err| panic!("{}", err)));
}

fn start(
    thread: &Thread,
    port: u16,
) -> impl Future<Item = (), Error = Box<StdError + Send + Sync + 'static>> {
    add_extern_module(&thread, "http.prim_types", load_types);
    add_extern_module(&thread, "http.prim", load);

    let thread = thread.root_thread();
    future::lazy(|| -> Result<_, Box<StdError + Send + Sync>> {
        // Last we run our `http_server.glu` module which returns a function which starts listening
        // on the port we passed from the command line
        let mut expr = String::new();
        {
            let mut file = File::open("examples/http/server.glu")?;
            file.read_to_string(&mut expr)?;
        }
        Ok(expr)
    }).and_then(move |expr| {
        Compiler::new()
            .run_expr_async::<OwnedFunction<fn(u16) -> IO<()>>>(
                &thread,
                "examples/http/server.glu",
                &expr,
            )
            .from_err()
            .and_then(move |(mut listen, _)| {
                FutureValue::Future(listen.call_async(port))
                    .from_err()
                    .map(|_| ())
            })
    })
}

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

    extern crate tokio_retry;

    use std::str;

    use hyper::Client;

    use tokio::runtime::Runtime;

    #[test]
    fn hello_world() {
        let mut runtime = Runtime::new().unwrap();

        let port = 1222;
        let thread = new_vm();

        runtime.spawn(future::lazy(move || {
            start(&thread, port).map_err(|err| error!("{}", err))
        }));

        let future =
            move || Client::new().get(format!("http://localhost:{}", port).parse().unwrap());

        let retry_strategy = tokio_retry::strategy::FixedInterval::from_millis(400).take(40);

        runtime
            .block_on(
                tokio_retry::Retry::spawn(retry_strategy, future)
                    .map_err(|err| panic!("{}", err))
                    .and_then(|response| {
                        response.into_body().concat2().map(|body| {
                            assert_eq!(str::from_utf8(&body).unwrap(), "Hello World");
                        })
                    }),
            )
            .unwrap();
    }

    #[test]
    fn echo() {
        let mut runtime = Runtime::new().unwrap();

        let port = 1223;
        let thread = new_vm();
        runtime.spawn(future::lazy(move || {
            start(&thread, port).map_err(|err| error!("{}", err))
        }));

        let future = move || {
            let request = hyper::Request::post(format!("http://localhost:{}/echo", port))
                .body(hyper::Body::from("test"))
                .unwrap();

            Client::new().request(request)
        };

        let retry_strategy = tokio_retry::strategy::FixedInterval::from_millis(400).take(40);

        runtime
            .block_on(
                tokio_retry::Retry::spawn(retry_strategy, future)
                    .map_err(|err| panic!("{}", err))
                    .and_then(|response| {
                        response.into_body().concat2().map(|body| {
                            assert_eq!(str::from_utf8(&body).unwrap(), "test");
                        })
                    }),
            )
            .unwrap();
    }
}
<commit_msg>test: Try to change ports to get travis passing<commit_after>//! This example uses [hyper][] to create a http server which handles requests asynchronously in
//! gluon. To do this we define a few types and functions in Rust with which we register in gluon
//! so that we can communicate with `hyper`. The rest of the implementation is done in gluon,
//! routing the requests and constructing the responses.
//!
//! [hyper]:https://hyper.rs

extern crate gluon;
extern crate gluon_base as base;
#[macro_use]
extern crate gluon_vm as vm;

#[macro_use]
extern crate collect_mac;
extern crate env_logger;
extern crate futures;
extern crate http;
extern crate hyper;
extern crate tokio;
#[macro_use]
extern crate log;

use std::env;
use std::error::Error as StdError;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::marker::PhantomData;
use std::sync::{Arc, Mutex};

use hyper::service::Service;
use hyper::Chunk;
use hyper::Server;

use http::StatusCode;

use futures::future::Either;
use futures::stream::Stream;
use futures::sync::oneshot;
use futures::{future, Async, Future};

use base::types::{ArcType, Type};

use vm::{Error as VmError, ExternModule, Result as VmResult};

use gluon::import::add_extern_module;
use vm::api::{
    Function, FutureResult, OpaqueValue, OwnedFunction, PushAsRef, Userdata, VmType, WithVM, IO,
};
use vm::future::FutureValue;
use vm::gc::{Gc, Traverseable};
use vm::thread::{RootedThread, Thread};

use gluon::{new_vm, Compiler};

// `Handler` is a type defined in http.glu but since we need to refer to it in the signature of
// listen we define a phantom type which we can use with `OpaqueValue` to store a `Handler` in Rust
struct Handler<T>(PhantomData<T>);

impl<T: VmType + 'static> VmType for Handler<T> {
    type Type = Self;
    fn make_type(vm: &Thread) -> ArcType {
        let typ = vm
            .find_type_info("examples.http.types.Handler")
            .unwrap_or_else(|err| panic!("{}", err))
            .into_type();
        Type::app(typ, collect![T::make_type(vm)])
    }
}

// Representation of a http body that is in the prograss of being read
pub struct Body(Arc<Mutex<Box<Stream<Item = PushAsRef<Chunk, [u8]>, Error = VmError> + Send>>>);

// By implementing `Userdata` on `Body` it can be automatically pushed and retrieved from gluon
// threads
impl Userdata for Body {}

// Types implementing `Userdata` requires a `std::fmt::Debug` implementation so it can be displayed
impl fmt::Debug for Body {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hyper::Body")
    }
}

// `Traverseable` is required by `Userdata` so that the garbage collector knows how to scan the
// value for garbage collected references. Normally objects do not contain any references so this
// can be empty
impl Traverseable for Body {
    fn traverse(&self, _: &mut Gc) {}
}

// `VmType` is the last trait required for a type to implement `Userdata` and defines the type used
// in gluon for this Rust type. For opaque `Userdata` values this minimal implementation is enough
// as the default implementation of `make_type` will lookup `VmType::Type` from the virtual machine
// which should have been registered earlier with `Thread::register_type`
impl VmType for Body {
    type Type = Self;
}

// Since `Body` implements `Userdata` gluon will automatically marshal the gluon representation
// into `&Body` argument
fn read_chunk(
    body: &Body,
) -> FutureResult<impl Future<Item = IO<Option<PushAsRef<Chunk, [u8]>>>, Error = VmError>> {
    use futures::future::poll_fn;

    let body = body.0.clone();
    // `FutureResult` is a wrapper type around `Future` which when returned to the interpreter is
    // polled until completion. After `poll` returns `Ready` the value is then returned to the
    // gluon function which called `read_chunk`
    FutureResult(poll_fn(move || {
        let mut stream = body.lock().unwrap();
        stream.poll().map(|async| async.map(IO::Value))
    }))
}

// A http body that is being written
pub struct ResponseBody(Arc<Mutex<Option<hyper::body::Sender>>>);

impl fmt::Debug for ResponseBody {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hyper::Response")
    }
}

impl Userdata for ResponseBody {}

impl Traverseable for ResponseBody {
    fn traverse(&self, _: &mut Gc) {}
}

impl VmType for ResponseBody {
    type Type = Self;
}

fn write_response(
    response: &ResponseBody,
    bytes: &[u8],
) -> FutureResult<impl Future<Item = IO<()>, Error = VmError>> {
    use futures::future::poll_fn;

    // Turn `bytes´ into a `Chunk` which can be sent to the http body
    let mut unsent_chunk = Some(bytes.to_owned().into());
    let response = response.0.clone();
    FutureResult(poll_fn(move || {
        info!("Starting response send");
        let mut sender = response.lock().unwrap();
        let sender = sender
            .as_mut()
            .expect("Sender has been dropped while still in use");
        let chunk = unsent_chunk
            .take()
            .expect("Attempt to poll after chunk is sent");
        match sender.poll_ready() {
            Ok(Async::NotReady) => {
                unsent_chunk = Some(chunk);
                return Ok(Async::NotReady);
            }
            Ok(Async::Ready(_)) => (),
            Err(_) => {
                info!("Could not send http response");
                return Ok(Async::Ready(IO::Value(())));
            }
        }
        match sender.send_data(chunk) {
            Ok(()) => Ok(Async::Ready(IO::Value(()))),
            Err(chunk) => {
                info!("Could not send http response");
                unsent_chunk = Some(chunk);
                Ok(Async::NotReady)
            }
        }
    }))
}

// Next we define some record types which are marshalled to and from gluon. These have equivalent
// definitions in http_types.glu
field_decl! { method, uri, status, body, request, response }

type Request = record_type!{
    method => String,
    uri => String,
    body => Body
};

type Response = record_type!{
    status => u16
};

type HttpState = record_type!{
    request => Request,
    response => ResponseBody
};

fn listen(
    port: i32,
    value: WithVM<OpaqueValue<RootedThread, Handler<Response>>>,
) -> FutureResult<impl Future<Item = IO<()>, Error = vm::Error> + Send + 'static> {
    let WithVM {
        value: handler,
        vm: thread,
    } = value;

    let thread = match thread.new_thread() {
        Ok(thread) => thread,
        Err(err) => return FutureResult(Either::A(future::err(err))),
    };

    // Retrieve the `handle` function from the http module which we use to evaluate values of type
    // `Handler Response`
    type ListenFn = fn(OpaqueValue<RootedThread, Handler<Response>>, HttpState) -> IO<Response>;
    let handle: Function<RootedThread, ListenFn> = thread
        .get_global("examples.http.http.handle")
        .unwrap_or_else(|err| panic!("{}", err));

    struct Listen {
        handle: Function<RootedThread, ListenFn>,
        handler: OpaqueValue<RootedThread, Handler<Response>>,
    }

    impl Service for Listen {
        type ReqBody = hyper::Body;
        type ResBody = hyper::Body;
        type Error = hyper::Error;
        type Future =
            Box<Future<Item = http::Response<hyper::Body>, Error = hyper::Error> + Send + 'static>;

        fn call(&mut self, request: http::Request<hyper::Body>) -> Self::Future {
            let gluon_request = record_no_decl! {
                method => request.method().as_str().to_owned(),
                uri => request.uri().to_string(),
                // Since `Body` implements `Userdata` it can be directly pushed to gluon
                body => Body(Arc::new(Mutex::new(Box::new(request.into_body()
                    .map_err(|err| VmError::Message(format!("{}", err)))
                    // `PushAsRef` makes the `body` parameter act as a `&[u8]` which means it is
                    // marshalled to `Array Byte` in gluon
                    .map(PushAsRef::<_, [u8]>::new)))))
            };
            let (response_sender, response_body) = hyper::Body::channel();
            let response_sender = Arc::new(Mutex::new(Some(response_sender)));
            let http_state = record_no_decl!{
                request => gluon_request,
                response => ResponseBody(response_sender.clone())
            };

            Box::new(
                self.handle
                    .clone()
                    .call_async(self.handler.clone(), http_state)
                    .then(move |result| match result {
                        Ok(value) => {
                            match value {
                                IO::Value(record_p!{ status }) => {
                                    // Drop the sender to so that it the receiver stops waiting for
                                    // more chunks
                                    *response_sender.lock().unwrap() = None;

                                    let status = StatusCode::from_u16(status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
                                    Ok(
                                        http::Response::builder()
                                            .status(status)
                                            .body(response_body).unwrap(),
                                    )
                                }
                                IO::Exception(err) => {
                                    eprintln!("{}", err);
                                    Ok(
                                        http::Response::builder()
                                            .status(StatusCode::INTERNAL_SERVER_ERROR).body("".into()).unwrap()
                                    )
                                }
                            }
                        }
                        Err(err) => {
                            eprintln!("{}", err);
                            Ok(http::Response::builder()
                                .status(StatusCode::INTERNAL_SERVER_ERROR)
                                .body("".into())
                                .unwrap())
                        }
                    }),
            )
        }
    }

    let addr = format!("127.0.0.1:{}", port).parse().unwrap();

    let (sender, receiver) = oneshot::channel();
    tokio::spawn(
        Server::bind(&addr)
            .serve(move || -> Result<_, hyper::Error> {
                Ok(Listen {
                    handle: handle.clone(),
                    handler: handler.clone(),
                })
            })
            .map_err(|err| {
                error!("{}", err);
            })
            .and_then(|_| sender.send(IO::Value(())).map_err(|_| ())),
    );
    FutureResult(Either::B(
        receiver.map_err(|err| vm::Error::from(format!("Server error: {}", err))),
    ))
}

// To let the `http_types` module refer to `Body` and `ResponseBody` we register these types in a
// separate function which is called before loading `http_types`
pub fn load_types(vm: &Thread) -> VmResult<ExternModule> {
    vm.register_type::<Body>("Body", &[])?;
    vm.register_type::<ResponseBody>("ResponseBody", &[])?;

    ExternModule::new(
        vm,
        record! {
            // Define the types so that they can be used from gluon
            type Body => Body,
            type ResponseBody => ResponseBody,
            type Method => String,
            type StatusCode => u16,
            type Request => Request,
            type Response => Response,
            type HttpState => HttpState
        },
    )
}

pub fn load(vm: &Thread) -> VmResult<ExternModule> {
    ExternModule::new(
        vm,
        record! {
            listen => primitive!(2 listen),
            read_chunk => primitive!(1 read_chunk),
            write_response => primitive!(2 write_response)
        },
    )
}

fn main() {
    env_logger::init();

    let port = env::args()
        .nth(1)
        .map(|port| port.parse::<u16>().expect("port"))
        .unwrap_or(80);

    let thread = new_vm();
    tokio::run(start(&thread, port).map_err(|err| panic!("{}", err)));
}

fn start(
    thread: &Thread,
    port: u16,
) -> impl Future<Item = (), Error = Box<StdError + Send + Sync + 'static>> {
    add_extern_module(&thread, "http.prim_types", load_types);
    add_extern_module(&thread, "http.prim", load);

    let thread = thread.root_thread();
    future::lazy(|| -> Result<_, Box<StdError + Send + Sync>> {
        // Last we run our `http_server.glu` module which returns a function which starts listening
        // on the port we passed from the command line
        let mut expr = String::new();
        {
            let mut file = File::open("examples/http/server.glu")?;
            file.read_to_string(&mut expr)?;
        }
        Ok(expr)
    }).and_then(move |expr| {
        Compiler::new()
            .run_expr_async::<OwnedFunction<fn(u16) -> IO<()>>>(
                &thread,
                "examples/http/server.glu",
                &expr,
            )
            .from_err()
            .and_then(move |(mut listen, _)| {
                FutureValue::Future(listen.call_async(port))
                    .from_err()
                    .map(|_| ())
            })
    })
}

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

    extern crate tokio_retry;

    use std::str;

    use hyper::Client;

    use tokio::runtime::Runtime;

    #[test]
    fn hello_world() {
        let mut runtime = Runtime::new().unwrap();

        let port = 12235;
        let thread = new_vm();

        runtime.spawn(future::lazy(move || {
            start(&thread, port).map_err(|err| error!("{}", err))
        }));

        let future =
            move || Client::new().get(format!("http://localhost:{}", port).parse().unwrap());

        let retry_strategy = tokio_retry::strategy::FixedInterval::from_millis(400).take(40);

        runtime
            .block_on(
                tokio_retry::Retry::spawn(retry_strategy, future)
                    .map_err(|err| panic!("{}", err))
                    .and_then(|response| {
                        response.into_body().concat2().map(|body| {
                            assert_eq!(str::from_utf8(&body).unwrap(), "Hello World");
                        })
                    }),
            )
            .unwrap();
    }

    #[test]
    fn echo() {
        let mut runtime = Runtime::new().unwrap();

        let port = 12234;
        let thread = new_vm();
        runtime.spawn(future::lazy(move || {
            start(&thread, port).map_err(|err| error!("{}", err))
        }));

        let future = move || {
            let request = hyper::Request::post(format!("http://localhost:{}/echo", port))
                .body(hyper::Body::from("test"))
                .unwrap();

            Client::new().request(request)
        };

        let retry_strategy = tokio_retry::strategy::FixedInterval::from_millis(400).take(40);

        runtime
            .block_on(
                tokio_retry::Retry::spawn(retry_strategy, future)
                    .map_err(|err| panic!("{}", err))
                    .and_then(|response| {
                        response.into_body().concat2().map(|body| {
                            assert_eq!(str::from_utf8(&body).unwrap(), "test");
                        })
                    }),
            )
            .unwrap();
    }
}
<|endoftext|>


<commit_before>#[cfg(target_arch = "x86")]
pub const ULONG_SIZE: usize = 4;

#[cfg(target_arch = "x86_64")]
pub const ULONG_SIZE: usize = 8;

#[cfg(target_arch = "x86")]
pub const MACH2PHYS_VIRT_START: usize = 0xF5800000;

#[cfg(target_arch = "x86_64")]
pub const MACH2PHYS_VIRT_START: usize = 0xFFFF800000000000;

pub const XEN_LEGACY_MAX_VCPUS: usize = 32;

/// unsigned long
pub type Ulong = usize;

/// xen_pfn_t
pub type Pfn = Ulong;

/// struct arch_vcpu_info
#[repr(C)]
pub struct ArchVcpuInfo {
    pub cr2: Ulong,
    pub pad: [Ulong; 5],
}

/// struct arch_shared_info
#[repr(C)]
pub struct ArchSharedInfo {
    pub max_pfn: Ulong,
    pub pfn_to_mfn_frame_list_list: Ulong,
    pub nmi_reason: Ulong,
}
<commit_msg>libxen: Add definition of FLAT_KERNEL_CS<commit_after>#[cfg(target_arch = "x86")]
mod defs {
    pub const ULONG_SIZE: usize = 4;
    pub const MACH2PHYS_VIRT_START: usize = 0xF5800000;
    pub const FLAT_KERNEL_CS: u16 = 0xe019;
}

#[cfg(target_arch = "x86_64")]
mod defs {
    pub const ULONG_SIZE: usize = 8;
    pub const MACH2PHYS_VIRT_START: usize = 0xFFFF800000000000;
    pub const FLAT_KERNEL_CS: u16 = 0xe033;
}

pub use self::defs::*;

pub const XEN_LEGACY_MAX_VCPUS: usize = 32;

/// unsigned long
pub type Ulong = usize;

/// xen_pfn_t
pub type Pfn = Ulong;

/// struct arch_vcpu_info
#[repr(C)]
pub struct ArchVcpuInfo {
    pub cr2: Ulong,
    pub pad: [Ulong; 5],
}

/// struct arch_shared_info
#[repr(C)]
pub struct ArchSharedInfo {
    pub max_pfn: Ulong,
    pub pfn_to_mfn_frame_list_list: Ulong,
    pub nmi_reason: Ulong,
}
<|endoftext|>


<commit_before>//! Functions for computing [local binary patterns](https://en.wikipedia.org/wiki/Local_binary_patterns).

use image::{
    GenericImage,
    Luma
};
use std::cmp;

/// Computes the basic local binary pattern of a pixel, or None
/// if it's too close to the image boundary.
pub fn local_binary_pattern<I>(image: &I, x: u32, y: u32) -> Option<u8>
    where I: GenericImage<Pixel=Luma<u8>> {

    let (width, height) = image.dimensions();
    if width == 0 || height == 0 {
        return None;
    }

    // TODO: It might be better to make this function private, and
    // TODO: require the caller to only provide valid x and y coordinates.
    if x == 0 || x >= width - 1 || y == 0 || y >= height - 1 {
        return None;
    }

    // TODO: As with the fast corner detectors, this would be more efficient if
    // TODO: generated a list of pixel offsets once per image, and used those
    // TODO: offsets directly when reading pixels. To do this we'd need some traits
    // TODO: for images whose pixels are stored in contiguous rows/columns.
    let mut pattern = 0u8;

    let center = image.get_pixel(x, y)[0];

    // The sampled pixels have the following labels.
    //
    // 7  0  1
    // 6  p  2
    // 5  4  3
    //
    // The nth bit of a pattern is 1 if the pixel p
    // is strictly brighter than the neighbor in position n.
    let neighbors = [
        image.get_pixel(x    , y - 1)[0],
        image.get_pixel(x + 1, y - 1)[0],
        image.get_pixel(x + 1, y    )[0],
        image.get_pixel(x + 1, y + 1)[0],
        image.get_pixel(x    , y + 1)[0],
        image.get_pixel(x - 1, y + 1)[0],
        image.get_pixel(x - 1, y    )[0],
        image.get_pixel(x - 1, y - 1)[0]
    ];

    for i in 0..8 {
        pattern |= (1 & (neighbors[i] < center) as u8) << i;
    }

    Some(pattern)
}

// TODO: add lookup tables from pattern to pattern class, one just assigning
// TODO: the least circular shift and the other lumping all non-uniform patterns together

/// Returns the least value of all rotations of a byte.
pub fn min_shift(byte: u8) -> u8 {
    let mut min = byte;
    for i in 1..8 {
        min = cmp::min(min, byte.rotate_right(i));
    }
    min
}

/// Lookup table for the least value of all rotations of a byte.
let static MIN_SHIFT: [u8; 256] = [
0,   // 0
1,   // 1
1,   // 2
3,   // 3
1,   // 4
5,   // 5
3,   // 6
7,   // 7
1,   // 8
9,   // 9
5,   // 10
11,  // 11
3,   // 12
13,  // 13
7,   // 14
15,  // 15
1,   // 16
17,  // 17
9,   // 18
19,  // 19
5,   // 20
21,  // 21
11,  // 22
23,  // 23
3,   // 24
25,  // 25
13,  // 26
27,  // 27
7,   // 28
29,  // 29
15,  // 30
31,  // 31
1,   // 32
9,   // 33
17,  // 34
25,  // 35
9,   // 36
37,  // 37
19,  // 38
39,  // 39
5,   // 40
37,  // 41
21,  // 42
43,  // 43
11,  // 44
45,  // 45
23,  // 46
47,  // 47
3,   // 48
19,  // 49
25,  // 50
51,  // 51
13,  // 52
53,  // 53
27,  // 54
55,  // 55
7,   // 56
39,  // 57
29,  // 58
59,  // 59
15,  // 60
61,  // 61
31,  // 62
63,  // 63
1,   // 64
5,   // 65
9,   // 66
13,  // 67
17,  // 68
21,  // 69
25,  // 70
29,  // 71
9,   // 72
37,  // 73
37,  // 74
45,  // 75
19,  // 76
53,  // 77
39,  // 78
61,  // 79
5,   // 80
21,  // 81
37,  // 82
53,  // 83
21,  // 84
85,  // 85
43,  // 86
87,  // 87
11,  // 88
43,  // 89
45,  // 90
91,  // 91
23,  // 92
87,  // 93
47,  // 94
95,  // 95
3,   // 96
11,  // 97
19,  // 98
27,  // 99
25,  // 100
43,  // 101
51,  // 102
59,  // 103
13,  // 104
45,  // 105
53,  // 106
91,  // 107
27,  // 108
91,  // 109
55,  // 110
111, // 111
7,   // 112
23,  // 113
39,  // 114
55,  // 115
29,  // 116
87,  // 117
59,  // 118
119, // 119
15,  // 120
47,  // 121
61,  // 122
111, // 123
31,  // 124
95,  // 125
63,  // 126
127, // 127
1,   // 128
3,   // 129
5,   // 130
7,   // 131
9,   // 132
11,  // 133
13,  // 134
15,  // 135
17,  // 136
19,  // 137
21,  // 138
23,  // 139
25,  // 140
27,  // 141
29,  // 142
31,  // 143
9,   // 144
25,  // 145
37,  // 146
39,  // 147
37,  // 148
43,  // 149
45,  // 150
47,  // 151
19,  // 152
51,  // 153
53,  // 154
55,  // 155
39,  // 156
59,  // 157
61,  // 158
63,  // 159
5,   // 160
13,  // 161
21,  // 162
29,  // 163
37,  // 164
45,  // 165
53,  // 166
61,  // 167
21,  // 168
53,  // 169
85,  // 170
87,  // 171
43,  // 172
91,  // 173
87,  // 174
95,  // 175
11,  // 176
27,  // 177
43,  // 178
59,  // 179
45,  // 180
91,  // 181
91,  // 182
111, // 183
23,  // 184
55,  // 185
87,  // 186
119, // 187
47,  // 188
111, // 189
95,  // 190
127, // 191
3,   // 192
7,   // 193
11,  // 194
15,  // 195
19,  // 196
23,  // 197
27,  // 198
31,  // 199
25,  // 200
39,  // 201
43,  // 202
47,  // 203
51,  // 204
55,  // 205
59,  // 206
63,  // 207
13,  // 208
29,  // 209
45,  // 210
61,  // 211
53,  // 212
87,  // 213
91,  // 214
95,  // 215
27,  // 216
59,  // 217
91,  // 218
111, // 219
55,  // 220
119, // 221
111, // 222
127, // 223
7,   // 224
15,  // 225
23,  // 226
31,  // 227
39,  // 228
47,  // 229
55,  // 230
63,  // 231
29,  // 232
61,  // 233
87,  // 234
95,  // 235
59,  // 236
111, // 237
119, // 238
127, // 239
15,  // 240
31,  // 241
47,  // 242
63,  // 243
61,  // 244
95,  // 245
111, // 246
127, // 247
31,  // 248
63,  // 249
95,  // 250
127, // 251
63,  // 252
127, // 253
127, // 254
255, // 255
];

#[cfg(test)]
mod test {

    use super::{
        local_binary_pattern,
        min_shift
    };
    use image::{
        GenericImage,
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_local_binary_pattern() {

        let image: GrayImage = ImageBuffer::from_raw(3, 3, vec![
            06, 11, 14,
            09, 10, 10,
            19, 00, 22]).unwrap();

        let expected = 0b11010000;
        let pattern = local_binary_pattern(&image, 1, 1).unwrap();

        assert_eq!(pattern, expected);
    }

    #[test]
    fn test_min_shift() {
        let byte = 0b10110100;
        assert_eq!(min_shift(byte), 0b00101101);
    }
}
<commit_msg>Add count_transitions<commit_after>//! Functions for computing [local binary patterns](https://en.wikipedia.org/wiki/Local_binary_patterns).

use image::{
    GenericImage,
    Luma
};
use std::cmp;

/// Computes the basic local binary pattern of a pixel, or None
/// if it's too close to the image boundary.
pub fn local_binary_pattern<I>(image: &I, x: u32, y: u32) -> Option<u8>
    where I: GenericImage<Pixel=Luma<u8>> {

    let (width, height) = image.dimensions();
    if width == 0 || height == 0 {
        return None;
    }

    // TODO: It might be better to make this function private, and
    // TODO: require the caller to only provide valid x and y coordinates.
    if x == 0 || x >= width - 1 || y == 0 || y >= height - 1 {
        return None;
    }

    // TODO: As with the fast corner detectors, this would be more efficient if
    // TODO: generated a list of pixel offsets once per image, and used those
    // TODO: offsets directly when reading pixels. To do this we'd need some traits
    // TODO: for images whose pixels are stored in contiguous rows/columns.
    let mut pattern = 0u8;

    let center = image.get_pixel(x, y)[0];

    // The sampled pixels have the following labels.
    //
    // 7  0  1
    // 6  p  2
    // 5  4  3
    //
    // The nth bit of a pattern is 1 if the pixel p
    // is strictly brighter than the neighbor in position n.
    let neighbors = [
        image.get_pixel(x    , y - 1)[0],
        image.get_pixel(x + 1, y - 1)[0],
        image.get_pixel(x + 1, y    )[0],
        image.get_pixel(x + 1, y + 1)[0],
        image.get_pixel(x    , y + 1)[0],
        image.get_pixel(x - 1, y + 1)[0],
        image.get_pixel(x - 1, y    )[0],
        image.get_pixel(x - 1, y - 1)[0]
    ];

    for i in 0..8 {
        pattern |= (1 & (neighbors[i] < center) as u8) << i;
    }

    Some(pattern)
}

// TODO: add lookup tables from pattern to pattern class, one just assigning
// TODO: the least circular shift and the other lumping all non-uniform patterns together

/// Returns the least value of all rotations of a byte.
pub fn min_shift(byte: u8) -> u8 {
    let mut min = byte;
    for i in 1..8 {
        min = cmp::min(min, byte.rotate_right(i));
    }
    min
}

/// Number of bit transitions in a byte, counting the last and final bits as adjacent.
pub fn count_transitions(byte: u8) -> u32 {
    (byte ^ byte.rotate_right(1)).count_ones()
}

/// Lookup table for the least value of all rotations of a byte.
pub static MIN_SHIFT: [u8; 256] = [
0,   // 0
1,   // 1
1,   // 2
3,   // 3
1,   // 4
5,   // 5
3,   // 6
7,   // 7
1,   // 8
9,   // 9
5,   // 10
11,  // 11
3,   // 12
13,  // 13
7,   // 14
15,  // 15
1,   // 16
17,  // 17
9,   // 18
19,  // 19
5,   // 20
21,  // 21
11,  // 22
23,  // 23
3,   // 24
25,  // 25
13,  // 26
27,  // 27
7,   // 28
29,  // 29
15,  // 30
31,  // 31
1,   // 32
9,   // 33
17,  // 34
25,  // 35
9,   // 36
37,  // 37
19,  // 38
39,  // 39
5,   // 40
37,  // 41
21,  // 42
43,  // 43
11,  // 44
45,  // 45
23,  // 46
47,  // 47
3,   // 48
19,  // 49
25,  // 50
51,  // 51
13,  // 52
53,  // 53
27,  // 54
55,  // 55
7,   // 56
39,  // 57
29,  // 58
59,  // 59
15,  // 60
61,  // 61
31,  // 62
63,  // 63
1,   // 64
5,   // 65
9,   // 66
13,  // 67
17,  // 68
21,  // 69
25,  // 70
29,  // 71
9,   // 72
37,  // 73
37,  // 74
45,  // 75
19,  // 76
53,  // 77
39,  // 78
61,  // 79
5,   // 80
21,  // 81
37,  // 82
53,  // 83
21,  // 84
85,  // 85
43,  // 86
87,  // 87
11,  // 88
43,  // 89
45,  // 90
91,  // 91
23,  // 92
87,  // 93
47,  // 94
95,  // 95
3,   // 96
11,  // 97
19,  // 98
27,  // 99
25,  // 100
43,  // 101
51,  // 102
59,  // 103
13,  // 104
45,  // 105
53,  // 106
91,  // 107
27,  // 108
91,  // 109
55,  // 110
111, // 111
7,   // 112
23,  // 113
39,  // 114
55,  // 115
29,  // 116
87,  // 117
59,  // 118
119, // 119
15,  // 120
47,  // 121
61,  // 122
111, // 123
31,  // 124
95,  // 125
63,  // 126
127, // 127
1,   // 128
3,   // 129
5,   // 130
7,   // 131
9,   // 132
11,  // 133
13,  // 134
15,  // 135
17,  // 136
19,  // 137
21,  // 138
23,  // 139
25,  // 140
27,  // 141
29,  // 142
31,  // 143
9,   // 144
25,  // 145
37,  // 146
39,  // 147
37,  // 148
43,  // 149
45,  // 150
47,  // 151
19,  // 152
51,  // 153
53,  // 154
55,  // 155
39,  // 156
59,  // 157
61,  // 158
63,  // 159
5,   // 160
13,  // 161
21,  // 162
29,  // 163
37,  // 164
45,  // 165
53,  // 166
61,  // 167
21,  // 168
53,  // 169
85,  // 170
87,  // 171
43,  // 172
91,  // 173
87,  // 174
95,  // 175
11,  // 176
27,  // 177
43,  // 178
59,  // 179
45,  // 180
91,  // 181
91,  // 182
111, // 183
23,  // 184
55,  // 185
87,  // 186
119, // 187
47,  // 188
111, // 189
95,  // 190
127, // 191
3,   // 192
7,   // 193
11,  // 194
15,  // 195
19,  // 196
23,  // 197
27,  // 198
31,  // 199
25,  // 200
39,  // 201
43,  // 202
47,  // 203
51,  // 204
55,  // 205
59,  // 206
63,  // 207
13,  // 208
29,  // 209
45,  // 210
61,  // 211
53,  // 212
87,  // 213
91,  // 214
95,  // 215
27,  // 216
59,  // 217
91,  // 218
111, // 219
55,  // 220
119, // 221
111, // 222
127, // 223
7,   // 224
15,  // 225
23,  // 226
31,  // 227
39,  // 228
47,  // 229
55,  // 230
63,  // 231
29,  // 232
61,  // 233
87,  // 234
95,  // 235
59,  // 236
111, // 237
119, // 238
127, // 239
15,  // 240
31,  // 241
47,  // 242
63,  // 243
61,  // 244
95,  // 245
111, // 246
127, // 247
31,  // 248
63,  // 249
95,  // 250
127, // 251
63,  // 252
127, // 253
127, // 254
255, // 255
];

#[cfg(test)]
mod test {

    use super::{
        count_transitions,
        local_binary_pattern,
        min_shift
    };
    use image::{
        GenericImage,
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_local_binary_pattern() {

        let image: GrayImage = ImageBuffer::from_raw(3, 3, vec![
            06, 11, 14,
            09, 10, 10,
            19, 00, 22]).unwrap();

        let expected = 0b11010000;
        let pattern = local_binary_pattern(&image, 1, 1).unwrap();

        assert_eq!(pattern, expected);
    }

    #[test]
    fn test_min_shift() {
        let byte = 0b10110100;
        assert_eq!(min_shift(byte), 0b00101101);
    }

    #[test]
    fn test_count_transitons() {
        let a = 0b11110000;
        assert_eq!(count_transitions(a), 2);
        let b = 0b00000000;
        assert_eq!(count_transitions(b), 0);
        let c = 0b10011001;
        assert_eq!(count_transitions(c), 3);
        let d = 0b1011001;
        assert_eq!(count_transitions(d), 4);
    }
}
<|endoftext|>


<commit_before>use memory::Frame;

pub struct Entry(u64);

impl Entry {
    pub fn unused(&self) -> bool {
        self.0 == 0
    }

    pub fn set_unused(&mut self) {
        self.0 = 0;
    }

    pub fn flags(&self) -> EntryFlags {
        EntryFlags::from_bits_truncate(self.0)
    }

    pub fn pointed_frame(&self) -> Option<Frame> {
        if self.flags().contains(PRESENT) {
            Some(Frame { number: ((self.0 & 0x000fffff_fffff000) >> 12) as usize })
        } else {
            None
        }
    }

    pub fn set(&mut self, frame: Frame, flags: EntryFlags) {
        let frame_addr = (frame.number << 12) & 0x000fffff_fffff000;
        self.0 = (frame_addr as u64) | flags.bits();
    }
}

bitflags! {
    flags EntryFlags: u64 {
        const PRESENT =         1 << 0,
        const WRITABLE =        1 << 1,
        const USER_ACCESSIBLE = 1 << 2,
        const WRITE_THROUGH =   1 << 3,
        const NO_CACHE =        1 << 4,
        const ACCESSED =        1 << 5,
        const DIRTY =           1 << 6,
        const HUGE_PAGE =       1 << 7,
        const GLOBAL =          1 << 8,
        const NO_EXECUTE =      1 << 63,
    }
}
<commit_msg>Use Frame::containing_address<commit_after>use memory::Frame;

pub struct Entry(u64);

impl Entry {
    pub fn unused(&self) -> bool {
        self.0 == 0
    }

    pub fn set_unused(&mut self) {
        self.0 = 0;
    }

    pub fn flags(&self) -> EntryFlags {
        EntryFlags::from_bits_truncate(self.0)
    }

    pub fn pointed_frame(&self) -> Option<Frame> {
        if self.flags().contains(PRESENT) {
            Some(Frame::containing_address(self.0 as usize & 0x000fffff_fffff000))
        } else {
            None
        }
    }

    pub fn set(&mut self, frame: Frame, flags: EntryFlags) {
        let frame_addr = (frame.number << 12) & 0x000fffff_fffff000;
        self.0 = (frame_addr as u64) | flags.bits();
    }
}

bitflags! {
    flags EntryFlags: u64 {
        const PRESENT =         1 << 0,
        const WRITABLE =        1 << 1,
        const USER_ACCESSIBLE = 1 << 2,
        const WRITE_THROUGH =   1 << 3,
        const NO_CACHE =        1 << 4,
        const ACCESSED =        1 << 5,
        const DIRTY =           1 << 6,
        const HUGE_PAGE =       1 << 7,
        const GLOBAL =          1 << 8,
        const NO_EXECUTE =      1 << 63,
    }
}
<|endoftext|>


<commit_before>use std::num;

pub trait Addressable<ADDR: Int, DATA: Int> {
	pub fn get (&self, addr: ADDR) -> DATA;
	pub fn set (&mut self, addr: ADDR, data: DATA);
}

// FIXME: With default methods, we won't need this anymore
trait AddressableUtil<ADDR: Int, DATA: Int> {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int+Copy, DATA: Int, A: Addressable<ADDR, DATA>> AddressableUtil<ADDR, DATA> for A {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}
}

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

	struct DummyData;
	impl Addressable<u16, u8> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x12), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x12, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<commit_msg>No need for an address to be copyable now that endian methods do bit shifting<commit_after>use std::num;

pub trait Addressable<ADDR: Int, DATA: Int> {
	pub fn get (&self, addr: ADDR) -> DATA;
	pub fn set (&mut self, addr: ADDR, data: DATA);
}

// FIXME: With default methods, we won't need this anymore
trait AddressableUtil<ADDR: Int, DATA: Int> {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T;
	pub fn get_le<T: Int> (&self, addr: ADDR) -> T;
	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T);
	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T);
}

impl<ADDR: Int, DATA: Int, A: Addressable<ADDR, DATA>> AddressableUtil<ADDR, DATA> for A {
	pub fn get_be<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn get_le<T: Int> (&self, addr: ADDR) -> T {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mut val = num::Zero::zero::<T>();
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: T = num::cast(self.get(addr + num::cast(i)));
			val = val + (d << shift);
		}
		val
	}

	pub fn set_be<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast((count-i-1) * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}

	pub fn set_le<T: Int> (&mut self, addr: ADDR, val: T) {
		assert!(num::Primitive::bits::<T>() % num::Primitive::bits::<DATA>() == 0);
		let count = num::Primitive::bits::<T>() / num::Primitive::bits::<DATA>();
		let mask = (1 << num::Primitive::bits::<DATA>()) - 1;
		let mut i = count;
		while i > 0 {
			i -= 1;
			let shift: T = num::cast(i * num::Primitive::bits::<DATA>());
			let d: DATA = num::cast((val >> shift) & num::cast(mask));
			self.set(addr + num::cast(i), d);
		}
	}
}

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

	struct DummyData;
	impl Addressable<u16, u8> for DummyData {
		pub fn get (&self, addr: u16) -> u8 {
			addr as u8
		}
		pub fn set (&mut self, addr: u16, data: u8) {
			assert_eq!(data, addr as u8);
		}
	}

	#[test]
	fn test_get () {
		let data = DummyData;
		assert_eq!(data.get(0x12), 0x12);
		assert_eq!(data.get(0x1234), 0x34);
	}

	#[test]
	fn test_get_big_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_be(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_be(0x0054_u16));
		assert_eq!(    0x0203_u16, data.get_be(0x0002_u16));
		assert_eq!(    0x5455_u16, data.get_be(0x0054_u16));
		assert_eq!(0x02030405_u32, data.get_be(0x0002_u16));
		assert_eq!(0x54555657_u32, data.get_be(0x0054_u16));
	}

	#[test]
	fn test_get_little_endian () {
		let data = DummyData;
		assert_eq!(      0x02_u8 , data.get_le(0x0002_u16));
		assert_eq!(      0x54_u8 , data.get_le(0x0054_u16));
		assert_eq!(    0x0302_u16, data.get_le(0x0002_u16));
		assert_eq!(    0x5554_u16, data.get_le(0x0054_u16));
		assert_eq!(0x05040302_u32, data.get_le(0x0002_u16));
		assert_eq!(0x57565554_u32, data.get_le(0x0054_u16));
	}

	#[test]
	fn test_set () {
		let mut data = DummyData;
		data.set(0x12, 0x12);
		data.set(0x1234, 0x34);
	}

	#[test]
	fn test_set_big_endian () {
		let mut data = DummyData;
		data.set_be(0x0002_u16, 0x02_u8);
		data.set_be(0x0054_u16, 0x54_u8);
		data.set_be(0x0002_u16, 0x0203_u16);
		data.set_be(0x0054_u16, 0x5455_u16);
		data.set_be(0x0002_u16, 0x02030405_u32);
		data.set_be(0x0054_u16, 0x54555657_u32);
	}

	#[test]
	fn test_set_little_endian () {
		let mut data = DummyData;
		data.set_le(0x0002_u16, 0x02_u8);
		data.set_le(0x0054_u16, 0x54_u8);
		data.set_le(0x0002_u16, 0x0302_u16);
		data.set_le(0x0054_u16, 0x5554_u16);
		data.set_le(0x0002_u16, 0x05040302_u32);
		data.set_le(0x0054_u16, 0x57565554_u32);
	}
}
<|endoftext|>