<commit_before>#![cfg(test)]

extern crate alloc_no_stdlib as alloc;
use alloc::{AllocatedStackMemory, Allocator, SliceWrapper, SliceWrapperMut, StackAllocator, bzero};
#[cfg(not(feature="no-stdlib"))]
use std::vec::Vec;
#[cfg(not(feature="no-stdlib"))]
use std::io;

use core::ops;

pub use super::{BrotliDecompressStream, BrotliResult, BrotliState, HuffmanCode};

declare_stack_allocator_struct!(MemPool, 4096, stack);

fn oneshot(input: &mut [u8], mut output: &mut [u8]) -> (BrotliResult, usize, usize) {
  let mut available_out: usize = output.len();
  let mut stack_u8_buffer = define_allocator_memory_pool!(4096, u8, [0; 400 * 1024], stack);
  let mut stack_u32_buffer = define_allocator_memory_pool!(4096, u32, [0; 48 * 1024], stack);
  let mut stack_hc_buffer = define_allocator_memory_pool!(4096,
                                                          super::HuffmanCode,
                                                          [HuffmanCode::default(); 48 * 1024],
                                                          stack);
  let stack_u8_allocator = MemPool::<u8>::new_allocator(&mut stack_u8_buffer, bzero);
  let stack_u32_allocator = MemPool::<u32>::new_allocator(&mut stack_u32_buffer, bzero);
  let stack_hc_allocator = MemPool::<HuffmanCode>::new_allocator(&mut stack_hc_buffer, bzero);
  let mut available_in: usize = input.len();
  let mut input_offset: usize = 0;
  let mut output_offset: usize = 0;
  let mut written: usize = 0;
  let mut brotli_state =
    BrotliState::new(stack_u8_allocator, stack_u32_allocator, stack_hc_allocator);
  let result = BrotliDecompressStream(&mut available_in,
                                      &mut input_offset,
                                      &input[..],
                                      &mut available_out,
                                      &mut output_offset,
                                      &mut output,
                                      &mut written,
                                      &mut brotli_state);
  brotli_state.BrotliStateCleanup();
  return (result, input_offset, output_offset);
}

#[test]
fn test_10x10y() {
  const BUFFER_SIZE: usize = 16384;
  let mut input: [u8; 12] = [0x1b, 0x13, 0x00, 0x00, 0xa4, 0xb0, 0xb2, 0xea, 0x81, 0x47, 0x02,
                             0x8a];
  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  let mut i: usize = 0;
  while i < 10 {
    assert_eq!(output[i], 'X' as u8);
    assert_eq!(output[i + 10], 'Y' as u8);
    i += 1;
  }
  assert_eq!(output_offset, 20);
  assert_eq!(input_offset, input.len());
}

#[test]
fn test_x() {
  const BUFFER_SIZE: usize = 16384;
  let mut input: [u8; 5] = [0x0b, 0x00, 0x80, 0x58, 0x03];
  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  assert_eq!(output[0], 'X' as u8);
  assert_eq!(output_offset, 1);
  assert_eq!(input_offset, input.len());
}

#[test]
fn test_empty() {
  const BUFFER_SIZE: usize = 16384;
  let mut input: [u8; 1] = [0x06];
  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  assert_eq!(output_offset, 0);
  assert_eq!(input_offset, input.len());
}
const QF_BUFFER_SIZE: usize = 180 * 1024;
static mut quick_fox_output: [u8; QF_BUFFER_SIZE] = [0u8; QF_BUFFER_SIZE];
#[test]
fn test_quickfox_repeated() {

  let mut input: [u8; 58] =
    [0x5B, 0xFF, 0xAF, 0x02, 0xC0, 0x22, 0x79, 0x5C, 0xFB, 0x5A, 0x8C, 0x42, 0x3B, 0xF4, 0x25,
     0x55, 0x19, 0x5A, 0x92, 0x99, 0xB1, 0x35, 0xC8, 0x19, 0x9E, 0x9E, 0x0A, 0x7B, 0x4B, 0x90,
     0xB9, 0x3C, 0x98, 0xC8, 0x09, 0x40, 0xF3, 0xE6, 0xD9, 0x4D, 0xE4, 0x6D, 0x65, 0x1B, 0x27,
     0x87, 0x13, 0x5F, 0xA6, 0xE9, 0x30, 0x96, 0x7B, 0x3C, 0x15, 0xD8, 0x53, 0x1C];

  let (result, input_offset, output_offset) = oneshot(&mut input[..],
                                                      unsafe {&mut quick_fox_output[..]});
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  assert_eq!(output_offset, 176128);
  assert_eq!(input_offset, input.len());
  const fox: [u8; 0x2b] = [0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6B, 0x20, 0x62, 0x72,
                           0x6F, 0x77, 0x6E, 0x20, 0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70,
                           0x73, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C,
                           0x61, 0x7A, 0x79, 0x20, 0x64, 0x6F, 0x67];
  let mut index: usize = 0;
  for item in unsafe{quick_fox_output[0..176128].iter_mut()} {
    assert_eq!(*item, fox[index]);
    index += 1;
    if index == 0x2b {
      index = 0;
    }
  }
}

#[cfg(not(feature="no-stdlib"))]
struct Buffer {
  data: Vec<u8>,
  read_offset: usize,
}
#[cfg(not(feature="no-stdlib"))]
impl Buffer {
  pub fn new(buf: &[u8]) -> Buffer {
    let mut ret = Buffer {
      data: Vec::<u8>::new(),
      read_offset: 0,
    };
    ret.data.extend(buf);
    return ret;
  }
}
#[cfg(not(feature="no-stdlib"))]
impl io::Read for Buffer {
  fn read(self: &mut Self, buf: &mut [u8]) -> io::Result<usize> {
    let bytes_to_read = ::core::cmp::min(buf.len(), self.data.len() - self.read_offset);
    if bytes_to_read > 0 {
      buf[0..bytes_to_read]
        .clone_from_slice(&self.data[self.read_offset..self.read_offset + bytes_to_read]);
    }
    self.read_offset += bytes_to_read;
    return Ok(bytes_to_read);
  }
}
#[cfg(not(feature="no-stdlib"))]
impl io::Write for Buffer {
  fn write(self: &mut Self, buf: &[u8]) -> io::Result<usize> {
    self.data.extend(buf);
    return Ok(buf.len());
  }
  fn flush(self: &mut Self) -> io::Result<()> {
    return Ok(());
  }
}

#[test]
#[cfg(not(feature="no-stdlib"))]
fn test_reader_quickfox_repeated() {
  let in_buf: [u8; 58] = [0x5B, 0xFF, 0xAF, 0x02, 0xC0, 0x22, 0x79, 0x5C, 0xFB, 0x5A, 0x8C, 0x42,
                          0x3B, 0xF4, 0x25, 0x55, 0x19, 0x5A, 0x92, 0x99, 0xB1, 0x35, 0xC8, 0x19,
                          0x9E, 0x9E, 0x0A, 0x7B, 0x4B, 0x90, 0xB9, 0x3C, 0x98, 0xC8, 0x09, 0x40,
                          0xF3, 0xE6, 0xD9, 0x4D, 0xE4, 0x6D, 0x65, 0x1B, 0x27, 0x87, 0x13, 0x5F,
                          0xA6, 0xE9, 0x30, 0x96, 0x7B, 0x3C, 0x15, 0xD8, 0x53, 0x1C];

  let mut output = Buffer::new(&[]);
  let mut input = super::Decompressor::new(Buffer::new(&in_buf), 4096);
  match super::copy_from_to(&mut input, &mut output) {
    Ok(_) => {}
    Err(e) => panic!("Error {:?}", e),
  }

  assert_eq!(output.data.len(), 176128);
  const fox: [u8; 0x2b] = [0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6B, 0x20, 0x62, 0x72,
                           0x6F, 0x77, 0x6E, 0x20, 0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70,
                           0x73, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C,
                           0x61, 0x7A, 0x79, 0x20, 0x64, 0x6F, 0x67];
  let mut index: usize = 0;
  for item in output.data[0..176128].iter_mut() {
    assert_eq!(*item, fox[index]);
    index += 1;
    if index == 0x2b {
      index = 0;
    }
  }
}
<commit_msg>revert global buffer and simply tighten the memory pool to fit on the stack<commit_after>#![cfg(test)]

extern crate alloc_no_stdlib as alloc;
use alloc::{AllocatedStackMemory, Allocator, SliceWrapper, SliceWrapperMut, StackAllocator, bzero};
#[cfg(not(feature="no-stdlib"))]
use std::vec::Vec;
#[cfg(not(feature="no-stdlib"))]
use std::io;

use core::ops;

pub use super::{BrotliDecompressStream, BrotliResult, BrotliState, HuffmanCode};

declare_stack_allocator_struct!(MemPool, 4096, stack);

fn oneshot(input: &mut [u8], mut output: &mut [u8]) -> (BrotliResult, usize, usize) {
  let mut available_out: usize = output.len();
  let mut stack_u8_buffer = define_allocator_memory_pool!(4096, u8, [0; 320 * 1024], stack);
  let mut stack_u32_buffer = define_allocator_memory_pool!(4096, u32, [0; 40 * 1024], stack);
  let mut stack_hc_buffer = define_allocator_memory_pool!(4096,
                                                          super::HuffmanCode,
                                                          [HuffmanCode::default(); 48 * 1024],
                                                          stack);
  let stack_u8_allocator = MemPool::<u8>::new_allocator(&mut stack_u8_buffer, bzero);
  let stack_u32_allocator = MemPool::<u32>::new_allocator(&mut stack_u32_buffer, bzero);
  let stack_hc_allocator = MemPool::<HuffmanCode>::new_allocator(&mut stack_hc_buffer, bzero);
  let mut available_in: usize = input.len();
  let mut input_offset: usize = 0;
  let mut output_offset: usize = 0;
  let mut written: usize = 0;
  let mut brotli_state =
    BrotliState::new(stack_u8_allocator, stack_u32_allocator, stack_hc_allocator);
  let result = BrotliDecompressStream(&mut available_in,
                                      &mut input_offset,
                                      &input[..],
                                      &mut available_out,
                                      &mut output_offset,
                                      &mut output,
                                      &mut written,
                                      &mut brotli_state);
  brotli_state.BrotliStateCleanup();
  return (result, input_offset, output_offset);
}

