<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

#![forbid(unsafe_code)]

use config_builder::FullNodeConfig;
use libra_config::config::{NodeConfig, PersistableConfig};
use parity_multiaddr::Multiaddr;
use std::{convert::TryInto, fs, path::PathBuf};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(about = "Tool to create Libra Validator Configs")]
struct Args {
    // Describe the validator networrk
    #[structopt(short = "n", long, default_value = "1")]
    /// Specify the number of nodes to configure
    nodes: usize,
    #[structopt(short = "s", long)]
    /// Use the provided seed for generating keys for each of the validators
    seed: Option<String>,

    // Parameters for this full node config
    #[structopt(short = "a", long, parse(from_str = parse_addr))]
    /// Advertised address for this node, if this is null, listen is reused
    advertised: Multiaddr,
    #[structopt(short = "b", long, parse(from_str = parse_addr))]
    /// Advertised address for the first node in this test net
    bootstrap: Multiaddr,
    #[structopt(short = "d", long, parse(from_os_str))]
    /// The data directory for the configs (e.g. /opt/libra/data)
    data_dir: PathBuf,
    #[structopt(short = "c", long)]
    /// Use the provided seed for generating keys for each of the FullNodes
    full_node_seed: Option<String>,
    #[structopt(short = "f", long, default_value = "1")]
    /// Total number of full nodes
    full_nodes: usize,
    #[structopt(short = "i", long, default_value = "0")]
    /// Specify the index into the number of nodes to write to output dir
    index: usize,
    #[structopt(short = "l", long, parse(from_str = parse_addr))]
    /// Listening address for this node
    listen: Multiaddr,
    #[structopt(short = "o", long, parse(from_os_str))]
    /// The output directory, note if a config exists already here, it will be updated to include
    /// this full node network
    output_dir: PathBuf,
    #[structopt(short = "p", long)]
    /// Public network, doesn't use any authentication or encryption
    public: bool,
    #[structopt(short = "t", long, parse(from_os_str))]
    /// Path to a template NodeConfig
    template: Option<PathBuf>,
}

fn parse_addr(src: &str) -> Multiaddr {
    src.parse::<Multiaddr>().unwrap()
}

fn main() {
    let args = Args::from_args();

    let template = if let Some(template_path) = args.template {
        NodeConfig::load(template_path).expect("Unable to load template")
    } else {
        NodeConfig::default()
    };

    let mut config_builder = FullNodeConfig::new();
    config_builder
        .advertised(args.advertised)
        .bootstrap(args.bootstrap)
        .full_node_index(args.index)
        .full_nodes(args.full_nodes)
        .listen(args.listen)
        .nodes(args.nodes)
        .template(template);

    if let Some(fn_seed) = args.full_node_seed.as_ref() {
        let fn_seed = hex::decode(fn_seed).expect("Invalid hex in full node seed.");
        config_builder.full_node_seed(fn_seed[..32].try_into().expect("Invalid full node seed"));
    }

    if args.public {
        config_builder.public();
    }

    if let Some(seed) = args.seed.as_ref() {
        let seed = hex::decode(seed).expect("Invalid hex in seed.");
        config_builder.seed(seed[..32].try_into().expect("Invalid seed"));
    }

    fs::create_dir_all(&args.output_dir).expect("Unable to create output directory");

    let config_file = args.output_dir.join("node.config.toml");

    let orig_config = NodeConfig::load_config(&config_file);
    let mut node_config = if let Ok(mut orig_config) = orig_config {
        if orig_config.base.role.is_validator() {
            config_builder
                .extend_validator(&mut orig_config)
                .expect("Unable to add full node network to validator");
        } else {
            config_builder
                .extend(&mut orig_config)
                .expect("Unable to append full node network");
        }
        orig_config
    } else {
        let mut new_config = config_builder.build().expect("ConfigBuilder failed");
        new_config.set_data_dir(args.data_dir);
        new_config
    };

    node_config
        .save(args.output_dir.join("node.config.toml"))
        .expect("Unable to save configs");
}
<commit_msg>[config] fix full node config<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

#![forbid(unsafe_code)]

use config_builder::FullNodeConfig;
use libra_config::config::NodeConfig;
use parity_multiaddr::Multiaddr;
use std::{convert::TryInto, fs, path::PathBuf};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(about = "Tool to create Libra Validator Configs")]
struct Args {
    // Describe the validator networrk
    #[structopt(short = "n", long, default_value = "1")]
    /// Specify the number of nodes to configure
    nodes: usize,
    #[structopt(short = "s", long)]
    /// Use the provided seed for generating keys for each of the validators
    seed: Option<String>,

    // Parameters for this full node config
    #[structopt(short = "a", long, parse(from_str = parse_addr))]
    /// Advertised address for this node, if this is null, listen is reused
    advertised: Multiaddr,
    #[structopt(short = "b", long, parse(from_str = parse_addr))]
    /// Advertised address for the first node in this test net
    bootstrap: Multiaddr,
    #[structopt(short = "d", long, parse(from_os_str))]
    /// The data directory for the configs (e.g. /opt/libra/data)
    data_dir: PathBuf,
    #[structopt(short = "c", long)]
    /// Use the provided seed for generating keys for each of the FullNodes
    full_node_seed: Option<String>,
    #[structopt(short = "f", long, default_value = "1")]
    /// Total number of full nodes
    full_nodes: usize,
    #[structopt(short = "i", long, default_value = "0")]
    /// Specify the index into the number of nodes to write to output dir
    index: usize,
    #[structopt(short = "l", long, parse(from_str = parse_addr))]
    /// Listening address for this node
    listen: Multiaddr,
    #[structopt(short = "o", long, parse(from_os_str))]
    /// The output directory, note if a config exists already here, it will be updated to include
    /// this full node network
    output_dir: PathBuf,
    #[structopt(short = "p", long)]
    /// Public network, doesn't use any authentication or encryption
    public: bool,
    #[structopt(short = "t", long, parse(from_os_str))]
    /// Path to a template NodeConfig
    template: Option<PathBuf>,
}

fn parse_addr(src: &str) -> Multiaddr {
    src.parse::<Multiaddr>().unwrap()
}

fn main() {
    let args = Args::from_args();

    let template = if let Some(template_path) = args.template {
        NodeConfig::load(template_path).expect("Unable to load template")
    } else {
        NodeConfig::default()
    };

    let mut config_builder = FullNodeConfig::new();
    config_builder
        .advertised(args.advertised)
        .bootstrap(args.bootstrap)
        .full_node_index(args.index)
        .full_nodes(args.full_nodes)
        .listen(args.listen)
        .nodes(args.nodes)
        .template(template);

    if let Some(fn_seed) = args.full_node_seed.as_ref() {
        let fn_seed = hex::decode(fn_seed).expect("Invalid hex in full node seed.");
        config_builder.full_node_seed(fn_seed[..32].try_into().expect("Invalid full node seed"));
    }

    if args.public {
        config_builder.public();
    }

    if let Some(seed) = args.seed.as_ref() {
        let seed = hex::decode(seed).expect("Invalid hex in seed.");
        config_builder.seed(seed[..32].try_into().expect("Invalid seed"));
    }

    fs::create_dir_all(&args.output_dir).expect("Unable to create output directory");

    let config_file = args.output_dir.join("node.config.toml");

    let orig_config = NodeConfig::load(&config_file);
    let mut node_config = if let Ok(mut orig_config) = orig_config {
        if orig_config.base.role.is_validator() {
            config_builder
                .extend_validator(&mut orig_config)
                .expect("Unable to add full node network to validator");
        } else {
            config_builder
                .extend(&mut orig_config)
                .expect("Unable to append full node network");
        }
        orig_config
    } else {
        let mut new_config = config_builder.build().expect("ConfigBuilder failed");
        new_config.set_data_dir(args.data_dir);
        new_config
    };

    node_config
        .save(args.output_dir.join("node.config.toml"))
        .expect("Unable to save configs");
}
<|endoftext|>


<commit_before>use std::time::{SystemTime, Duration};
use std::thread::sleep;

pub struct FrameTimer {
    n_frame_per_second_length: Duration,
    //I allocate the frame_duration varible here so that I can avoid an allocation each frame
    frame_duration: Duration,
    sleep_duration: Duration,
    frame_start: SystemTime,
    frame_end: SystemTime,
}

impl FrameTimer {
    pub fn new() -> Self {

        let sleep_duration = Duration::from_millis(0);
        //TODO: Make this more then just a 60 FPS timer
        let sixty_frames_per_second_length = Duration::from_millis(16);

        let frame_duration = Duration::from_millis(0);
        let frame_start = SystemTime::now();
        let frame_end = SystemTime::now();

        FrameTimer {
            n_frame_per_second_length: sixty_frames_per_second_length,
            frame_duration: frame_duration,
            sleep_duration: sleep_duration,
            frame_start: frame_start,
            frame_end: frame_end
        }
    }

    pub fn frame_start(&mut self) {
        self.frame_start = SystemTime::now();
    }

    pub fn frame_end(&mut self) {
        self.frame_end = SystemTime::now();
        self.frame_duration = self.frame_start.duration_since(self.frame_start).unwrap();
        if self.frame_duration.as_secs() > 0 {
            return;
        }

        if self.sleep_duration.subsec_nanos() < self.n_frame_per_second_length.subsec_nanos() {
            self.sleep_duration = self.n_frame_per_second_length - self.frame_duration;
            sleep(self.sleep_duration);
        }
    }
}<commit_msg>a test for delta time<commit_after>use std::time::{SystemTime, Duration};
use std::thread::sleep;

//John Renner
//
trait AsMillis {
    fn as_millis(&self) -> u64;
}

impl AsMillis for Duration {
    fn as_millis(&self) -> u64 {
        self.as_secs() * 1000 + (self.subsec_nanos() / 1_000_000u32) as u64
    }
}

pub struct FrameTimer {
    n_frame_per_second_length: Duration,
    //I allocate the frame_duration varible here so that I can avoid an allocation each frame
    frame_duration: Duration,
    sleep_duration: Duration,
    frame_start: SystemTime,
    frame_end: SystemTime,
    delta_time: u64
}

impl FrameTimer {
    pub fn new() -> Self {

        let sleep_duration = Duration::from_millis(0);
        //TODO: Make this more then just a 60 FPS timer
        let sixty_frames_per_second_length = Duration::from_millis(16);

        let frame_duration = Duration::from_millis(0);
        let frame_start = SystemTime::now();
        let frame_end = SystemTime::now();

        FrameTimer {
            n_frame_per_second_length: sixty_frames_per_second_length,
            frame_duration: frame_duration,
            sleep_duration: sleep_duration,
            frame_start: frame_start,
            frame_end: frame_end,
            delta_time: 0u64
        }
    }

    pub fn frame_start(&mut self) {
        self.frame_start = SystemTime::now();
    }

    pub fn delta_time(&self) -> f32 {
        (self.delta_time as f32 / 1000f32)
    }

    pub fn frame_end(&mut self) {

        self.frame_end = SystemTime::now();
        self.frame_duration = self.frame_start.duration_since(self.frame_start).unwrap();
        self.delta_time = self.frame_duration.as_millis();
        if self.frame_duration.as_secs() > 0 {
            return;
        }

        if self.sleep_duration.subsec_nanos() < self.n_frame_per_second_length.subsec_nanos() {
            self.sleep_duration = self.n_frame_per_second_length - self.frame_duration;
            sleep(self.sleep_duration);
        }
    }
}<|endoftext|>


<commit_before>//! Module that provides interaction with radare2.
//! Uses r2pipe.
#![allow(dead_code)]
use r2pipe::R2Pipe;
use rustc_serialize::json::Json;

struct R2 {
    pipe: R2Pipe,
    readin: String,
}

struct JsonWrapper<T> {
    json: Json,
    data: T,
}

// fn send and recv allow users to send their own commands, i.e. The ones that are not currently
// abstracted by the R2 API.
// Ideally, all commonly used commands must be supported for easier use.

