<commit_before>use std::net::IpAddr;
use std::io::{Write, ErrorKind};
use std::io::Read;

use mio::*;
use mio::tcp::TcpStream;
use mio::unix::UnixReady;
use nom::IResult::*;
use nom::Offset;
use network::protocol::proxy_protocol::header;
use network::{Protocol, ClientResult};
use network::Readiness;
use network::protocol::ProtocolResult;
use network::socket::{SocketHandler, SocketResult};
use network::buffer_queue::BufferQueue;
use network::SessionMetrics;
use network::protocol::pipe::Pipe;
use network::pool::Checkout;
use parser::proxy_protocol::parse_v2_header;
use super::header::ProxyAddr;

#[derive(Clone,Copy)]
pub enum HeaderLen {
  V4,
  V6,
  Unix
}

pub struct ExpectProxyProtocol<Front:SocketHandler> {
  pub frontend:       Front,
  pub frontend_token: Token,
  pub buf:            [u8; 232],
  pub index:          usize,
  pub header_len:     HeaderLen,
  pub readiness:      Readiness,
  pub addresses:      Option<ProxyAddr>,
}

impl <Front:SocketHandler + Read>ExpectProxyProtocol<Front> {
  pub fn new(frontend: Front, frontend_token: Token) -> Self {
    println!("expect starting, connection from {:?}", frontend.socket_ref().peer_addr());
    ExpectProxyProtocol {
      frontend,
      frontend_token,
      buf: [0; 232],
      index: 0,
      header_len: HeaderLen::V4,
      readiness: Readiness {
        front_interest:  UnixReady::from(Ready::readable()) | UnixReady::hup() | UnixReady::error(),
        back_interest:   UnixReady::hup() | UnixReady::error(),
        front_readiness: UnixReady::from(Ready::empty()),
        back_readiness:  UnixReady::from(Ready::empty()),
      },
      addresses: None,
    }
  }

  pub fn readable(&mut self, metrics: &mut SessionMetrics) -> (ProtocolResult, ClientResult) {
    let total_len = match self.header_len {
      HeaderLen::V4   => 28,
      HeaderLen::V6   => 52,
      HeaderLen::Unix => 232,
    };

    let (sz, res) = self.frontend.socket_read(&mut self.buf[self.index..total_len]);
    trace!("FRONT proxy protocol [{:?}]: read {} bytes and res={:?}, index = {}, total_len = {}",
      self.frontend_token, sz, res, self.index, total_len);

    if sz > 0 {
      self.index += sz;

      count!("bytes_in", sz as i64);
      metrics.bin += sz;

      if self.index == self.buf.len() {
        self.readiness.front_interest.remove(Ready::readable());
      }
    }

    if res == SocketResult::Error {
      error!("[{:?}] front socket error, closing the connection", self.frontend_token);
      metrics.service_stop();
      incr!("proxy_protocol.errors");
      self.readiness.reset();
      return (ProtocolResult::Continue, ClientResult::CloseClient);
    }

    if res == SocketResult::WouldBlock {
      self.readiness.front_readiness.remove(Ready::readable());
    }

    match parse_v2_header(&self.buf[..self.index]) {
      Done(rest, header) => {
        trace!("got expect header: {:?}, rest.len() = {}", header, rest.len());
        self.addresses = Some(header.addr);
        return (ProtocolResult::Upgrade, ClientResult::Continue);
      },
      Incomplete(_) => {
        match self.header_len {
          HeaderLen::V4 => if self.index == 28 {
            self.header_len = HeaderLen::V6;
          },
          HeaderLen::V6 => if self.index == 52 {
            self.header_len = HeaderLen::Unix;
          },
          HeaderLen::Unix => if self.index == 232 {
            error!("[{:?}] front socket parse error, closing the connection", self.frontend_token);
            metrics.service_stop();
            incr!("proxy_protocol.errors");
            self.readiness.reset();
            return (ProtocolResult::Continue, ClientResult::CloseClient)
          }
        };
        return (ProtocolResult::Continue, ClientResult::Continue)
      },
      Error(e) => {
        error!("[{:?}] front socket parse error, closing the connection: {:?}", self.frontend_token, e);
        metrics.service_stop();
        incr!("proxy_protocol.errors");
        self.readiness.reset();
        return (ProtocolResult::Continue, ClientResult::CloseClient)
      }
    };

    (ProtocolResult::Upgrade, ClientResult::Continue)
  }

  pub fn front_socket(&self) -> &TcpStream {
    self.frontend.socket_ref()
  }

  pub fn readiness(&mut self) -> &mut Readiness {
    &mut self.readiness
  }

  pub fn into_pipe(self, front_buf: Checkout<BufferQueue>, back_buf: Checkout<BufferQueue>, backend_socket: Option<TcpStream>, backend_token: Option<Token>) -> Pipe<Front> {
    let addr = if let Some(ref backend_socket) = backend_socket {
      backend_socket.peer_addr().map(|s| s.ip()).ok()
    } else {
      None
    };

    let mut pipe = Pipe::new(
      self.frontend,
      self.frontend_token,
      backend_socket,
      front_buf,
      back_buf,
      addr,
    );

    pipe.readiness.front_readiness = self.readiness.front_readiness;
    pipe.readiness.back_readiness  = self.readiness.back_readiness;

    if let Some(backend_token) = backend_token {
      pipe.set_back_token(backend_token);
    }

    pipe
  }
}

#[cfg(test)]
mod expect_test {

 use super::*;

  use parser::proxy_protocol::parse_v2_header;
  use nom::IResult::Done;
  use network::pool::Pool;

  use std::{sync::{Arc, Barrier}, thread::{self, JoinHandle}, time::Duration, net::{SocketAddr, IpAddr, Ipv4Addr}};
  use mio::net::{TcpListener, TcpStream};
  use std::net::{TcpListener as StdTcpListener, TcpStream as StdTcpStream};

  use network::protocol::proxy_protocol::header::*;

  // Flow diagram of the test below
  //                [connect]   [send proxy protocol]
  //upfront proxy  ----------------------X
  //              /     |           |
  //  sozu     ---------v-----------v----X
  #[test]
  fn middleware_should_receive_proxy_protocol_header_from_an_upfront_middleware() {
    setup_test_logger!();
    let middleware_addr: SocketAddr = "127.0.0.1:3500".parse().expect("parse address error");
    let barrier = Arc::new(Barrier::new(2));

    let upfront = start_upfront_middleware(middleware_addr.clone(), barrier.clone());
    start_middleware(middleware_addr, barrier);

    upfront.join().expect("should join");
  }

  // Accept connection from an upfront proxy and expect to read a proxy protocol header in this stream.
  fn start_middleware(middleware_addr: SocketAddr, barrier: Arc<Barrier>) {
    let upfront_middleware_conn_listener = TcpListener::bind(&middleware_addr).expect("could not accept upfront middleware connection");
    let mut client_stream: Option<TcpStream> = None;
    barrier.wait();

    // mio::TcpListener use a nonblocking mode so we have to loop on accept
    loop {
      if let Ok((stream, _addr)) = upfront_middleware_conn_listener.accept() {
        client_stream = Some(stream);
        break;
      }
    }

    let mut session_metrics = SessionMetrics::new();
    let mut expect_pp = ExpectProxyProtocol::new(client_stream.unwrap(), Token(0));

    if (ProtocolResult::Upgrade, ClientResult::Continue) != expect_pp.readable(&mut session_metrics) {
      panic!("Should receive a complete proxy protocol header");
    };
  }

  // Connect to the next middleware and send a proxy protocol header
  fn start_upfront_middleware(next_middleware_addr: SocketAddr, barrier: Arc<Barrier>) -> JoinHandle<()> {
    thread::spawn(move|| {
      let src_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(125, 25, 10, 1)), 8080);
      let dst_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 4, 5, 8)), 4200);
      let proxy_protocol = HeaderV2::new(Command::Local, src_addr, dst_addr).into_bytes();

      barrier.wait();
      match StdTcpStream::connect(&next_middleware_addr) {
        Ok(mut stream) => {
          stream.write(&proxy_protocol).unwrap();
        },
        Err(e) => panic!("could not connect to the next middleware: {}", e),
      };
    })
  }
}
<commit_msg>fix time dependent test<commit_after>use std::net::IpAddr;
use std::io::{Write, ErrorKind};
use std::io::Read;

use mio::*;
use mio::tcp::TcpStream;
use mio::unix::UnixReady;
use nom::IResult::*;
use nom::Offset;
use network::protocol::proxy_protocol::header;
use network::{Protocol, ClientResult};
use network::Readiness;
use network::protocol::ProtocolResult;
use network::socket::{SocketHandler, SocketResult};
use network::buffer_queue::BufferQueue;
use network::SessionMetrics;
use network::protocol::pipe::Pipe;
use network::pool::Checkout;
use parser::proxy_protocol::parse_v2_header;
use super::header::ProxyAddr;

#[derive(Clone,Copy)]
pub enum HeaderLen {
  V4,
  V6,
  Unix
}

pub struct ExpectProxyProtocol<Front:SocketHandler> {
  pub frontend:       Front,
  pub frontend_token: Token,
  pub buf:            [u8; 232],
  pub index:          usize,
  pub header_len:     HeaderLen,
  pub readiness:      Readiness,
  pub addresses:      Option<ProxyAddr>,
}