#[test]
fn test_10x10y() {
  const BUFFER_SIZE: usize = 16384;
  let mut input: [u8; 12] = [0x1b, 0x13, 0x00, 0x00, 0xa4, 0xb0, 0xb2, 0xea, 0x81, 0x47, 0x02,
                             0x8a];
  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  let mut i: usize = 0;
  while i < 10 {
    assert_eq!(output[i], 'X' as u8);
    assert_eq!(output[i + 10], 'Y' as u8);
    i += 1;
  }
  assert_eq!(output_offset, 20);
  assert_eq!(input_offset, input.len());
}

#[test]
fn test_x() {
  const BUFFER_SIZE: usize = 16384;
  let mut input: [u8; 5] = [0x0b, 0x00, 0x80, 0x58, 0x03];
  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  assert_eq!(output[0], 'X' as u8);
  assert_eq!(output_offset, 1);
  assert_eq!(input_offset, input.len());
}

#[test]
fn test_empty() {
  const BUFFER_SIZE: usize = 16384;
  let mut input: [u8; 1] = [0x06];
  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  assert_eq!(output_offset, 0);
  assert_eq!(input_offset, input.len());
}

#[test]
fn test_quickfox_repeated() {
  const BUFFER_SIZE: usize = 180 * 1024;
  let mut input: [u8; 58] =
    [0x5B, 0xFF, 0xAF, 0x02, 0xC0, 0x22, 0x79, 0x5C, 0xFB, 0x5A, 0x8C, 0x42, 0x3B, 0xF4, 0x25,
     0x55, 0x19, 0x5A, 0x92, 0x99, 0xB1, 0x35, 0xC8, 0x19, 0x9E, 0x9E, 0x0A, 0x7B, 0x4B, 0x90,
     0xB9, 0x3C, 0x98, 0xC8, 0x09, 0x40, 0xF3, 0xE6, 0xD9, 0x4D, 0xE4, 0x6D, 0x65, 0x1B, 0x27,
     0x87, 0x13, 0x5F, 0xA6, 0xE9, 0x30, 0x96, 0x7B, 0x3C, 0x15, 0xD8, 0x53, 0x1C];

  let mut output = [0u8; BUFFER_SIZE];
  let (result, input_offset, output_offset) = oneshot(&mut input[..], &mut output[..]);
  match result {
    BrotliResult::ResultSuccess => {}
    _ => assert!(false),
  }
  assert_eq!(output_offset, 176128);
  assert_eq!(input_offset, input.len());
  const fox: [u8; 0x2b] = [0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6B, 0x20, 0x62, 0x72,
                           0x6F, 0x77, 0x6E, 0x20, 0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70,
                           0x73, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C,
                           0x61, 0x7A, 0x79, 0x20, 0x64, 0x6F, 0x67];
  let mut index: usize = 0;
  for item in output[0..176128].iter_mut() {
    assert_eq!(*item, fox[index]);
    index += 1;
    if index == 0x2b {
      index = 0;
    }
  }
}

#[cfg(not(feature="no-stdlib"))]
struct Buffer {
  data: Vec<u8>,
  read_offset: usize,
}
#[cfg(not(feature="no-stdlib"))]
impl Buffer {
  pub fn new(buf: &[u8]) -> Buffer {
    let mut ret = Buffer {
      data: Vec::<u8>::new(),
      read_offset: 0,
    };
    ret.data.extend(buf);
    return ret;
  }
}
#[cfg(not(feature="no-stdlib"))]
impl io::Read for Buffer {
  fn read(self: &mut Self, buf: &mut [u8]) -> io::Result<usize> {
    let bytes_to_read = ::core::cmp::min(buf.len(), self.data.len() - self.read_offset);
    if bytes_to_read > 0 {
      buf[0..bytes_to_read]
        .clone_from_slice(&self.data[self.read_offset..self.read_offset + bytes_to_read]);
    }
    self.read_offset += bytes_to_read;
    return Ok(bytes_to_read);
  }
}
#[cfg(not(feature="no-stdlib"))]
impl io::Write for Buffer {
  fn write(self: &mut Self, buf: &[u8]) -> io::Result<usize> {
    self.data.extend(buf);
    return Ok(buf.len());
  }
  fn flush(self: &mut Self) -> io::Result<()> {
    return Ok(());
  }
}

#[test]
#[cfg(not(feature="no-stdlib"))]
fn test_reader_quickfox_repeated() {
  let in_buf: [u8; 58] = [0x5B, 0xFF, 0xAF, 0x02, 0xC0, 0x22, 0x79, 0x5C, 0xFB, 0x5A, 0x8C, 0x42,
                          0x3B, 0xF4, 0x25, 0x55, 0x19, 0x5A, 0x92, 0x99, 0xB1, 0x35, 0xC8, 0x19,
                          0x9E, 0x9E, 0x0A, 0x7B, 0x4B, 0x90, 0xB9, 0x3C, 0x98, 0xC8, 0x09, 0x40,
                          0xF3, 0xE6, 0xD9, 0x4D, 0xE4, 0x6D, 0x65, 0x1B, 0x27, 0x87, 0x13, 0x5F,
                          0xA6, 0xE9, 0x30, 0x96, 0x7B, 0x3C, 0x15, 0xD8, 0x53, 0x1C];

  let mut output = Buffer::new(&[]);
  let mut input = super::Decompressor::new(Buffer::new(&in_buf), 4096);
  match super::copy_from_to(&mut input, &mut output) {
    Ok(_) => {}
    Err(e) => panic!("Error {:?}", e),
  }

  assert_eq!(output.data.len(), 176128);
  const fox: [u8; 0x2b] = [0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6B, 0x20, 0x62, 0x72,
                           0x6F, 0x77, 0x6E, 0x20, 0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70,
                           0x73, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6C,
                           0x61, 0x7A, 0x79, 0x20, 0x64, 0x6F, 0x67];
  let mut index: usize = 0;
  for item in output.data[0..176128].iter_mut() {
    assert_eq!(*item, fox[index]);
    index += 1;
    if index == 0x2b {
      index = 0;
    }
  }
}
<|endoftext|>


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

use super::*;

#[test]
fn connect_google() {

    let mut builder = ClientBuilder::new().unwrap();
    let s = TcpStream::connect("google.com:443").unwrap();
    let mut socket = builder.handshake("google.com", s).unwrap();

    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut result = vec![];
    socket.read_to_end(&mut result).unwrap();

    println!("{}", String::from_utf8_lossy(&result));
    assert!(result.starts_with(b"HTTP/1.0"));
    assert!(result.ends_with(b"\r\n") || result.ends_with(b""));
}
<commit_msg>Clean up whitespace<commit_after>use std::net::TcpStream;
use std::io::{Read, Write};

use super::*;

#[test]
fn connect_google() {
    let mut builder = ClientBuilder::new().unwrap();
    let s = TcpStream::connect("google.com:443").unwrap();
    let mut socket = builder.handshake("google.com", s).unwrap();

    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut result = vec![];
    socket.read_to_end(&mut result).unwrap();

    println!("{}", String::from_utf8_lossy(&result));
    assert!(result.starts_with(b"HTTP/1.0"));
    assert!(result.ends_with(b"\r\n") || result.ends_with(b""));
}
<|endoftext|>


<commit_before>//! Two-step verification of TOTP algorithm
//!
//! # Example
//!
//! ```
//! extern crate otpauth;
//! extern crate time;
//!
//! fn main() {
//!     let auth = otpauth::TOTP::new("python");
//!     let timestamp1 = time::now().to_timespec().sec as usize;
//!     let code = auth.generate(30, timestamp1);
//!     let timestamp2 = time::now().to_timespec().sec as usize;
//!     assert_eq!(true, auth.verify(code, 30, timestamp2));
//! }
//!
use super::hotp;

pub struct TOTP {
    /// A secret token for the authentication
    pub secret: String,
}

impl TOTP {
    /// Constructs a new `TOTP`
    pub fn new(secret: &str) -> TOTP {
        TOTP {
            secret: secret.to_string(),
        }
    }

    /// Generate a TOTP code.
    ///
    /// A TOTP code is an extension of HOTP algorithm.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Create TOTP at this given timestamp
    pub fn generate(&self, period: usize, timestamp: usize) -> u32 {
        let counter = timestamp / period;
        let hotp_auth = hotp::HOTP::new(&self.secret[..]);
        hotp_auth.generate(counter)
    }

    /// Valid a TOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Validate TOTP at this given timestamp
    pub fn verify(&self, code: u32, period: usize, timestamp: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        let valid_code = self.generate(period, timestamp).to_string();
        let valid_bytes = valid_code.as_bytes();
        if code_bytes.len() != valid_code.len() {
            return false;
        }
        let mut rv = 0;
        for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
            rv |= a ^ b;
        }
        rv == 0
    }

    /// Generate the otpauth protocal string.
    ///
    /// ``label``: Label of the identifier.
    ///
    /// ``issuer``: The company, the organization or something else.
    pub fn to_uri(&self, label: &str, issuer: &str) -> String {
        use base32::encode;
        use base32::Alphabet::RFC4648;

        let encoded_secret = encode(RFC4648 { padding: false }, self.secret.as_bytes());
        format!("otpauth://totp/{}?secret={}&issuer={}", label, encoded_secret, issuer)
    }
}
<commit_msg>Fix typo<commit_after>//! Two-step verification of TOTP algorithm
//!
//! # Example
//!
//! ```
//! extern crate otpauth;
//! extern crate time;
//!
//! fn main() {
//!     let auth = otpauth::TOTP::new("python");
//!     let timestamp1 = time::now().to_timespec().sec as usize;
//!     let code = auth.generate(30, timestamp1);
//!     let timestamp2 = time::now().to_timespec().sec as usize;
//!     assert_eq!(true, auth.verify(code, 30, timestamp2));
//! }
//! ```
//!
use super::hotp;

pub struct TOTP {
    /// A secret token for the authentication
    pub secret: String,
}

impl TOTP {
    /// Constructs a new `TOTP`
    pub fn new(secret: &str) -> TOTP {
        TOTP {
            secret: secret.to_string(),
        }
    }

    /// Generate a TOTP code.
    ///
    /// A TOTP code is an extension of HOTP algorithm.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Create TOTP at this given timestamp
    pub fn generate(&self, period: usize, timestamp: usize) -> u32 {
        let counter = timestamp / period;
        let hotp_auth = hotp::HOTP::new(&self.secret[..]);
        hotp_auth.generate(counter)
    }