impl R2 {
    pub fn new(path: &str) -> R2 {
        let pipe = open_pipe!(path).unwrap();
        R2 { pipe: pipe, readin: String::new() }
    }

    pub fn close(&mut self) {
        self.send("q!");
    }

    pub fn send(&mut self, cmd: &str) {
        self.readin = self.pipe.cmd(cmd);
    }

    pub fn recv(&mut self) -> String {
        let res = self.readin.clone();
        self.flush();
        res
    }

    pub fn recv_json(&mut self) -> Json {
        let res = self.recv().replace("\n", "");
        Json::from_str(&*res).unwrap()
    }

    pub fn flush(&mut self) {
        self.readin = String::from("");
    }

    pub fn analyze(&mut self) {
        self.send("aa");
        self.flush();
    }

    pub fn get_fn_list(&mut self) -> Json {
        self.send("aflj");
        self.recv_json()
    }

}

mod test {
    use frontend::r2::R2;

    #[test]
    fn test1() {
        let mut r2 = R2::new("/bin/ls");
        r2.analyze();
        println!("{}", r2.get_fn_list().as_array().unwrap()[0].find_path(&["name"]).unwrap());
        //println!("{}", r2.recv());
    }
}
<commit_msg>Added better json parsing<commit_after>//! Module that provides interaction with radare2.
//! Uses r2pipe.
#![allow(dead_code)]
use r2pipe::R2Pipe;
use rustc_serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
struct R2 {
    pipe: R2Pipe,
    readin: String,
}

pub trait Search {
    fn get_values(&self, key: &[&str], deep: bool) -> Option<Json>;
}

impl Search for Json {
    fn get_values(&self, key: &[&str], deep: bool) -> Option<Json> {
        match *self {
            Json::Array(ref arr) => {
                let mut tmp = Vec::new();
                for x in arr.iter() {
                    x.get_values(key, deep)
                     .map_or((), |e| tmp.push(e));
                }
                if tmp.len() > 0 {
                    return Some(tmp.to_json());
                }
            },

            Json::Object(ref obj) => {
                let mut result: BTreeMap<String, Json> = BTreeMap::new();
                for k in key {
                    obj.get((*k)).map_or((), |val| {
                        result.insert((*k).to_string(), val.clone());
                    });
                }

                // If we have found something, return.
                if result.keys().len() > 0 {
                    return Some(result.to_json());
                }

                // If we don't want a deep search, we just return None at this point.
                if !deep {
                    return None;
                }

                // Manually iterate through the keys and check if the values have the key.
                for (_, val) in obj.iter() {
                    let res = val.get_values(key, deep);
                    if res.is_some() {
                        return res;
                    }
                }
            },

            _ => return None,
        }
        return None;
    }
}

// fn send and recv allow users to send their own commands, i.e. The ones that are not currently
// abstracted by the R2 API.
// Ideally, all commonly used commands must be supported for easier use.

impl R2 {
    pub fn new(path: &str) -> R2 {
        let pipe = open_pipe!(path).unwrap();
        R2 { pipe: pipe, readin: String::new() }
    }

    pub fn close(&mut self) {
        self.send("q!");
    }

    pub fn send(&mut self, cmd: &str) {
        self.readin = self.pipe.cmd(cmd);
    }

    pub fn recv(&mut self) -> String {
        let res = self.readin.clone();
        self.flush();
        res
    }

    pub fn recv_json(&mut self) -> Json {
        let res = self.recv().replace("\n", "");
        Json::from_str(&*res).unwrap()
    }

    pub fn flush(&mut self) {
        self.readin = String::from("");
    }

    pub fn analyze(&mut self) {
        self.send("aa");
        self.flush();
    }

    fn build_type(&mut self) {
    }

    pub fn get_fn_list(&mut self) -> Json {
        self.send("aflj");
        self.recv_json()
    }
}

mod test {
    use frontend::r2::R2;
    use frontend::r2::Search;

    #[test]
    fn test1() {
        let mut r2 = R2::new("./key");
        r2.analyze();
        let fn_data = r2.get_fn_list();
        assert_eq!(fn_data.get_values(&["addr"], false), None);
        assert!(fn_data.get_values(&["addr"], true).is_some());
        println!("{}", fn_data.get_values(&["name", "offset"], false).unwrap().pretty());
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::ops;
use std::ops::{Range, RangeFrom, RangeTo, RangeFull};

use super::util;

// This is useful til the RangeArgument is made stable
trait FromRange {
    #[inline(always)]
    fn from_range(&self, seg: &Segment) -> (usize, usize);
}

impl FromRange for RangeFull {
    #[inline(always)]
    fn from_range(&self, seg: &Segment) -> (usize, usize) {
        return (0, seg.len());
    }
}

impl FromRange for Range<usize> {
    #[inline(always)]
    fn from_range(&self, _: &Segment) -> (usize, usize) {
        return (self.start, self.end);
    }
}

impl FromRange for RangeFrom<usize> {
    #[inline(always)]
    fn from_range(&self, seg: &Segment) -> (usize, usize) {
        return (self.start, seg.len());
    }
}

impl FromRange for RangeTo<usize> {
    #[inline(always)]
    fn from_range(&self, _: &Segment) -> (usize, usize) {
        return (0, self.end);
    }
}

pub struct Segment {
    vecs: Vec<Vec<u8>>,
    length: usize,
}

#[derive(Copy, Clone)]
struct Index {
    outer: usize,
    inner: usize,
}

pub struct Items<'a> {
    seg: &'a Segment,
    index: Index,
    num_elem: Option<usize>,
}

pub struct MutItems<'a> {
    seg: &'a mut Segment,
    index: Index,
    num_elem: Option<usize>,
}

pub struct Slices<'a> {
    seg: &'a Segment,
    outer: usize,
}

static MIN_BLOCK_SIZE: usize = 1024 * 1024;
static MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024;

impl Segment {
    /// Create a new, empty segment
    pub fn new() -> Segment {
        Segment {
            vecs: Vec::new(),
            length: 0,
        }
    }

    /// Create a segment by consuming a vec as the initial data vector
    pub fn from_vec(values: Vec<u8>) -> Segment {
        let len = values.len();
        Segment {
            vecs: vec!(values),
            length: len,
        }
    }

    /// Create a segment by copying in values from a slice
    pub fn from_slice(values: &[u8]) -> Segment {
        Segment {
            vecs: vec!(values.into()),
            length: values.len(),
        }
    }

    /// Return the length of the segment
    pub fn len(&self) -> usize {
        self.length
    }

    /// Update the saved length value so that the len func will be -O(1)
    fn calc_len(&mut self) {
        self.length = 0;
        for len in self.vecs.iter().map(|v| v.len()) {
            self.length += len
        }
    }

    /// Convert a global pos to a locall index
    fn pos_to_index(&self, pos: usize, for_insert: bool) -> Index {
        if pos == 0 {
            return Index { outer: 0, inner: 0 };
        }

        let mut cur_pos = pos;
        for (i, vec) in self.vecs.iter().enumerate() {
            if cur_pos < vec.len() || (for_insert && cur_pos == vec.len()) {
                return Index {
                    outer: i,
                    inner: cur_pos,
                }
            }
            cur_pos -= vec.len();
        }

        panic!("Position {} is out of bounds", pos);
    }

    /// Give an iterator over a given range
    pub fn iter_range<'a, R: FromRange>(&'a self, range: R) -> Items<'a> {
        let (from, to) = range.from_range(self);
        if to < from {
            panic!("to ({}) is smaller than from ({})!", to, from);
        }

        let idx = self.pos_to_index(from, false);
        Items {
            seg: self,
            index: idx,
            num_elem: Some(to - from),
        }
    }

    /// Give a mutable iterator over a given range
    pub fn mut_iter_range<'a, R: FromRange>(&'a mut self, range: R) -> MutItems<'a> {
        let (from, to) = range.from_range(self);
        if to < from {
            panic!("to ({}) is smaller than from ({})!", to, from);
        }

        let idx = self.pos_to_index(from, false);
        MutItems {
            seg: self,
            index: idx,
            num_elem: Some(to - from),
        }
    }

    /// Provide an iterator over continuous meory slices
    /// This is useful for doing an efficient save to disk
    pub fn iter_slices<'a>(&'a self) -> Slices<'a> {
        Slices {
            seg: self,
            outer: 0,
        }
    }

    /// Prepare an index for future text insertion, splitting/merging big/small sections respectively
    fn prepare_insert(&mut self, index: Index) -> Index {
        if index.outer >= self.vecs.len() {
            self.vecs.push(Vec::new());
        }

        if self.vecs[index.outer].len() < MAX_BLOCK_SIZE {
            return index;
        }

        let page_start_idx = (index.inner / MIN_BLOCK_SIZE) * MIN_BLOCK_SIZE;
        if page_start_idx == 0 {
            if self.vecs[index.outer].len() > MAX_BLOCK_SIZE {
                let insert_vec: Vec < _ >= self.vecs[index.outer][MIN_BLOCK_SIZE..].into();
                self.vecs.insert(index.outer + 1, insert_vec);
                self.vecs[index.outer].truncate(MIN_BLOCK_SIZE);
            }

            return index;
        } else {
            let insert_vec: Vec<_> = self.vecs[index.outer][page_start_idx..].into();
            self.vecs.insert(index.outer + 1, insert_vec);
            self.vecs[index.outer].truncate(page_start_idx);
            return self.prepare_insert(Index {
                outer: index.outer + 1,
                inner: index.inner - page_start_idx
            })
        }
    }

    /// insert all values from a slice into the segment
    pub fn insert(&mut self, offset: usize, values: &[u8]) {
        let mut index = self.pos_to_index(offset, true);
        index = self.prepare_insert(index);

        // This is needed for the mut borrow vec
        {
            let vec = &mut self.vecs[index.outer];
            // TODO: There has to be a better way for this range
            for val in values.into_iter().rev() {
                vec.insert(index.inner, *val);
            }
        }

        self.calc_len();
    }

    /// Moves data between start_ & end_offset out of the segment
    pub fn move_out_slice(&mut self, start_offset: usize, end_offset: usize) -> Vec<u8> {
        // TODO: Convert to drain when that settles
        assert!(start_offset <= end_offset);
        let mut res = Vec::new();
        let mut index = self.pos_to_index(start_offset, false);
        let num_elem = end_offset - start_offset;

        for _ in 0..num_elem {
            let c = self.vecs[index.outer].remove(index.inner);
            res.push(c);

            if index.inner >= self.vecs[index.outer].len() {
                if self.vecs[index.outer].len() == 0 {
                    self.vecs.remove(index.outer);
                } else {
                    index.inner = 0;
                    index.outer += 1;
                }
            }
        }

        self.calc_len();

        res
    }

    /// Find a slice inside the segment
    pub fn find_slice(&self, needle: &[u8]) -> Option<usize> {
        self.find_slice_from(0, needle)
    }

    /// Find a slice from a certain index and onward
    pub fn find_slice_from(&self, from: usize, needle: &[u8]) -> Option<usize> {
        for i in from..self.len() {
                return Some(i);
            if util::iter_equals(self.iter_range(i..i+needle.len()), needle.iter()) {
            }
        }
        None
    }

    #[cfg(test)]
    fn get_lengths(&self) -> Vec<usize> {
        self.vecs.iter().map(|v| v.len()).collect::<Vec<usize>>()
    }
}

impl ops::Index<usize> for Segment {
    type Output = u8;
    fn index<'a>(&'a self, _index: usize) -> &'a u8 {
        let idx = self.pos_to_index(_index, false);
        &self.vecs[idx.outer][idx.inner]
    }
}

impl ops::IndexMut<usize> for Segment {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut u8 {
        let idx = self.pos_to_index(_index, false);
        &mut self.vecs[idx.outer][idx.inner]
    }
}

impl fmt::Debug for Segment {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.vecs.fmt(f)
    }
}