impl <Front:SocketHandler + Read>ExpectProxyProtocol<Front> {
  pub fn new(frontend: Front, frontend_token: Token) -> Self {
    println!("expect starting, connection from {:?}", frontend.socket_ref().peer_addr());
    ExpectProxyProtocol {
      frontend,
      frontend_token,
      buf: [0; 232],
      index: 0,
      header_len: HeaderLen::V4,
      readiness: Readiness {
        front_interest:  UnixReady::from(Ready::readable()) | UnixReady::hup() | UnixReady::error(),
        back_interest:   UnixReady::hup() | UnixReady::error(),
        front_readiness: UnixReady::from(Ready::empty()),
        back_readiness:  UnixReady::from(Ready::empty()),
      },
      addresses: None,
    }
  }

  pub fn readable(&mut self, metrics: &mut SessionMetrics) -> (ProtocolResult, ClientResult) {
    let total_len = match self.header_len {
      HeaderLen::V4   => 28,
      HeaderLen::V6   => 52,
      HeaderLen::Unix => 232,
    };

    let (sz, res) = self.frontend.socket_read(&mut self.buf[self.index..total_len]);
    trace!("FRONT proxy protocol [{:?}]: read {} bytes and res={:?}, index = {}, total_len = {}",
      self.frontend_token, sz, res, self.index, total_len);

    if sz > 0 {
      self.index += sz;

      count!("bytes_in", sz as i64);
      metrics.bin += sz;

      if self.index == self.buf.len() {
        self.readiness.front_interest.remove(Ready::readable());
      }
    }

    if res == SocketResult::Error {
      error!("[{:?}] front socket error, closing the connection", self.frontend_token);
      metrics.service_stop();
      incr!("proxy_protocol.errors");
      self.readiness.reset();
      return (ProtocolResult::Continue, ClientResult::CloseClient);
    }

    if res == SocketResult::WouldBlock {
      self.readiness.front_readiness.remove(Ready::readable());
    }

    match parse_v2_header(&self.buf[..self.index]) {
      Done(rest, header) => {
        trace!("got expect header: {:?}, rest.len() = {}", header, rest.len());
        self.addresses = Some(header.addr);
        return (ProtocolResult::Upgrade, ClientResult::Continue);
      },
      Incomplete(_) => {
        match self.header_len {
          HeaderLen::V4 => if self.index == 28 {
            self.header_len = HeaderLen::V6;
          },
          HeaderLen::V6 => if self.index == 52 {
            self.header_len = HeaderLen::Unix;
          },
          HeaderLen::Unix => if self.index == 232 {
            error!("[{:?}] front socket parse error, closing the connection", self.frontend_token);
            metrics.service_stop();
            incr!("proxy_protocol.errors");
            self.readiness.reset();
            return (ProtocolResult::Continue, ClientResult::CloseClient)
          }
        };
        return (ProtocolResult::Continue, ClientResult::Continue)
      },
      Error(e) => {
        error!("[{:?}] front socket parse error, closing the connection: {:?}", self.frontend_token, e);
        metrics.service_stop();
        incr!("proxy_protocol.errors");
        self.readiness.reset();
        return (ProtocolResult::Continue, ClientResult::CloseClient)
      }
    };

    (ProtocolResult::Upgrade, ClientResult::Continue)
  }

  pub fn front_socket(&self) -> &TcpStream {
    self.frontend.socket_ref()
  }

  pub fn readiness(&mut self) -> &mut Readiness {
    &mut self.readiness
  }

  pub fn into_pipe(self, front_buf: Checkout<BufferQueue>, back_buf: Checkout<BufferQueue>, backend_socket: Option<TcpStream>, backend_token: Option<Token>) -> Pipe<Front> {
    let addr = if let Some(ref backend_socket) = backend_socket {
      backend_socket.peer_addr().map(|s| s.ip()).ok()
    } else {
      None
    };

    let mut pipe = Pipe::new(
      self.frontend,
      self.frontend_token,
      backend_socket,
      front_buf,
      back_buf,
      addr,
    );

    pipe.readiness.front_readiness = self.readiness.front_readiness;
    pipe.readiness.back_readiness  = self.readiness.back_readiness;

    if let Some(backend_token) = backend_token {
      pipe.set_back_token(backend_token);
    }

    pipe
  }
}

#[cfg(test)]
mod expect_test {

 use super::*;

  use parser::proxy_protocol::parse_v2_header;
  use nom::IResult::Done;
  use network::pool::Pool;

  use std::{sync::{Arc, Barrier}, thread::{self, JoinHandle}, time::Duration, net::{SocketAddr, IpAddr, Ipv4Addr}};
  use mio::net::{TcpListener, TcpStream};
  use std::net::{TcpListener as StdTcpListener, TcpStream as StdTcpStream};

  use network::protocol::proxy_protocol::header::*;

  // Flow diagram of the test below
  //                [connect]   [send proxy protocol]
  //upfront proxy  ----------------------X
  //              /     |           |
  //  sozu     ---------v-----------v----X
  #[test]
  fn middleware_should_receive_proxy_protocol_header_from_an_upfront_middleware() {
    setup_test_logger!();
    let middleware_addr: SocketAddr = "127.0.0.1:3500".parse().expect("parse address error");
    let barrier = Arc::new(Barrier::new(2));

    let upfront = start_upfront_middleware(middleware_addr.clone(), barrier.clone());
    start_middleware(middleware_addr, barrier);

    upfront.join().expect("should join");
  }

  // Accept connection from an upfront proxy and expect to read a proxy protocol header in this stream.
  fn start_middleware(middleware_addr: SocketAddr, barrier: Arc<Barrier>) {
    let upfront_middleware_conn_listener = TcpListener::bind(&middleware_addr).expect("could not accept upfront middleware connection");
    let mut client_stream: Option<TcpStream> = None;
    barrier.wait();

    // mio::TcpListener use a nonblocking mode so we have to loop on accept
    loop {
      if let Ok((stream, _addr)) = upfront_middleware_conn_listener.accept() {
        client_stream = Some(stream);
        break;
      }
    }

    let mut session_metrics = SessionMetrics::new();
    let mut expect_pp = ExpectProxyProtocol::new(client_stream.unwrap(), Token(0));

    let mut res = (ProtocolResult::Continue, ClientResult::Continue);
    while res == (ProtocolResult::Continue, ClientResult::Continue) {
      res = expect_pp.readable(&mut session_metrics);
    }

    if res != (ProtocolResult::Upgrade, ClientResult::Continue) {
      panic!("Should receive a complete proxy protocol header, res = {:?}", res);
    };
  }

  // Connect to the next middleware and send a proxy protocol header
  fn start_upfront_middleware(next_middleware_addr: SocketAddr, barrier: Arc<Barrier>) -> JoinHandle<()> {
    thread::spawn(move|| {
      let src_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(125, 25, 10, 1)), 8080);
      let dst_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 4, 5, 8)), 4200);
      let proxy_protocol = HeaderV2::new(Command::Local, src_addr, dst_addr).into_bytes();

      barrier.wait();
      match StdTcpStream::connect(&next_middleware_addr) {
        Ok(mut stream) => {
          stream.write(&proxy_protocol).unwrap();
        },
        Err(e) => panic!("could not connect to the next middleware: {}", e),
      };
    })
  }
}
<|endoftext|>


<commit_before>use std::fmt::{self, Display};

pub static HEADER: &str = include_str!("include/cxx.h");

pub fn get(guard: &str) -> &'static str {
    let ifndef = format!("#ifndef {}", guard);
    let endif = format!("#endif // {}", guard);
    let begin = HEADER.find(&ifndef);
    let end = HEADER.find(&endif);
    if let (Some(begin), Some(end)) = (begin, end) {
        &HEADER[begin..end + endif.len()]
    } else {
        panic!("not found in cxx.h header: {}", guard)
    }
}

#[derive(Default)]
pub struct Includes {
    custom: Vec<String>,
    pub cstdint: bool,
    pub cstring: bool,
    pub memory: bool,
    pub string: bool,
    pub type_traits: bool,
}

impl Includes {
    pub fn new() -> Self {
        Includes::default()
    }

    pub fn insert(&mut self, include: String) {
        self.custom.push(include);
    }
}

impl Display for Includes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for include in &self.custom {
            writeln!(f, "#include \"{}\"", include.escape_default())?;
        }
        if self.cstdint {
            writeln!(f, "#include <cstdint>")?;
        }
        if self.cstring {
            writeln!(f, "#include <cstring>")?;
        }
        if self.memory {
            writeln!(f, "#include <memory>")?;
        }
        if self.string {
            writeln!(f, "#include <string>")?;
        }
        if self.type_traits {
            writeln!(f, "#include <type_traits>")?;
        }
        Ok(())
    }
}
<commit_msg>Look for end of line when finding headers ifdefs<commit_after>use std::fmt::{self, Display};

pub static HEADER: &str = include_str!("include/cxx.h");

pub fn get(guard: &str) -> &'static str {
    let ifndef = format!("#ifndef {}", guard);
    let endif = format!("#endif // {}", guard);
    let begin = find_line(&ifndef);
    let end = find_line(&endif);
    if let (Some(begin), Some(end)) = (begin, end) {
        &HEADER[begin..end + endif.len()]
    } else {
        panic!("not found in cxx.h header: {}", guard)
    }
}

fn find_line(line: &str) -> Option<usize> {
    let mut offset = 0;
    loop {
        offset += HEADER[offset..].find(line)?;
        let rest = &HEADER[offset + line.len()..];
        if rest.starts_with('\n') || rest.starts_with('\r') {
            return Some(offset);
        }
        offset += line.len();
    }
}