    /// Valid a TOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Validate TOTP at this given timestamp
    pub fn verify(&self, code: u32, period: usize, timestamp: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        let valid_code = self.generate(period, timestamp).to_string();
        let valid_bytes = valid_code.as_bytes();
        if code_bytes.len() != valid_code.len() {
            return false;
        }
        let mut rv = 0;
        for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
            rv |= a ^ b;
        }
        rv == 0
    }

    /// Generate the otpauth protocal string.
    ///
    /// ``label``: Label of the identifier.
    ///
    /// ``issuer``: The company, the organization or something else.
    pub fn to_uri(&self, label: &str, issuer: &str) -> String {
        use base32::encode;
        use base32::Alphabet::RFC4648;

        let encoded_secret = encode(RFC4648 { padding: false }, self.secret.as_bytes());
        format!("otpauth://totp/{}?secret={}&issuer={}", label, encoded_secret, issuer)
    }
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use ffi;
use types::{gchar,gsize};
use types::{gpointer};

use libc;
use libc::c_char;
use std::c_str::{CString,ToCStr};
use std::kinds::marker;
use std::mem::transmute;
use std::ptr::copy_nonoverlapping_memory;
use std::slice;
use std::str;
use std::string;

pub struct UTF8Chars<'a> {
    data: *const gchar,
    lifetime: marker::ContravariantLifetime<'a>
}

impl<'a> UTF8Chars<'a> {
    pub unsafe fn wrap(ptr: *const gchar) -> UTF8Chars<'a> {
        UTF8Chars { data: ptr, lifetime: marker::ContravariantLifetime }
    }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf(self.data as *const u8)
        }
    }
}

#[inline]
unsafe fn utf8_cont_bits(p: *const gchar) -> u32 {
    let byte = *(p as *const u8);
    debug_assert!((byte & 0xC0) == 0x80);
    (byte & 0x3F) as u32
}

impl<'a> Iterator<char> for UTF8Chars<'a> {
    fn next(&mut self) -> Option<char> {
        let p = self.data;
        let first_byte = unsafe { *(p as *const u8) };
        if first_byte == 0 {
            return None;
        }
        unsafe {
            let mut wc: u32;
            if first_byte < 0xC0 {
                debug_assert!(first_byte < 0x80);
                wc = first_byte as u32;
                self.data = p.offset(1);
            } else {
                let c1 = utf8_cont_bits(p.offset(1));
                if first_byte < 0xE0 {
                    wc = ((first_byte & 0x1F) as u32 << 6) | c1;
                    debug_assert!(wc >= 0x80);
                    self.data = p.offset(2);
                } else {
                    let c2 = utf8_cont_bits(p.offset(2));
                    if first_byte < 0xF0 {
                        wc = ((first_byte & 0x0F) as u32 << 12)
                             | (c1 << 6) | c2;
                        debug_assert!(wc >= 0x0800);
                        debug_assert!((wc & 0xF800) != 0xD800);
                        self.data = p.offset(3);
                    } else {
                        debug_assert!(first_byte <= 0xF4);
                        let c3 = utf8_cont_bits(p.offset(3));
                        wc = ((first_byte & 0x07) as u32 << 18)
                             | (c1 << 12) | (c2 << 6) | c3;
                        debug_assert!(wc >= 0x010000 && wc <= 0x10FFFF);
                        self.data = p.offset(4);
                    }
                }
            }
            Some(transmute(wc))
        }
    }
}

unsafe fn dup_to_c_str(source: *const c_char, len: uint) -> CString {
    let copy = libc::malloc(len as libc::size_t + 1) as *mut c_char;
    copy_nonoverlapping_memory(copy, source, len + 1);
    CString::new(copy as *const c_char, true)
}

impl<'a> ToCStr for UTF8Chars<'a> {

    #[inline]
    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        let src = self.data as *const c_char;
        let len = libc::strlen(src) as uint;
        dup_to_c_str(src, len)
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }
}

pub struct UTF8Buf {
    data: *mut gchar,
}

impl UTF8Buf {

    pub unsafe fn wrap(data: *mut gchar) -> UTF8Buf {
        UTF8Buf { data: data }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> {
        unsafe { UTF8Chars::wrap(self.data as *const gchar) }
    }

    pub fn into_collection(self) -> UTF8Str {
        unsafe {
            let len = libc::strlen(self.data as *const c_char);
            UTF8Str { buf: transmute(self), len: len as uint }
        }
    }

    #[inline]
    pub fn to_string(&self) -> String { self.chars().to_string() }

    #[inline]
    pub fn into_string(self) -> String { self.to_string() }

    pub fn is_empty(&self) -> bool { unsafe { *self.data == 0 } }
}

impl Drop for UTF8Buf {
    fn drop(&mut self) {
        unsafe { ffi::g_free(self.data as gpointer) }
    }
}

impl Clone for UTF8Buf {
    fn clone(&self) -> UTF8Buf {
        unsafe {
            UTF8Buf::wrap(ffi::g_strdup(self.data as *const gchar))
        }
    }
}

impl ToCStr for UTF8Buf {

    #[inline]
    fn to_c_str(&self) -> CString {
        self.chars().to_c_str()
    }

    #[inline]
    unsafe fn to_c_str_unchecked(&self) -> CString {
        self.chars().to_c_str_unchecked()
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        f(self.data as *const i8)
    }
}

pub struct UTF8Str {
    buf: UTF8Buf,
    len: uint
}

const NUL: gchar = 0;

impl UTF8Str {

    pub unsafe fn wrap(data: *mut gchar, len: uint) -> UTF8Str {
        UTF8Str { buf: UTF8Buf::wrap(data), len: len }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> { self.buf.chars() }

    pub fn len(&self) -> uint { return self.len }

    pub fn is_empty(&self) -> bool { return self.len == 0 }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf_len(self.buf.data as *const u8, self.len)
        }
    }
}

impl Clone for UTF8Str {
    fn clone(&self) -> UTF8Str {
        unsafe {
            let copy = ffi::g_malloc((self.len + 1) as gsize) as *mut gchar;
            copy_nonoverlapping_memory(copy,
                    self.buf.data as *const gchar, self.len);
            *copy.offset(self.len as int) = NUL;
            UTF8Str::wrap(copy, self.len)
        }
    }
}

impl Str for UTF8Str {
    fn as_slice<'a>(&'a self) -> &'a str {
        unsafe {
            slice::raw::buf_as_slice(
                self.buf.data as *const u8,
                self.len,
                |bytes| {
                    let s = str::raw::from_utf8(bytes);
                    transmute(s)
                })
        }
    }
}

impl StrAllocating for UTF8Str {
    fn into_string(self) -> String { self.to_string() }
}

impl ToCStr for UTF8Str {

    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        dup_to_c_str(self.buf.data as *const c_char, self.len)
    }

    fn with_c_str<T>(&self, f: |*const i8| -> T) -> T {
        self.buf.with_c_str(f)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const i8| -> T) -> T {
        self.buf.with_c_str_unchecked(f)
    }
}

impl PartialEq for UTF8Str {
    fn eq(&self, other: &UTF8Str) -> bool {
        self.as_slice() == other.as_slice()
    }
}

impl Eq for UTF8Str { }

impl<S: Str> Equiv<S> for UTF8Str {
    fn equiv(&self, other: &S) -> bool {
        self.as_slice() == other.as_slice()
    }
}

pub trait WithUTF8 for Sized? {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T;
}

impl<'a> WithUTF8 for UTF8Chars<'a> {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data)
    }
}

impl WithUTF8 for UTF8Buf {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data as *const gchar)
    }
}

impl WithUTF8 for UTF8Str {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.buf.with_utf8_c_str(f)
    }
}

impl WithUTF8 for str {
    #[inline]
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}

impl<'a, Sized? T: WithUTF8> WithUTF8 for &'a T {
    #[inline]
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        (**self).with_utf8_c_str(f)
    }
}

impl WithUTF8 for String {
    #[inline]
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}
<commit_msg>utf8: Lessons learned from c_compat<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use ffi;
use types::{gchar,gsize};
use types::{gpointer};

use libc;
use libc::c_char;
use std::c_str::{CString,ToCStr};
use std::kinds::marker;
use std::mem::transmute;
use std::ptr::copy_nonoverlapping_memory;
use std::slice;
use std::str;
use std::string;

pub struct UTF8Chars<'a> {
    data: *const gchar,
    lifetime: marker::ContravariantLifetime<'a>
}

impl<'a> UTF8Chars<'a> {
    pub unsafe fn wrap(ptr: *const gchar) -> UTF8Chars<'a> {
        UTF8Chars { data: ptr, lifetime: marker::ContravariantLifetime }
    }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf(self.data as *const u8)
        }
    }
}

#[inline]
unsafe fn utf8_cont_bits(p: *const gchar) -> u32 {
    let byte = *(p as *const u8);
    debug_assert!((byte & 0xC0) == 0x80);
    (byte & 0x3F) as u32
}

impl<'a> Iterator<char> for UTF8Chars<'a> {
    fn next(&mut self) -> Option<char> {
        let p = self.data;
        let first_byte = unsafe { *(p as *const u8) };
        if first_byte == 0 {
            return None;
        }
        unsafe {
            let mut wc: u32;
            if first_byte < 0xC0 {
                debug_assert!(first_byte < 0x80);
                wc = first_byte as u32;
                self.data = p.offset(1);
            } else {
                let c1 = utf8_cont_bits(p.offset(1));
                if first_byte < 0xE0 {
                    wc = ((first_byte & 0x1F) as u32 << 6) | c1;
                    debug_assert!(wc >= 0x80);
                    self.data = p.offset(2);
                } else {
                    let c2 = utf8_cont_bits(p.offset(2));
                    if first_byte < 0xF0 {
                        wc = ((first_byte & 0x0F) as u32 << 12)
                             | (c1 << 6) | c2;
                        debug_assert!(wc >= 0x0800);
                        debug_assert!((wc & 0xF800) != 0xD800);
                        self.data = p.offset(3);
                    } else {
                        debug_assert!(first_byte <= 0xF4);
                        let c3 = utf8_cont_bits(p.offset(3));
                        wc = ((first_byte & 0x07) as u32 << 18)
                             | (c1 << 12) | (c2 << 6) | c3;
                        debug_assert!(wc >= 0x010000 && wc <= 0x10FFFF);
                        self.data = p.offset(4);
                    }
                }
            }
            Some(transmute(wc))
        }
    }
}

unsafe fn dup_to_c_str(source: *const c_char, len: uint) -> CString {
    let copy = libc::malloc(len as libc::size_t + 1) as *mut c_char;
    if copy.is_null() {
        ::alloc::oom();
    }
    copy_nonoverlapping_memory(copy, source, len + 1);
    CString::new(copy as *const c_char, true)
}

impl<'a> ToCStr for UTF8Chars<'a> {