impl<'a> Iterator for Items<'a> {
    type Item = &'a u8;
    fn next(&mut self) -> Option<&'a u8> {
        if self.index.outer >= self.seg.vecs.len() {
            return None;
        }
        if let Some(ref mut num_elem) = self.num_elem {
            if *num_elem <= 0 {
                return None;
            }
            *num_elem -= 1;
        }

        let elem = {
            let vv = &self.seg.vecs[self.index.outer];
            &vv[self.index.inner]
        };

        self.index.inner += 1;
        if self.index.inner >= self.seg.vecs[self.index.outer].len() {
            self.index.inner = 0;
            self.index.outer += 1;
        }

        Some(elem)
    }
}

impl<'a> Iterator for MutItems<'a> {
    type Item = &'a mut u8;
    fn next(&mut self) -> Option<&'a mut u8> {
        if self.index.outer >= self.seg.vecs.len() {
            return None;
        }
        if let Some(ref mut num_elem) = self.num_elem {
            if *num_elem <= 0 {
                return None;
            }
            *num_elem -= 1;
        }

        let elem_raw: *mut u8 = {
            let vv = &mut self.seg.vecs[self.index.outer];
            &mut vv[self.index.inner]
        };

        self.index.inner += 1;
        if self.index.inner >= self.seg.vecs[self.index.outer].len() {
            self.index.inner = 0;
            self.index.outer += 1;
        }

        Some(unsafe { &mut *elem_raw })
    }
}

impl<'a> Iterator for Slices<'a> {
    type Item = &'a [u8];
    fn next(&mut self) -> Option<&'a [u8]> {
        if self.outer >= self.seg.vecs.len() {
            None
        } else {
            let i = self.outer;
            self.outer += 1;
            Some(&self.seg.vecs[i])
        }
    }
}

#[test]
fn test_small_segment() {
    let size = 1024;
    let mut seg = Segment::from_vec(vec![1, 2, 3, 4, 5]);
    assert_eq!(Some(4), seg.find_slice(&[5]));

    let seg_len = seg.len();
    seg.insert(seg_len/2, &vec![1 as u8; size]);

    assert_eq!(Some(size + 4), seg.find_slice(&[5]));
}

#[test]
fn test_large_segment() {
    let big_size = 4*1024*1024;
    let small_size = 1024;
    let mut seg = Segment::from_vec(vec![0; big_size]);

    seg.insert(big_size/2, &vec![1 as u8; small_size]);

    assert_eq!(Some(big_size/2 -1), seg.find_slice(&[0, 1]));

    // Make sure we actually tested a "split" version
    let seg_lengths = seg.get_lengths();
    assert_eq!(2, seg_lengths.len());
    let index = seg_lengths[0];
    let sentinal = 100;
    seg[index] = sentinal;
    seg[index+1] = sentinal +1;
    assert_eq!(Some(index), seg.find_slice(&[sentinal, sentinal+1]));
}
<commit_msg>Fix for find_slice<commit_after>use std::fmt;
use std::ops;
use std::ops::{Range, RangeFrom, RangeTo, RangeFull};

use super::util;

// This is useful til the RangeArgument is made stable
trait FromRange {
    #[inline(always)]
    fn from_range(&self, seg: &Segment) -> (usize, usize);
}

impl FromRange for RangeFull {
    #[inline(always)]
    fn from_range(&self, seg: &Segment) -> (usize, usize) {
        return (0, seg.len());
    }
}

impl FromRange for Range<usize> {
    #[inline(always)]
    fn from_range(&self, _: &Segment) -> (usize, usize) {
        return (self.start, self.end);
    }
}

impl FromRange for RangeFrom<usize> {
    #[inline(always)]
    fn from_range(&self, seg: &Segment) -> (usize, usize) {
        return (self.start, seg.len());
    }
}

impl FromRange for RangeTo<usize> {
    #[inline(always)]
    fn from_range(&self, _: &Segment) -> (usize, usize) {
        return (0, self.end);
    }
}

pub struct Segment {
    vecs: Vec<Vec<u8>>,
    length: usize,
}

#[derive(Copy, Clone)]
struct Index {
    outer: usize,
    inner: usize,
}

pub struct Items<'a> {
    seg: &'a Segment,
    index: Index,
    num_elem: Option<usize>,
}

pub struct MutItems<'a> {
    seg: &'a mut Segment,
    index: Index,
    num_elem: Option<usize>,
}

pub struct Slices<'a> {
    seg: &'a Segment,
    outer: usize,
}

static MIN_BLOCK_SIZE: usize = 1024 * 1024;
static MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024;

impl Segment {
    /// Create a new, empty segment
    pub fn new() -> Segment {
        Segment {
            vecs: Vec::new(),
            length: 0,
        }
    }

    /// Create a segment by consuming a vec as the initial data vector
    pub fn from_vec(values: Vec<u8>) -> Segment {
        let len = values.len();
        Segment {
            vecs: vec!(values),
            length: len,
        }
    }

    /// Create a segment by copying in values from a slice
    pub fn from_slice(values: &[u8]) -> Segment {
        Segment {
            vecs: vec!(values.into()),
            length: values.len(),
        }
    }

    /// Return the length of the segment
    pub fn len(&self) -> usize {
        self.length
    }

    /// Update the saved length value so that the len func will be -O(1)
    fn calc_len(&mut self) {
        self.length = 0;
        for len in self.vecs.iter().map(|v| v.len()) {
            self.length += len
        }
    }

    /// Convert a global pos to a locall index
    fn pos_to_index(&self, pos: usize, for_insert: bool) -> Index {
        if pos == 0 {
            return Index { outer: 0, inner: 0 };
        }

        let mut cur_pos = pos;
        for (i, vec) in self.vecs.iter().enumerate() {
            if cur_pos < vec.len() || (for_insert && cur_pos == vec.len()) {
                return Index {
                    outer: i,
                    inner: cur_pos,
                }
            }
            cur_pos -= vec.len();
        }

        panic!("Position {} is out of bounds", pos);
    }

    /// Give an iterator over a given range
    pub fn iter_range<'a, R: FromRange>(&'a self, range: R) -> Items<'a> {
        let (from, to) = range.from_range(self);
        if to < from {
            panic!("to ({}) is smaller than from ({})!", to, from);
        }

        let idx = self.pos_to_index(from, false);
        Items {
            seg: self,
            index: idx,
            num_elem: Some(to - from),
        }
    }

    /// Give a mutable iterator over a given range
    pub fn mut_iter_range<'a, R: FromRange>(&'a mut self, range: R) -> MutItems<'a> {
        let (from, to) = range.from_range(self);
        if to < from {
            panic!("to ({}) is smaller than from ({})!", to, from);
        }

        let idx = self.pos_to_index(from, false);
        MutItems {
            seg: self,
            index: idx,
            num_elem: Some(to - from),
        }
    }

    /// Provide an iterator over continuous meory slices
    /// This is useful for doing an efficient save to disk
    pub fn iter_slices<'a>(&'a self) -> Slices<'a> {
        Slices {
            seg: self,
            outer: 0,
        }
    }

    /// Prepare an index for future text insertion, splitting/merging big/small sections respectively
    fn prepare_insert(&mut self, index: Index) -> Index {
        if index.outer >= self.vecs.len() {
            self.vecs.push(Vec::new());
        }

        if self.vecs[index.outer].len() < MAX_BLOCK_SIZE {
            return index;
        }

        let page_start_idx = (index.inner / MIN_BLOCK_SIZE) * MIN_BLOCK_SIZE;
        if page_start_idx == 0 {
            if self.vecs[index.outer].len() > MAX_BLOCK_SIZE {
                let insert_vec: Vec < _ >= self.vecs[index.outer][MIN_BLOCK_SIZE..].into();
                self.vecs.insert(index.outer + 1, insert_vec);
                self.vecs[index.outer].truncate(MIN_BLOCK_SIZE);
            }

            return index;
        } else {
            let insert_vec: Vec<_> = self.vecs[index.outer][page_start_idx..].into();
            self.vecs.insert(index.outer + 1, insert_vec);
            self.vecs[index.outer].truncate(page_start_idx);
            return self.prepare_insert(Index {
                outer: index.outer + 1,
                inner: index.inner - page_start_idx
            })
        }
    }

    /// insert all values from a slice into the segment
    pub fn insert(&mut self, offset: usize, values: &[u8]) {
        let mut index = self.pos_to_index(offset, true);
        index = self.prepare_insert(index);

        // This is needed for the mut borrow vec
        {
            let vec = &mut self.vecs[index.outer];
            // TODO: There has to be a better way for this range
            for val in values.into_iter().rev() {
                vec.insert(index.inner, *val);
            }
        }

        self.calc_len();
    }

    /// Moves data between start_ & end_offset out of the segment
    pub fn move_out_slice(&mut self, start_offset: usize, end_offset: usize) -> Vec<u8> {
        // TODO: Convert to drain when that settles
        assert!(start_offset <= end_offset);
        let mut res = Vec::new();
        let mut index = self.pos_to_index(start_offset, false);
        let num_elem = end_offset - start_offset;

        for _ in 0..num_elem {
            let c = self.vecs[index.outer].remove(index.inner);
            res.push(c);

            if index.inner >= self.vecs[index.outer].len() {
                if self.vecs[index.outer].len() == 0 {
                    self.vecs.remove(index.outer);
                } else {
                    index.inner = 0;
                    index.outer += 1;
                }
            }
        }

        self.calc_len();

        res
    }

    /// Find a slice inside the segment
    pub fn find_slice(&self, needle: &[u8]) -> Option<usize> {
        self.find_slice_from(0, needle)
    }

    /// Find a slice from a certain index and onward
    pub fn find_slice_from(&self, from: usize, needle: &[u8]) -> Option<usize> {
        for i in from..self.len() {
            if util::iter_equals(self.iter_range(i..i+needle.len()), needle.iter()) {
                return Some(i);
            }
        }
        None
    }

    #[cfg(test)]
    fn get_lengths(&self) -> Vec<usize> {
        self.vecs.iter().map(|v| v.len()).collect::<Vec<usize>>()
    }
}

impl ops::Index<usize> for Segment {
    type Output = u8;
    fn index<'a>(&'a self, _index: usize) -> &'a u8 {
        let idx = self.pos_to_index(_index, false);
        &self.vecs[idx.outer][idx.inner]
    }
}

impl ops::IndexMut<usize> for Segment {
    fn index_mut<'a>(&'a mut self, _index: usize) -> &'a mut u8 {
        let idx = self.pos_to_index(_index, false);
        &mut self.vecs[idx.outer][idx.inner]
    }
}

impl fmt::Debug for Segment {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.vecs.fmt(f)
    }
}

impl<'a> Iterator for Items<'a> {
    type Item = &'a u8;
    fn next(&mut self) -> Option<&'a u8> {
        if self.index.outer >= self.seg.vecs.len() {
            return None;
        }
        if let Some(ref mut num_elem) = self.num_elem {
            if *num_elem <= 0 {
                return None;
            }
            *num_elem -= 1;
        }

        let elem = {
            let vv = &self.seg.vecs[self.index.outer];
            &vv[self.index.inner]
        };

        self.index.inner += 1;
        if self.index.inner >= self.seg.vecs[self.index.outer].len() {
            self.index.inner = 0;
            self.index.outer += 1;
        }

        Some(elem)
    }
}

impl<'a> Iterator for MutItems<'a> {
    type Item = &'a mut u8;
    fn next(&mut self) -> Option<&'a mut u8> {
        if self.index.outer >= self.seg.vecs.len() {
            return None;
        }
        if let Some(ref mut num_elem) = self.num_elem {
            if *num_elem <= 0 {
                return None;
            }
            *num_elem -= 1;
        }

        let elem_raw: *mut u8 = {
            let vv = &mut self.seg.vecs[self.index.outer];
            &mut vv[self.index.inner]
        };

        self.index.inner += 1;
        if self.index.inner >= self.seg.vecs[self.index.outer].len() {
            self.index.inner = 0;
            self.index.outer += 1;
        }