#[derive(Default)]
pub struct Includes {
    custom: Vec<String>,
    pub cstdint: bool,
    pub cstring: bool,
    pub memory: bool,
    pub string: bool,
    pub type_traits: bool,
}

impl Includes {
    pub fn new() -> Self {
        Includes::default()
    }

    pub fn insert(&mut self, include: String) {
        self.custom.push(include);
    }
}

impl Display for Includes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for include in &self.custom {
            writeln!(f, "#include \"{}\"", include.escape_default())?;
        }
        if self.cstdint {
            writeln!(f, "#include <cstdint>")?;
        }
        if self.cstring {
            writeln!(f, "#include <cstring>")?;
        }
        if self.memory {
            writeln!(f, "#include <memory>")?;
        }
        if self.string {
            writeln!(f, "#include <string>")?;
        }
        if self.type_traits {
            writeln!(f, "#include <type_traits>")?;
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>extern crate cfg_if;
extern crate resize;
extern crate wasm_bindgen;

mod utils;

use cfg_if::cfg_if;
use resize::Pixel;
use resize::Type;
use wasm_bindgen::prelude::*;

mod srgb;
use srgb::{linear_to_srgb, Clamp};

cfg_if! {
    // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
    // allocator.
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}

include!("./lut.inc");

// If `with_space_conversion` is true, this function returns 2 functions that
// convert from sRGB to linear RGB and vice versa. If `with_space_conversion` is
// false, the 2 functions returned do nothing.
fn srgb_converter_funcs(with_space_conversion: bool) -> (fn(u8) -> f32, fn(f32) -> u8) {
    if with_space_conversion {
        (
            |v| SRGB_TO_LINEAR_LUT[v as usize],
            |v| (linear_to_srgb(v) * 255.0).clamp(0.0, 255.0) as u8,
        )
    } else {
        (
            |v| (v as f32) / 255.0,
            |v| (v * 255.0).clamp(0.0, 255.0) as u8,
        )
    }
}

// If `with_alpha_premultiplication` is true, this function returns a function
// that premultiply the alpha channel with the given channel value and another
// function that reverses that process. If `with_alpha_premultiplication` is
// false, the functions just return the channel value.
fn alpha_multiplier_funcs(
    with_alpha_premultiplication: bool,
) -> (fn(f32, f32) -> f32, fn(f32, f32) -> f32) {
    if with_alpha_premultiplication {
        (|v, a| v * a, |v, a| v / a)
    } else {
        (|v, _a| v, |v, _a| v)
    }
}

#[wasm_bindgen]
#[no_mangle]
pub fn resize(
    input_image: Vec<u8>,
    input_width: usize,
    input_height: usize,
    output_width: usize,
    output_height: usize,
    typ_idx: usize,
    premultiply: bool,
    color_space_conversion: bool,
) -> Vec<u8> {
    let typ = match typ_idx {
        0 => Type::Triangle,
        1 => Type::Catrom,
        2 => Type::Mitchell,
        3 => Type::Lanczos3,
        _ => panic!("Nope"),
    };
    let num_input_pixels = input_width * input_height;
    let num_output_pixels = output_width * output_height;

    let mut output_image: Vec<u8> = vec_with_len(num_output_pixels * 4, 0);

    // If both options are false, there is no preprocessing on the pixel values
    // and we can skip the loop.
    if !premultiply && !color_space_conversion {
        let mut resizer = resize::new(
            input_width,
            input_height,
            output_width,
            output_height,
            Pixel::RGBA,
            typ,
        );
        resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
        return output_image;
    }

    // Otherwise, we convert to f32 images to keep the
    // conversions as lossless and high-fidelity as possible.
    let (to_linear, to_srgb) = srgb_converter_funcs(color_space_conversion);
    let (premultiplier, demultiplier) = alpha_multiplier_funcs(premultiply);

    let mut preprocessed_input_image: Vec<f32> = Vec::with_capacity(input_image.len());
    preprocessed_input_image.resize(input_image.len(), 0.0f32);
    for i in 0..num_input_pixels {
        for j in 0..3 {
            preprocessed_input_image[4 * i + j] = premultiplier(
                to_linear(input_image[4 * i + j]),
                (input_image[4 * i + 3] as f32) / 255.0,
            );
            preprocessed_input_image[4 * i + 3] = (input_image[4 * i + 3] as f32) / 255.0;
        }
    }

    let mut unprocessed_output_image = vec![0.0f32; num_output_pixels * 4];

    let mut resizer = resize::new(
        input_width,
        input_height,
        output_width,
        output_height,
        Pixel::RGBAF32,
        typ,
    );
    resizer.resize(
        preprocessed_input_image.as_slice(),
        unprocessed_output_image.as_mut_slice(),
    );

    for i in 0..num_output_pixels {
        for j in 0..3 {
            output_image[4 * i + j] = to_srgb(demultiplier(
                unprocessed_output_image[4 * i + j],
                unprocessed_output_image[4 * i + 3],
            ));
        }
        output_image[4 * i + 3] =
            (unprocessed_output_image[4 * i + 3] * 255.0).clamp(0.0, 255.0) as u8;
    }

    return output_image;
}
<commit_msg>Update codecs/resize/src/lib.rs<commit_after>extern crate cfg_if;
extern crate resize;
extern crate wasm_bindgen;

mod utils;

use cfg_if::cfg_if;
use resize::Pixel;
use resize::Type;
use wasm_bindgen::prelude::*;

mod srgb;
use srgb::{linear_to_srgb, Clamp};

cfg_if! {
    // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
    // allocator.
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}

include!("./lut.inc");

// If `with_space_conversion` is true, this function returns 2 functions that
// convert from sRGB to linear RGB and vice versa. If `with_space_conversion` is
// false, the 2 functions returned do nothing.
fn srgb_converter_funcs(with_space_conversion: bool) -> (fn(u8) -> f32, fn(f32) -> u8) {
    if with_space_conversion {
        (
            |v| SRGB_TO_LINEAR_LUT[v as usize],
            |v| (linear_to_srgb(v) * 255.0).clamp(0.0, 255.0) as u8,
        )
    } else {
        (
            |v| (v as f32) / 255.0,
            |v| (v * 255.0).clamp(0.0, 255.0) as u8,
        )
    }
}

// If `with_alpha_premultiplication` is true, this function returns a function
// that premultiply the alpha channel with the given channel value and another
// function that reverses that process. If `with_alpha_premultiplication` is
// false, the functions just return the channel value.
fn alpha_multiplier_funcs(
    with_alpha_premultiplication: bool,
) -> (fn(f32, f32) -> f32, fn(f32, f32) -> f32) {
    if with_alpha_premultiplication {
        (|v, a| v * a, |v, a| v / a)
    } else {
        (|v, _a| v, |v, _a| v)
    }
}

#[wasm_bindgen]
#[no_mangle]
pub fn resize(
    input_image: Vec<u8>,
    input_width: usize,
    input_height: usize,
    output_width: usize,
    output_height: usize,
    typ_idx: usize,
    premultiply: bool,
    color_space_conversion: bool,
) -> Vec<u8> {
    let typ = match typ_idx {
        0 => Type::Triangle,
        1 => Type::Catrom,
        2 => Type::Mitchell,
        3 => Type::Lanczos3,
        _ => panic!("Nope"),
    };
    let num_input_pixels = input_width * input_height;
    let num_output_pixels = output_width * output_height;

    let mut output_image = vec![0u8; num_output_pixels * 4];

    // If both options are false, there is no preprocessing on the pixel values
    // and we can skip the loop.
    if !premultiply && !color_space_conversion {
        let mut resizer = resize::new(
            input_width,
            input_height,
            output_width,
            output_height,
            Pixel::RGBA,
            typ,
        );
        resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
        return output_image;
    }

    // Otherwise, we convert to f32 images to keep the
    // conversions as lossless and high-fidelity as possible.
    let (to_linear, to_srgb) = srgb_converter_funcs(color_space_conversion);
    let (premultiplier, demultiplier) = alpha_multiplier_funcs(premultiply);

    let mut preprocessed_input_image: Vec<f32> = Vec::with_capacity(input_image.len());
    preprocessed_input_image.resize(input_image.len(), 0.0f32);
    for i in 0..num_input_pixels {
        for j in 0..3 {
            preprocessed_input_image[4 * i + j] = premultiplier(
                to_linear(input_image[4 * i + j]),
                (input_image[4 * i + 3] as f32) / 255.0,
            );
            preprocessed_input_image[4 * i + 3] = (input_image[4 * i + 3] as f32) / 255.0;
        }
    }

    let mut unprocessed_output_image = vec![0.0f32; num_output_pixels * 4];

    let mut resizer = resize::new(
        input_width,
        input_height,
        output_width,
        output_height,
        Pixel::RGBAF32,
        typ,
    );
    resizer.resize(
        preprocessed_input_image.as_slice(),
        unprocessed_output_image.as_mut_slice(),
    );

    for i in 0..num_output_pixels {
        for j in 0..3 {
            output_image[4 * i + j] = to_srgb(demultiplier(
                unprocessed_output_image[4 * i + j],
                unprocessed_output_image[4 * i + 3],
            ));
        }
        output_image[4 * i + 3] =
            (unprocessed_output_image[4 * i + 3] * 255.0).clamp(0.0, 255.0) as u8;
    }

    return output_image;
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

use std::os::unix::io::{RawFd, AsRawFd};
use std::io::{Read, Write, Error, ErrorKind};

use super::super::frame::{self, FrameState};
use super::super::stream::{SRecv, SSend, SStream, StreamShutdown};

#[derive(Clone)]
pub struct Plain<T> {
    inner: T,
    state: FrameState,
    buffer: Vec<u8>,
    scratch: Vec<u8>,
    tx_queue: Vec<Vec<u8>>,
    rx_queue: Vec<Vec<u8>>,
}

impl<T: Read + Write + AsRawFd + StreamShutdown> Plain<T> {
    pub fn new(stream: T) -> Plain<T> {
        Plain {
            inner: stream,
            state: FrameState::Start,
            buffer: Vec::with_capacity(3),
            scratch: Vec::new(),
            tx_queue: Vec::new(),
            rx_queue: Vec::new()
        }
    }
}

impl<T> Plain<T> {
    fn buf_with_scratch(&mut self, buf: &[u8], len: usize) -> Vec<u8> {
        let mut new_buf = Vec::<u8>::with_capacity(self.scratch.len() + len);
        for byte in self.scratch.iter() {
            new_buf.push(*byte);
        }
        self.scratch = Vec::<u8>::new();
        for x in 0..len {
            new_buf.push(buf[x]);
        }
        new_buf
    }

    fn read_for_frame_start(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            if buf[*offset] == frame::START {
                self.buffer.push(buf[*offset]);
                self.state = FrameState::PayloadLen;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload_len(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == 3 {
                let len = self.payload_len() + 1;
                self.buffer.reserve_exact(len);
                self.state = FrameState::Payload;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == self.payload_len() + 3 {
                self.state = FrameState::End;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_for_frame_end(&mut self, buf: &[u8], offset: usize, len: usize) -> Result<Vec<u8>, ()> {
        if offset < len {
            let expected_end_byte = buf[offset];
            if expected_end_byte == frame::END {
                let mut payload = Vec::<u8>::with_capacity(self.payload_len());
                for x in 3..self.buffer.len() {
                    payload.push(self.buffer[x]);
                }

                self.state = FrameState::Start;
                self.buffer = Vec::<u8>::with_capacity(3);

                // If there is anything left in buf, we need to put it in our
                // scratch space because we're exiting here
                let mut offset = offset;
                offset += 1;
                self.scratch = Vec::<u8>::with_capacity(len - offset);
                for x in offset..len {
                    self.scratch.push(buf[x]);
                }
                return Ok(payload);
            }

            // If we're here, the frame was wrong. Maybe our fault, who knows?
            // Either way, we're going to reset and try to start again from the start byte.
            // We need to dump whatever is left in the buffer into our scratch because it
            // might be in there?
            self.state = FrameState::Start;
            self.buffer = Vec::<u8>::with_capacity(3);
            self.scratch = Vec::<u8>::with_capacity(len - offset);
            for x in offset..len {
                self.scratch.push(buf[x]);
            }
        }
        Err(())
    }

    fn payload_len(&self) -> usize {
        let mask = 0xFFFFu16;
        let len = ((self.buffer[1] as u16) << 8) & mask;
        (len | self.buffer[2] as u16) as usize
    }

    fn vec_from_slice(&self, slice: &[u8]) -> Vec<u8> {
        let mut buf = Vec::<u8>::with_capacity(slice.len());
        for byte in slice.iter() {
            buf.push(*byte);
        }
        buf
    }
}

impl<T: Read + AsRawFd> SRecv for Plain<T> {
    fn recv(&mut self) -> Result<(), Error> {
        loop {
            let mut buf = Vec::<u8>::with_capacity(1024);
            unsafe {
                buf.set_len(1024);
            }
            let result = self.inner.read(&mut buf[..]);
            if result.is_err() {
                let err = result.unwrap_err();
                if err.kind() == ErrorKind::WouldBlock {
                    if self.rx_queue.len() > 0 {
                        return Ok(());
                    }
                }
                return Err(err);
            }
            let num_read = result.unwrap();

            buf = self.buf_with_scratch(&buf[..], num_read);
            let len = buf.len();
            let mut seek_pos = 0usize;

            if self.state == FrameState::Start {
                self.read_for_frame_start(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::PayloadLen {
                self.read_payload_len(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::Payload {
                self.read_payload(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::End {
                let result = self.read_for_frame_end(&buf[..], seek_pos, len);
                if result.is_ok() {
                    self.rx_queue.push(result.unwrap());
                }
            }
        }
    }

    fn drain_rx_queue(&mut self) -> Vec<Vec<u8>> {
        let buf = self.rx_queue.clone();
        self.rx_queue = Vec::new();
        buf
    }
}

impl<T: Write + AsRawFd> SSend for Plain<T> {
    fn send(&mut self, buf: &[u8]) -> Result<usize, Error> {
        let mut total_written = 0usize;
        self.tx_queue.push(frame::from_slice(buf));
        for x in 0..self.tx_queue.len() {
            let b = self.tx_queue.remove(x);
            let result = self.inner.write(&b[..]);
            if result.is_err() {
                let err = result.unwrap_err();
                if err.kind() == ErrorKind::WouldBlock {
                    self.tx_queue.insert(x, b);
                    return Ok(total_written);
                }
                return Err(err);
            }

            let num_written = result.unwrap();
            total_written += num_written;
            if num_written < b.len() {
                let remainder = self.vec_from_slice(&b[(b.len() - num_written)..b.len()]);
                self.tx_queue.insert(x, remainder);
                return Ok(total_written);
            }
        }
        Ok(total_written)
    }
}

impl<T: StreamShutdown> StreamShutdown for Plain<T> {
    fn shutdown(&mut self) -> Result<(), Error> {
        self.inner.shutdown()
    }
}

impl<T: AsRawFd> AsRawFd for Plain<T> {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

impl<T: 'static + Read + Write + AsRawFd + Clone + Send + StreamShutdown> SStream for Plain<T> {}
<commit_msg>Fixed bug that reported Error on EAGAIN when a complete message was not received.<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL was not
// distributed with this file, You can obtain one at
// http://mozilla.org/MPL/2.0/.

use std::os::unix::io::{RawFd, AsRawFd};
use std::io::{Read, Write, Error, ErrorKind};

use super::super::frame::{self, FrameState};
use super::super::stream::{SRecv, SSend, SStream, StreamShutdown};

#[derive(Clone)]
pub struct Plain<T> {
    inner: T,
    state: FrameState,
    buffer: Vec<u8>,
    scratch: Vec<u8>,
    tx_queue: Vec<Vec<u8>>,
    rx_queue: Vec<Vec<u8>>,
}

impl<T: Read + Write + AsRawFd + StreamShutdown> Plain<T> {
    pub fn new(stream: T) -> Plain<T> {
        Plain {
            inner: stream,
            state: FrameState::Start,
            buffer: Vec::with_capacity(3),
            scratch: Vec::new(),
            tx_queue: Vec::new(),
            rx_queue: Vec::new()
        }
    }
}

impl<T> Plain<T> {
    fn buf_with_scratch(&mut self, buf: &[u8], len: usize) -> Vec<u8> {
        let mut new_buf = Vec::<u8>::with_capacity(self.scratch.len() + len);
        for byte in self.scratch.iter() {
            new_buf.push(*byte);
        }
        self.scratch = Vec::<u8>::new();
        for x in 0..len {
            new_buf.push(buf[x]);
        }
        new_buf
    }

    fn read_for_frame_start(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            if buf[*offset] == frame::START {
                self.buffer.push(buf[*offset]);
                self.state = FrameState::PayloadLen;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload_len(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == 3 {
                let len = self.payload_len() + 1;
                self.buffer.reserve_exact(len);
                self.state = FrameState::Payload;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_payload(&mut self, buf: &[u8], offset: &mut usize, len: usize) {
        for _ in *offset..len {
            self.buffer.push(buf[*offset]);
            if self.buffer.len() == self.payload_len() + 3 {
                self.state = FrameState::End;
                *offset += 1;
                break;
            }
            *offset += 1;
        }
    }

    fn read_for_frame_end(&mut self, buf: &[u8], offset: usize, len: usize) -> Result<Vec<u8>, ()> {
        if offset < len {
            let expected_end_byte = buf[offset];
            if expected_end_byte == frame::END {
                let mut payload = Vec::<u8>::with_capacity(self.payload_len());
                for x in 3..self.buffer.len() {
                    payload.push(self.buffer[x]);
                }

                self.state = FrameState::Start;
                self.buffer = Vec::<u8>::with_capacity(3);

                // If there is anything left in buf, we need to put it in our
                // scratch space because we're exiting here
                let mut offset = offset;
                offset += 1;
                self.scratch = Vec::<u8>::with_capacity(len - offset);
                for x in offset..len {
                    self.scratch.push(buf[x]);
                }
                return Ok(payload);
            }

            // If we're here, the frame was wrong. Maybe our fault, who knows?
            // Either way, we're going to reset and try to start again from the start byte.
            // We need to dump whatever is left in the buffer into our scratch because it
            // might be in there?
            self.state = FrameState::Start;
            self.buffer = Vec::<u8>::with_capacity(3);
            self.scratch = Vec::<u8>::with_capacity(len - offset);
            for x in offset..len {
                self.scratch.push(buf[x]);
            }
        }
        Err(())
    }

    fn payload_len(&self) -> usize {
        let mask = 0xFFFFu16;
        let len = ((self.buffer[1] as u16) << 8) & mask;
        (len | self.buffer[2] as u16) as usize
    }

    fn vec_from_slice(&self, slice: &[u8]) -> Vec<u8> {
        let mut buf = Vec::<u8>::with_capacity(slice.len());
        for byte in slice.iter() {
            buf.push(*byte);
        }
        buf
    }
}

impl<T: Read + AsRawFd> SRecv for Plain<T> {
    fn recv(&mut self) -> Result<(), Error> {
        loop {
            let mut buf = Vec::<u8>::with_capacity(1024);
            unsafe {
                buf.set_len(1024);
            }
            let result = self.inner.read(&mut buf[..]);
            if result.is_err() {
                let err = result.unwrap_err();
                if err.kind() == ErrorKind::WouldBlock {
                    return Ok(());
                }
                return Err(err);
            }
            let num_read = result.unwrap();

            buf = self.buf_with_scratch(&buf[..], num_read);
            let len = buf.len();
            let mut seek_pos = 0usize;

            if self.state == FrameState::Start {
                self.read_for_frame_start(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::PayloadLen {
                self.read_payload_len(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::Payload {
                self.read_payload(&buf[..], &mut seek_pos, len);
            }

            if self.state == FrameState::End {
                let result = self.read_for_frame_end(&buf[..], seek_pos, len);
                if result.is_ok() {
                    self.rx_queue.push(result.unwrap());
                }
            }
        }
    }

    fn drain_rx_queue(&mut self) -> Vec<Vec<u8>> {
        let buf = self.rx_queue.clone();
        self.rx_queue = Vec::new();
        buf
    }
}

impl<T: Write + AsRawFd> SSend for Plain<T> {
    fn send(&mut self, buf: &[u8]) -> Result<usize, Error> {
        let mut total_written = 0usize;
        self.tx_queue.push(frame::from_slice(buf));
        for x in 0..self.tx_queue.len() {
            let b = self.tx_queue.remove(x);
            let result = self.inner.write(&b[..]);
            if result.is_err() {
                let err = result.unwrap_err();
                if err.kind() == ErrorKind::WouldBlock {
                    self.tx_queue.insert(x, b);
                    return Ok(total_written);
                }
                return Err(err);
            }

            let num_written = result.unwrap();
            total_written += num_written;
            if num_written < b.len() {
                let remainder = self.vec_from_slice(&b[(b.len() - num_written)..b.len()]);
                self.tx_queue.insert(x, remainder);
                return Ok(total_written);
            }
        }
        Ok(total_written)
    }
}

impl<T: StreamShutdown> StreamShutdown for Plain<T> {
    fn shutdown(&mut self) -> Result<(), Error> {
        self.inner.shutdown()
    }
}

impl<T: AsRawFd> AsRawFd for Plain<T> {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

impl<T: 'static + Read + Write + AsRawFd + Clone + Send + StreamShutdown> SStream for Plain<T> {}
<|endoftext|>


<commit_before>use redox::*;

use super::Mode;
use super::Mode::*;
use super::Editor;

pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match key_event.character {
                '0' if !no_mult => times *= 10,

                '1' if no_mult => times = 1,
                '1' => times = times * 10 + 1,

                '2' if no_mult => times = 2,
                '2' => times = times * 10 + 2,

                '3' if no_mult => times = 3,
                '3' => times = times * 10 + 3,

                '4' if no_mult => times = 4,
                '4' => times = times * 10 + 4,

                '5' if no_mult => times = 5,
                '5' => times = times * 10 + 5,

                '6' if no_mult => times = 6,
                '6' => times = times * 10 + 6,

                '7' if no_mult => times = 7,
                '7' => times = times * 10 + 7,

                '8' if no_mult => times = 8,
                '8' => times = times * 10 + 8,

                '9' if no_mult => times = 9,
                '9' => times = times * 10 + 9,
                _ => {
                    for _ in 0 .. times {
                        match (m, key_event.character) {
                            (Normal, 'i') => {
                                *mode = Insert;
                                *last_change = editor.string.clone();
                            },
                            (Normal, 'h') => editor.left(),
                            (Normal, 'l') => editor.right(),
                            (Normal, 'k') => editor.up(),
                            (Normal, 'j') => editor.down(),
                            (Normal, 'G') => editor.offset = editor.string.len(),
                            (Normal, 'a') => {
                                editor.right();
                                *mode = Insert;
                                *last_change = editor.string.clone();
                            },
                            (Normal, 'x') => editor.delete(window),
                            (Normal, 'X') => editor.backspace(window),
                            (Normal, 'u') => {
                                editor.offset = 0;
                                ::core::mem::swap(last_change, &mut editor.string);
                            },
                            (Normal, 'o') => {
                                exec(editor, mode, multiplier, last_change, KeyEvent {
                                    character: '$',
                                    scancode: 0,
                                    pressed: true,
                                }, window);
                                exec(editor, mode, multiplier, last_change, KeyEvent {
                                    character: 'i',
                                    scancode: 0,
                                    pressed: true,
                                }, window);
                                exec(editor, mode, multiplier, last_change, KeyEvent {
                                    character: '\n',
                                    scancode: 0,
                                    pressed: true,
                                }, window);
                            },
                            (Normal, '$') => {
                                let mut new_offset = editor.string.len();
                                for i in editor.offset..editor.string.len() {
                                    match editor.string.as_bytes()[i] {
                                        0 => break,
                                        10 => {
                                            new_offset = i;
                                            break;
                                        }
                                        _ => (),
                                    }
                                }
                                editor.offset = new_offset;
                            },
                            (Normal, '0') => {

                                let mut new_offset = 0;
                                for i in 2..editor.offset {
                                    match editor.string.as_bytes()[editor.offset - i] {
                                        0 => break,
                                        10 => {
                                            new_offset = editor.offset - i + 1;
                                            break;
                                        }
                                        _ => (),
                                    }
                                }
                                editor.offset = new_offset;
                            },
                            (Insert, '\0') => (),
                            (Insert, _) => {
                                window.set_title(&format!("{}{}{}","Editor (", &editor.url, ") Changed"));
                                editor.string = editor.string[0 .. editor.offset].to_string() +
                                    &key_event.character.to_string() +
                                    &editor.string[editor.offset .. editor.string.len()];
                                editor.offset += 1;
                            },
                            _ => {},
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<commit_msg>Add gg commmand<commit_after>use redox::*;

use super::Mode;
use super::Mode::*;
use super::Editor;

pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match key_event.character {
                '0' if !no_mult => times *= 10,

                '1' if no_mult => times = 1,
                '1' => times = times * 10 + 1,

                '2' if no_mult => times = 2,
                '2' => times = times * 10 + 2,

                '3' if no_mult => times = 3,
                '3' => times = times * 10 + 3,

                '4' if no_mult => times = 4,
                '4' => times = times * 10 + 4,

                '5' if no_mult => times = 5,
                '5' => times = times * 10 + 5,

                '6' if no_mult => times = 6,
                '6' => times = times * 10 + 6,

                '7' if no_mult => times = 7,
                '7' => times = times * 10 + 7,

                '8' if no_mult => times = 8,
                '8' => times = times * 10 + 8,

                '9' if no_mult => times = 9,
                '9' => times = times * 10 + 9,
                _ => {
                    for _ in 0 .. times {
                        match (m, key_event.character) {
                            (Normal, 'i') => {
                                *mode = Insert;
                                *last_change = editor.string.clone();
                            },
                            (Normal, 'h') => editor.left(),
                            (Normal, 'l') => editor.right(),
                            (Normal, 'k') => editor.up(),
                            (Normal, 'j') => editor.down(),
                            (Normal, 'g') => editor.offset = 0,
                            (Normal, 'G') => editor.offset = editor.string.len(),
                            (Normal, 'a') => {
                                editor.right();
                                *mode = Insert;
                                *last_change = editor.string.clone();
                            },
                            (Normal, 'x') => editor.delete(window),
                            (Normal, 'X') => editor.backspace(window),
                            (Normal, 'u') => {
                                editor.offset = 0;
                                ::core::mem::swap(last_change, &mut editor.string);
                            },
                            (Normal, 'o') => {
                                exec(editor, mode, multiplier, last_change, KeyEvent {
                                    character: '$',
                                    scancode: 0,
                                    pressed: true,
                                }, window);
                                exec(editor, mode, multiplier, last_change, KeyEvent {
                                    character: 'i',
                                    scancode: 0,
                                    pressed: true,
                                }, window);
                                exec(editor, mode, multiplier, last_change, KeyEvent {
                                    character: '\n',
                                    scancode: 0,
                                    pressed: true,
                                }, window);
                            },
                            (Normal, '$') => {
                                let mut new_offset = editor.string.len();
                                for i in editor.offset..editor.string.len() {
                                    match editor.string.as_bytes()[i] {
                                        0 => break,
                                        10 => {
                                            new_offset = i;
                                            break;
                                        }
                                        _ => (),
                                    }
                                }
                                editor.offset = new_offset;
                            },
                            (Normal, '0') => {

                                let mut new_offset = 0;
                                for i in 2..editor.offset {
                                    match editor.string.as_bytes()[editor.offset - i] {
                                        0 => break,
                                        10 => {
                                            new_offset = editor.offset - i + 1;
                                            break;
                                        }
                                        _ => (),
                                    }
                                }
                                editor.offset = new_offset;
                            },
                            (Insert, '\0') => (),
                            (Insert, _) => {
                                window.set_title(&format!("{}{}{}","Editor (", &editor.url, ") Changed"));
                                editor.string = editor.string[0 .. editor.offset].to_string() +
                                    &key_event.character.to_string() +
                                    &editor.string[editor.offset .. editor.string.len()];
                                editor.offset += 1;
                            },
                            _ => {},
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(as_unsafe_cell)]
#![feature(borrow_state)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(custom_derive)]
#![feature(fnbox)]
#![feature(iter_arith)]
#![feature(mpsc_select)]
#![feature(nonzero)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(peekable_is_empty)]
#![feature(plugin)]
#![feature(slice_patterns)]
#![feature(stmt_expr_attributes)]
#![feature(question_mark)]

#![deny(unsafe_code)]
#![allow(non_snake_case)]

#![doc = "The script crate contains all matters DOM."]

#![plugin(heapsize_plugin)]
#![plugin(phf_macros)]
#![plugin(plugins)]

extern crate angle;
extern crate app_units;
#[allow(unused_extern_crates)]
#[macro_use]
extern crate bitflags;
extern crate canvas;
extern crate canvas_traits;
extern crate caseless;
extern crate core;
extern crate cssparser;
extern crate devtools_traits;
extern crate encoding;
extern crate euclid;
extern crate fnv;
extern crate gfx_traits;
extern crate heapsize;
extern crate html5ever;
extern crate hyper;
extern crate image;
extern crate ipc_channel;
extern crate js;
extern crate libc;
#[macro_use]
extern crate log;
#[macro_use]
extern crate mime;
extern crate msg;
extern crate net_traits;
extern crate num_traits;
extern crate offscreen_gl_context;
extern crate open;
extern crate phf;
#[macro_use]
extern crate profile_traits;
extern crate rand;
extern crate ref_filter_map;
extern crate ref_slice;
extern crate regex;
extern crate rustc_serialize;
extern crate script_traits;
extern crate selectors;
extern crate serde;
extern crate smallvec;
#[macro_use(atom, ns)] extern crate string_cache;
#[macro_use]
extern crate style;
extern crate time;
#[cfg(any(target_os = "macos", target_os = "linux"))]
extern crate tinyfiledialogs;
extern crate unicase;
extern crate url;
#[macro_use]
extern crate util;
extern crate uuid;
extern crate webrender_traits;
extern crate websocket;
extern crate xml5ever;

pub mod bluetooth_blacklist;
pub mod clipboard_provider;
pub mod cors;
mod devtools;
pub mod document_loader;
#[macro_use]
pub mod dom;
pub mod layout_interface;
mod mem;
mod network_listener;
pub mod origin;
pub mod parse;
pub mod reporter;
pub mod script_runtime;
#[allow(unsafe_code)]
pub mod script_thread;
mod task_source;
pub mod textinput;
mod timers;
mod unpremultiplytable;
mod webdriver_handlers;

use dom::bindings::codegen::RegisterBindings;
use js::jsapi::SetDOMProxyInformation;
use std::ptr;

#[cfg(target_os = "linux")]
#[allow(unsafe_code)]
fn perform_platform_specific_initialization() {
    use std::mem;
    // 4096 is default max on many linux systems
    const MAX_FILE_LIMIT: libc::rlim_t = 4096;

    // Bump up our number of file descriptors to save us from impending doom caused by an onslaught
    // of iframes.
    unsafe {
        let mut rlim: libc::rlimit = mem::uninitialized();
        match libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) {
            0 => {
                if rlim.rlim_cur >= MAX_FILE_LIMIT {
                    // we have more than enough
                    return;
                }

                rlim.rlim_cur = match rlim.rlim_max {
                    libc::RLIM_INFINITY => MAX_FILE_LIMIT,
                    _ => {
                        if rlim.rlim_max < MAX_FILE_LIMIT {
                            rlim.rlim_max
                        } else {
                            MAX_FILE_LIMIT
                        }
                    }
                };
                match libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) {
                    0 => (),
                    _ => warn!("Failed to set file count limit"),
                };
            },
            _ => warn!("Failed to get file count limit"),
        };
    }
}

#[cfg(not(target_os = "linux"))]
fn perform_platform_specific_initialization() {}

#[allow(unsafe_code)]
pub fn init() {
    unsafe {
        assert_eq!(js::jsapi::JS_Init(), true);
        SetDOMProxyInformation(ptr::null(), 0, Some(script_thread::shadow_check_callback));
    }

    // Create the global vtables used by the (generated) DOM
    // bindings to implement JS proxies.
    RegisterBindings::RegisterProxyHandlers();

    perform_platform_specific_initialization();
}
<commit_msg>Remove spurious JS_Init call.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(as_unsafe_cell)]
#![feature(borrow_state)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(custom_derive)]
#![feature(fnbox)]
#![feature(iter_arith)]
#![feature(mpsc_select)]
#![feature(nonzero)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(peekable_is_empty)]
#![feature(plugin)]
#![feature(slice_patterns)]
#![feature(stmt_expr_attributes)]
#![feature(question_mark)]

#![deny(unsafe_code)]
#![allow(non_snake_case)]

#![doc = "The script crate contains all matters DOM."]

#![plugin(heapsize_plugin)]
#![plugin(phf_macros)]
#![plugin(plugins)]

extern crate angle;
extern crate app_units;
#[allow(unused_extern_crates)]
#[macro_use]
extern crate bitflags;
extern crate canvas;
extern crate canvas_traits;
extern crate caseless;
extern crate core;
extern crate cssparser;
extern crate devtools_traits;
extern crate encoding;
extern crate euclid;
extern crate fnv;
extern crate gfx_traits;
extern crate heapsize;
extern crate html5ever;
extern crate hyper;
extern crate image;
extern crate ipc_channel;
extern crate js;
extern crate libc;
#[macro_use]
extern crate log;
#[macro_use]
extern crate mime;
extern crate msg;
extern crate net_traits;
extern crate num_traits;
extern crate offscreen_gl_context;
extern crate open;
extern crate phf;
#[macro_use]
extern crate profile_traits;
extern crate rand;
extern crate ref_filter_map;
extern crate ref_slice;
extern crate regex;
extern crate rustc_serialize;
extern crate script_traits;
extern crate selectors;
extern crate serde;
extern crate smallvec;
#[macro_use(atom, ns)] extern crate string_cache;
#[macro_use]
extern crate style;
extern crate time;
#[cfg(any(target_os = "macos", target_os = "linux"))]
extern crate tinyfiledialogs;
extern crate unicase;
extern crate url;
#[macro_use]
extern crate util;
extern crate uuid;
extern crate webrender_traits;
extern crate websocket;
extern crate xml5ever;

pub mod bluetooth_blacklist;
pub mod clipboard_provider;
pub mod cors;
mod devtools;
pub mod document_loader;
#[macro_use]
pub mod dom;
pub mod layout_interface;
mod mem;
mod network_listener;
pub mod origin;
pub mod parse;
pub mod reporter;
pub mod script_runtime;
#[allow(unsafe_code)]
pub mod script_thread;
mod task_source;
pub mod textinput;
mod timers;
mod unpremultiplytable;
mod webdriver_handlers;

use dom::bindings::codegen::RegisterBindings;
use js::jsapi::SetDOMProxyInformation;
use std::ptr;

#[cfg(target_os = "linux")]
#[allow(unsafe_code)]
fn perform_platform_specific_initialization() {
    use std::mem;
    // 4096 is default max on many linux systems
    const MAX_FILE_LIMIT: libc::rlim_t = 4096;

    // Bump up our number of file descriptors to save us from impending doom caused by an onslaught
    // of iframes.
    unsafe {
        let mut rlim: libc::rlimit = mem::uninitialized();
        match libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) {
            0 => {
                if rlim.rlim_cur >= MAX_FILE_LIMIT {
                    // we have more than enough
                    return;
                }

                rlim.rlim_cur = match rlim.rlim_max {
                    libc::RLIM_INFINITY => MAX_FILE_LIMIT,
                    _ => {
                        if rlim.rlim_max < MAX_FILE_LIMIT {
                            rlim.rlim_max
                        } else {
                            MAX_FILE_LIMIT
                        }
                    }
                };
                match libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) {
                    0 => (),
                    _ => warn!("Failed to set file count limit"),
                };
            },
            _ => warn!("Failed to get file count limit"),
        };
    }
}

#[cfg(not(target_os = "linux"))]
fn perform_platform_specific_initialization() {}

#[allow(unsafe_code)]
pub fn init() {
    unsafe {
        SetDOMProxyInformation(ptr::null(), 0, Some(script_thread::shadow_check_callback));
    }

    // Create the global vtables used by the (generated) DOM
    // bindings to implement JS proxies.
    RegisterBindings::RegisterProxyHandlers();

    perform_platform_specific_initialization();
}
<|endoftext|>


<commit_before>use super::*;

impl Editor {
    /// Get pos of next char
    pub fn next_pos(&mut self) -> (usize, usize) {
        // TODO: Add numerals
        if self.x() == self.text[self.y()].len() {
            if self.y() < self.text.len() - 1 {
                (0, self.y() + 1)
            } else {
                (self.x(), self.y())
            }
        } else {
            (self.x() + 1, self.y())
        }
    }

    /// Get pos of previous char
    pub fn previous_pos(&mut self) -> (usize, usize) {
        if self.x() == 0 {
            if self.y() > 0 {
                (self.text[self.y()].len(), self.y() - 1)
            } else {
                (self.x(), self.y())
            }
        } else {
            (self.x() - 1, self.y())
        }
    }

    pub fn next(&mut self) {
        let (x, y) = self.next_pos();
        self.cursor_mut().x = x;
        self.cursor_mut().y = y;
    }
    pub fn previous(&mut self) {
        let (x, y) = self.previous_pos();
        self.cursor_mut().x = x;
        self.cursor_mut().y = y;
    }

    /// Go right
    pub fn right(&mut self, n: usize) {
        let x = self.x() + n;
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.x += n;

        if x > text[y].len() {
            curs.x = text[y].len();
        }
    }

    /// Go left
    pub fn left(&mut self, n: usize) {
        let x = self.x();
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        if n <= x {
            curs.x = x - n;
        } else {
            curs.x = 0;
        }

    }

    /// Go up
    pub fn up(&mut self, n: usize) {
        let y = self.y();
        let curs = self.cursor_mut();
        if n <= y {
            curs.y -= n;
        } else {
            curs.y = 0;
        }
    }

    /// Go down
    pub fn down(&mut self, n: usize) {
        let x = self.x();
        let y = self.y() + n;

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.y += n;

        if y >= text.len() {
            curs.y = text.len() - 1;
        }
    }
}
<commit_msg>Remove unused mut<commit_after>use super::*;

impl Editor {
    /// Get pos of next char
    pub fn next_pos(&self) -> (usize, usize) {
        // TODO: Add numerals
        if self.x() == self.text[self.y()].len() {
            if self.y() < self.text.len() - 1 {
                (0, self.y() + 1)
            } else {
                (self.x(), self.y())
            }
        } else {
            (self.x() + 1, self.y())
        }
    }

    /// Get pos of previous char
    pub fn previous_pos(&self) -> (usize, usize) {
        if self.x() == 0 {
            if self.y() > 0 {
                (self.text[self.y()].len(), self.y() - 1)
            } else {
                (self.x(), self.y())
            }
        } else {
            (self.x() - 1, self.y())
        }
    }

    pub fn next(&mut self) {
        let (x, y) = self.next_pos();
        self.cursor_mut().x = x;
        self.cursor_mut().y = y;
    }
    pub fn previous(&mut self) {
        let (x, y) = self.previous_pos();
        self.cursor_mut().x = x;
        self.cursor_mut().y = y;
    }

    /// Go right
    pub fn right(&mut self, n: usize) {
        let x = self.x() + n;
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.x += n;

        if x > text[y].len() {
            curs.x = text[y].len();
        }
    }

    /// Go left
    pub fn left(&mut self, n: usize) {
        let x = self.x();
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        if n <= x {
            curs.x = x - n;
        } else {
            curs.x = 0;
        }

    }

    /// Go up
    pub fn up(&mut self, n: usize) {
        let y = self.y();
        let curs = self.cursor_mut();
        if n <= y {
            curs.y -= n;
        } else {
            curs.y = 0;
        }
    }

    /// Go down
    pub fn down(&mut self, n: usize) {
        let x = self.x();
        let y = self.y() + n;

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.y += n;

        if y >= text.len() {
            curs.y = text.len() - 1;
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

pub struct Cache {
    capacity: u32,
//    key_maxlen: u32,
//    value_maxlen: u32,
    storage: HashMap<Vec<u8>, Vec<u8>>,
}

impl Cache {
    fn new(capacity: u32) -> Cache {
        Cache {
            capacity: capacity,
            storage: HashMap::new(),
        }
    }

    fn get(&self, key: Vec<u8>) -> Option<&Vec<u8>> {
        // check key size

        self.storage.get(&key)
    }

    fn set(&mut self, key: Vec<u8>, value: Vec<u8>) {
        // check key & value sizes
        // check capacity

        self.storage.insert(key, value);
    }
}

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

    #[test]
    fn test_set_one_key() {
        let mut cache = Cache::new(1);

        let key = "name".to_string().into_bytes();
        let value = "jimmy".to_string().into_bytes();

        cache.set(key.clone(), value.clone());
        let value_found = cache.get(key).unwrap();

        assert_eq!(&value, value_found);
    }
}
<commit_msg>simplify test<commit_after>use std::collections::HashMap;

pub struct Cache {
    capacity: u32,
//    key_maxlen: u32,
//    value_maxlen: u32,
    storage: HashMap<Vec<u8>, Vec<u8>>,
}

impl Cache {
    fn new(capacity: u32) -> Cache {
        Cache {
            capacity: capacity,
            storage: HashMap::new(),
        }
    }

    fn get(&self, key: Vec<u8>) -> Option<&Vec<u8>> {
        // check key size

        self.storage.get(&key)
    }

    fn set(&mut self, key: Vec<u8>, value: Vec<u8>) {
        // check key & value sizes
        // check capacity

        self.storage.insert(key, value);
    }
}

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

    #[test]
    fn test_set_one_key() {
        let mut cache = Cache::new(1);

        let key = [1, 2, 3];
        let value = [4, 5, 6];

        cache.set(key.clone(), value.clone());
        let value_found = cache.get(key).unwrap();

        assert_eq!(&value, value_found);
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate backtrace;
extern crate euclid;
#[cfg(target_os = "windows")] extern crate gdi32;
extern crate gleam;
extern crate glutin;
#[macro_use] extern crate lazy_static;
// The window backed by glutin
#[cfg(any(target_os = "linux", target_os = "macos"))] extern crate osmesa_sys;
extern crate servo;
#[cfg(feature = "unstable")]
#[macro_use]
extern crate sig;
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
extern crate tinyfiledialogs;
extern crate winit;
#[cfg(target_os = "windows")] extern crate winapi;
#[cfg(target_os = "windows")] extern crate user32;

mod glutin_app;
mod resources;

use backtrace::Backtrace;
use servo::Servo;
use servo::compositing::windowing::WindowEvent;
use servo::config::opts::{self, ArgumentParsingResult, parse_url_or_filename};
use servo::config::servo_version;
use servo::ipc_channel::ipc;
use servo::servo_config::prefs::PREFS;
use servo::servo_url::ServoUrl;
use std::env;
use std::panic;
use std::process;
use std::thread;

mod browser;

pub mod platform {
    #[cfg(target_os = "macos")]
    pub use platform::macos::deinit;

    #[cfg(target_os = "macos")]
    pub mod macos;

    #[cfg(not(target_os = "macos"))]
    pub fn deinit() {}
}

#[cfg(feature = "unstable")]
fn install_crash_handler() {
    use backtrace::Backtrace;
    use sig::ffi::Sig;
    use std::intrinsics::abort;
    use std::thread;

    fn handler(_sig: i32) {
        let name = thread::current()
            .name()
            .map(|n| format!(" for thread \"{}\"", n))
            .unwrap_or("".to_owned());
        println!("Stack trace{}\n{:?}", name, Backtrace::new());
        unsafe {
            // N.B. Using process::abort() here causes the crash handler to be
            //      triggered recursively.
            abort();
        }
    }

    signal!(Sig::SEGV, handler); // handle segfaults
    signal!(Sig::ILL, handler); // handle stack overflow and unsupported CPUs
    signal!(Sig::IOT, handler); // handle double panics
    signal!(Sig::BUS, handler); // handle invalid memory access
}

pub fn main() {
    install_crash_handler();

    resources::init();

    // Parse the command line options and store them globally
    let args: Vec<String> = env::args().collect();
    let opts_result = opts::from_cmdline_args(&args);

    let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result {
        Some(token)
    } else {
        if opts::get().is_running_problem_test && env::var("RUST_LOG").is_err() {
            env::set_var("RUST_LOG", "compositing::constellation");
        }

        None
    };

    // TODO: once log-panics is released, can this be replaced by
    // log_panics::init()?
    panic::set_hook(Box::new(|info| {
        warn!("Panic hook called.");
        let msg = match info.payload().downcast_ref::<&'static str>() {
            Some(s) => *s,
            None => {
                match info.payload().downcast_ref::<String>() {
                    Some(s) => &**s,
                    None => "Box<Any>",
                }
            },
        };
        let current_thread = thread::current();
        let name = current_thread.name().unwrap_or("<unnamed>");
        if let Some(location) = info.location() {
            println!("{} (thread {}, at {}:{})",
                     msg,
                     name,
                     location.file(),
                     location.line());
        } else {
            println!("{} (thread {})", msg, name);
        }
        if env::var("RUST_BACKTRACE").is_ok() {
            println!("{:?}", Backtrace::new());
        }

        error!("{}", msg);
    }));

    if let Some(token) = content_process_token {
        return servo::run_content_process(token);
    }

    if opts::get().is_printing_version {
        println!("{}", servo_version());
        process::exit(0);
    }

    let window = glutin_app::create_window();

    let mut browser = browser::Browser::new(window.clone());

    // If the url is not provided, we fallback to the homepage in PREFS,
    // or a blank page in case the homepage is not set either.
    let cwd = env::current_dir().unwrap();
    let cmdline_url = opts::get().url.clone();
    let pref_url = PREFS.get("shell.homepage").as_string()
        .and_then(|str| parse_url_or_filename(&cwd, str).ok());
    let blank_url = ServoUrl::parse("about:blank").ok();

    let target_url = cmdline_url.or(pref_url).or(blank_url).unwrap();

    let mut servo = Servo::new(window.clone());

    let (sender, receiver) = ipc::channel().unwrap();
    servo.handle_events(vec![WindowEvent::NewBrowser(target_url, sender)]);
    let browser_id = receiver.recv().unwrap();
    browser.set_browser_id(browser_id);
    servo.handle_events(vec![WindowEvent::SelectBrowser(browser_id)]);

    servo.setup_logging();

    window.run(|| {
        let win_events = window.get_events();

        // FIXME: this could be handled by Servo. We don't need
        // a repaint_synchronously function exposed.
        let need_resize = win_events.iter().any(|e| match *e {
            WindowEvent::Resize => true,
            _ => false,
        });

        browser.handle_window_events(win_events);

        let mut servo_events = servo.get_events();
        loop {
            browser.handle_servo_events(servo_events);
            servo.handle_events(browser.get_events());
            if browser.shutdown_requested() {
                return true;
            }
            servo_events = servo.get_events();
            if servo_events.is_empty() {
                break;
            }
        }

        if need_resize {
            servo.repaint_synchronously();
        }
        false
    });

    servo.deinit();

    platform::deinit()
}

// These functions aren't actually called. They are here as a link
// hack because Skia references them.

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glBindVertexArrayOES(_array: usize)
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glDeleteVertexArraysOES(_n: isize, _arrays: *const ())
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glGenVertexArraysOES(_n: isize, _arrays: *const ())
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glRenderbufferStorageMultisampleIMG(_: isize, _: isize, _: isize, _: isize, _: isize)
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glFramebufferTexture2DMultisampleIMG(_: isize, _: isize, _: isize, _: isize, _: isize, _: isize)
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glDiscardFramebufferEXT(_: isize, _: isize, _: *const ())
{
    unimplemented!()
}

<commit_msg>Move a comment back next to what it was documenting<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

extern crate backtrace;
extern crate euclid;
#[cfg(target_os = "windows")] extern crate gdi32;
extern crate gleam;
extern crate glutin;
#[macro_use] extern crate lazy_static;
#[cfg(any(target_os = "linux", target_os = "macos"))] extern crate osmesa_sys;
extern crate servo;
#[cfg(feature = "unstable")]
#[macro_use]
extern crate sig;
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
extern crate tinyfiledialogs;
extern crate winit;
#[cfg(target_os = "windows")] extern crate winapi;
#[cfg(target_os = "windows")] extern crate user32;

// The window backed by glutin
mod glutin_app;

mod resources;

mod browser;

use backtrace::Backtrace;
use servo::Servo;
use servo::compositing::windowing::WindowEvent;
use servo::config::opts::{self, ArgumentParsingResult, parse_url_or_filename};
use servo::config::servo_version;
use servo::ipc_channel::ipc;
use servo::servo_config::prefs::PREFS;
use servo::servo_url::ServoUrl;
use std::env;
use std::panic;
use std::process;
use std::thread;

pub mod platform {
    #[cfg(target_os = "macos")]
    pub use platform::macos::deinit;

    #[cfg(target_os = "macos")]
    pub mod macos;

    #[cfg(not(target_os = "macos"))]
    pub fn deinit() {}
}

#[cfg(feature = "unstable")]
fn install_crash_handler() {
    use backtrace::Backtrace;
    use sig::ffi::Sig;
    use std::intrinsics::abort;
    use std::thread;

    fn handler(_sig: i32) {
        let name = thread::current()
            .name()
            .map(|n| format!(" for thread \"{}\"", n))
            .unwrap_or("".to_owned());
        println!("Stack trace{}\n{:?}", name, Backtrace::new());
        unsafe {
            // N.B. Using process::abort() here causes the crash handler to be
            //      triggered recursively.
            abort();
        }
    }

    signal!(Sig::SEGV, handler); // handle segfaults
    signal!(Sig::ILL, handler); // handle stack overflow and unsupported CPUs
    signal!(Sig::IOT, handler); // handle double panics
    signal!(Sig::BUS, handler); // handle invalid memory access
}

pub fn main() {
    install_crash_handler();

    resources::init();

    // Parse the command line options and store them globally
    let args: Vec<String> = env::args().collect();
    let opts_result = opts::from_cmdline_args(&args);

    let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result {
        Some(token)
    } else {
        if opts::get().is_running_problem_test && env::var("RUST_LOG").is_err() {
            env::set_var("RUST_LOG", "compositing::constellation");
        }

        None
    };

    // TODO: once log-panics is released, can this be replaced by
    // log_panics::init()?
    panic::set_hook(Box::new(|info| {
        warn!("Panic hook called.");
        let msg = match info.payload().downcast_ref::<&'static str>() {
            Some(s) => *s,
            None => {
                match info.payload().downcast_ref::<String>() {
                    Some(s) => &**s,
                    None => "Box<Any>",
                }
            },
        };
        let current_thread = thread::current();
        let name = current_thread.name().unwrap_or("<unnamed>");
        if let Some(location) = info.location() {
            println!("{} (thread {}, at {}:{})",
                     msg,
                     name,
                     location.file(),
                     location.line());
        } else {
            println!("{} (thread {})", msg, name);
        }
        if env::var("RUST_BACKTRACE").is_ok() {
            println!("{:?}", Backtrace::new());
        }

        error!("{}", msg);
    }));

    if let Some(token) = content_process_token {
        return servo::run_content_process(token);
    }

    if opts::get().is_printing_version {
        println!("{}", servo_version());
        process::exit(0);
    }

    let window = glutin_app::create_window();

    let mut browser = browser::Browser::new(window.clone());

    // If the url is not provided, we fallback to the homepage in PREFS,
    // or a blank page in case the homepage is not set either.
    let cwd = env::current_dir().unwrap();
    let cmdline_url = opts::get().url.clone();
    let pref_url = PREFS.get("shell.homepage").as_string()
        .and_then(|str| parse_url_or_filename(&cwd, str).ok());
    let blank_url = ServoUrl::parse("about:blank").ok();

    let target_url = cmdline_url.or(pref_url).or(blank_url).unwrap();

    let mut servo = Servo::new(window.clone());

    let (sender, receiver) = ipc::channel().unwrap();
    servo.handle_events(vec![WindowEvent::NewBrowser(target_url, sender)]);
    let browser_id = receiver.recv().unwrap();
    browser.set_browser_id(browser_id);
    servo.handle_events(vec![WindowEvent::SelectBrowser(browser_id)]);

    servo.setup_logging();

    window.run(|| {
        let win_events = window.get_events();

        // FIXME: this could be handled by Servo. We don't need
        // a repaint_synchronously function exposed.
        let need_resize = win_events.iter().any(|e| match *e {
            WindowEvent::Resize => true,
            _ => false,
        });

        browser.handle_window_events(win_events);

        let mut servo_events = servo.get_events();
        loop {
            browser.handle_servo_events(servo_events);
            servo.handle_events(browser.get_events());
            if browser.shutdown_requested() {
                return true;
            }
            servo_events = servo.get_events();
            if servo_events.is_empty() {
                break;
            }
        }

        if need_resize {
            servo.repaint_synchronously();
        }
        false
    });

    servo.deinit();

    platform::deinit()
}

// These functions aren't actually called. They are here as a link
// hack because Skia references them.

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glBindVertexArrayOES(_array: usize)
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glDeleteVertexArraysOES(_n: isize, _arrays: *const ())
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glGenVertexArraysOES(_n: isize, _arrays: *const ())
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glRenderbufferStorageMultisampleIMG(_: isize, _: isize, _: isize, _: isize, _: isize)
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glFramebufferTexture2DMultisampleIMG(_: isize, _: isize, _: isize, _: isize, _: isize, _: isize)
{
    unimplemented!()
}

#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn glDiscardFramebufferEXT(_: isize, _: isize, _: *const ())
{
    unimplemented!()
}

<|endoftext|>


<commit_before>use std::path::Path;

#[derive(Debug, PartialEq)]
pub enum Type {
    JSON,
    XML,
    Ruby
}

pub fn from_path(path: &Path) -> Option<Type> {
    match path.to_str() {
        Some(filename) => {
            let extension = filename.split('.').last();
            match extension {
                Some("json") => Some(Type::JSON),
                Some("xml") => Some(Type::XML),
                Some("rb") => Some(Type::Ruby),
                _ => None,
            }
        },
        None => return None,
    }
}

mod tests {
    use std::path::Path;
    use super::from_path;
    use super::Type;

    #[test]
    fn from_path_works() {
        let buffer_type = from_path(&Path::new("file.json")).unwrap();
        assert_eq!(buffer_type, Type::JSON);
    }
}
<commit_msg>Add test configuration attribute to type detection tests module.<commit_after>use std::path::Path;

#[derive(Debug, PartialEq)]
pub enum Type {
    JSON,
    XML,
    Ruby
}

pub fn from_path(path: &Path) -> Option<Type> {
    match path.to_str() {
        Some(filename) => {
            let extension = filename.split('.').last();
            match extension {
                Some("json") => Some(Type::JSON),
                Some("xml") => Some(Type::XML),
                Some("rb") => Some(Type::Ruby),
                _ => None,
            }
        },
        None => return None,
    }
}

#[cfg(test)]
mod tests {
    use std::path::Path;
    use super::from_path;
    use super::Type;

    #[test]
    fn from_path_works() {
        let buffer_type = from_path(&Path::new("file.json")).unwrap();
        assert_eq!(buffer_type, Type::JSON);
    }
}
<|endoftext|>