    #[inline]
    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        dup_to_c_str(self.data, libc::strlen(self.data) as uint)
    }

    fn with_c_str<T>(&self, f: |*const c_char| -> T) -> T {
        f(self.data)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const c_char| -> T) -> T {
        f(self.data)
    }
}

pub struct UTF8Buf {
    data: *const gchar,
}

impl UTF8Buf {

    pub unsafe fn wrap(data: *mut gchar) -> UTF8Buf {
        UTF8Buf { data: data as *const gchar }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> {
        unsafe { UTF8Chars::wrap(self.data) }
    }

    pub fn into_collection(self) -> UTF8Str {
        unsafe {
            let len = libc::strlen(self.data);
            UTF8Str { buf: transmute(self), len: len as uint }
        }
    }

    #[inline]
    pub fn to_string(&self) -> String { self.chars().to_string() }

    #[inline]
    pub fn into_string(self) -> String { self.to_string() }

    pub fn is_empty(&self) -> bool { unsafe { *self.data == 0 } }
}

impl Drop for UTF8Buf {
    fn drop(&mut self) {
        unsafe { ffi::g_free(self.data as gpointer) }
    }
}

impl Clone for UTF8Buf {
    fn clone(&self) -> UTF8Buf {
        unsafe {
            UTF8Buf::wrap(ffi::g_strdup(self.data))
        }
    }
}

impl ToCStr for UTF8Buf {

    #[inline]
    fn to_c_str(&self) -> CString {
        self.chars().to_c_str()
    }

    #[inline]
    unsafe fn to_c_str_unchecked(&self) -> CString {
        self.chars().to_c_str_unchecked()
    }

    fn with_c_str<T>(&self, f: |*const c_char| -> T) -> T {
        f(self.data)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const c_char| -> T) -> T {
        f(self.data)
    }
}

pub struct UTF8Str {
    buf: UTF8Buf,
    len: uint
}

const NUL: gchar = 0;

impl UTF8Str {

    pub unsafe fn wrap(data: *mut gchar, len: uint) -> UTF8Str {
        UTF8Str { buf: UTF8Buf::wrap(data), len: len }
    }

    pub fn chars<'a>(&'a self) -> UTF8Chars<'a> { self.buf.chars() }

    pub fn len(&self) -> uint { return self.len }

    pub fn is_empty(&self) -> bool { return self.len == 0 }

    pub fn to_string(&self) -> String {
        unsafe {
            string::raw::from_buf_len(self.buf.data as *const u8, self.len)
        }
    }
}

impl Clone for UTF8Str {
    fn clone(&self) -> UTF8Str {
        unsafe {
            let copy = ffi::g_malloc((self.len + 1) as gsize) as *mut gchar;
            copy_nonoverlapping_memory(copy,
                    self.buf.data as *const gchar, self.len);
            *copy.offset(self.len as int) = NUL;
            UTF8Str::wrap(copy, self.len)
        }
    }
}

impl Str for UTF8Str {
    fn as_slice<'a>(&'a self) -> &'a str {
        unsafe {
            slice::raw::buf_as_slice(
                self.buf.data as *const u8,
                self.len,
                |bytes| {
                    let s = str::raw::from_utf8(bytes);
                    transmute(s)
                })
        }
    }
}

impl StrAllocating for UTF8Str {
    fn into_string(self) -> String { self.to_string() }
}

impl ToCStr for UTF8Str {

    fn to_c_str(&self) -> CString {
        unsafe { self.to_c_str_unchecked() }
    }

    unsafe fn to_c_str_unchecked(&self) -> CString {
        dup_to_c_str(self.buf.data, self.len)
    }

    fn with_c_str<T>(&self, f: |*const c_char| -> T) -> T {
        self.buf.with_c_str(f)
    }

    unsafe fn with_c_str_unchecked<T>(&self, f: |*const c_char| -> T) -> T {
        self.buf.with_c_str_unchecked(f)
    }
}

impl PartialEq for UTF8Str {
    fn eq(&self, other: &UTF8Str) -> bool {
        self.as_slice() == other.as_slice()
    }
}

impl Eq for UTF8Str { }

impl<S: Str> Equiv<S> for UTF8Str {
    fn equiv(&self, other: &S) -> bool {
        self.as_slice() == other.as_slice()
    }
}

pub trait WithUTF8 for Sized? {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T;
}

impl<'a> WithUTF8 for UTF8Chars<'a> {
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data)
    }
}

impl WithUTF8 for UTF8Buf {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        f(self.data as *const gchar)
    }
}

impl WithUTF8 for UTF8Str {

    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.buf.with_utf8_c_str(f)
    }
}

impl WithUTF8 for str {
    #[inline]
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}

impl<'a, Sized? T: WithUTF8> WithUTF8 for &'a T {
    #[inline]
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        (**self).with_utf8_c_str(f)
    }
}

impl WithUTF8 for String {
    #[inline]
    fn with_utf8_c_str<T>(&self, f: |*const gchar| -> T) -> T {
        self.with_c_str(f)
    }
}
<|endoftext|>


<commit_before>//! CLI tool to use the functions provided by the [cretonne-wasm](../cton_wasm/index.html) crate.
//!
//! Reads Wasm binary files (one Wasm module per file), translates the functions' code to Cretonne
//! IL. Can also executes the `start` function of the module by laying out the memories, globals
//! and tables, then emitting the translated code with hardcoded addresses to memory.

use cton_wasm::{translate_module, DummyRuntime, WasmRuntime};
use std::path::PathBuf;
use cretonne::Context;
use cretonne::verifier;
use cretonne::settings::{self, Configurable};
use std::fs::File;
use std::error::Error;
use std::io;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
use tempdir::TempDir;
use term;
use utils::pretty_verifier_error;

macro_rules! vprintln {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            println!($($tts)*);
        }
    }
}

macro_rules! vprint {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            print!($($tts)*);
        }
    }
}

fn read_wasm_file(path: PathBuf) -> Result<Vec<u8>, io::Error> {
    let mut buf: Vec<u8> = Vec::new();
    let file = File::open(path)?;
    let mut buf_reader = BufReader::new(file);
    buf_reader.read_to_end(&mut buf)?;
    Ok(buf)
}

pub fn run(
    files: Vec<String>,
    flag_verbose: bool,
    flag_optimize: bool,
    flag_check: bool,
    flag_enable: Vec<String>,
) -> Result<(), String> {
    let mut flag_builder = settings::builder();
    for enable in flag_enable {
        flag_builder.enable(&enable).map_err(|_| {
            format!("unrecognized flag: {}", enable)
        })?;
    }
    let flags = settings::Flags::new(&flag_builder);

    for filename in files {
        let path = Path::new(&filename);
        let name = String::from(path.as_os_str().to_string_lossy());
        handle_module(
            flag_verbose,
            flag_optimize,
            flag_check,
            path.to_path_buf(),
            name,
            &flags,
        )?;
    }
    Ok(())
}

fn handle_module(
    flag_verbose: bool,
    flag_optimize: bool,
    flag_check: bool,
    path: PathBuf,
    name: String,
    flags: &settings::Flags,
) -> Result<(), String> {
    let mut terminal = term::stdout().unwrap();
    terminal.fg(term::color::YELLOW).unwrap();
    vprint!(flag_verbose, "Handling: ");
    terminal.reset().unwrap();
    vprintln!(flag_verbose, "\"{}\"", name);
    terminal.fg(term::color::MAGENTA).unwrap();
    vprint!(flag_verbose, "Translating...");
    terminal.reset().unwrap();
    let data = match path.extension() {
        None => {
            return Err(String::from("the file extension is not wasm or wat"));
        }
        Some(ext) => {
            match ext.to_str() {
                Some("wasm") => {
                    read_wasm_file(path.clone()).map_err(|err| {
                        String::from(err.description())
                    })?
                }
                Some("wat") => {
                    let tmp_dir = TempDir::new("cretonne-wasm").unwrap();
                    let file_path = tmp_dir.path().join("module.wasm");
                    File::create(file_path.clone()).unwrap();
                    Command::new("wat2wasm")
                        .arg(path.clone())
                        .arg("-o")
                        .arg(file_path.to_str().unwrap())
                        .output()
                        .or_else(|e| if let io::ErrorKind::NotFound = e.kind() {
                            return Err(String::from("wat2wasm not found"));
                        } else {
                            return Err(String::from(e.description()));
                        })
                        .unwrap();
                    read_wasm_file(file_path).map_err(|err| {
                        String::from(err.description())
                    })?
                }
                None | Some(&_) => {
                    return Err(String::from("the file extension is not wasm or wat"));
                }
            }
        }
    };
    let mut dummy_runtime = DummyRuntime::with_flags(flags.clone());
    let translation = {
        let runtime: &mut WasmRuntime = &mut dummy_runtime;
        translate_module(&data, runtime)?
    };
    terminal.fg(term::color::GREEN).unwrap();
    vprintln!(flag_verbose, " ok");
    terminal.reset().unwrap();
    if flag_check {
        terminal.fg(term::color::MAGENTA).unwrap();
        vprint!(flag_verbose, "Checking...   ");
        terminal.reset().unwrap();
        for func in &translation.functions {
            verifier::verify_function(func, None).map_err(|err| {
                pretty_verifier_error(func, None, err)
            })?;
        }
        terminal.fg(term::color::GREEN).unwrap();
        vprintln!(flag_verbose, " ok");
        terminal.reset().unwrap();
    }
    if flag_optimize {
        terminal.fg(term::color::MAGENTA).unwrap();
        vprint!(flag_verbose, "Optimizing... ");
        terminal.reset().unwrap();
        for func in &translation.functions {
            let mut context = Context::new();
            context.func = func.clone();
            verifier::verify_context(&context.func, &context.cfg, &context.domtree, None)
                .map_err(|err| pretty_verifier_error(&context.func, None, err))?;
            context.licm();
            verifier::verify_context(&context.func, &context.cfg, &context.domtree, None)
                .map_err(|err| pretty_verifier_error(&context.func, None, err))?;
            context.simple_gvn();
            verifier::verify_context(&context.func, &context.cfg, &context.domtree, None)
                .map_err(|err| pretty_verifier_error(&context.func, None, err))?;
        }
        terminal.fg(term::color::GREEN).unwrap();
        vprintln!(flag_verbose, " ok");
        terminal.reset().unwrap();
    }
    Ok(())
}
<commit_msg>Refactor code to use Context::verify instead of doing it manually.<commit_after>//! CLI tool to use the functions provided by the [cretonne-wasm](../cton_wasm/index.html) crate.
//!
//! Reads Wasm binary files (one Wasm module per file), translates the functions' code to Cretonne
//! IL. Can also executes the `start` function of the module by laying out the memories, globals
//! and tables, then emitting the translated code with hardcoded addresses to memory.