        Some(unsafe { &mut *elem_raw })
    }
}

impl<'a> Iterator for Slices<'a> {
    type Item = &'a [u8];
    fn next(&mut self) -> Option<&'a [u8]> {
        if self.outer >= self.seg.vecs.len() {
            None
        } else {
            let i = self.outer;
            self.outer += 1;
            Some(&self.seg.vecs[i])
        }
    }
}

#[test]
fn test_small_segment() {
    let size = 1024;
    let mut seg = Segment::from_vec(vec![1, 2, 3, 4, 5]);
    assert_eq!(Some(4), seg.find_slice(&[5]));

    let seg_len = seg.len();
    seg.insert(seg_len/2, &vec![1 as u8; size]);

    assert_eq!(Some(size + 4), seg.find_slice(&[5]));
}

#[test]
fn test_large_segment() {
    let big_size = 4*1024*1024;
    let small_size = 1024;
    let mut seg = Segment::from_vec(vec![0; big_size]);

    seg.insert(big_size/2, &vec![1 as u8; small_size]);

    assert_eq!(Some(big_size/2 -1), seg.find_slice(&[0, 1]));

    // Make sure we actually tested a "split" version
    let seg_lengths = seg.get_lengths();
    assert_eq!(2, seg_lengths.len());
    let index = seg_lengths[0];
    let sentinal = 100;
    seg[index] = sentinal;
    seg[index+1] = sentinal +1;
    assert_eq!(Some(index), seg.find_slice(&[sentinal, sentinal+1]));
}
<|endoftext|>


<commit_before>use nom::{
  IResult,
  ErrorCode, Err,
  Needed,
};

use frame;
use frame::subframe;
use frame::SubFrame;

fn leading_zeros(input: (&[u8], usize)) -> IResult<(&[u8], usize), u32> {
  let (bytes, mut offset) = input;

  let mut index     = 0;
  let mut count     = 0;
  let mut is_parsed = false;
  let bytes_len     = bytes.len();

  for i in 0..bytes_len {
    // Clear the number of offset bits
    let byte  = bytes[i] << offset;
    let zeros = byte.leading_zeros() as usize;

    if byte > 0 {
      index     = i;
      is_parsed = true;
      count    += zeros;
      offset   += zeros + 1;

      if offset >= 8 {
        index  += 1;
        offset -= 8;
      }

      break;
    } else {
      count += zeros - offset;
      offset = 0;
    }
  }

  if is_parsed {
    IResult::Done((&bytes[index..], offset), count as u32)
  } else if index + 1 > bytes_len {
    IResult::Incomplete(Needed::Size(index + 1))
  } else {
    IResult::Error(Err::Position(ErrorCode::TakeUntil as u32, bytes))
  }
}

pub fn subframe_parser<'a>(input: (&'a [u8], usize),
                           frame_header: &frame::Header)
                           -> IResult<'a, (&'a [u8], usize), SubFrame> {
  chain!(input,
    subframe_header: header ~
    wasted_bits: map!(
      cond!(subframe_header.1, leading_zeros),
      |option: Option<u32>| option.map_or(0, |zeros| zeros + 1)
    ) ~
    subframe_data: apply!(data, frame_header, subframe_header.0 as usize,
                          wasted_bits as usize),
    || {
      SubFrame {
        data: subframe_data,
        wasted_bits: wasted_bits,
      }
    }
  )
}

fn header(input: (&[u8], usize)) -> IResult<(&[u8], usize), (u8, bool)> {
  match take_bits!(input, u8, 8) {
    IResult::Done(i, byte)    => {
      let is_valid        = (byte >> 7) == 0;
      let subframe_type   = (byte >> 1) & 0b111111;
      let has_wasted_bits = (byte & 0b01) == 1;

      if is_valid {
        IResult::Done(i, (subframe_type, has_wasted_bits))
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input.0))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn data<'a>(input: (&'a [u8], usize),
            frame_header: &frame::Header,
            subframe_type: usize,
            wasted_bits: usize)
            -> IResult<'a, (&'a [u8], usize), subframe::Data> {
  let bits_per_sample = frame_header.bits_per_sample - wasted_bits;
  let block_size      = frame_header.block_size as usize;

  match subframe_type {
    0b000000 => constant(input, bits_per_sample),
    0b000001 => verbatim(input, bits_per_sample, block_size),
    _        => IResult::Error(Err::Position(ErrorCode::Alt as u32, input.0))
  }
}

fn constant(input: (&[u8], usize), bits_per_sample: usize)
            -> IResult<(&[u8], usize), subframe::Data> {
  map!(input, take_bits!(i32, bits_per_sample), subframe::Data::Constant)
}

fn verbatim(input: (&[u8], usize), bits_per_sample: usize, block_size: usize)
            -> IResult<(&[u8], usize), subframe::Data> {
  // TODO: Use nom's `count!` macro as soon as it is fixed for bit parsers.
  map!(input, count_bits!(take_bits!(i32, bits_per_sample), block_size),
       subframe::Data::Verbatim)
}

fn unencoded_residuals<'a>(input: (&'a [u8], usize),
                           bits_per_sample: usize,
                           raw_bit: &mut u32,
                           samples: &mut [i32])
                           -> IResult<'a, (&'a[u8], usize), ()> {
  *raw_bit = bits_per_sample as u32;

  count_slice!(input, take_bits!(i32, bits_per_sample), &mut samples[..])
}

fn encoded_residuals<'a>(input: (&'a [u8], usize),
                         parameter: u32,
                         raw_bit: &mut u32,
                         samples: &mut [i32])
                         -> IResult<'a, (&'a[u8], usize), ()> {
  let length = samples.len();

  let mut count     = 0;
  let mut is_error  = false;
  let mut mut_input = input;

  *raw_bit = 0;

  for sample in samples {
    let result = chain!(mut_input,
      quotient: leading_zeros ~
      remainder: take_bits!(u32, parameter as usize),
      || {
        let value = quotient * parameter + remainder;

        ((value as i32) >> 1) ^ -((value as i32) & 1)
      });

    match result {
      IResult::Done(i, value) => {
        mut_input = i;
        count    += 1;

        *sample = value
      }
      IResult::Error(_)       => {
        is_error = true;

        break;
      }
      IResult::Incomplete(_)  => break,
    }
  }

  if is_error {
    IResult::Error(Err::Position(ErrorCode::Count as u32, input.0))
  } else if count == length {
    IResult::Done(mut_input, ())
  } else {
    IResult::Incomplete(Needed::Unknown)
  }
}
<commit_msg>Add top level `residual_data` parser<commit_after>use nom::{
  IResult,
  ErrorCode, Err,
  Needed,
};

use frame;
use frame::subframe;
use frame::SubFrame;

fn leading_zeros(input: (&[u8], usize)) -> IResult<(&[u8], usize), u32> {
  let (bytes, mut offset) = input;

  let mut index     = 0;
  let mut count     = 0;
  let mut is_parsed = false;
  let bytes_len     = bytes.len();

  for i in 0..bytes_len {
    // Clear the number of offset bits
    let byte  = bytes[i] << offset;
    let zeros = byte.leading_zeros() as usize;

    if byte > 0 {
      index     = i;
      is_parsed = true;
      count    += zeros;
      offset   += zeros + 1;

      if offset >= 8 {
        index  += 1;
        offset -= 8;
      }

      break;
    } else {
      count += zeros - offset;
      offset = 0;
    }
  }

  if is_parsed {
    IResult::Done((&bytes[index..], offset), count as u32)
  } else if index + 1 > bytes_len {
    IResult::Incomplete(Needed::Size(index + 1))
  } else {
    IResult::Error(Err::Position(ErrorCode::TakeUntil as u32, bytes))
  }
}

pub fn subframe_parser<'a>(input: (&'a [u8], usize),
                           frame_header: &frame::Header)
                           -> IResult<'a, (&'a [u8], usize), SubFrame> {
  chain!(input,
    subframe_header: header ~
    wasted_bits: map!(
      cond!(subframe_header.1, leading_zeros),
      |option: Option<u32>| option.map_or(0, |zeros| zeros + 1)
    ) ~
    subframe_data: apply!(data, frame_header, subframe_header.0 as usize,
                          wasted_bits as usize),
    || {
      SubFrame {
        data: subframe_data,
        wasted_bits: wasted_bits,
      }
    }
  )
}

fn header(input: (&[u8], usize)) -> IResult<(&[u8], usize), (u8, bool)> {
  match take_bits!(input, u8, 8) {
    IResult::Done(i, byte)    => {
      let is_valid        = (byte >> 7) == 0;
      let subframe_type   = (byte >> 1) & 0b111111;
      let has_wasted_bits = (byte & 0b01) == 1;

      if is_valid {
        IResult::Done(i, (subframe_type, has_wasted_bits))
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input.0))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn data<'a>(input: (&'a [u8], usize),
            frame_header: &frame::Header,
            subframe_type: usize,
            wasted_bits: usize)
            -> IResult<'a, (&'a [u8], usize), subframe::Data> {
  let bits_per_sample = frame_header.bits_per_sample - wasted_bits;
  let block_size      = frame_header.block_size as usize;

  match subframe_type {
    0b000000 => constant(input, bits_per_sample),
    0b000001 => verbatim(input, bits_per_sample, block_size),
    _        => IResult::Error(Err::Position(ErrorCode::Alt as u32, input.0))
  }
}

fn constant(input: (&[u8], usize), bits_per_sample: usize)
            -> IResult<(&[u8], usize), subframe::Data> {
  map!(input, take_bits!(i32, bits_per_sample), subframe::Data::Constant)
}

fn verbatim(input: (&[u8], usize), bits_per_sample: usize, block_size: usize)
            -> IResult<(&[u8], usize), subframe::Data> {
  // TODO: Use nom's `count!` macro as soon as it is fixed for bit parsers.
  map!(input, count_bits!(take_bits!(i32, bits_per_sample), block_size),
       subframe::Data::Verbatim)
}

fn residual_data<'a>(input: (&'a [u8], usize),
                     option: Option<usize>,
                     rice_parameter: u32,
                     raw_bit: &mut u32,
                     samples: &mut [i32])
                     -> IResult<'a, (&'a [u8], usize), ()> {
  if let Some(size) = option {
    unencoded_residuals(input, size, raw_bit, samples)
  } else {
    encoded_residuals(input, rice_parameter, raw_bit, samples)
  }
}

fn unencoded_residuals<'a>(input: (&'a [u8], usize),
                           bits_per_sample: usize,
                           raw_bit: &mut u32,
                           samples: &mut [i32])
                           -> IResult<'a, (&'a[u8], usize), ()> {
  *raw_bit = bits_per_sample as u32;

  count_slice!(input, take_bits!(i32, bits_per_sample), &mut samples[..])
}

fn encoded_residuals<'a>(input: (&'a [u8], usize),
                         parameter: u32,
                         raw_bit: &mut u32,
                         samples: &mut [i32])
                         -> IResult<'a, (&'a[u8], usize), ()> {
  let length = samples.len();

  let mut count     = 0;
  let mut is_error  = false;
  let mut mut_input = input;

  *raw_bit = 0;

  for sample in samples {
    let result = chain!(mut_input,
      quotient: leading_zeros ~
      remainder: take_bits!(u32, parameter as usize),
      || {
        let value = quotient * parameter + remainder;

        ((value as i32) >> 1) ^ -((value as i32) & 1)
      });

    match result {
      IResult::Done(i, value) => {
        mut_input = i;
        count    += 1;

        *sample = value
      }
      IResult::Error(_)       => {
        is_error = true;

        break;
      }
      IResult::Incomplete(_)  => break,
    }
  }

  if is_error {
    IResult::Error(Err::Position(ErrorCode::Count as u32, input.0))
  } else if count == length {
    IResult::Done(mut_input, ())
  } else {
    IResult::Incomplete(Needed::Unknown)
  }
}
<|endoftext|>