use cton_wasm::{translate_module, DummyRuntime, WasmRuntime};
use std::path::PathBuf;
use cretonne::Context;
use cretonne::verifier;
use cretonne::settings::{self, Configurable};
use std::fs::File;
use std::error::Error;
use std::io;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
use tempdir::TempDir;
use term;
use utils::pretty_verifier_error;

macro_rules! vprintln {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            println!($($tts)*);
        }
    }
}

macro_rules! vprint {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            print!($($tts)*);
        }
    }
}

fn read_wasm_file(path: PathBuf) -> Result<Vec<u8>, io::Error> {
    let mut buf: Vec<u8> = Vec::new();
    let file = File::open(path)?;
    let mut buf_reader = BufReader::new(file);
    buf_reader.read_to_end(&mut buf)?;
    Ok(buf)
}

pub fn run(
    files: Vec<String>,
    flag_verbose: bool,
    flag_optimize: bool,
    flag_check: bool,
    flag_enable: Vec<String>,
) -> Result<(), String> {
    let mut flag_builder = settings::builder();
    for enable in flag_enable {
        flag_builder.enable(&enable).map_err(|_| {
            format!("unrecognized flag: {}", enable)
        })?;
    }
    let flags = settings::Flags::new(&flag_builder);

    for filename in files {
        let path = Path::new(&filename);
        let name = String::from(path.as_os_str().to_string_lossy());
        handle_module(
            flag_verbose,
            flag_optimize,
            flag_check,
            path.to_path_buf(),
            name,
            &flags,
        )?;
    }
    Ok(())
}

fn handle_module(
    flag_verbose: bool,
    flag_optimize: bool,
    flag_check: bool,
    path: PathBuf,
    name: String,
    flags: &settings::Flags,
) -> Result<(), String> {
    let mut terminal = term::stdout().unwrap();
    terminal.fg(term::color::YELLOW).unwrap();
    vprint!(flag_verbose, "Handling: ");
    terminal.reset().unwrap();
    vprintln!(flag_verbose, "\"{}\"", name);
    terminal.fg(term::color::MAGENTA).unwrap();
    vprint!(flag_verbose, "Translating...");
    terminal.reset().unwrap();
    let data = match path.extension() {
        None => {
            return Err(String::from("the file extension is not wasm or wat"));
        }
        Some(ext) => {
            match ext.to_str() {
                Some("wasm") => {
                    read_wasm_file(path.clone()).map_err(|err| {
                        String::from(err.description())
                    })?
                }
                Some("wat") => {
                    let tmp_dir = TempDir::new("cretonne-wasm").unwrap();
                    let file_path = tmp_dir.path().join("module.wasm");
                    File::create(file_path.clone()).unwrap();
                    Command::new("wat2wasm")
                        .arg(path.clone())
                        .arg("-o")
                        .arg(file_path.to_str().unwrap())
                        .output()
                        .or_else(|e| if let io::ErrorKind::NotFound = e.kind() {
                            return Err(String::from("wat2wasm not found"));
                        } else {
                            return Err(String::from(e.description()));
                        })
                        .unwrap();
                    read_wasm_file(file_path).map_err(|err| {
                        String::from(err.description())
                    })?
                }
                None | Some(&_) => {
                    return Err(String::from("the file extension is not wasm or wat"));
                }
            }
        }
    };
    let mut dummy_runtime = DummyRuntime::with_flags(flags.clone());
    let translation = {
        let runtime: &mut WasmRuntime = &mut dummy_runtime;
        translate_module(&data, runtime)?
    };
    terminal.fg(term::color::GREEN).unwrap();
    vprintln!(flag_verbose, " ok");
    terminal.reset().unwrap();
    if flag_check {
        terminal.fg(term::color::MAGENTA).unwrap();
        vprint!(flag_verbose, "Checking...   ");
        terminal.reset().unwrap();
        for func in &translation.functions {
            verifier::verify_function(func, None).map_err(|err| {
                pretty_verifier_error(func, None, err)
            })?;
        }
        terminal.fg(term::color::GREEN).unwrap();
        vprintln!(flag_verbose, " ok");
        terminal.reset().unwrap();
    }
    if flag_optimize {
        terminal.fg(term::color::MAGENTA).unwrap();
        vprint!(flag_verbose, "Optimizing... ");
        terminal.reset().unwrap();
        for func in &translation.functions {
            let mut context = Context::new();
            context.func = func.clone();
            context.verify(None).map_err(|err| {
                pretty_verifier_error(&context.func, None, err)
            })?;
            context.licm();
            context.verify(None).map_err(|err| {
                pretty_verifier_error(&context.func, None, err)
            })?;
            context.simple_gvn();
            context.verify(None).map_err(|err| {
                pretty_verifier_error(&context.func, None, err)
            })?;
        }
        terminal.fg(term::color::GREEN).unwrap();
        vprintln!(flag_verbose, " ok");
        terminal.reset().unwrap();
    }
    Ok(())
}
<|endoftext|>


<commit_before>//! Print sizes of structs and enums
//!
//! Run with `cargo test sizes -- --nocapture`
//! to get the printed output.

use std::collections::BTreeMap;

use stencila_schema::*;

macro_rules! sizeof {
    ($type:ty) => {{
        let size = std::mem::size_of::<$type>();
        println!("{}: {}", stringify!($type), size);
        size
    }};
}

#[test]
fn sizes() {
    println!();
    println!("----------------------------------------------");
    sizeof!(Node);
    println!("----------------------------------------------");
    sizeof!(ArrayValidator);
    sizeof!(Article);
    sizeof!(AudioObject);
    sizeof!(BooleanValidator);
    sizeof!(Brand);
    sizeof!(CitationIntent);
    sizeof!(Cite);
    sizeof!(CiteGroup);
    sizeof!(Claim);
    sizeof!(CodeStatic);
    sizeof!(CodeBlock);
    sizeof!(CodeChunk);
    sizeof!(CodeError);
    sizeof!(CodeExpression);
    sizeof!(CodeFragment);
    sizeof!(Collection);
    sizeof!(Comment);
    sizeof!(ConstantValidator);
    sizeof!(ContactPoint);
    sizeof!(CreativeWork);
    sizeof!(Datatable);
    sizeof!(DatatableColumn);
    sizeof!(Date);
    sizeof!(DefinedTerm);
    sizeof!(Delete);
    sizeof!(Emphasis);
    sizeof!(EnumValidator);
    sizeof!(Enumeration);
    sizeof!(Executable);
    sizeof!(Figure);
    sizeof!(Function);
    sizeof!(Grant);
    sizeof!(Heading);
    sizeof!(ImageObject);
    sizeof!(Include);
    sizeof!(IntegerValidator);
    sizeof!(Link);
    sizeof!(List);
    sizeof!(ListItem);
    sizeof!(Mark);
    sizeof!(Math);
    sizeof!(MathBlock);
    sizeof!(MathFragment);
    sizeof!(MediaObject);
    sizeof!(MonetaryGrant);
    sizeof!(NontextualAnnotation);
    sizeof!(Note);
    sizeof!(NumberValidator);
    sizeof!(Organization);
    sizeof!(Paragraph);
    sizeof!(Parameter);
    sizeof!(Periodical);
    sizeof!(Person);
    sizeof!(PostalAddress);
    sizeof!(Product);
    sizeof!(PropertyValue);
    sizeof!(PublicationIssue);
    sizeof!(PublicationVolume);
    sizeof!(Quote);
    sizeof!(QuoteBlock);
    sizeof!(Review);
    sizeof!(SoftwareApplication);
    sizeof!(SoftwareEnvironment);
    sizeof!(SoftwareSession);
    sizeof!(SoftwareSourceCode);
    sizeof!(StringValidator);
    sizeof!(Strong);
    sizeof!(Subscript);
    sizeof!(Superscript);
    sizeof!(Table);
    sizeof!(TableCell);
    sizeof!(TableRow);
    sizeof!(ThematicBreak);
    sizeof!(Thing);
    sizeof!(TupleValidator);
    sizeof!(Validator);
    sizeof!(Variable);
    sizeof!(VideoObject);
    sizeof!(VolumeMount);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    sizeof!(InlineContent);
    println!("----------------------------------------------");
    sizeof!(AudioObjectSimple);
    sizeof!(Cite);
    sizeof!(CiteGroup);
    sizeof!(CodeExpression);
    sizeof!(CodeFragment);
    sizeof!(Delete);
    sizeof!(Emphasis);
    sizeof!(ImageObjectSimple);
    sizeof!(Link);
    sizeof!(MathFragment);
    sizeof!(NontextualAnnotation);
    sizeof!(Note);
    sizeof!(Parameter);
    sizeof!(Quote);
    sizeof!(Strong);
    sizeof!(Subscript);
    sizeof!(Superscript);
    sizeof!(VideoObjectSimple);
    sizeof!(bool);
    sizeof!(i64);
    sizeof!(f64);
    sizeof!(String);
    sizeof!(Vec<Primitive>);
    sizeof!(BTreeMap<String, Primitive>);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    sizeof!(BlockContent);
    println!("----------------------------------------------");
    sizeof!(ClaimSimple);
    sizeof!(CodeBlock);
    sizeof!(CodeChunk);
    sizeof!(CollectionSimple);
    sizeof!(FigureSimple);
    sizeof!(Heading);
    sizeof!(Include);
    sizeof!(List);
    sizeof!(MathBlock);
    sizeof!(Paragraph);
    sizeof!(QuoteBlock);
    sizeof!(TableSimple);
    sizeof!(ThematicBreak);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    sizeof!(CreativeWorkTypes);
    println!("----------------------------------------------");
    sizeof!(CreativeWork);
    sizeof!(Article);
    sizeof!(AudioObject);
    sizeof!(Claim);
    sizeof!(Collection);
    sizeof!(Comment);
    sizeof!(Datatable);
    sizeof!(Figure);
    sizeof!(ImageObject);
    sizeof!(MediaObject);
    sizeof!(Periodical);
    sizeof!(PublicationIssue);
    sizeof!(PublicationVolume);
    sizeof!(Review);
    sizeof!(SoftwareApplication);
    sizeof!(SoftwareSourceCode);
    sizeof!(Table);
    sizeof!(VideoObject);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    println!("Reference");
    println!("----------------------------------------------");
    sizeof!(bool);
    sizeof!(Option<bool>);
    sizeof!(String);
    sizeof!(Option<String>);
    sizeof!(Option<Box<String>>);
    println!("----------------------------------------------");
}
<commit_msg>test(Schema): Removed type<commit_after>//! Print sizes of structs and enums
//!
//! Run with `cargo test sizes -- --nocapture`
//! to get the printed output.

use std::collections::BTreeMap;

use stencila_schema::*;

macro_rules! sizeof {
    ($type:ty) => {{
        let size = std::mem::size_of::<$type>();
        println!("{}: {}", stringify!($type), size);
        size
    }};
}

#[test]
fn sizes() {
    println!();
    println!("----------------------------------------------");
    sizeof!(Node);
    println!("----------------------------------------------");
    sizeof!(ArrayValidator);
    sizeof!(Article);
    sizeof!(AudioObject);
    sizeof!(BooleanValidator);
    sizeof!(Brand);
    sizeof!(CitationIntent);
    sizeof!(Cite);
    sizeof!(CiteGroup);
    sizeof!(Claim);
    sizeof!(CodeStatic);
    sizeof!(CodeBlock);
    sizeof!(CodeChunk);
    sizeof!(CodeError);
    sizeof!(CodeExpression);
    sizeof!(CodeFragment);
    sizeof!(Collection);
    sizeof!(Comment);
    sizeof!(ConstantValidator);
    sizeof!(ContactPoint);
    sizeof!(CreativeWork);
    sizeof!(Datatable);
    sizeof!(DatatableColumn);
    sizeof!(Date);
    sizeof!(DefinedTerm);
    sizeof!(Delete);
    sizeof!(Emphasis);
    sizeof!(EnumValidator);
    sizeof!(Enumeration);
    sizeof!(Executable);
    sizeof!(Figure);
    sizeof!(Function);
    sizeof!(Grant);
    sizeof!(Heading);
    sizeof!(ImageObject);
    sizeof!(Include);
    sizeof!(IntegerValidator);
    sizeof!(Link);
    sizeof!(List);
    sizeof!(ListItem);
    sizeof!(Mark);
    sizeof!(Math);
    sizeof!(MathBlock);
    sizeof!(MathFragment);
    sizeof!(MediaObject);
    sizeof!(MonetaryGrant);
    sizeof!(NontextualAnnotation);
    sizeof!(Note);
    sizeof!(NumberValidator);
    sizeof!(Organization);
    sizeof!(Paragraph);
    sizeof!(Parameter);
    sizeof!(Periodical);
    sizeof!(Person);
    sizeof!(PostalAddress);
    sizeof!(Product);
    sizeof!(PropertyValue);
    sizeof!(PublicationIssue);
    sizeof!(PublicationVolume);
    sizeof!(Quote);
    sizeof!(QuoteBlock);
    sizeof!(Review);
    sizeof!(SoftwareApplication);
    sizeof!(SoftwareEnvironment);
    sizeof!(SoftwareSession);
    sizeof!(SoftwareSourceCode);
    sizeof!(StringValidator);
    sizeof!(Strong);
    sizeof!(Subscript);
    sizeof!(Superscript);
    sizeof!(Table);
    sizeof!(TableCell);
    sizeof!(TableRow);
    sizeof!(ThematicBreak);
    sizeof!(Thing);
    sizeof!(TupleValidator);
    sizeof!(Validator);
    sizeof!(Variable);
    sizeof!(VideoObject);
    sizeof!(VolumeMount);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    sizeof!(InlineContent);
    println!("----------------------------------------------");
    sizeof!(AudioObjectSimple);
    sizeof!(Cite);
    sizeof!(CiteGroup);
    sizeof!(CodeExpression);
    sizeof!(CodeFragment);
    sizeof!(Delete);
    sizeof!(Emphasis);
    sizeof!(ImageObjectSimple);
    sizeof!(Link);
    sizeof!(MathFragment);
    sizeof!(NontextualAnnotation);
    sizeof!(Note);
    sizeof!(Parameter);
    sizeof!(Quote);
    sizeof!(Strong);
    sizeof!(Subscript);
    sizeof!(Superscript);
    sizeof!(VideoObjectSimple);
    sizeof!(bool);
    sizeof!(i64);
    sizeof!(f64);
    sizeof!(String);
    sizeof!(Vec<Primitive>);
    sizeof!(BTreeMap<String, Primitive>);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    sizeof!(BlockContent);
    println!("----------------------------------------------");
    sizeof!(ClaimSimple);
    sizeof!(CodeBlock);
    sizeof!(CodeChunk);
    sizeof!(FigureSimple);
    sizeof!(Heading);
    sizeof!(Include);
    sizeof!(List);
    sizeof!(MathBlock);
    sizeof!(Paragraph);
    sizeof!(QuoteBlock);
    sizeof!(TableSimple);
    sizeof!(ThematicBreak);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    sizeof!(CreativeWorkTypes);
    println!("----------------------------------------------");
    sizeof!(CreativeWork);
    sizeof!(Article);
    sizeof!(AudioObject);
    sizeof!(Claim);
    sizeof!(Collection);
    sizeof!(Comment);
    sizeof!(Datatable);
    sizeof!(Figure);
    sizeof!(ImageObject);
    sizeof!(MediaObject);
    sizeof!(Periodical);
    sizeof!(PublicationIssue);
    sizeof!(PublicationVolume);
    sizeof!(Review);
    sizeof!(SoftwareApplication);
    sizeof!(SoftwareSourceCode);
    sizeof!(Table);
    sizeof!(VideoObject);
    println!("----------------------------------------------");

    println!();
    println!("----------------------------------------------");
    println!("Reference");
    println!("----------------------------------------------");
    sizeof!(bool);
    sizeof!(Option<bool>);
    sizeof!(String);
    sizeof!(Option<String>);
    sizeof!(Option<Box<String>>);
    println!("----------------------------------------------");
}
<|endoftext|>


<commit_before>use seed::prelude::*;
use crate::Msg;

extern crate num_bigint as bigint;
extern crate num_traits;

use crate::utils::nth;
use regex::Regex;

mod numerics_to_text {
    use num_traits::{Num,ToPrimitive,Zero};
    use num_bigint::{BigUint,ToBigUint};

    pub fn convert(str_num: String) -> String{
        let units:Vec<&str> = vec![
            "",
            " one",
            " two",
            " three",
            " four",
            " five",
            " six",
            " seven",
            " eight",
            " nine",
            " ten",
            " eleven",
            " twelve",
            " thirteen",
            " fourteen",
            " fifteen",
            " sixteen",
            " seventeen",
            " eighteen",
            " nineteen"
        ];
        let tens:Vec<&str> = vec![
            "",
            "",
            " twenty",
            " thirty",
            " forty",
            " fifty",
            " sixty",
            " seventy",
            " eighty",
            " ninety"
        ];
        let triplets:Vec<&str> = vec![
            "",
            " thousand",
            " million",
            " billion",
            " trillion",
            " quadrillion",
            " quintillion",
            " sextillion",
            " septillion",
            " octillion",
            " nonillion",
            " decillion",
            " undecillion",
            " duodecillion",
            " tredecillion",
            " quattuordecillion",
            " quindecillion",
            " sexdecillion",
            " septendecillion",
            " octodecillion",
            " novemdecillion",
            " vigintillion",
            " unvigintillion",
            " duovigintillion",
            " tresvigintillion",
            " quattuorvigintillion",
            " quinquavigintillion",
            " sesvigintillion",
            " septemvigintillion",
            " octovigintillion",
            " novemvigintillion",
            " trigintillion",
            " untrigintillion",
            " duotrigintillion",
            " trestrigintillion",
            " quattuortrigintillion",
            " quinquatrigintillion",
            " sestrigintillion",
            " septentrigintillion",
            " octotrigintillion",
            " noventrigintillion",
            " quadragintillion",
            " ERROR ",
        ];

        let num:BigUint = num_bigint::BigUint::from_str_radix(&str_num, 10).unwrap();
        convert_tri(num, Zero::zero(), units, tens, triplets)
    }

    fn convert_tri(num:BigUint, tri:usize, units:Vec<&str>, tens:Vec<&str>, triplets:Vec<&str>) -> String {
        // chunk the number, ...rxyy
        let ten:BigUint = 10.to_biguint().unwrap();
        let hundred:BigUint = 100.to_biguint().unwrap();
        let thousand:BigUint = 1000.to_biguint().unwrap();
        let r = &num / &thousand; // this in theory is rounding down to an int
        let x:usize = ((&num / &hundred) % &ten).to_usize().unwrap();
        let y:usize = (&num % &hundred).to_usize().unwrap();
        // init the output string
        let mut string:String = "".to_owned();
        // do hundreds
        if x > 0 {
            string.push_str(units[x]);
            string.push_str(" hundred");
        }
        // do units and tens
        if y < 20 {
            string.push_str(units[y]);
        } else {
            string.push_str(tens[(y / 10)]);
            string.push_str(units[(y / 10)]);
        }
        // add triplet modifier only if there
        // is some output to be modified...
        if string != "" {
            match triplets[tri] {
                _s => string.push_str(&triplets[tri].to_string()),
            }
        }
        // continue recursing?
        if r > Zero::zero() {
            let mut string2:String = convert_tri(r, tri + 1, units, tens, triplets);
            string2.push_str(&string);
            string2
        } else {
            string
        }
    }

}