<commit_before>use time::{at_utc, Tm, Timespec};
use json::{FromJsonnable, ToJsonnable};
use serde::de::{Error, Type};
use serde_json::value::Value;
use serde_json::error::Error as JsonError;
use serde_json::builder::ObjectBuilder;

impl FromJsonnable for Tm {
	// Deserialize via Timespec
	fn from_json(json: Value) -> Result<Self, JsonError> {
		match json {
			Value::Object(map) => {
				let sec =
					match map.get("sec") {
						Some(sec) =>
							match sec {
								&Value::I64(sec) => sec,
								&Value::U64(sec) => sec as i64,  // The types get weird here
								_ => return Err(JsonError::type_mismatch(Type::I64)),
							},
						None => return Err(JsonError::missing_field("Missing \"sec\"")),
					};
				let nsec =
					match map.get("nsec") {
						Some(nsec) =>
							match nsec {
								&Value::I64(nsec) => nsec as i32,
								&Value::U64(nsec) => nsec as i32,
								_ => return Err(JsonError::type_mismatch(Type::I32)),
							},
						None => return Err(JsonError::missing_field("Missing \"nsec\"")),
					};

				Ok(at_utc(Timespec::new(sec, nsec)))
			},
			_ => Err(JsonError::type_mismatch(Type::Struct)),
		}
	}
}

impl ToJsonnable for Tm {
	// Serialize via Timespec
	fn to_json(&self) -> Value {
		let spec = self.to_timespec();
		ObjectBuilder::new().insert("sec", &spec.sec)
		                    .insert("nsec", &spec.nsec)
		                    .unwrap()
	}
}

impl<T: FromJsonnable> FromJsonnable for Vec<T> {
	fn from_json(json: Value) -> Result<Self, JsonError> {
		match json {
			Value::Array(arr) => {
				let mut elems: Vec<T> = Vec::with_capacity(arr.len());
				for elem in arr {
					match T::from_json(elem) {
						Ok(elem) => elems.push(elem),
						Err(e) => return Err(e),
					}
				}
				Ok(elems)
			},
			_ => Err(JsonError::type_mismatch(Type::Seq)),
		}
	}
}

impl<T: ToJsonnable> ToJsonnable for Vec<T> {
	fn to_json(&self) -> Value {
		Value::Array(self.iter().map(|ref elem| elem.to_json()).collect())
	}
}

macro_rules! primitive_to_json {
	($t:ty, $v:ident, $d:ty) => {
		impl ToJsonnable for $t {
			fn to_json(&self) -> Value {
				Value::$v(self.clone() as $d)
			}
		}
	};
}

macro_rules! primitive_from_json {
	($t:ty, $v:ident) => {
		impl FromJsonnable for $t {
			fn from_json(json: Value) -> Result<Self, JsonError> {
				match json {
					Value::$v(value) => Ok(value as $t),
					_ => Err(JsonError::type_mismatch(Type::$v)),
				}
			}
		}
	};
}

primitive_to_json!(i8,  I64, i64);
primitive_to_json!(i16, I64, i64);
primitive_to_json!(i32, I64, i64);
primitive_to_json!(i64, I64, i64);

primitive_to_json!(u8,  U64, u64);
primitive_to_json!(u16, U64, u64);
primitive_to_json!(u32, U64, u64);
primitive_to_json!(u64, U64, u64);

primitive_to_json!(f32, F64, f64);
primitive_to_json!(f64, F64, f64);

primitive_from_json!(i8,  I64);
primitive_from_json!(i16, I64);
primitive_from_json!(i32, I64);
primitive_from_json!(i64, I64);

primitive_from_json!(u8,  U64);
primitive_from_json!(u16, U64);
primitive_from_json!(u32, U64);
primitive_from_json!(u64, U64);

primitive_from_json!(f32, F64);
primitive_from_json!(f64, F64);
<commit_msg>Corectly handle signed numbers without a sign<commit_after>use time::{at_utc, Tm, Timespec};
use json::{FromJsonnable, ToJsonnable};
use serde::de::{Error, Type};
use serde_json::value::Value;
use serde_json::error::Error as JsonError;
use serde_json::builder::ObjectBuilder;

impl FromJsonnable for Tm {
	// Deserialize via Timespec
	fn from_json(json: Value) -> Result<Self, JsonError> {
		match json {
			Value::Object(map) => {
				let sec =
					match map.get("sec") {
						Some(sec) =>
							match sec {
								&Value::I64(sec) => sec,
								&Value::U64(sec) => sec as i64,  // The types get weird here
								_ => return Err(JsonError::type_mismatch(Type::I64)),
							},
						None => return Err(JsonError::missing_field("Missing \"sec\"")),
					};
				let nsec =
					match map.get("nsec") {
						Some(nsec) =>
							match nsec {
								&Value::I64(nsec) => nsec as i32,
								&Value::U64(nsec) => nsec as i32,
								_ => return Err(JsonError::type_mismatch(Type::I32)),
							},
						None => return Err(JsonError::missing_field("Missing \"nsec\"")),
					};

				Ok(at_utc(Timespec::new(sec, nsec)))
			},
			_ => Err(JsonError::type_mismatch(Type::Struct)),
		}
	}
}

impl ToJsonnable for Tm {
	// Serialize via Timespec
	fn to_json(&self) -> Value {
		let spec = self.to_timespec();
		ObjectBuilder::new().insert("sec", &spec.sec)
		                    .insert("nsec", &spec.nsec)
		                    .unwrap()
	}
}

impl<T: FromJsonnable> FromJsonnable for Vec<T> {
	fn from_json(json: Value) -> Result<Self, JsonError> {
		match json {
			Value::Array(arr) => {
				let mut elems: Vec<T> = Vec::with_capacity(arr.len());
				for elem in arr {
					match T::from_json(elem) {
						Ok(elem) => elems.push(elem),
						Err(e) => return Err(e),
					}
				}
				Ok(elems)
			},
			_ => Err(JsonError::type_mismatch(Type::Seq)),
		}
	}
}

impl<T: ToJsonnable> ToJsonnable for Vec<T> {
	fn to_json(&self) -> Value {
		Value::Array(self.iter().map(|ref elem| elem.to_json()).collect())
	}
}

macro_rules! primitive_to_json {
	($t:ty, $v:ident, $d:ty) => {
		impl ToJsonnable for $t {
			fn to_json(&self) -> Value {
				Value::$v(self.clone() as $d)
			}
		}
	};
}

macro_rules! primitive_from_json {
	($t:ty, $expected:ident, $($v:ident)+) => {
		impl FromJsonnable for $t {
			fn from_json(json: Value) -> Result<Self, JsonError> {
				match json {
					$(
						Value::$v(value) => Ok(value as $t),
					)+
					_ => Err(JsonError::type_mismatch(Type::$expected)),
				}
			}
		}
	};
}

primitive_to_json!(i8,  I64, i64);
primitive_to_json!(i16, I64, i64);
primitive_to_json!(i32, I64, i64);
primitive_to_json!(i64, I64, i64);

primitive_to_json!(u8,  U64, u64);
primitive_to_json!(u16, U64, u64);
primitive_to_json!(u32, U64, u64);
primitive_to_json!(u64, U64, u64);

primitive_to_json!(f32, F64, f64);
primitive_to_json!(f64, F64, f64);

primitive_from_json!(i8,  I64, I64 U64);  // Non-signed numbers are interpreted as unsigned
primitive_from_json!(i16, I64, I64 U64);
primitive_from_json!(i32, I64, I64 U64);
primitive_from_json!(i64, I64, I64 U64);

primitive_from_json!(u8,  U64, U64);
primitive_from_json!(u16, U64, U64);
primitive_from_json!(u32, U64, U64);
primitive_from_json!(u64, U64, U64);

primitive_from_json!(f32, F64, F64);
primitive_from_json!(f64, F64, F64);
<|endoftext|>


<commit_before>//! Completion for derives
use hir::HasAttrs;
use itertools::Itertools;
use rustc_hash::FxHashMap;
use syntax::ast;

use crate::{
    context::CompletionContext,
    item::{CompletionItem, CompletionItemKind, CompletionKind},
    Completions,
};

pub(super) fn complete_derive(
    acc: &mut Completions,
    ctx: &CompletionContext,
    derive_input: ast::TokenTree,
) {
    if let Some(existing_derives) = super::parse_comma_sep_input(derive_input) {
        for (derive, docs) in get_derive_names_in_scope(ctx) {
            let (label, lookup) = if let Some(derive_completion) = DEFAULT_DERIVE_COMPLETIONS
                .iter()
                .find(|derive_completion| derive_completion.label == derive)
            {
                let mut components = vec![derive_completion.label];
                components.extend(
                    derive_completion
                        .dependencies
                        .iter()
                        .filter(|&&dependency| !existing_derives.contains(dependency)),
                );
                let lookup = components.join(", ");
                let label = components.iter().rev().join(", ");
                (label, Some(lookup))
            } else {
                (derive, None)
            };
            let mut item =
                CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label);
            item.kind(CompletionItemKind::Attribute);
            if let Some(docs) = docs {
                item.documentation(docs);
            }
            if let Some(lookup) = lookup {
                item.lookup_by(lookup);
            }
            item.add_to(acc);
        }
    }
}

fn get_derive_names_in_scope(
    ctx: &CompletionContext,
) -> FxHashMap<String, Option<hir::Documentation>> {
    let mut result = FxHashMap::default();
    ctx.scope.process_all_names(&mut |name, scope_def| {
        if let hir::ScopeDef::MacroDef(mac) = scope_def {
            if mac.kind() == hir::MacroKind::Derive {
                result.insert(name.to_string(), mac.docs(ctx.db));
            }
        }
    });
    result
}

struct DeriveDependencies {
    label: &'static str,
    dependencies: &'static [&'static str],
}

/// Standard Rust derives that have dependencies
/// (the dependencies are needed so that the main derive don't break the compilation when added)
const DEFAULT_DERIVE_COMPLETIONS: &[DeriveDependencies] = &[
    DeriveDependencies { label: "Copy", dependencies: &["Clone"] },
    DeriveDependencies { label: "Eq", dependencies: &["PartialEq"] },
    DeriveDependencies { label: "Ord", dependencies: &["PartialOrd", "Eq", "PartialEq"] },
    DeriveDependencies { label: "PartialOrd", dependencies: &["PartialEq"] },
];

#[cfg(test)]
mod tests {
    use expect_test::{expect, Expect};

    use crate::{test_utils::completion_list, CompletionKind};

    fn check(ra_fixture: &str, expect: Expect) {
        let builtin_derives = r#"
#[rustc_builtin_macro]
pub macro Clone {}
#[rustc_builtin_macro]
pub macro Copy {}
#[rustc_builtin_macro]
pub macro Default {}
#[rustc_builtin_macro]
pub macro Debug {}
#[rustc_builtin_macro]
pub macro Hash {}
#[rustc_builtin_macro]
pub macro PartialEq {}
#[rustc_builtin_macro]
pub macro Eq {}
#[rustc_builtin_macro]
pub macro PartialOrd {}
#[rustc_builtin_macro]
pub macro Ord {}

"#;
        let actual = completion_list(
            &format!("{} {}", builtin_derives, ra_fixture),
            CompletionKind::Attribute,
        );
        expect.assert_eq(&actual);
    }