fn html_form() -> seed::dom_types::Node<Msg> {
    div![
        h1!["Number Cruncher"],
        "Welcome to the number cruncher.
        Type in a number in the box below and we will crunch it for you.",
        br![],
        br![],
        "You will be taken to a page that tells you the following information about your number:",
        ul![
            li!["Is it odd or even?"],
            li!["Is it a palindrome?"],
            li!["Is it a prime number? (Checks numbers upto 11 digits in length)"],
            li!["Is it a ",a!["mersenne prime", attrs!{At::Class => "link", At::Href => "https://en.wikipedia.org/wiki/Mersenne_prime"}],"? (Checks numbers upto 2993 digits in length)"],
            li!["Is it a ",a!["fermat prime", attrs!{At::Class => "link", At::Href => "https://www.fermatsearch.org/"}],"? (Checks numbers upto 155 digits in length"],
            li!["Is it a ",a!["perfect number", attrs!{At::Class => "link", At::Href => "https://en.wikipedia.org/wiki/Perfect_number"}],"? (Checks numbers upto 12003 digits in length)"],
            li!["Is it a triangle number? (Checks numbers upto 40 digits in length)"],
            li!["Is it a square number?"],
            li!["Is it a cube number? (Checks numbers upto 17 digits in length)"],
            li!["Is it a factorial number?"],
            br![],
            br![],
            li!["All factors of the number will be listed (for numbers upto 9 digits)"],
            li!["The page will also show a list of base conversions. e.g. binary, octal and hexadecimal (Numbers upto 500 digits in length)"],
            li!["The number will be converted to roman numerals (Upto 6 digits in length)"],
            li!["The number will be converted to egyptian numerals (Upto 7 digits in length)"],
            li!["The number will be converted to chinese numerals (Upto 6 digits in length)"],
            li!["The number will be converted to babylonian numerals (Upto 13 digits in length)"],
        ],
        br![],
        br![],
	    "Please type your number here:",
        form![attrs!{At::Name => "crunchy", At::Action => "/cruncher/", At::Method => "get", At::Target => "_top"},
            div![
                textarea![attrs!{At::Name => "number", At::Cols => "85", At::Rows => "10", At::OnKeyDown => "if (event.keyCode == 13){document.location='/cruncher/'+crunchy.number.value+'/'}"}],
                br![],
                input![attrs!{At::Type => "button", At::Value => "Crunch", At::OnClick => "document.location='/cruncher/'+crunchy.number.value+'/'"}],
            ],
        ],
    ]
}

fn html_crunched_number(slug:String) -> seed::dom_types::Node<Msg> {
    let table_style = style!{"border" => "1px #000 solid"};
    div![style!{"width" => "75%"; "padding" => "3px"},
        br![],
        br![],
        b!["The number you submitted to be crunched was:"],
        h1![slug.to_string()," - ",numerics_to_text::convert(slug.to_string())],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![
                        "It is an odd number.",
                        br![],
                        "It is the ",nth(4)," prime number.",
                        br![],
                        "It is the 2nd ",a!["mersenne prime", attrs!{At::Class => "link", At::Href => "http://en.wikipedia.org/wiki/Mersenne_prime"}],".",
                        br![],
                        "It is not a ",a!["fermat prime", attrs!{At::Class => "link", At::Href => "https://www.fermatsearch.org/"}],".",
                        br![],
                        "It is not a ",a!["perfect number", attrs!{At::Class => "link", At::Href => "https://en.wikipedia.org/wiki/Perfect_number"}],".",
                        br![],
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![
                        "It is not a triangle number.",
                        br![],
                        "It is not a square number.",
                        br![],
                        "It is not a cube number.",
                        br![],
                        br![],
                        "It is not a factorial number.",
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![
                        "It it has no factors except itself and 1.",
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 2 (Binary):",
                    ],
                    td![
                        "111",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 3 (Ternary):",
                    ],
                    td![
                        "21",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 4 (Quaternary):",
                    ],
                    td![
                        "13",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 5 (Quinary):",
                    ],
                    td![
                        "12",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 8 (Octal):",
                    ],
                    td![
                        "7",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 10 (Denary):",
                    ],
                    td![
                        "7",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 16 (Hexadecimal):",
                    ],
                    td![
                        "7",
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![attrs!{At::Width => "200"},
                        "Roman Numerals:",
                    ],
                    td![attrs!{At::Width => "40"},
                        "VII",
                    ],
                ],
                tr![
                    td![
                        "Egyptian Numerals:",
                    ],
                    td![
                        "𓐀",
                    ]
                ],
                tr![
                    td![
                        "Chinese Numerals:",
                    ],
                    td![style!{"vertical-align" => "middle"; "background-color" => "#FFF"},
                        "柒",
                    ]
                ],
                tr![
                    td![
                        "Babylonian Numerals:",
                    ],
                    td![style!{"vertical-align" => "middle"; "background-color" => "#FFF"},
                        img![attrs!{At::Src => "https://static.bigprimes.net/imgs/babnumbers/bab_7.gif", At::Alt => "7"}],
                    ]
                ],
            ],
        ],
    ]
}

pub fn render(slug:String) -> seed::dom_types::Node<Msg> {
    let rgx = Regex::new(r"^([1-9]+[0-9]*)$").unwrap();

    match rgx.is_match(&slug) {
        true => html_crunched_number(slug),
        _ => html_form()
    }
}
<commit_msg>units displaying tens bug fixed<commit_after>use seed::prelude::*;
use crate::Msg;

extern crate num_bigint as bigint;
extern crate num_traits;

use crate::utils::nth;
use regex::Regex;

mod numerics_to_text {
    use num_traits::{Num,ToPrimitive,Zero};
    use num_bigint::{BigUint,ToBigUint};

    pub fn convert(str_num: String) -> String{
        let units:Vec<&str> = vec![
            "",
            " one",
            " two",
            " three",
            " four",
            " five",
            " six",
            " seven",
            " eight",
            " nine",
            " ten",
            " eleven",
            " twelve",
            " thirteen",
            " fourteen",
            " fifteen",
            " sixteen",
            " seventeen",
            " eighteen",
            " nineteen"
        ];
        let tens:Vec<&str> = vec![
            "",
            "",
            " twenty",
            " thirty",
            " forty",
            " fifty",
            " sixty",
            " seventy",
            " eighty",
            " ninety"
        ];
        let triplets:Vec<&str> = vec![
            "",
            " thousand",
            " million",
            " billion",
            " trillion",
            " quadrillion",
            " quintillion",
            " sextillion",
            " septillion",
            " octillion",
            " nonillion",
            " decillion",
            " undecillion",
            " duodecillion",
            " tredecillion",
            " quattuordecillion",
            " quindecillion",
            " sexdecillion",
            " septendecillion",
            " octodecillion",
            " novemdecillion",
            " vigintillion",
            " unvigintillion",
            " duovigintillion",
            " tresvigintillion",
            " quattuorvigintillion",
            " quinquavigintillion",
            " sesvigintillion",
            " septemvigintillion",
            " octovigintillion",
            " novemvigintillion",
            " trigintillion",
            " untrigintillion",
            " duotrigintillion",
            " trestrigintillion",
            " quattuortrigintillion",
            " quinquatrigintillion",
            " sestrigintillion",
            " septentrigintillion",
            " octotrigintillion",
            " noventrigintillion",
            " quadragintillion",
            " ERROR ",
        ];

        let num:BigUint = num_bigint::BigUint::from_str_radix(&str_num, 10).unwrap();
        convert_tri(num, Zero::zero(), units, tens, triplets)
    }

    fn convert_tri(num:BigUint, tri:usize, units:Vec<&str>, tens:Vec<&str>, triplets:Vec<&str>) -> String {
        // chunk the number, ...rxyy
        let ten:BigUint = 10.to_biguint().unwrap();
        let hundred:BigUint = 100.to_biguint().unwrap();
        let thousand:BigUint = 1000.to_biguint().unwrap();
        let r = &num / &thousand; // this in theory is rounding down to an int
        let x:usize = ((&num / &hundred) % &ten).to_usize().unwrap();
        let y:usize = (&num % &hundred).to_usize().unwrap();
        // init the output string
        let mut string:String = "".to_owned();
        // do hundreds
        if x > 0 {
            string.push_str(units[x]);
            string.push_str(" hundred");
        }
        // do units and tens
        if y < 20 {
            string.push_str(units[y]);
        } else {
            string.push_str(tens[(y / 10)]);
            string.push_str(units[(y % 10)]);
        }
        // add triplet modifier only if there
        // is some output to be modified...
        if string != "" {
            match triplets[tri] {
                _s => string.push_str(&triplets[tri].to_string()),
            }
        }
        // continue recursing?
        if r > Zero::zero() {
            let mut string2:String = convert_tri(r, tri + 1, units, tens, triplets);
            string2.push_str(&string);
            string2
        } else {
            string
        }
    }

}

fn html_form() -> seed::dom_types::Node<Msg> {
    div![
        h1!["Number Cruncher"],
        "Welcome to the number cruncher.
        Type in a number in the box below and we will crunch it for you.",
        br![],
        br![],
        "You will be taken to a page that tells you the following information about your number:",
        ul![
            li!["Is it odd or even?"],
            li!["Is it a palindrome?"],
            li!["Is it a prime number? (Checks numbers upto 11 digits in length)"],
            li!["Is it a ",a!["mersenne prime", attrs!{At::Class => "link", At::Href => "https://en.wikipedia.org/wiki/Mersenne_prime"}],"? (Checks numbers upto 2993 digits in length)"],
            li!["Is it a ",a!["fermat prime", attrs!{At::Class => "link", At::Href => "https://www.fermatsearch.org/"}],"? (Checks numbers upto 155 digits in length"],
            li!["Is it a ",a!["perfect number", attrs!{At::Class => "link", At::Href => "https://en.wikipedia.org/wiki/Perfect_number"}],"? (Checks numbers upto 12003 digits in length)"],
            li!["Is it a triangle number? (Checks numbers upto 40 digits in length)"],
            li!["Is it a square number?"],
            li!["Is it a cube number? (Checks numbers upto 17 digits in length)"],
            li!["Is it a factorial number?"],
            br![],
            br![],
            li!["All factors of the number will be listed (for numbers upto 9 digits)"],
            li!["The page will also show a list of base conversions. e.g. binary, octal and hexadecimal (Numbers upto 500 digits in length)"],
            li!["The number will be converted to roman numerals (Upto 6 digits in length)"],
            li!["The number will be converted to egyptian numerals (Upto 7 digits in length)"],
            li!["The number will be converted to chinese numerals (Upto 6 digits in length)"],
            li!["The number will be converted to babylonian numerals (Upto 13 digits in length)"],
        ],
        br![],
        br![],
	    "Please type your number here:",
        form![attrs!{At::Name => "crunchy", At::Action => "/cruncher/", At::Method => "get", At::Target => "_top"},
            div![
                textarea![attrs!{At::Name => "number", At::Cols => "85", At::Rows => "10", At::OnKeyDown => "if (event.keyCode == 13){document.location='/cruncher/'+crunchy.number.value+'/'}"}],
                br![],
                input![attrs!{At::Type => "button", At::Value => "Crunch", At::OnClick => "document.location='/cruncher/'+crunchy.number.value+'/'"}],
            ],
        ],
    ]
}

fn html_crunched_number(slug:String) -> seed::dom_types::Node<Msg> {
    let table_style = style!{"border" => "1px #000 solid"};
    div![style!{"width" => "75%"; "padding" => "3px"},
        br![],
        br![],
        b!["The number you submitted to be crunched was:"],
        h1![slug.to_string()," - ",numerics_to_text::convert(slug.to_string())],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![
                        "It is an odd number.",
                        br![],
                        "It is the ",nth(4)," prime number.",
                        br![],
                        "It is the 2nd ",a!["mersenne prime", attrs!{At::Class => "link", At::Href => "http://en.wikipedia.org/wiki/Mersenne_prime"}],".",
                        br![],
                        "It is not a ",a!["fermat prime", attrs!{At::Class => "link", At::Href => "https://www.fermatsearch.org/"}],".",
                        br![],
                        "It is not a ",a!["perfect number", attrs!{At::Class => "link", At::Href => "https://en.wikipedia.org/wiki/Perfect_number"}],".",
                        br![],
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![
                        "It is not a triangle number.",
                        br![],
                        "It is not a square number.",
                        br![],
                        "It is not a cube number.",
                        br![],
                        br![],
                        "It is not a factorial number.",
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![
                        "It it has no factors except itself and 1.",
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 2 (Binary):",
                    ],
                    td![
                        "111",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 3 (Ternary):",
                    ],
                    td![
                        "21",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 4 (Quaternary):",
                    ],
                    td![
                        "13",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 5 (Quinary):",
                    ],
                    td![
                        "12",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 8 (Octal):",
                    ],
                    td![
                        "7",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 10 (Denary):",
                    ],
                    td![
                        "7",
                    ],
                ],
                tr![
                    td![attrs!{At::Width => "200"},
                        "Base 16 (Hexadecimal):",
                    ],
                    td![
                        "7",
                    ],
                ],
            ],
        ],
        br![],
        br![],
        table![attrs!{At::Class => "text", At::Width => "100%"}, &table_style,
            tbody![
                tr![
                    td![attrs!{At::Width => "200"},
                        "Roman Numerals:",
                    ],
                    td![attrs!{At::Width => "40"},
                        "VII",
                    ],
                ],
                tr![
                    td![
                        "Egyptian Numerals:",
                    ],
                    td![
                        "𓐀",
                    ]
                ],
                tr![
                    td![
                        "Chinese Numerals:",
                    ],
                    td![style!{"vertical-align" => "middle"; "background-color" => "#FFF"},
                        "柒",
                    ]
                ],
                tr![
                    td![
                        "Babylonian Numerals:",
                    ],
                    td![style!{"vertical-align" => "middle"; "background-color" => "#FFF"},
                        img![attrs!{At::Src => "https://static.bigprimes.net/imgs/babnumbers/bab_7.gif", At::Alt => "7"}],
                    ]
                ],
            ],
        ],
    ]
}

pub fn render(slug:String) -> seed::dom_types::Node<Msg> {
    let rgx = Regex::new(r"^([1-9]+[0-9]*)$").unwrap();

    match rgx.is_match(&slug) {
        true => html_crunched_number(slug),
        _ => html_form()
    }
}
<|endoftext|>


<commit_before>extern crate matroska;
extern crate av_format;
extern crate av_data;
extern crate nom;

use av_format::buffer::AccReader;
use av_format::demuxer::{self, Event};
use av_format::muxer::{self};
use std::io::Cursor;
use std::sync::Arc;
use std::fs::File;

use matroska::demuxer::MKV_DESC;
use matroska::muxer::MkvMuxer;

fn main() {
  //const webm: &'static [u8] = include_bytes!("../assets/big-buck-bunny_trailer.webm");
  const WEBM: &'static [u8] = include_bytes!("../assets/bbb-vp9-opus.webm");
  //const webm: &'static [u8] = include_bytes!("../assets/single_stream.mkv");
  let d = MKV_DESC.create();
  let c = Cursor::new(WEBM);
  //let acc = AccReader::with_capacity(5242880, c);
  let acc = AccReader::with_capacity(20000, c);
  let input = Box::new(acc);
  let mut demuxer = demuxer::Context::new(d, input);

  println!("read headers: {:?}", demuxer.read_headers().unwrap());
  println!("global info: {:#?}", demuxer.info);

  let mux = Box::new(MkvMuxer::webm());
  let output = File::create("output.webm").unwrap();

  let mut muxer = muxer::Context::new(mux, Box::new(output));
  muxer.configure().unwrap();
  muxer.set_global_info(demuxer.info.clone()).unwrap();
  muxer.write_header().unwrap();

  loop {
    match demuxer.read_event() {
      Ok(event) => {
        //println!("event: {:?}", event);
        match event {
          Event::MoreDataNeeded(sz) => panic!("we needed more data: {} bytes", sz),
          Event::NewStream(s) => panic!("new stream :{:?}", s),
          Event::NewPacket(packet) => {
            //println!("writing packet");
            muxer.write_packet(Arc::new(packet)).unwrap();
          }
        }
      },
      Err(e) => {
        println!("error: {:?}", e);
        muxer.write_trailer().unwrap();
        break;
      }
    }
  }
}

<commit_msg>handle the eof event<commit_after>extern crate matroska;
extern crate av_format;
extern crate av_data;
extern crate nom;

use av_format::buffer::AccReader;
use av_format::demuxer::{self, Event};
use av_format::muxer::{self};
use std::io::Cursor;
use std::sync::Arc;
use std::fs::File;

use matroska::demuxer::MKV_DESC;
use matroska::muxer::MkvMuxer;

fn main() {
  //const webm: &'static [u8] = include_bytes!("../assets/big-buck-bunny_trailer.webm");
  const WEBM: &'static [u8] = include_bytes!("../assets/bbb-vp9-opus.webm");
  //const webm: &'static [u8] = include_bytes!("../assets/single_stream.mkv");
  let d = MKV_DESC.create();
  let c = Cursor::new(WEBM);
  //let acc = AccReader::with_capacity(5242880, c);
  let acc = AccReader::with_capacity(20000, c);
  let input = Box::new(acc);
  let mut demuxer = demuxer::Context::new(d, input);

  println!("read headers: {:?}", demuxer.read_headers().unwrap());
  println!("global info: {:#?}", demuxer.info);

  let mux = Box::new(MkvMuxer::webm());
  let output = File::create("output.webm").unwrap();

  let mut muxer = muxer::Context::new(mux, Box::new(output));
  muxer.configure().unwrap();
  muxer.set_global_info(demuxer.info.clone()).unwrap();
  muxer.write_header().unwrap();

  loop {
    match demuxer.read_event() {
      Ok(event) => {
        //println!("event: {:?}", event);
        match event {
          Event::MoreDataNeeded(sz) => panic!("we needed more data: {} bytes", sz),
          Event::NewStream(s) => panic!("new stream :{:?}", s),
          Event::NewPacket(packet) => {
            //println!("writing packet");
            muxer.write_packet(Arc::new(packet)).unwrap();
          }
          Event::Eof => {
            muxer.write_trailer().unwrap();
            break;
          }
        }
      },
      Err(e) => {
        println!("error: {:?}", e);
        break;
      }
    }
  }
}

<|endoftext|>


<commit_before>// ignore-windows: Concurrency on Windows is not supported yet.
// compile-flags: -Zmiri-check-number-validity

use std::thread;

fn create_and_detach() {
    thread::spawn(|| ());
}

fn create_and_join() {
    thread::spawn(|| ()).join().unwrap();
}

fn create_and_get_result() {
    let nine = thread::spawn(|| 5 + 4).join().unwrap();
    assert_eq!(nine, 9);
}

fn create_and_leak_result() {
    thread::spawn(|| 7);
}

fn create_nested_and_detach() {
    thread::spawn(|| {
        thread::spawn(|| ());
    });
}

fn create_nested_and_join() {
    let handle = thread::spawn(|| thread::spawn(|| ()));
    let handle_nested = handle.join().unwrap();
    handle_nested.join().unwrap();
}

fn create_move_in() {
    let x = String::from("Hello!");
    thread::spawn(move || {
        assert_eq!(x.len(), 6);
    })
    .join()
    .unwrap();
}

fn create_move_out() {
    let result = thread::spawn(|| {
        String::from("Hello!")
    })
    .join()
    .unwrap();
    assert_eq!(result.len(), 6);
}

fn panic() {
    let result = thread::spawn(|| {
        panic!("Hello!")
    })
    .join()
    .unwrap_err();
    let msg = result.downcast_ref::<&'static str>().unwrap();
    assert_eq!(*msg, "Hello!");
}

fn panic_named() {
    thread::Builder::new().name("childthread".to_string()).spawn(move || {
        panic!("Hello, world!");
    })
    .unwrap()
    .join()
    .unwrap_err();
}

fn main() {
    create_and_detach();
    create_and_join();
    create_and_get_result();
    create_and_leak_result();
    create_nested_and_detach();
    create_nested_and_join();
    create_move_in();
    create_move_out();
    panic();
    panic_named();
}
<commit_msg>thread name setting works with strict provenance now :)<commit_after>// ignore-windows: Concurrency on Windows is not supported yet.
// compile-flags: -Zmiri-strict-provenance

use std::thread;

fn create_and_detach() {
    thread::spawn(|| ());
}

fn create_and_join() {
    thread::spawn(|| ()).join().unwrap();
}

fn create_and_get_result() {
    let nine = thread::spawn(|| 5 + 4).join().unwrap();
    assert_eq!(nine, 9);
}

fn create_and_leak_result() {
    thread::spawn(|| 7);
}

fn create_nested_and_detach() {
    thread::spawn(|| {
        thread::spawn(|| ());
    });
}

fn create_nested_and_join() {
    let handle = thread::spawn(|| thread::spawn(|| ()));
    let handle_nested = handle.join().unwrap();
    handle_nested.join().unwrap();
}

fn create_move_in() {
    let x = String::from("Hello!");
    thread::spawn(move || {
        assert_eq!(x.len(), 6);
    })
    .join()
    .unwrap();
}

fn create_move_out() {
    let result = thread::spawn(|| {
        String::from("Hello!")
    })
    .join()
    .unwrap();
    assert_eq!(result.len(), 6);
}

fn panic() {
    let result = thread::spawn(|| {
        panic!("Hello!")
    })
    .join()
    .unwrap_err();
    let msg = result.downcast_ref::<&'static str>().unwrap();
    assert_eq!(*msg, "Hello!");
}

fn panic_named() {
    thread::Builder::new().name("childthread".to_string()).spawn(move || {
        panic!("Hello, world!");
    })
    .unwrap()
    .join()
    .unwrap_err();
}

fn main() {
    create_and_detach();
    create_and_join();
    create_and_get_result();
    create_and_leak_result();
    create_nested_and_detach();
    create_nested_and_join();
    create_move_in();
    create_move_out();
    panic();
    panic_named();
}
<|endoftext|>