    #[test]
    fn no_completion_for_incorrect_derive() {
        check(r#"#[derive{$0)] struct Test;"#, expect![[]])
    }

    #[test]
    fn empty_derive() {
        check(
            r#"#[derive($0)] struct Test;"#,
            expect![[r#"
            at PartialEq
            at Default
            at PartialEq, Eq
            at PartialEq, Eq, PartialOrd, Ord
            at Clone, Copy
            at Debug
            at Clone
            at Hash
            at PartialEq, PartialOrd
        "#]],
        );
    }

    #[test]
    fn derive_with_input() {
        check(
            r#"#[derive(serde::Serialize, PartialEq, $0)] struct Test;"#,
            expect![[r#"
            at PartialEq
            at Default
            at Eq
            at Eq, PartialOrd, Ord
            at Clone, Copy
            at Debug
            at Clone
            at Hash
            at PartialOrd
        "#]],
        )
    }

    #[test]
    fn derive_with_input2() {
        check(
            r#"#[derive($0 serde::Serialize, PartialEq)] struct Test;"#,
            expect![[r#"
            at PartialEq
            at Default
            at Eq
            at Eq, PartialOrd, Ord
            at Clone, Copy
            at Debug
            at Clone
            at Hash
            at PartialOrd
        "#]],
        )
    }
}
<commit_msg>Don't complete already used derive attributes<commit_after>//! Completion for derives
use hir::HasAttrs;
use itertools::Itertools;
use rustc_hash::FxHashMap;
use syntax::ast;

use crate::{
    context::CompletionContext,
    item::{CompletionItem, CompletionItemKind, CompletionKind},
    Completions,
};

pub(super) fn complete_derive(
    acc: &mut Completions,
    ctx: &CompletionContext,
    derive_input: ast::TokenTree,
) {
    if let Some(existing_derives) = super::parse_comma_sep_input(derive_input) {
        for (derive, docs) in get_derive_names_in_scope(ctx) {
            let (label, lookup) = if let Some(derive_completion) = DEFAULT_DERIVE_COMPLETIONS
                .iter()
                .find(|derive_completion| derive_completion.label == derive)
            {
                let mut components = vec![derive_completion.label];
                components.extend(
                    derive_completion
                        .dependencies
                        .iter()
                        .filter(|&&dependency| !existing_derives.contains(dependency)),
                );
                let lookup = components.join(", ");
                let label = components.iter().rev().join(", ");
                (label, Some(lookup))
            } else if existing_derives.contains(&derive) {
                continue;
            } else {
                (derive, None)
            };
            let mut item =
                CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label);
            item.kind(CompletionItemKind::Attribute);
            if let Some(docs) = docs {
                item.documentation(docs);
            }
            if let Some(lookup) = lookup {
                item.lookup_by(lookup);
            }
            item.add_to(acc);
        }
    }
}

fn get_derive_names_in_scope(
    ctx: &CompletionContext,
) -> FxHashMap<String, Option<hir::Documentation>> {
    let mut result = FxHashMap::default();
    ctx.scope.process_all_names(&mut |name, scope_def| {
        if let hir::ScopeDef::MacroDef(mac) = scope_def {
            if mac.kind() == hir::MacroKind::Derive {
                result.insert(name.to_string(), mac.docs(ctx.db));
            }
        }
    });
    result
}

struct DeriveDependencies {
    label: &'static str,
    dependencies: &'static [&'static str],
}

/// Standard Rust derives that have dependencies
/// (the dependencies are needed so that the main derive don't break the compilation when added)
const DEFAULT_DERIVE_COMPLETIONS: &[DeriveDependencies] = &[
    DeriveDependencies { label: "Copy", dependencies: &["Clone"] },
    DeriveDependencies { label: "Eq", dependencies: &["PartialEq"] },
    DeriveDependencies { label: "Ord", dependencies: &["PartialOrd", "Eq", "PartialEq"] },
    DeriveDependencies { label: "PartialOrd", dependencies: &["PartialEq"] },
];

#[cfg(test)]
mod tests {
    use expect_test::{expect, Expect};

    use crate::{test_utils::completion_list, CompletionKind};

    fn check(ra_fixture: &str, expect: Expect) {
        let builtin_derives = r#"
#[rustc_builtin_macro]
pub macro Clone {}
#[rustc_builtin_macro]
pub macro Copy {}
#[rustc_builtin_macro]
pub macro Default {}
#[rustc_builtin_macro]
pub macro Debug {}
#[rustc_builtin_macro]
pub macro Hash {}
#[rustc_builtin_macro]
pub macro PartialEq {}
#[rustc_builtin_macro]
pub macro Eq {}
#[rustc_builtin_macro]
pub macro PartialOrd {}
#[rustc_builtin_macro]
pub macro Ord {}

"#;
        let actual = completion_list(
            &format!("{} {}", builtin_derives, ra_fixture),
            CompletionKind::Attribute,
        );
        expect.assert_eq(&actual);
    }

    #[test]
    fn no_completion_for_incorrect_derive() {
        check(r#"#[derive{$0)] struct Test;"#, expect![[]])
    }

    #[test]
    fn empty_derive() {
        check(
            r#"#[derive($0)] struct Test;"#,
            expect![[r#"
            at PartialEq
            at Default
            at PartialEq, Eq
            at PartialEq, Eq, PartialOrd, Ord
            at Clone, Copy
            at Debug
            at Clone
            at Hash
            at PartialEq, PartialOrd
        "#]],
        );
    }

    #[test]
    fn derive_with_input() {
        check(
            r#"#[derive(serde::Serialize, PartialEq, $0)] struct Test;"#,
            expect![[r#"
                at Default
                at Eq
                at Eq, PartialOrd, Ord
                at Clone, Copy
                at Debug
                at Clone
                at Hash
                at PartialOrd
            "#]],
        )
    }

    #[test]
    fn derive_with_input2() {
        check(
            r#"#[derive($0 serde::Serialize, PartialEq)] struct Test;"#,
            expect![[r#"
                at Default
                at Eq
                at Eq, PartialOrd, Ord
                at Clone, Copy
                at Debug
                at Clone
                at Hash
                at PartialOrd
            "#]],
        )
    }
}
<|endoftext|>


<commit_before>extern crate websocket;

use std;
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use std::collections::BTreeMap;

use websocket::{Message, Sender, Receiver};
use websocket::message::Type;
use websocket::client::request::Url;

use hyper::header::{Cookie, CookieJar};

use time;

use rustc_serialize::json;
use rustc_serialize::json::Json;
use rustc_serialize::Decodable;

use game::Clock;

// making a move
// out {"t":"move","d":{"from":"e2","to":"e4","b":1}}
// in {t: "ack"}
// in {"v":1,"t":"move","d":{"uci":"e2e4","san":"e4","fen":"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR","ply":1,"clock":{"white":172800,"black":172800},"dests":{"b8":"a6c6","g8":"f6h6","h7":"h6h5","d7":"d6d5","g7":"g6g5","c7":"c6c5","f7":"f6f5","b7":"b6b5","e7":"e6e5","a7":"a6a5"},"crazyhouse":{"pockets":[{},{}]}}}
// other player moved
// in {"v":2,"t":"move","d":{"uci":"g7g5","san":"g5","fen":"rnbqkbnr/pppppp1p/8/6p1/4P3/8/PPPP1PPP/RNBQKBNR","ply":2,"clock":{"white":172800,"black":172800},"dests":{"a2":"a3a4","g1":"f3h3e2","d1":"e2f3g4h5","e1":"e2","d2":"d3d4","b1":"a3c3","e4":"e5","f1":"e2d3c4b5a6","h2":"h3h4","b2":"b3b4","f2":"f3f4","c2":"c3c4","g2":"g3g4"},"crazyhouse":{"pockets":[{},{}]}}}

enum LilaMessage {
    Move(Move),
    Clock(Clock),
}

impl LilaMessage {
    fn decode(obj: &BTreeMap<String, json::Json>) -> Option<LilaMessage> {
        fn decode<T: Decodable>(data: &json::Json) -> Option<T> {
            let mut decoder = json::Decoder::new(data.to_owned());
            Decodable::decode(&mut decoder)
                .map_err(|e| error!("could not decode: {}", e)).ok()
        }
        let data = obj.get("d");
        match (obj.get("t").and_then(|t| t.as_string()), data) {
            // TODO: gone, crowd, end, tvSelect, challenges, drop,
            // following_enters, following_leaves, following_onlines,
            // following_playing, following_stopped_plaing,
            // message, analysisProgress, reload, and more
            (Some("move"), Some(data)) => decode(data).map(|d| LilaMessage::Move(d)),
            (Some("clock"), Some(data)) => decode(data).map(|d| LilaMessage::Clock(d)),
            (Some(ref t), d) => {
                warn!("unhandled: {}, {:?}", t, d);
                None
            },
            _ => {
                warn!("unhandled: Missing type");
                None
            }
        }
    }

}

#[derive(RustcDecodable)]
struct Move {
    clock: Option<Clock>,
    fen: String,
}

#[derive(RustcEncodable)]
struct PingPacket {
    t: String,
    v: u64
}

impl PingPacket {
    pub fn new(version: u64) -> PingPacket {
        PingPacket {
            t: "p".to_string(),
            v: version
        }
    }

    pub fn to_message(&self) -> Message<'static> {
        Message::text(json::encode(self).unwrap())
    }
}

#[allow(dead_code)]
#[derive(RustcEncodable)]
pub struct MovePacket {
    t: String,
    d: Dest,
}

#[allow(dead_code)]
#[derive(RustcEncodable)]
pub struct Dest {
    pub from: String,
    pub to: String,
    // pub: i8, // bool, but 0 or 1
}

pub fn connect(cjar: &CookieJar, url: String, version: u64, pov: Arc<Mutex<super::Pov>>) {
    // wraps version for usage in receive and ping threads
    let version = Arc::new(Mutex::new(version));
    let url = Url::parse(&url).unwrap();
    // TODO: this unwrap fails when url is wrong, port for example
    let mut request = websocket::Client::connect(url).unwrap();
    request.headers.set(Cookie::from_cookie_jar(&cjar));

    let response = request.send().unwrap();

    match response.validate() {
        Ok(()) => (),
        Err(e) => {
            error!("reponse validation error: {:?}", e);
            debug!("reponse status: {:?}, headers: {:?}", response.status, response.headers);
            return;
        }
    };

    //println!("Successfully connected");

    let (mut sender, mut receiver) = response.begin().split();

    let (tx, rx) = mpsc::channel();

    let tx_1 = tx.clone();

    let _send_loop = thread::spawn(move || {
        loop {
            let message: Message = match rx.recv() {
                Ok(m) => m,
                Err(e) => {
                    error!("Send loop, could not read next message: {:?}", e);
                    return;
                }
            };
            trace!("Transmit raw: {:?}", message);
            debug!("Transmit msg: {}",
                   &std::str::from_utf8(&message.payload).unwrap());
            match message.opcode {
                Type::Close => {
                    let _ = sender.send_message(&message);
                    return;
                }
                _ => (),
            }
            match sender.send_message(&message) {
                Ok(()) => (),
                Err(e) => {
                    error!("Send loop: could not send message: {:?}", e);
                    let _ = sender.send_message(&Message::close());
                    return;
                }
            }
        }
    });

    let (pong_tx, pong_rx) = mpsc::channel();
    let pov_1 = pov.clone();
    let version_1 = version.clone();
    let _receive_loop = thread::spawn(move || {

        let handle = |obj: &BTreeMap<String, json::Json>| {
            if let (Some(v), Ok(mut version)) = (obj.get("v").and_then(|v| v.as_u64()), version_1.lock()) {
                if v <= *version {
                    debug!("Already has event {}", v);
                    return;
                } else if *version + 1 < v {
                    debug!("Event gap detected from {} to {}", *version, v);
                    return;
                }
                *version = v;
            }
            let mut pov = pov_1.lock().unwrap();
            match LilaMessage::decode(obj) {
                Some(LilaMessage::Move(m)) => {
                    pov.game.fen = m.fen;
                    if let Some(c) = m.clock {
                        pov.clock = Some(c);
                    };
                },
                Some(LilaMessage::Clock(c)) => {
                    pov.clock = Some(c);
                },
                //LilaMessage::End => tx_1.send(Message::close()).unwrap(),
                _ => ()
            };
        };

        for message in receiver.incoming_messages() {
            let message: Message = match message {
                Ok(m) => m,
                Err(e) => {
                    warn!("Receive loop error: {:?}", e);
                    let _ = tx_1.send(Message::close());
                    return;
                }
            };
            match message.opcode {
                Type::Close => {
                    let _ = tx_1.send(Message::close());
                    return;
                }
                Type::Ping => match tx_1.send(Message::pong(message.payload)) {
                    Ok(()) => (),
                    Err(e) => {
                        warn!("Could not send pong: {:?}", e);
                        return;
                    }
                },
                Type::Text => {
                    let str_payload = std::str::from_utf8(&message.payload).unwrap();
                    trace!("Received raw: {:?}", &message.payload);
                    trace!("Received str: {}", str_payload);
                    let json = Json::from_str(str_payload).unwrap();
                    debug!("Received obj: {:?}", json);
                    if json.is_object() {
                        let obj = json.as_object().unwrap();
                        match obj.get("t").and_then(|t| t.as_string()) {
                            Some("n") => pong_tx.send(()).unwrap(),
                            Some("b") => { // batch
                                let data = obj.get("d").unwrap();
                                for item in data.as_array().unwrap().iter() {
                                    let obj = item.as_object().unwrap();
                                    handle(obj);
                                }
                            },
                            _ => handle(obj)
                        }
                    }
                }
                _ => debug!("Unhandled message: {:?}", message),
            }
        }
    });

    let tx_2 = tx.clone();
    let version_2 = version.clone();
    thread::spawn(move || loop {
        thread::sleep(Duration::from_millis(2000));

        let ping;
        { ping = PingPacket::new(*version_2.lock().unwrap()).to_message(); }
        let before = time::now_utc();
        tx_2.send(ping).unwrap(); // TODO: stop pinging when socket is closed
        pong_rx.recv().unwrap();
        let after = time::now_utc();
        debug!("Ping time: {}", after-before);
    });

    //let _ = send_loop.join();
    //let _ = receive_loop.join();
}

<commit_msg>this fixes about half of the latency overhead<commit_after>extern crate websocket;

use std;
use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use std::collections::BTreeMap;

use websocket::{Message, Sender, Receiver};
use websocket::message::Type;
use websocket::client::request::Url;

use hyper::header::{Cookie, CookieJar};

use time;

use rustc_serialize::json;
use rustc_serialize::json::Json;
use rustc_serialize::Decodable;

use game::Clock;

// making a move
// out {"t":"move","d":{"from":"e2","to":"e4","b":1}}
// in {t: "ack"}
// in {"v":1,"t":"move","d":{"uci":"e2e4","san":"e4","fen":"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR","ply":1,"clock":{"white":172800,"black":172800},"dests":{"b8":"a6c6","g8":"f6h6","h7":"h6h5","d7":"d6d5","g7":"g6g5","c7":"c6c5","f7":"f6f5","b7":"b6b5","e7":"e6e5","a7":"a6a5"},"crazyhouse":{"pockets":[{},{}]}}}
// other player moved
// in {"v":2,"t":"move","d":{"uci":"g7g5","san":"g5","fen":"rnbqkbnr/pppppp1p/8/6p1/4P3/8/PPPP1PPP/RNBQKBNR","ply":2,"clock":{"white":172800,"black":172800},"dests":{"a2":"a3a4","g1":"f3h3e2","d1":"e2f3g4h5","e1":"e2","d2":"d3d4","b1":"a3c3","e4":"e5","f1":"e2d3c4b5a6","h2":"h3h4","b2":"b3b4","f2":"f3f4","c2":"c3c4","g2":"g3g4"},"crazyhouse":{"pockets":[{},{}]}}}

enum LilaMessage {
    Move(Move),
    Clock(Clock),
}

impl LilaMessage {
    fn decode(obj: &BTreeMap<String, json::Json>) -> Option<LilaMessage> {
        fn decode<T: Decodable>(data: &json::Json) -> Option<T> {
            let mut decoder = json::Decoder::new(data.to_owned());
            Decodable::decode(&mut decoder)
                .map_err(|e| error!("could not decode: {}", e)).ok()
        }
        let data = obj.get("d");
        match (obj.get("t").and_then(|t| t.as_string()), data) {
            // TODO: gone, crowd, end, tvSelect, challenges, drop,
            // following_enters, following_leaves, following_onlines,
            // following_playing, following_stopped_plaing,
            // message, analysisProgress, reload, and more
            (Some("move"), Some(data)) => decode(data).map(|d| LilaMessage::Move(d)),
            (Some("clock"), Some(data)) => decode(data).map(|d| LilaMessage::Clock(d)),
            (Some(ref t), d) => {
                warn!("unhandled: {}, {:?}", t, d);
                None
            },
            _ => {
                warn!("unhandled: Missing type");
                None
            }
        }
    }

}

#[derive(RustcDecodable)]
struct Move {
    clock: Option<Clock>,
    fen: String,
}

#[derive(RustcEncodable)]
struct PingPacket {
    t: String,
    v: u64
}

impl PingPacket {
    pub fn new(version: u64) -> PingPacket {
        PingPacket {
            t: "p".to_string(),
            v: version
        }
    }

    pub fn to_message(&self) -> Message<'static> {
        Message::text(json::encode(self).unwrap())
    }
}

#[allow(dead_code)]
#[derive(RustcEncodable)]
pub struct MovePacket {
    t: String,
    d: Dest,
}

#[allow(dead_code)]
#[derive(RustcEncodable)]
pub struct Dest {
    pub from: String,
    pub to: String,
    // pub: i8, // bool, but 0 or 1
}

pub fn connect(cjar: &CookieJar, url: String, version: u64, pov: Arc<Mutex<super::Pov>>) {
    // wraps version for usage in receive and ping threads
    let version = Arc::new(Mutex::new(version));
    let url = Url::parse(&url).unwrap();
    // TODO: this unwrap fails when url is wrong, port for example
    let mut request = websocket::Client::connect(url).unwrap();
    request.headers.set(Cookie::from_cookie_jar(&cjar));

    let response = request.send().unwrap();

    match response.validate() {
        Ok(()) => (),
        Err(e) => {
            error!("reponse validation error: {:?}", e);
            debug!("reponse status: {:?}, headers: {:?}", response.status, response.headers);
            return;
        }
    };

    //println!("Successfully connected");

    let (mut sender, mut receiver) = response.begin().split();
    sender.get_mut().set_nodelay(true).unwrap();

    let (tx, rx) = mpsc::channel();

    let tx_1 = tx.clone();

    let _send_loop = thread::spawn(move || {
        loop {
            let message: Message = match rx.recv() {
                Ok(m) => m,
                Err(e) => {
                    error!("Send loop, could not read next message: {:?}", e);
                    return;
                }
            };
            trace!("Transmit raw: {:?}", message);
            debug!("Transmit msg: {}",
                   &std::str::from_utf8(&message.payload).unwrap());
            match message.opcode {
                Type::Close => {
                    let _ = sender.send_message(&message);
                    return;
                }
                _ => (),
            }
            match sender.send_message(&message) {
                Ok(()) => (),
                Err(e) => {
                    error!("Send loop: could not send message: {:?}", e);
                    let _ = sender.send_message(&Message::close());
                    return;
                }
            }
        }
    });

    let (pong_tx, pong_rx) = mpsc::channel();
    let pov_1 = pov.clone();
    let version_1 = version.clone();
    let _receive_loop = thread::spawn(move || {

        let handle = |obj: &BTreeMap<String, json::Json>| {
            if let (Some(v), Ok(mut version)) = (obj.get("v").and_then(|v| v.as_u64()), version_1.lock()) {
                if v <= *version {
                    debug!("Already has event {}", v);
                    return;
                } else if *version + 1 < v {
                    debug!("Event gap detected from {} to {}", *version, v);
                    return;
                }
                *version = v;
            }
            let mut pov = pov_1.lock().unwrap();
            match LilaMessage::decode(obj) {
                Some(LilaMessage::Move(m)) => {
                    pov.game.fen = m.fen;
                    if let Some(c) = m.clock {
                        pov.clock = Some(c);
                    };
                },
                Some(LilaMessage::Clock(c)) => {
                    pov.clock = Some(c);
                },
                //LilaMessage::End => tx_1.send(Message::close()).unwrap(),
                _ => ()
            };
        };

        for message in receiver.incoming_messages() {
            let message: Message = match message {
                Ok(m) => m,
                Err(e) => {
                    warn!("Receive loop error: {:?}", e);
                    let _ = tx_1.send(Message::close());
                    return;
                }
            };
            match message.opcode {
                Type::Close => {
                    let _ = tx_1.send(Message::close());
                    return;
                }
                Type::Ping => match tx_1.send(Message::pong(message.payload)) {
                    Ok(()) => (),
                    Err(e) => {
                        warn!("Could not send pong: {:?}", e);
                        return;
                    }
                },
                Type::Text => {
                    let str_payload = std::str::from_utf8(&message.payload).unwrap();
                    trace!("Received raw: {:?}", &message.payload);
                    trace!("Received str: {}", str_payload);
                    let json = Json::from_str(str_payload).unwrap();
                    debug!("Received obj: {:?}", json);
                    if json.is_object() {
                        let obj = json.as_object().unwrap();
                        match obj.get("t").and_then(|t| t.as_string()) {
                            Some("n") => pong_tx.send(()).unwrap(),
                            Some("b") => { // batch
                                let data = obj.get("d").unwrap();
                                for item in data.as_array().unwrap().iter() {
                                    let obj = item.as_object().unwrap();
                                    handle(obj);
                                }
                            },
                            _ => handle(obj)
                        }
                    }
                }
                _ => debug!("Unhandled message: {:?}", message),
            }
        }
    });

    let tx_2 = tx.clone();
    let version_2 = version.clone();
    thread::spawn(move || loop {
        thread::sleep(Duration::from_millis(2000));

        let ping;
        { ping = PingPacket::new(*version_2.lock().unwrap()).to_message(); }
        let before = time::now_utc();
        tx_2.send(ping).unwrap(); // TODO: stop pinging when socket is closed
        pong_rx.recv().unwrap();
        let after = time::now_utc();
        debug!("Ping time: {}", after-before);
    });

    //let _ = send_loop.join();
    //let _ = receive_loop.join();
}

<|endoftext|>


<commit_before>//   Copyright 2014 Colin Sherratt
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

#![crate_name = "snowmew"]
#![feature(globs)]

extern crate "snowmew-core"         as _core;
extern crate "snowmew-graphics"     as _graphics;
extern crate "snowmew-loader"       as _loader;
extern crate "snowmew-physics"      as _physics;
extern crate "snowmew-position"     as _position;
extern crate "snowmew-render-mux"   as _render;
extern crate "snowmew-render-data"  as _render_data;

pub use _core::common::ObjectKey as ObjectKey;

pub mod render {
    pub use _render::RenderFactory as DefaultRender;
    pub use _render_data::{
        RenderData,
        Renderable
    };
    pub use _core::{
        RenderFactory,
        Render,
    };
}

pub mod graphics {
    pub use _graphics::{
        Drawable,
        Geometry,
        geometry,
        Graphics,
        GraphicsData,
        light,
        Light,
        material,
        Material,
        texture,
        Texture,
        texture_atlas,
        VertexBuffer,
        VertexBufferIter,
    };
}

pub mod position {
    pub use _position::{
        MatrixManager,
        Deltas,
        ComputedPositionGL,
        ComputedPosition,
        CalcPositionsCl,
        PositionData,
        Positions
    };
}

pub mod core {
    pub use _core::{
        DisplayConfig,
        Render,
        IOManager,
    };

    pub use _core::io::{
        InputHandle,
        Window,
    };

    pub use _core::game::Game;
}

pub mod common {
    pub use _core::common::{
        Common,
        CommonData,
        ObjectKey,
        Duplicate
    };
}

pub mod config  {
    pub use _core::SnowmewConfig as SnowmewConfig;
}

pub mod input {
    pub use _core::input::*;
    pub use _core::input_integrator::{
        InputIntegrator,
        InputIntegratorGameData,
        InputIntegratorState,
    };
    pub use _core::input_integrator::input_integrator as integrator;
}

pub mod debug {
    pub use _core::debugger::{
        Debugger,
        DebuggerGameData,
        debugger
    };
}<commit_msg>export Delete<commit_after>//   Copyright 2014 Colin Sherratt
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

#![crate_name = "snowmew"]
#![feature(globs)]

extern crate "snowmew-core"         as _core;
extern crate "snowmew-graphics"     as _graphics;
extern crate "snowmew-loader"       as _loader;
extern crate "snowmew-physics"      as _physics;
extern crate "snowmew-position"     as _position;
extern crate "snowmew-render-mux"   as _render;
extern crate "snowmew-render-data"  as _render_data;

pub use _core::common::ObjectKey as ObjectKey;

pub mod render {
    pub use _render::RenderFactory as DefaultRender;
    pub use _render_data::{
        RenderData,
        Renderable
    };
    pub use _core::{
        RenderFactory,
        Render,
    };
}

pub mod graphics {
    pub use _graphics::{
        Drawable,
        Geometry,
        geometry,
        Graphics,
        GraphicsData,
        light,
        Light,
        material,
        Material,
        texture,
        Texture,
        texture_atlas,
        VertexBuffer,
        VertexBufferIter,
    };
}

pub mod position {
    pub use _position::{
        MatrixManager,
        Deltas,
        ComputedPositionGL,
        ComputedPosition,
        CalcPositionsCl,
        PositionData,
        Positions
    };
}

pub mod core {
    pub use _core::{
        DisplayConfig,
        Render,
        IOManager,
    };

    pub use _core::io::{
        InputHandle,
        Window,
    };

    pub use _core::game::Game;
}

pub mod common {
    pub use _core::common::{
        Common,
        CommonData,
        ObjectKey,
        Duplicate,
        Delete
    };
}

pub mod config  {
    pub use _core::SnowmewConfig as SnowmewConfig;
}

pub mod input {
    pub use _core::input::*;
    pub use _core::input_integrator::{
        InputIntegrator,
        InputIntegratorGameData,
        InputIntegratorState,
    };
    pub use _core::input_integrator::input_integrator as integrator;
}

pub mod debug {
    pub use _core::debugger::{
        Debugger,
        DebuggerGameData,
        debugger
    };
}<|endoftext|>


<commit_before>use executor::*;
use il::*;
use std::rc::Rc;
use translator::mips::*;
use types::Endian;

#[cfg(test)]
fn get_scalar(
    instruction_bytes: &[u8],
    scalars: Vec<(&str, Expression)>,
    memory: memory::Memory,
    result_scalar: &str
) -> Constant {

    let mut bytes = vec![0x00, 0x00, 0x00, 0x00];
    bytes.append(&mut instruction_bytes.to_vec());
    bytes.append(&mut vec![0x00, 0x00, 0x00, 0x00]);

    let block_translation_result = Mips::new().translate_block(&bytes, 0).unwrap();
    let control_flow_graph = block_translation_result.control_flow_graph();
    let num_blocks = control_flow_graph.blocks().len();
    let function = Function::new(0, control_flow_graph.clone());
    let mut program = Program::new();

    program.add_function(function);

    let location = ProgramLocation::new(0, FunctionLocation::EmptyBlock(0));

    let arch = Mips::new();

    let mut engine = engine::Engine::new(memory);
    for scalar in scalars {
        engine.set_scalar(scalar.0, scalar.1);
    }

    let mut driver = driver::Driver::new(Rc::new(program), location, engine, &arch);

    loop {
        driver = driver.step().unwrap();
        if let Some(index) = driver.location().block_index() {
            if index == num_blocks as u64 - 1 {
                break;
            }
        }
    }

    return driver.engine()
                 .symbolize_and_eval(driver.engine().get_scalar(result_scalar).unwrap())
                 .unwrap();
}

#[cfg(test)]
fn get_raise(
    instruction_bytes: &[u8],
    scalars: Vec<(&str, Expression)>,
    memory: memory::Memory
) -> Option<Expression> {

    let mut bytes = vec![0x00, 0x00, 0x00, 0x00];
    bytes.append(&mut instruction_bytes.to_vec());
    bytes.append(&mut vec![0x00, 0x00, 0x00, 0x00]);

    let block_translation_result = Mips::new().translate_block(&bytes, 0).unwrap();
    let control_flow_graph = block_translation_result.control_flow_graph();
    let num_blocks = control_flow_graph.blocks().len();
    let function = Function::new(0, control_flow_graph.clone());
    let mut program = Program::new();

    program.add_function(function);

    let location = ProgramLocation::new(0, FunctionLocation::EmptyBlock(0));

    let arch = Mips::new();

    let mut engine = engine::Engine::new(memory);
    for scalar in scalars {
        engine.set_scalar(scalar.0, scalar.1);
    }

    let mut driver = driver::Driver::new(Rc::new(program), location, engine, &arch);

    loop {
        driver = driver.step().unwrap();
        let location = driver.location().apply(driver.program()).unwrap();
        println!("{}", location);
        if let Some(instruction) = location.instruction() {
            if let Operation::Raise { ref expr } = *instruction.operation() {
                return Some(expr.clone());
            }
        }
        if let Some(index) = driver.location().block_index() {
            if index == num_blocks as u64 - 1 {
                break;
            }
        }
    }

    None
}

#[test]
fn add() {
    // add $a0, $a1, $a2
    let instruction_bytes = &[0x00, 0xa6, 0x20, 0x20];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(1, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 2);

    let result = get_raise(
        instruction_bytes,
        vec![("$a1", expr_const(0x7fffffff, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big)
    ).unwrap();
    if let Expression::Scalar(ref scalar) = result {
        assert_eq!(scalar.name(), "IntegerOverflow");
    }
    else {
        assert!(false);
    }

    let result = get_raise(
        instruction_bytes,
        vec![("$a1", expr_const(0xffffffff, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big)
    ).unwrap();
    if let Expression::Scalar(ref scalar) = result {
        assert_eq!(scalar.name(), "IntegerOverflow");
    }
    else {
        assert!(false);
    }
}

#[test]
fn addi() {
    // add $a0, $a1, 0x1234
    let instruction_bytes = &[0x20, 0xa4, 0x12, 0x34];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x1235);

    let result = get_raise(
        instruction_bytes,
        vec![("$a1", expr_const(0x7fffffff, 32))],
        memory::Memory::new(Endian::Big)
    ).unwrap();
    if let Expression::Scalar(ref scalar) = result {
        assert_eq!(scalar.name(), "IntegerOverflow");
    }
    else {
        assert!(false);
    }
}<commit_msg>more mips tests<commit_after>use executor::*;
use il::*;
use std::rc::Rc;
use translator::mips::*;
use types::Endian;

#[cfg(test)]
fn get_scalar(
    instruction_bytes: &[u8],
    scalars: Vec<(&str, Expression)>,
    memory: memory::Memory,
    result_scalar: &str
) -> Constant {

    let mut bytes = vec![0x00, 0x00, 0x00, 0x00];
    bytes.append(&mut instruction_bytes.to_vec());
    bytes.append(&mut vec![0x00, 0x00, 0x00, 0x00]);

    let block_translation_result = Mips::new().translate_block(&bytes, 0).unwrap();
    let control_flow_graph = block_translation_result.control_flow_graph();
    let num_blocks = control_flow_graph.blocks().len();
    let function = Function::new(0, control_flow_graph.clone());
    let mut program = Program::new();

    program.add_function(function);

    let location = ProgramLocation::new(0, FunctionLocation::EmptyBlock(0));

    let arch = Mips::new();

    let mut engine = engine::Engine::new(memory);
    for scalar in scalars {
        engine.set_scalar(scalar.0, scalar.1);
    }

    let mut driver = driver::Driver::new(Rc::new(program), location, engine, &arch);

    loop {
        driver = driver.step().unwrap();
        if let Some(index) = driver.location().block_index() {
            if index == num_blocks as u64 - 1 {
                break;
            }
        }
    }

    return driver.engine()
                 .symbolize_and_eval(driver.engine().get_scalar(result_scalar).unwrap())
                 .unwrap();
}

#[cfg(test)]
fn get_raise(
    instruction_bytes: &[u8],
    scalars: Vec<(&str, Expression)>,
    memory: memory::Memory
) -> Option<Expression> {

    let mut bytes = vec![0x00, 0x00, 0x00, 0x00];
    bytes.append(&mut instruction_bytes.to_vec());
    bytes.append(&mut vec![0x00, 0x00, 0x00, 0x00]);

    let block_translation_result = Mips::new().translate_block(&bytes, 0).unwrap();
    let control_flow_graph = block_translation_result.control_flow_graph();
    let num_blocks = control_flow_graph.blocks().len();
    let function = Function::new(0, control_flow_graph.clone());
    let mut program = Program::new();

    program.add_function(function);

    let location = ProgramLocation::new(0, FunctionLocation::EmptyBlock(0));

    let arch = Mips::new();

    let mut engine = engine::Engine::new(memory);
    for scalar in scalars {
        engine.set_scalar(scalar.0, scalar.1);
    }

    let mut driver = driver::Driver::new(Rc::new(program), location, engine, &arch);

    loop {
        driver = driver.step().unwrap();
        let location = driver.location().apply(driver.program()).unwrap();
        println!("{}", location);
        if let Some(instruction) = location.instruction() {
            if let Operation::Raise { ref expr } = *instruction.operation() {
                return Some(expr.clone());
            }
        }
        if let Some(index) = driver.location().block_index() {
            if index == num_blocks as u64 - 1 {
                break;
            }
        }
    }

    None
}

#[test]
fn add() {
    // add $a0, $a1, $a2
    let instruction_bytes = &[0x00, 0xa6, 0x20, 0x20];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(1, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 2);

    let result = get_raise(
        instruction_bytes,
        vec![("$a1", expr_const(0x7fffffff, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big)
    ).unwrap();
    if let Expression::Scalar(ref scalar) = result {
        assert_eq!(scalar.name(), "IntegerOverflow");
    }
    else {
        assert!(false);
    }

    let result = get_raise(
        instruction_bytes,
        vec![("$a1", expr_const(0xffffffff, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big)
    ).unwrap();
    if let Expression::Scalar(ref scalar) = result {
        assert_eq!(scalar.name(), "IntegerOverflow");
    }
    else {
        assert!(false);
    }
}

#[test]
fn addi() {
    // addi $a0, $a1, 0x1234
    let instruction_bytes = &[0x20, 0xa4, 0x12, 0x34];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x1235);

    let result = get_raise(
        instruction_bytes,
        vec![("$a1", expr_const(0x7fffffff, 32))],
        memory::Memory::new(Endian::Big)
    ).unwrap();
    if let Expression::Scalar(ref scalar) = result {
        assert_eq!(scalar.name(), "IntegerOverflow");
    }
    else {
        assert!(false);
    }
}

#[test]
fn addiu() {
    // addiu $a0, $a1, 0x1234
    let instruction_bytes = &[0x24, 0xa4, 0x12, 0x34];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x1235);

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(0x7fffffff, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x80001233);
}

#[test]
fn addu() {
    // addu $a0, $a1, $a2
    let instruction_bytes = &[0x00, 0xa6, 0x20, 0x21];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(1, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 2);

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(0x7fffffff, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x80000000);

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(0xffffffff, 32)),
             ("$a2", expr_const(1, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0);
}

#[test]
fn and() {
    // and $a0, $a1, $a2
    let instruction_bytes = &[0x00, 0xa6, 0x20, 0x24];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(0x8000ffff, 32)),
             ("$a2", expr_const(0x1234, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x1234);
}

#[test]
fn andi() {
    // andi $a0, $a1, 0x1234
    let instruction_bytes = &[0x30, 0xa4, 0x12, 0x34];

    let result = get_scalar(
        instruction_bytes,
        vec![("$a1", expr_const(0x8000ffff, 32))],
        memory::Memory::new(Endian::Big),
        "$a0"
    );
    assert_eq!(result.value(), 0x1234);
}<|endoftext|>