<commit_before>use std::collections::HashMap;
use decoders::basics::*;
use std::str;
use num::FromPrimitive;

enum_from_primitive! {
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Tag {
  ImageWidth     = 0x0100,
  ImageLength    = 0x0101,
  BitsPerSample  = 0x0102,
  Compression    = 0x0103,
  Make           = 0x010F,
  Model          = 0x0110,
  StripOffsets   = 0x0111,
  StripByteCounts= 0x0117,
  SubIFDs        = 0x014A,
  OlympusRedMul  = 0x1017,
  OlympusBlueMul = 0x1018,
  OlympusImgProc = 0x2040,
  SonyCurve      = 0x7010,
  SonyOffset     = 0x7200,
  SonyLength     = 0x7201,
  SonyKey        = 0x7221,
  SonyGRBG       = 0x7303,
  SonyRGGB       = 0x7313,
  ExifIFDPointer = 0x8769,
  Makernote      = 0x927C,
  DNGPrivateArea = 0xC634,

}
}
                          // 0-1-2-3-4-5-6-7-8-9-10-11-12-13
const DATASHIFTS: [u8;14] = [0,0,0,1,2,3,0,0,1,2, 3, 2, 3, 2];

fn t (tag: Tag) -> u16 {
  tag as u16
}

#[derive(Debug, Copy, Clone)]
pub struct TiffEntry<'a> {
  tag: u16,
  typ: u16,
  count: u32,
  parent_offset: usize,
  doffset: usize,
  data: &'a [u8],
  endian: Endian,
}

#[derive(Debug, Clone)]
pub struct TiffIFD<'a> {
  entries: HashMap<u16,TiffEntry<'a>>,
  subifds: Vec<TiffIFD<'a>>,
  nextifd: usize,
  endian: Endian,
}

impl<'a> TiffIFD<'a> {
  pub fn new_root(buf: &'a[u8], offset: usize, depth: u32, e: Endian) -> TiffIFD<'a> {
    let mut subifds = Vec::new();
    let mut nextifd = e.ru32(buf, offset) as usize;

    for _ in 0..100 { // Never read more than 100 IFDs
      let ifd = TiffIFD::new(buf, nextifd, 0, depth, e).unwrap();
      nextifd = ifd.nextifd;
      subifds.push(ifd);
      if nextifd == 0 {
        break
      }
    }

    TiffIFD {
      entries: HashMap::new(),
      subifds: subifds,
      nextifd: 0,
      endian: e,
    }
  }

  pub fn new(buf: &'a[u8], offset: usize, base_offset: usize, depth: u32, e: Endian) -> Result<TiffIFD<'a>, String> {
    let mut entries = HashMap::new();
    let mut subifds = Vec::new();

    let num = e.ru16(buf, offset); // Directory entries in this IFD
    if num > 4000 {
      return Err(format!("too many entries in IFD ({})", num).to_string())
    }
    for i in 0..num {
      let entry_offset: usize = offset + 2 + (i as usize)*12;
      if Tag::from_u16(e.ru16(buf, entry_offset)).is_none() {
        // Skip entries we don't know about to speedup decoding
        continue;
      }
      let entry = TiffEntry::new(buf, entry_offset, base_offset, offset, e);

      if entry.tag == t(Tag::SubIFDs) || entry.tag == t(Tag::ExifIFDPointer) {
        if depth < 10 { // Avoid infinite looping IFDs
          for i in 0..entry.count {
            let ifd = TiffIFD::new(buf, entry.get_u32(i as usize) as usize, base_offset, depth+1, e);
            match ifd {
              Ok(val) => {subifds.push(val);},
              Err(_) => {entries.insert(entry.tag, entry);}, // Ignore unparsable IFDs
            }
          }
        }
      } else if entry.tag == t(Tag::Makernote) {
        if depth < 10 { // Avoid infinite looping IFDs
          let ifd = TiffIFD::new_makernote(buf, entry.doffset(), base_offset, depth+1, e);
          match ifd {
            Ok(val) => {subifds.push(val);},
            Err(_) => {entries.insert(entry.tag, entry);}, // Ignore unparsable IFDs
          }
        }
      } else {
        entries.insert(entry.tag, entry);
      }
    }

    Ok(TiffIFD {
      entries: entries,
      subifds: subifds,
      nextifd: e.ru32(buf, offset + (2+num*12) as usize) as usize,
      endian: e,
    })
  }

  pub fn new_makernote(buf: &'a[u8], offset: usize, base_offset: usize, depth: u32, e: Endian) -> Result<TiffIFD<'a>, String> {
    let mut off = offset;
    let data = &buf[offset..];

    // Olympus starts the makernote with their own name, sometimes truncated
    if data[0..5] == b"OLYMP"[..] {
      off += 8;
      if data[0..7] == b"OLYMPUS"[..] {
        off += 4;
      }
    }

    TiffIFD::new(buf, off, base_offset, depth, e)
  }

  pub fn find_entry(&self, tag: Tag) -> Option<&TiffEntry> {
    if self.entries.contains_key(&t(tag)) {
      self.entries.get(&t(tag))
    } else {
      for ifd in &self.subifds {
        match ifd.find_entry(tag) {
          Some(x) => return Some(x),
          None => {},
        }
      }
      None
    }
  }

  pub fn find_ifds_with_tag(&self, tag: Tag) -> Vec<&TiffIFD> {
    let mut ifds = Vec::new();
    for ifd in &self.subifds {
      if ifd.entries.contains_key(&t(tag)) {
        ifds.push(ifd);
      }
      ifds.extend(ifd.find_ifds_with_tag(tag));
    }
    ifds
  }

  pub fn get_endian(&self) -> Endian { self.endian }
  pub fn little_endian(&self) -> bool { self.endian.little() }
}

impl<'a> TiffEntry<'a> {
  pub fn new(buf: &'a[u8], offset: usize, base_offset: usize, parent_offset: usize, e: Endian) -> TiffEntry<'a> {
    let tag = e.ru16(buf, offset);
    let mut typ = e.ru16(buf, offset+2);
    let count = e.ru32(buf, offset+4);

    // If we don't know the type assume byte data
    if typ == 0 || typ > 13 {
      typ = 1;
    }

    let bytesize: usize = (count as usize) << DATASHIFTS[typ as usize];
    let doffset: usize = if bytesize <= 4 {
      (offset + 8)
    } else {
      (e.ru32(buf, offset+8) as usize) - base_offset
    };

    TiffEntry {
      tag: tag,
      typ: typ,
      count: count,
      parent_offset: parent_offset,
      doffset: doffset,
      data: &buf[doffset .. doffset+bytesize],
      endian: e,
    }
  }

  pub fn copy_with_new_data(&self, data: &'a[u8]) -> TiffEntry<'a> {
    let mut copy = self.clone();
    copy.data = data;
    copy
  }

  pub fn doffset(&self) -> usize { self.doffset }
  pub fn parent_offset(&self) -> usize { self.parent_offset }
  pub fn count(&self) -> u32 { self.count }
  //pub fn typ(&self) -> u16 { self.typ }

  pub fn get_u32(&self, idx: usize) -> u32 {
    match self.typ {
      3 => self.endian.ru16(self.data, idx*2) as u32,
      4 | 13 => self.endian.ru32(self.data, idx*4),
      _ => panic!(format!("Trying to read typ {} for a u32", self.typ).to_string()),
    }
  }

  pub fn get_str(&self) -> &str {
    // Truncate the string when there are \0 bytes
    let len = match self.data.iter().position(|&x| x == 0) {
      Some(p) => p,
      None => self.data.len(),
    };
    match str::from_utf8(&self.data[0..len]) {
      Result::Ok(val) => val.trim(),
      Result::Err(err) => panic!(err),
    }
  }
}
<commit_msg>TIFF: be more liberal in what constitutes a u32<commit_after>use std::collections::HashMap;
use decoders::basics::*;
use std::str;
use num::FromPrimitive;

enum_from_primitive! {
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Tag {
  ImageWidth     = 0x0100,
  ImageLength    = 0x0101,
  BitsPerSample  = 0x0102,
  Compression    = 0x0103,
  Make           = 0x010F,
  Model          = 0x0110,
  StripOffsets   = 0x0111,
  StripByteCounts= 0x0117,
  SubIFDs        = 0x014A,
  OlympusRedMul  = 0x1017,
  OlympusBlueMul = 0x1018,
  OlympusImgProc = 0x2040,
  SonyCurve      = 0x7010,
  SonyOffset     = 0x7200,
  SonyLength     = 0x7201,
  SonyKey        = 0x7221,
  SonyGRBG       = 0x7303,
  SonyRGGB       = 0x7313,
  ExifIFDPointer = 0x8769,
  Makernote      = 0x927C,
  DNGPrivateArea = 0xC634,

}
}
                          // 0-1-2-3-4-5-6-7-8-9-10-11-12-13
const DATASHIFTS: [u8;14] = [0,0,0,1,2,3,0,0,1,2, 3, 2, 3, 2];

fn t (tag: Tag) -> u16 {
  tag as u16
}

#[derive(Debug, Copy, Clone)]
pub struct TiffEntry<'a> {
  tag: u16,
  typ: u16,
  count: u32,
  parent_offset: usize,
  doffset: usize,
  data: &'a [u8],
  endian: Endian,
}

#[derive(Debug, Clone)]
pub struct TiffIFD<'a> {
  entries: HashMap<u16,TiffEntry<'a>>,
  subifds: Vec<TiffIFD<'a>>,
  nextifd: usize,
  endian: Endian,
}

impl<'a> TiffIFD<'a> {
  pub fn new_root(buf: &'a[u8], offset: usize, depth: u32, e: Endian) -> TiffIFD<'a> {
    let mut subifds = Vec::new();
    let mut nextifd = e.ru32(buf, offset) as usize;

    for _ in 0..100 { // Never read more than 100 IFDs
      let ifd = TiffIFD::new(buf, nextifd, 0, depth, e).unwrap();
      nextifd = ifd.nextifd;
      subifds.push(ifd);
      if nextifd == 0 {
        break
      }
    }

    TiffIFD {
      entries: HashMap::new(),
      subifds: subifds,
      nextifd: 0,
      endian: e,
    }
  }

  pub fn new(buf: &'a[u8], offset: usize, base_offset: usize, depth: u32, e: Endian) -> Result<TiffIFD<'a>, String> {
    let mut entries = HashMap::new();
    let mut subifds = Vec::new();

    let num = e.ru16(buf, offset); // Directory entries in this IFD
    if num > 4000 {
      return Err(format!("too many entries in IFD ({})", num).to_string())
    }
    for i in 0..num {
      let entry_offset: usize = offset + 2 + (i as usize)*12;
      if Tag::from_u16(e.ru16(buf, entry_offset)).is_none() {
        // Skip entries we don't know about to speedup decoding
        continue;
      }
      let entry = TiffEntry::new(buf, entry_offset, base_offset, offset, e);

      if entry.tag == t(Tag::SubIFDs) || entry.tag == t(Tag::ExifIFDPointer) {
        if depth < 10 { // Avoid infinite looping IFDs
          for i in 0..entry.count {
            let ifd = TiffIFD::new(buf, entry.get_u32(i as usize) as usize, base_offset, depth+1, e);
            match ifd {
              Ok(val) => {subifds.push(val);},
              Err(_) => {entries.insert(entry.tag, entry);}, // Ignore unparsable IFDs
            }
          }
        }
      } else if entry.tag == t(Tag::Makernote) {
        if depth < 10 { // Avoid infinite looping IFDs
          let ifd = TiffIFD::new_makernote(buf, entry.doffset(), base_offset, depth+1, e);
          match ifd {
            Ok(val) => {subifds.push(val);},
            Err(_) => {entries.insert(entry.tag, entry);}, // Ignore unparsable IFDs
          }
        }
      } else {
        entries.insert(entry.tag, entry);
      }
    }

    Ok(TiffIFD {
      entries: entries,
      subifds: subifds,
      nextifd: e.ru32(buf, offset + (2+num*12) as usize) as usize,
      endian: e,
    })
  }

  pub fn new_makernote(buf: &'a[u8], offset: usize, base_offset: usize, depth: u32, e: Endian) -> Result<TiffIFD<'a>, String> {
    let mut off = offset;
    let data = &buf[offset..];

    // Olympus starts the makernote with their own name, sometimes truncated
    if data[0..5] == b"OLYMP"[..] {
      off += 8;
      if data[0..7] == b"OLYMPUS"[..] {
        off += 4;
      }
    }

    TiffIFD::new(buf, off, base_offset, depth, e)
  }

  pub fn find_entry(&self, tag: Tag) -> Option<&TiffEntry> {
    if self.entries.contains_key(&t(tag)) {
      self.entries.get(&t(tag))
    } else {
      for ifd in &self.subifds {
        match ifd.find_entry(tag) {
          Some(x) => return Some(x),
          None => {},
        }
      }
      None
    }
  }

  pub fn find_ifds_with_tag(&self, tag: Tag) -> Vec<&TiffIFD> {
    let mut ifds = Vec::new();
    for ifd in &self.subifds {
      if ifd.entries.contains_key(&t(tag)) {
        ifds.push(ifd);
      }
      ifds.extend(ifd.find_ifds_with_tag(tag));
    }
    ifds
  }

  pub fn get_endian(&self) -> Endian { self.endian }
  pub fn little_endian(&self) -> bool { self.endian.little() }
}

impl<'a> TiffEntry<'a> {
  pub fn new(buf: &'a[u8], offset: usize, base_offset: usize, parent_offset: usize, e: Endian) -> TiffEntry<'a> {
    let tag = e.ru16(buf, offset);
    let mut typ = e.ru16(buf, offset+2);
    let count = e.ru32(buf, offset+4);

    // If we don't know the type assume byte data
    if typ == 0 || typ > 13 {
      typ = 1;
    }

    let bytesize: usize = (count as usize) << DATASHIFTS[typ as usize];
    let doffset: usize = if bytesize <= 4 {
      (offset + 8)
    } else {
      (e.ru32(buf, offset+8) as usize) - base_offset
    };

    TiffEntry {
      tag: tag,
      typ: typ,
      count: count,
      parent_offset: parent_offset,
      doffset: doffset,
      data: &buf[doffset .. doffset+bytesize],
      endian: e,
    }
  }

  pub fn copy_with_new_data(&self, data: &'a[u8]) -> TiffEntry<'a> {
    let mut copy = self.clone();
    copy.data = data;
    copy
  }

  pub fn doffset(&self) -> usize { self.doffset }
  pub fn parent_offset(&self) -> usize { self.parent_offset }
  pub fn count(&self) -> u32 { self.count }
  //pub fn typ(&self) -> u16 { self.typ }

  pub fn get_u32(&self, idx: usize) -> u32 {
    match self.typ {
      3 | 8              => self.endian.ru16(self.data, idx*2) as u32,
      1 | 4 | 7 | 9 | 13 => self.endian.ru32(self.data, idx*4),
      _ => panic!(format!("Trying to read typ {} for a u32", self.typ).to_string()),
    }
  }

  pub fn get_str(&self) -> &str {
    // Truncate the string when there are \0 bytes
    let len = match self.data.iter().position(|&x| x == 0) {
      Some(p) => p,
      None => self.data.len(),
    };
    match str::from_utf8(&self.data[0..len]) {
      Result::Ok(val) => val.trim(),
      Result::Err(err) => panic!(err),
    }
  }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate mazes;
extern crate test;

use mazes::generators;
use mazes::renderers;
use mazes::pathing;
use mazes::squaregrid;
use test::Bencher;

#[bench]
fn render_grid(b: &mut Bencher) {

    let grid_size = 200;
    let mut maze_grid = squaregrid::SquareGrid::<u32>::new(grid_size);
    let start_coord = squaregrid::GridCoordinate::new(0, 0);
    generators::recursive_backtracker(&mut maze_grid);
    let distances = pathing::DijkstraDistances::<u32>::new(&maze_grid, start_coord);

    let render_options = renderers::RenderOptionsBuilder::new()
             .colour_distances(true)
             .mark_start_end(true)
             .start(Some(start_coord))
             .end(Some(squaregrid::GridCoordinate::new(199, 199)))
             .show_path(true)
             .distances(distances.as_ref())
             .build();

    // Todo - why does SDL_LogCritical get called so much by fill_rect/draw_line?
    b.iter(|| renderers::render_square_grid(&maze_grid, &render_options));
}
<commit_msg>Log calls debug.<commit_after>#![feature(test)]

extern crate mazes;
extern crate test;

use mazes::generators;
use mazes::renderers;
use mazes::pathing;
use mazes::squaregrid;

use std::ptr;
use test::Bencher;

extern "C" {
                                            // maybe null function pointer
    pub fn SDL_LogSetOutputFunction(callback: Option<extern fn()>,
                                    userdata: Option<extern fn()>);
}

#[bench]
fn render_grid(b: &mut Bencher) {

    unsafe { SDL_LogSetOutputFunction(None, None); }

    let grid_size = 200;
    let mut maze_grid = squaregrid::SquareGrid::<u32>::new(grid_size);
    let start_coord = squaregrid::GridCoordinate::new(0, 0);
    generators::recursive_backtracker(&mut maze_grid);
    let distances = pathing::DijkstraDistances::<u32>::new(&maze_grid, start_coord);

    let render_options = renderers::RenderOptionsBuilder::new()
             .colour_distances(true)
             .mark_start_end(true)
             .start(Some(start_coord))
             .end(Some(squaregrid::GridCoordinate::new(199, 199)))
             .show_path(true)
             .distances(distances.as_ref())
             .build();

    // Todo - why does SDL_LogCritical get called so much by fill_rect/draw_line?
    // render recursive-backtracker image --mark-start-end --grid-size 2500 --cell-pixels 8 --show-path --image-out=perf-test-maze.png --colour-distances
    // 23% of samples
    // and it does not improve when setting SDL_LogSetOutputFunction to nothing
    b.iter(|| renderers::render_square_grid(&maze_grid, &render_options));
}

// void SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata);
// static void SDL_LogOutput(void *userdata,
//                           int category, SDL_LogPriority priority,
//                           const char *message);

// ?
// static void
// debug_print(const char *fmt, ...)
// {
//     va_list ap;
//     va_start(ap, fmt);
//     SDL_LogMessageV(SDL_LOG_CATEGORY_ASSERT, SDL_LOG_PRIORITY_WARN, fmt, ap);
//     va_end(ap);
// }
//
// SDL_SetError if in debug
//
//  #if LOG_WINDOW_EVENTS==1
<|endoftext|>


<commit_before>//! Output a video as a series of short audio tracks, short enough to make
//! it easy to skip backwards a conversation with most MP3 players.

use err::Result;
use export::Exporter;
use time::Period;

// Should we merge two time periods into one?
fn should_merge(p1: Period, p2: Period) -> bool {
    if p1.duration() >= 30.0 {
        false
    } else {
        match p1.distance(p2) {
            None => true,
            Some(d) if d <= 5.0 => true,
            _ => false
        }
    }
}

/// Export the video as a set of tracks.
pub fn export_tracks(exporter: &mut Exporter) -> Result<()> {
    let mut convs: Vec<Period> = vec!();

    // Figure out how to combine subtitles into conversations.
    for sub in &exporter.foreign().subtitles.subtitles {
        if let Some(prev) = convs.last_mut() {
            if should_merge(*prev, sub.period) {
                *prev = prev.union(sub.period);
                continue;
            }
        }
        convs.push(sub.period);
    }

    // Add padding to each audio clip.
    for conv in convs.iter_mut() {
        *conv = conv.grow(2.5, 2.5);
    }

    // Turn overlapping clips into seamless transitions.
    // TODO: Fade in/out when not a seamless transition.
    for i in 1..convs.len() {
        if convs[i].begin() < convs[i-1].end()  {
            let overlap = Period::new(convs[i].begin(), convs[i-1].end())
                .unwrap();
            let midpoint = overlap.midpoint();
            debug!("Overlap: {:?} {:?} {:?} {}",
                   convs[i-1], convs[i], overlap, midpoint);
            convs[i-1] = Period::new(convs[i-1].begin(), midpoint).unwrap();
            convs[i] = Period::new(midpoint, convs[i].end()).unwrap();
            assert!(convs[i].begin() >= convs[i-1].end());
        }
    }

    // Schedule exports.
    // TODO: Genre, artist, album, track title, track number.
    let foreign_lang = exporter.foreign().language;
    for conv in convs {
        exporter.schedule_audio_export(foreign_lang, conv);
        debug!("Conv: {:7.1} -> {:7.1} for {:7.1}",
               conv.begin(), conv.end(), conv.duration());
    }

    // Extract our media files.
    try!(exporter.finish_exports());

    Ok(())
}
<commit_msg>Implement m3u8 playlists<commit_after>//! Output a video as a series of short audio tracks, short enough to make
//! it easy to skip backwards a conversation with most MP3 players.

use std::io::{Cursor, Write};

use err::Result;
use export::Exporter;
use time::Period;

// Should we merge two time periods into one?
fn should_merge(p1: Period, p2: Period) -> bool {
    if p1.duration() >= 30.0 {
        false
    } else {
        match p1.distance(p2) {
            None => true,
            Some(d) if d <= 5.0 => true,
            _ => false
        }
    }
}

/// Export the video as a set of tracks.
pub fn export_tracks(exporter: &mut Exporter) -> Result<()> {
    let mut convs: Vec<Period> = vec!();

    // Figure out how to combine subtitles into conversations.
    for sub in &exporter.foreign().subtitles.subtitles {
        if let Some(prev) = convs.last_mut() {
            if should_merge(*prev, sub.period) {
                *prev = prev.union(sub.period);
                continue;
            }
        }
        convs.push(sub.period);
    }

    // Add padding to each audio clip.
    for conv in convs.iter_mut() {
        *conv = conv.grow(2.5, 2.5);
    }

    // Turn overlapping clips into seamless transitions.
    // TODO: Fade in/out when not a seamless transition.
    for i in 1..convs.len() {
        if convs[i].begin() < convs[i-1].end()  {
            let overlap = Period::new(convs[i].begin(), convs[i-1].end())
                .unwrap();
            let midpoint = overlap.midpoint();
            debug!("Overlap: {:?} {:?} {:?} {}",
                   convs[i-1], convs[i], overlap, midpoint);
            convs[i-1] = Period::new(convs[i-1].begin(), midpoint).unwrap();
            convs[i] = Period::new(midpoint, convs[i].end()).unwrap();
            assert!(convs[i].begin() >= convs[i-1].end());
        }
    }

    // Schedule exports and write our our m3u8 playlist (like m3u, but
    // UTF-8).
    //
    // TODO: Genre, artist, album, track title, track number.
    let foreign_lang = exporter.foreign().language;
    let mut buff = Cursor::new(vec!());
    for conv in convs {
        let path = exporter.schedule_audio_export(foreign_lang, conv);
        try!(writeln!(buff, "{}", &path));
        debug!("Conv: {:7.1} -> {:7.1} for {:7.1}",
               conv.begin(), conv.end(), conv.duration());
    }
    try!(exporter.export_data_file("playlist.m3u8", &buff.get_ref()));

    // Extract our media files.
    try!(exporter.finish_exports());

    Ok(())
}
<|endoftext|>


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

use anyhow::{bail, format_err, Error, Result};
use futures::future::{err, ok, Future};
use libra_config::config::NodeConfig;
use libra_types::{
    account_address::{AccountAddress, ADDRESS_LENGTH},
    account_config::get_account_resource_or_default,
    get_with_proof::{RequestItem, ResponseItem},
    transaction::SignedTransaction,
    vm_error::VMStatus,
};
use scratchpad::SparseMerkleTree;
use std::sync::Arc;
use storage_client::{StorageRead, VerifiedStateView};
use vm_runtime::{LibraVM, VMVerifier};

#[cfg(test)]
#[path = "unit_tests/vm_validator_test.rs"]
mod vm_validator_test;

pub trait TransactionValidation: Send + Sync + Clone {
    type ValidationInstance: VMVerifier;
    /// Validate a txn from client
    fn validate_transaction(
        &self,
        _txn: SignedTransaction,
    ) -> Box<dyn Future<Item = Option<VMStatus>, Error = Error> + Send>;
}

#[derive(Clone)]
pub struct VMValidator {
    storage_read_client: Arc<dyn StorageRead>,
    vm: LibraVM,
}

impl VMValidator {
    pub fn new(config: &NodeConfig, storage_read_client: Arc<dyn StorageRead>) -> Self {
        VMValidator {
            storage_read_client,
            vm: LibraVM::new(&config.vm_config),
        }
    }
}

impl TransactionValidation for VMValidator {
    type ValidationInstance = LibraVM;

    fn validate_transaction(
        &self,
        txn: SignedTransaction,
    ) -> Box<dyn Future<Item = Option<VMStatus>, Error = Error> + Send> {
        // TODO: For transaction validation, there are two options to go:
        // 1. Trust storage: there is no need to get root hash from storage here. We will
        // create another struct similar to `VerifiedStateView` that implements `StateView`
        // but does not do verification.
        // 2. Don't trust storage. This requires more work:
        // 1) AC must have validator set information
        // 2) Get state_root from transaction info which can be verified with signatures of
        // validator set.
        // 3) Create VerifiedStateView with verified state
        // root.

        // Just ask something from storage. It doesn't matter what it is -- we just need the
        // transaction info object in account state proof which contains the state root hash.
        let address = AccountAddress::new([0xff; ADDRESS_LENGTH]);
        let item = RequestItem::GetAccountState { address };

        match self
            .storage_read_client
            .update_to_latest_ledger(/* client_known_version = */ 0, vec![item])
        {
            Ok((mut items, ledger_info_with_sigs, _, _)) => {
                if items.len() != 1 {
                    return Box::new(err(format_err!(
                        "Unexpected number of items ({}).",
                        items.len()
                    )));
                }

                match items.remove(0) {
                    ResponseItem::GetAccountState {
                        account_state_with_proof,
                    } => {
                        let transaction_info = account_state_with_proof.proof.transaction_info();
                        let state_root = transaction_info.state_root_hash();
                        let smt = SparseMerkleTree::new(state_root);
                        let state_view = VerifiedStateView::new(
                            Arc::clone(&self.storage_read_client),
                            Some(ledger_info_with_sigs.ledger_info().version()),
                            state_root,
                            &smt,
                        );
                        Box::new(ok(self.vm.validate_transaction(txn, &state_view)))
                    }
                    _ => panic!("Unexpected item in response."),
                }
            }
            Err(e) => Box::new(err(e)),
        }
    }
}

/// read account state
/// returns account's current sequence number and balance
pub async fn get_account_state(
    storage_read_client: Arc<dyn StorageRead>,
    address: AccountAddress,
) -> Result<(u64, u64)> {
    let req_item = RequestItem::GetAccountState { address };
    let (response_items, _, _, _) = storage_read_client
        .update_to_latest_ledger_async(0 /* client_known_version */, vec![req_item])
        .await?;
    let account_state = match &response_items[0] {
        ResponseItem::GetAccountState {
            account_state_with_proof,
        } => &account_state_with_proof.blob,
        _ => bail!("Not account state response."),
    };
    let account_resource = get_account_resource_or_default(account_state)?;
    let sequence_number = account_resource.sequence_number();
    let balance = account_resource.balance();
    Ok((sequence_number, balance))
}
<commit_msg>[VMValidator] Do not use update_to_latest_ledger to find latest state root hash<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use anyhow::{bail, Error, Result};
use futures::future::{err, ok, Future};
use libra_config::config::NodeConfig;
use libra_types::{
    account_address::AccountAddress,
    account_config::get_account_resource_or_default,
    get_with_proof::{RequestItem, ResponseItem},
    transaction::SignedTransaction,
    vm_error::VMStatus,
};
use scratchpad::SparseMerkleTree;
use std::sync::Arc;
use storage_client::{StorageRead, VerifiedStateView};
use vm_runtime::{LibraVM, VMVerifier};

#[cfg(test)]
#[path = "unit_tests/vm_validator_test.rs"]
mod vm_validator_test;

pub trait TransactionValidation: Send + Sync + Clone {
    type ValidationInstance: VMVerifier;
    /// Validate a txn from client
    fn validate_transaction(
        &self,
        _txn: SignedTransaction,
    ) -> Box<dyn Future<Item = Option<VMStatus>, Error = Error> + Send>;
}

#[derive(Clone)]
pub struct VMValidator {
    storage_read_client: Arc<dyn StorageRead>,
    vm: LibraVM,
}

impl VMValidator {
    pub fn new(config: &NodeConfig, storage_read_client: Arc<dyn StorageRead>) -> Self {
        VMValidator {
            storage_read_client,
            vm: LibraVM::new(&config.vm_config),
        }
    }
}

impl TransactionValidation for VMValidator {
    type ValidationInstance = LibraVM;

    fn validate_transaction(
        &self,
        txn: SignedTransaction,
    ) -> Box<dyn Future<Item = Option<VMStatus>, Error = Error> + Send> {
        match self.storage_read_client.get_latest_state_root() {
            Ok((version, state_root)) => {
                let smt = SparseMerkleTree::new(state_root);
                let state_view = VerifiedStateView::new(
                    Arc::clone(&self.storage_read_client),
                    Some(version),
                    state_root,
                    &smt,
                );
                Box::new(ok(self.vm.validate_transaction(txn, &state_view)))
            }
            Err(e) => Box::new(err(e)),
        }
    }
}

/// read account state
/// returns account's current sequence number and balance
pub async fn get_account_state(
    storage_read_client: Arc<dyn StorageRead>,
    address: AccountAddress,
) -> Result<(u64, u64)> {
    let req_item = RequestItem::GetAccountState { address };
    let (response_items, _, _, _) = storage_read_client
        .update_to_latest_ledger_async(0 /* client_known_version */, vec![req_item])
        .await?;
    let account_state = match &response_items[0] {
        ResponseItem::GetAccountState {
            account_state_with_proof,
        } => &account_state_with_proof.blob,
        _ => bail!("Not account state response."),
    };
    let account_resource = get_account_resource_or_default(account_state)?;
    let sequence_number = account_resource.sequence_number();
    let balance = account_resource.balance();
    Ok((sequence_number, balance))
}
<|endoftext|>


<commit_before>extern crate glsl_to_spirv;
extern crate proc_macro;
extern crate syn;
extern crate vulkano_shaders;

use std::path::Path;
use std::fs::File;
use std::io::Read;

use proc_macro::TokenStream;

enum SourceKind {
    Src(String),
    Path(String),
}

#[proc_macro_derive(VulkanoShader, attributes(src, path, ty))]
pub fn derive(input: TokenStream) -> TokenStream {
    let syn_item = syn::parse_macro_input(&input.to_string()).unwrap();

    let src = {
        let mut iter = syn_item.attrs.iter().filter_map(|attr| {
            match attr.value {
                syn::MetaItem::NameValue(ref i, syn::Lit::Str(ref val, _)) if i == "src" => {
                    Some(SourceKind::Src(val.clone()))
                },

                syn::MetaItem::NameValue(ref i, syn::Lit::Str(ref val, _)) if i == "path" => {
                    Some(SourceKind::Path(val.clone()))
                },

                _ => None
            }
        });

        let source = iter.next().expect("No source attribute given ; put #[src = \"...\"] or #[path = \"...\"]");

        if iter.next().is_some() {
            panic!("Multiple src or path attributes given ; please provide only one");
        }

        match source {
            SourceKind::Src(src) => src,

            SourceKind::Path(path) => {
                let root = std::env::var("CARGO_MANIFEST_DIR").unwrap_or(".".into());
                let path = Path::new(&root).join(&path);

                if path.is_file() {
                    let mut buf = String::new();
                    File::open(path).and_then(|mut file| file.read_to_string(&mut buf)).expect("Unable to read source from given file");
                    buf
                } else {
                    panic!("Given source file does not exist");
                }
            }
        }
    };

    let ty_str = syn_item.attrs.iter().filter_map(|attr| {
        match attr.value {
            syn::MetaItem::NameValue(ref i, syn::Lit::Str(ref val, _)) if i == "ty" => {
                Some(val.clone())
            },
            _ => None
        }
    }).next().expect("Can't find `ty` attribute ; put #[ty = \"vertex\"] for example.");

    let ty = match &ty_str[..] {
        "vertex" => glsl_to_spirv::ShaderType::Vertex,
        "fragment" => glsl_to_spirv::ShaderType::Fragment,
        "geometry" => glsl_to_spirv::ShaderType::Geometry,
        "tess_ctrl" => glsl_to_spirv::ShaderType::TessellationControl,
        "tess_eval" => glsl_to_spirv::ShaderType::TessellationEvaluation,
        "compute" => glsl_to_spirv::ShaderType::Compute,
        _ => panic!("Unexpected shader type ; valid values: vertex, fragment, geometry, tess_ctrl, tess_eval, compute")
    };

    let spirv_data = match glsl_to_spirv::compile(&src, ty) {
        Ok(compiled) => compiled,
        Err(message) => panic!("{}\nfailed to compile shader", message),
    };

    vulkano_shaders::reflect("Shader", spirv_data).unwrap().parse().unwrap()
}
<commit_msg>Added path to panic messages<commit_after>extern crate glsl_to_spirv;
extern crate proc_macro;
extern crate syn;
extern crate vulkano_shaders;

use std::path::Path;
use std::fs::File;
use std::io::Read;

use proc_macro::TokenStream;

enum SourceKind {
    Src(String),
    Path(String),
}

#[proc_macro_derive(VulkanoShader, attributes(src, path, ty))]
pub fn derive(input: TokenStream) -> TokenStream {
    let syn_item = syn::parse_macro_input(&input.to_string()).unwrap();

    let src = {
        let mut iter = syn_item.attrs.iter().filter_map(|attr| {
            match attr.value {
                syn::MetaItem::NameValue(ref i, syn::Lit::Str(ref val, _)) if i == "src" => {
                    Some(SourceKind::Src(val.clone()))
                },

                syn::MetaItem::NameValue(ref i, syn::Lit::Str(ref val, _)) if i == "path" => {
                    Some(SourceKind::Path(val.clone()))
                },

                _ => None
            }
        });

        let source = iter.next().expect("No source attribute given ; put #[src = \"...\"] or #[path = \"...\"]");

        if iter.next().is_some() {
            panic!("Multiple src or path attributes given ; please provide only one");
        }

        match source {
            SourceKind::Src(src) => src,

            SourceKind::Path(path) => {
                let root = std::env::var("CARGO_MANIFEST_DIR").unwrap_or(".".into());
                let full_path = Path::new(&root).join(&path);

                if full_path.is_file() {
                    let mut buf = String::new();
                    File::open(full_path)
                        .and_then(|mut file| file.read_to_string(&mut buf))
                        .expect(&format!("Error reading source from {:?}", path));
                    buf
                } else {
                    panic!("File {:?} was not found ; note that the path must be relative to your Cargo.toml", path);
                }
            }
        }
    };

    let ty_str = syn_item.attrs.iter().filter_map(|attr| {
        match attr.value {
            syn::MetaItem::NameValue(ref i, syn::Lit::Str(ref val, _)) if i == "ty" => {
                Some(val.clone())
            },
            _ => None
        }
    }).next().expect("Can't find `ty` attribute ; put #[ty = \"vertex\"] for example.");

    let ty = match &ty_str[..] {
        "vertex" => glsl_to_spirv::ShaderType::Vertex,
        "fragment" => glsl_to_spirv::ShaderType::Fragment,
        "geometry" => glsl_to_spirv::ShaderType::Geometry,
        "tess_ctrl" => glsl_to_spirv::ShaderType::TessellationControl,
        "tess_eval" => glsl_to_spirv::ShaderType::TessellationEvaluation,
        "compute" => glsl_to_spirv::ShaderType::Compute,
        _ => panic!("Unexpected shader type ; valid values: vertex, fragment, geometry, tess_ctrl, tess_eval, compute")
    };

    let spirv_data = match glsl_to_spirv::compile(&src, ty) {
        Ok(compiled) => compiled,
        Err(message) => panic!("{}\nfailed to compile shader", message),
    };

    vulkano_shaders::reflect("Shader", spirv_data).unwrap().parse().unwrap()
}
<|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(plugin)]
#![plugin(plugins)]

#![crate_name = "gfx_traits"]
#![crate_type = "rlib"]

#![deny(unsafe_code)]

extern crate heapsize;
#[macro_use] extern crate heapsize_derive;
#[macro_use]
extern crate range;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;

pub mod print_tree;

use range::RangeIndex;
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};

/// The next ID that will be used for a special stacking context.
///
/// A special stacking context is a stacking context that is one of (a) the outer stacking context
/// of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b).
static NEXT_SPECIAL_STACKING_CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

/// If none of the bits outside this mask are set, the stacking context is a special stacking
/// context.
///
/// Note that we assume that the top 16 bits of the address space are unused on the platform.
const SPECIAL_STACKING_CONTEXT_ID_MASK: usize = 0xffff;

// Units for use with euclid::length and euclid::scale_factor.

/// One hardware pixel.
///
/// This unit corresponds to the smallest addressable element of the display hardware.
#[derive(Copy, Clone, RustcEncodable, Debug)]
pub enum DevicePixel {}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LayerKind {
    NoTransform,
    HasTransform,
}

#[derive(Clone, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf)]
pub enum LayerType {
    /// A layer for the fragment body itself.
    FragmentBody,
    /// An extra layer created for a DOM fragments with overflow:scroll.
    OverflowScroll,
    /// A layer created to contain ::before pseudo-element content.
    BeforePseudoContent,
    /// A layer created to contain ::after pseudo-element content.
    AfterPseudoContent,
}

/// The scrolling policy of a layer.
#[derive(Clone, PartialEq, Eq, Copy, Deserialize, Serialize, Debug, HeapSizeOf)]
pub enum ScrollPolicy {
    /// These layers scroll when the parent receives a scrolling message.
    Scrollable,
    /// These layers do not scroll when the parent receives a scrolling message.
    FixedPosition,
}

/// A newtype struct for denoting the age of messages; prevents race conditions.
#[derive(PartialEq, Eq, Debug, Copy, Clone, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Epoch(pub u32);

impl Epoch {
    pub fn next(&mut self) {
        self.0 += 1;
    }
}

/// A unique ID for every stacking context.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
pub struct StackingContextId(
    /// The identifier for this StackingContext, derived from the Flow's memory address
    /// and fragment type.  As a space optimization, these are combined into a single word.
    usize
);

impl StackingContextId {
    #[inline]
    pub fn new(id: usize) -> StackingContextId {
        StackingContextId::new_of_type(id, FragmentType::FragmentBody)
    }

    /// Returns a new stacking context ID for a special stacking context.
    fn next_special_id() -> usize {
        // We shift this left by 2 to make room for the fragment type ID.
        ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) &
            SPECIAL_STACKING_CONTEXT_ID_MASK
    }

    #[inline]
    pub fn new_of_type(id: usize, fragment_type: FragmentType) -> StackingContextId {
        debug_assert_eq!(id & (fragment_type as usize), 0);
        if fragment_type == FragmentType::FragmentBody {
            StackingContextId(id)
        } else {
            StackingContextId(StackingContextId::next_special_id() | (fragment_type as usize))
        }
    }

    /// Returns the stacking context ID for the outer document/layout root.
    #[inline]
    pub fn root() -> StackingContextId {
        StackingContextId(0)
    }
}

/// A unique ID for every scrolling root.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
pub struct ScrollRootId(
    /// The identifier for this StackingContext, derived from the Flow's memory address
    /// and fragment type.  As a space optimization, these are combined into a single word.
    pub usize
);

impl ScrollRootId {
    /// Returns a new stacking context ID for a special stacking context.
    fn next_special_id() -> usize {
        // We shift this left by 2 to make room for the fragment type ID.
        ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) &
            SPECIAL_STACKING_CONTEXT_ID_MASK
    }

    #[inline]
    pub fn new_of_type(id: usize, fragment_type: FragmentType) -> ScrollRootId {
        debug_assert_eq!(id & (fragment_type as usize), 0);
        if fragment_type == FragmentType::FragmentBody {
            ScrollRootId(id)
        } else {
            ScrollRootId(ScrollRootId::next_special_id() | (fragment_type as usize))
        }
    }

    /// Returns the stacking context ID for the outer document/layout root.
    #[inline]
    pub fn root() -> ScrollRootId {
        ScrollRootId(0)
    }

    /// Returns true if this is a special stacking context.
    ///
    /// A special stacking context is a stacking context that is one of (a) the outer stacking
    /// context of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b).
    #[inline]
    pub fn is_special(&self) -> bool {
        (self.0 & !SPECIAL_STACKING_CONTEXT_ID_MASK) == 0
    }

    #[inline]
    pub fn id(&self) -> usize {
        self.0 & !3
    }

    #[inline]
    pub fn fragment_type(&self) -> FragmentType {
        FragmentType::from_usize(self.0 & 3)
    }
}

/// The type of fragment that a stacking context represents.
///
/// This can only ever grow to maximum 4 entries. That's because we cram the value of this enum
/// into the lower 2 bits of the `StackingContextId`, which otherwise contains a 32-bit-aligned
/// heap address.
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf)]
pub enum FragmentType {
    /// A StackingContext for the fragment body itself.
    FragmentBody,
    /// A StackingContext created to contain ::before pseudo-element content.
    BeforePseudoContent,
    /// A StackingContext created to contain ::after pseudo-element content.
    AfterPseudoContent,
}

impl FragmentType {
    #[inline]
    pub fn from_usize(n: usize) -> FragmentType {
        debug_assert!(n < 3);
        match n {
            0 => FragmentType::FragmentBody,
            1 => FragmentType::BeforePseudoContent,
            _ => FragmentType::AfterPseudoContent,
        }
    }
}

int_range_index! {
    #[derive(Deserialize, Serialize, RustcEncodable)]
    #[doc = "An index that refers to a byte offset in a text run. This could \
             point to the middle of a glyph."]
    #[derive(HeapSizeOf)]
    struct ByteIndex(isize)
}
<commit_msg>Remove unused LayerKind and LayerType enums.<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(plugin)]
#![plugin(plugins)]

#![crate_name = "gfx_traits"]
#![crate_type = "rlib"]

#![deny(unsafe_code)]

extern crate heapsize;
#[macro_use] extern crate heapsize_derive;
#[macro_use]
extern crate range;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;

pub mod print_tree;

use range::RangeIndex;
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};

/// The next ID that will be used for a special stacking context.
///
/// A special stacking context is a stacking context that is one of (a) the outer stacking context
/// of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b).
static NEXT_SPECIAL_STACKING_CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;

/// If none of the bits outside this mask are set, the stacking context is a special stacking
/// context.
///
/// Note that we assume that the top 16 bits of the address space are unused on the platform.
const SPECIAL_STACKING_CONTEXT_ID_MASK: usize = 0xffff;

// Units for use with euclid::length and euclid::scale_factor.

/// One hardware pixel.
///
/// This unit corresponds to the smallest addressable element of the display hardware.
#[derive(Copy, Clone, RustcEncodable, Debug)]
pub enum DevicePixel {}

/// The scrolling policy of a layer.
#[derive(Clone, PartialEq, Eq, Copy, Deserialize, Serialize, Debug, HeapSizeOf)]
pub enum ScrollPolicy {
    /// These layers scroll when the parent receives a scrolling message.
    Scrollable,
    /// These layers do not scroll when the parent receives a scrolling message.
    FixedPosition,
}

/// A newtype struct for denoting the age of messages; prevents race conditions.
#[derive(PartialEq, Eq, Debug, Copy, Clone, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Epoch(pub u32);

impl Epoch {
    pub fn next(&mut self) {
        self.0 += 1;
    }
}

/// A unique ID for every stacking context.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
pub struct StackingContextId(
    /// The identifier for this StackingContext, derived from the Flow's memory address
    /// and fragment type.  As a space optimization, these are combined into a single word.
    usize
);

impl StackingContextId {
    #[inline]
    pub fn new(id: usize) -> StackingContextId {
        StackingContextId::new_of_type(id, FragmentType::FragmentBody)
    }

    /// Returns a new stacking context ID for a special stacking context.
    fn next_special_id() -> usize {
        // We shift this left by 2 to make room for the fragment type ID.
        ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) &
            SPECIAL_STACKING_CONTEXT_ID_MASK
    }

    #[inline]
    pub fn new_of_type(id: usize, fragment_type: FragmentType) -> StackingContextId {
        debug_assert_eq!(id & (fragment_type as usize), 0);
        if fragment_type == FragmentType::FragmentBody {
            StackingContextId(id)
        } else {
            StackingContextId(StackingContextId::next_special_id() | (fragment_type as usize))
        }
    }

    /// Returns the stacking context ID for the outer document/layout root.
    #[inline]
    pub fn root() -> StackingContextId {
        StackingContextId(0)
    }
}

/// A unique ID for every scrolling root.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
pub struct ScrollRootId(
    /// The identifier for this StackingContext, derived from the Flow's memory address
    /// and fragment type.  As a space optimization, these are combined into a single word.
    pub usize
);

impl ScrollRootId {
    /// Returns a new stacking context ID for a special stacking context.
    fn next_special_id() -> usize {
        // We shift this left by 2 to make room for the fragment type ID.
        ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) &
            SPECIAL_STACKING_CONTEXT_ID_MASK
    }

    #[inline]
    pub fn new_of_type(id: usize, fragment_type: FragmentType) -> ScrollRootId {
        debug_assert_eq!(id & (fragment_type as usize), 0);
        if fragment_type == FragmentType::FragmentBody {
            ScrollRootId(id)
        } else {
            ScrollRootId(ScrollRootId::next_special_id() | (fragment_type as usize))
        }
    }

    /// Returns the stacking context ID for the outer document/layout root.
    #[inline]
    pub fn root() -> ScrollRootId {
        ScrollRootId(0)
    }

    /// Returns true if this is a special stacking context.
    ///
    /// A special stacking context is a stacking context that is one of (a) the outer stacking
    /// context of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b).
    #[inline]
    pub fn is_special(&self) -> bool {
        (self.0 & !SPECIAL_STACKING_CONTEXT_ID_MASK) == 0
    }

    #[inline]
    pub fn id(&self) -> usize {
        self.0 & !3
    }

    #[inline]
    pub fn fragment_type(&self) -> FragmentType {
        FragmentType::from_usize(self.0 & 3)
    }
}

/// The type of fragment that a stacking context represents.
///
/// This can only ever grow to maximum 4 entries. That's because we cram the value of this enum
/// into the lower 2 bits of the `StackingContextId`, which otherwise contains a 32-bit-aligned
/// heap address.
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Deserialize, Serialize, HeapSizeOf)]
pub enum FragmentType {
    /// A StackingContext for the fragment body itself.
    FragmentBody,
    /// A StackingContext created to contain ::before pseudo-element content.
    BeforePseudoContent,
    /// A StackingContext created to contain ::after pseudo-element content.
    AfterPseudoContent,
}

impl FragmentType {
    #[inline]
    pub fn from_usize(n: usize) -> FragmentType {
        debug_assert!(n < 3);
        match n {
            0 => FragmentType::FragmentBody,
            1 => FragmentType::BeforePseudoContent,
            _ => FragmentType::AfterPseudoContent,
        }
    }
}

int_range_index! {
    #[derive(Deserialize, Serialize, RustcEncodable)]
    #[doc = "An index that refers to a byte offset in a text run. This could \
             point to the middle of a glyph."]
    #[derive(HeapSizeOf)]
    struct ByteIndex(isize)
}
<|endoftext|>


<commit_before>// need to raise recursion limit because many combinators
#![recursion_limit = "128"]
#![deny(bare_trait_objects)]

use std::io::{BufReader, Write as _};
use std::path::PathBuf;

use structopt::StructOpt;

use futures::{future, stream, Stream};
use log::{error, info};

use gerritbot as bot;
use gerritbot_gerrit as gerrit;
use gerritbot_spark as spark;

#[derive(StructOpt, Debug)]
struct Args {
    /// Gerrit username
    #[structopt(short = "u")]
    username: String,
    /// Gerrit hostname
    hostname: String,
    /// Gerrit SSH port
    #[structopt(short = "p", default_value = "29418")]
    port: u32,
    /// Path to SSH private key
    #[structopt(short = "i", parse(from_os_str))]
    private_key_path: PathBuf,
    /// Enable verbose output
    #[structopt(short = "v")]
    verbose: bool,
    /// Gerrit user email address
    email: String,
    #[structopt(long = "format-script")]
    format_script: Option<String>,
}

#[derive(Clone)]
struct ConsoleSparkClient;

impl bot::SparkClient for ConsoleSparkClient {
    type ReplyFuture = future::FutureResult<(), spark::Error>;
    fn reply(&self, person_id: &spark::PersonId, msg: &str) -> Self::ReplyFuture {
        // Write synchronously and crash if writing fails. There's no point in
        // error handling here.
        write!(std::io::stdout(), "{}: {}\n", person_id, msg).expect("writing to stdout failed");
        future::ok(())
    }
}

fn main() {
    let args = Args::from_args();
    stderrlog::new()
        .module(module_path!())
        .module("gerritbot")
        .module("gerritbot_gerrit")
        .timestamp(stderrlog::Timestamp::Second)
        .verbosity(if args.verbose { 5 } else { 2 })
        .init()
        .unwrap();

    let connect_to_gerrit = || {
        info!(
            "Connecting to gerrit with username {} at {}:{}",
            args.username, args.hostname, args.port,
        );
        gerrit::Connection::connect(
            format!("{}:{}", args.hostname, args.port),
            args.username.clone(),
            args.private_key_path.clone(),
        )
        .unwrap_or_else(|e| {
            error!("failed to connect to gerrit: {}", e);
            std::process::exit(1);
        })
    };
    let gerrit_event_stream = gerrit::extended_event_stream(
        connect_to_gerrit(),
        connect_to_gerrit(),
        bot::request_extended_gerrit_info,
    );
    let gerrit_command_runner = gerrit::CommandRunner::new(connect_to_gerrit());
    let bot_builder = bot::Builder::new(bot::State::new());
    let bot_builder = {
        if let Some(format_script) = args.format_script {
            bot_builder
                .with_format_script(format_script)
                .unwrap_or_else(|err| {
                    error!("Failed to set format script: {:?}", err);
                    std::process::exit(1);
                })
        } else {
            bot_builder
        }
    };
    let email = args.email.clone();
    let stdin_lines = tokio::io::lines(BufReader::new(tokio::io::stdin()))
        .map_err(|e| error!("failed to read line from stdin: {}", e));
    let console_spark_messages = stream::once(Ok("enable\n".to_string()))
        .chain(stdin_lines)
        .filter_map(|line| Some(line).filter(|line| !line.is_empty()))
        .map(move |line| {
            spark::Message::test_message(
                spark::Email::new(email.clone()),
                spark::PersonId::new(email.clone()),
                line,
            )
        });

    let bot = bot_builder.build(gerrit_command_runner, ConsoleSparkClient);
    tokio::run(bot.run(gerrit_event_stream, console_spark_messages));
}
<commit_msg>fix gerritbot-console utility<commit_after>// need to raise recursion limit because many combinators
#![recursion_limit = "128"]
#![deny(bare_trait_objects)]

use std::io::{BufRead as _, BufReader, Write as _};
use std::path::PathBuf;

use structopt::StructOpt;

use futures::{future, stream, Future as _, Sink as _, Stream as _};
use log::{error, info};

use gerritbot as bot;
use gerritbot_gerrit as gerrit;
use gerritbot_spark as spark;

#[derive(StructOpt, Debug)]
struct Args {
    /// Gerrit username
    #[structopt(short = "u")]
    username: String,
    /// Gerrit hostname
    hostname: String,
    /// Gerrit SSH port
    #[structopt(short = "p", default_value = "29418")]
    port: u32,
    /// Path to SSH private key
    #[structopt(short = "i", parse(from_os_str))]
    private_key_path: PathBuf,
    /// Enable verbose output
    #[structopt(short = "v")]
    verbose: bool,
    /// Gerrit user email address
    email: String,
    #[structopt(long = "format-script")]
    format_script: Option<String>,
}

#[derive(Clone)]
struct ConsoleSparkClient;

impl bot::SparkClient for ConsoleSparkClient {
    type ReplyFuture = future::FutureResult<(), spark::Error>;
    fn reply(&self, person_id: &spark::PersonId, msg: &str) -> Self::ReplyFuture {
        // Write synchronously and crash if writing fails. There's no point in
        // error handling here.
        write!(std::io::stdout(), "{}: {}\n", person_id, msg).expect("writing to stdout failed");
        future::ok(())
    }
}

fn main() {
    let args = Args::from_args();
    stderrlog::new()
        .module(module_path!())
        .module("gerritbot")
        .module("gerritbot_gerrit")
        .timestamp(stderrlog::Timestamp::Second)
        .verbosity(if args.verbose { 5 } else { 2 })
        .init()
        .unwrap();

    let connect_to_gerrit = || {
        info!(
            "Connecting to gerrit with username {} at {}:{}",
            args.username, args.hostname, args.port,
        );
        gerrit::Connection::connect(
            format!("{}:{}", args.hostname, args.port),
            args.username.clone(),
            args.private_key_path.clone(),
        )
        .unwrap_or_else(|e| {
            error!("failed to connect to gerrit: {}", e);
            std::process::exit(1);
        })
    };
    let gerrit_event_stream = gerrit::extended_event_stream(
        connect_to_gerrit(),
        connect_to_gerrit(),
        bot::request_extended_gerrit_info,
    );
    let gerrit_command_runner = gerrit::CommandRunner::new(connect_to_gerrit());
    let bot_builder = bot::Builder::new(bot::State::new());
    let bot_builder = {
        if let Some(format_script) = args.format_script {
            bot_builder
                .with_format_script(format_script)
                .unwrap_or_else(|err| {
                    error!("Failed to set format script: {:?}", err);
                    std::process::exit(1);
                })
        } else {
            bot_builder
        }
    };
    let email = args.email.clone();
    let (stdin_lines_sender, stdin_lines) = futures::sync::mpsc::channel::<String>(1);
    std::thread::spawn(move || {
        stream::iter_ok::<_, ()>(
            BufReader::new(std::io::stdin())
                .lines()
                .filter_map(Result::ok),
        )
        .forward(stdin_lines_sender.sink_map_err(|e| error!("sink error: {}", e)))
        .wait()
    });
    let console_spark_messages = stream::once(Ok("enable\n".to_string()))
        .chain(stdin_lines)
        .filter_map(|line| Some(line).filter(|line| !line.is_empty()))
        .map(move |line| {
            spark::Message::test_message(
                spark::Email::new(email.clone()),
                spark::PersonId::new(email.clone()),
                line,
            )
        });

    let bot = bot_builder.build(gerrit_command_runner, ConsoleSparkClient);
    tokio::run(bot.run(gerrit_event_stream, console_spark_messages));
}
<|endoftext|>


<commit_before>use std::i32;
use std::iter::repeat;
use std::cmp::max;
use std::collections::Bitv;

use alignment::{Alignment, AlignmentOperation};

#[derive(Copy)]
enum AlignmentType {
    Global,
    Semiglobal,
    Local
}

/// Calculate alignments with a generalized variant of the Smith Waterman algorithm.
/// Complexity: O(n * m) for strings of length m and n.
///
/// # Example
///
/// ```
/// use bio::alignment::pairwise::Aligner;
/// use bio::alignment::AlignmentOperation::{Match, Subst, Ins, Del};
/// let x = b"ACCGTGGAT";
/// let y = b"AAAAACCGTTGAT";
/// let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
/// let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
/// let alignment = aligner.semiglobal(x, y);
/// assert_eq!(alignment.i, 4);
/// assert_eq!(alignment.j, 0);
/// assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
/// ```
#[allow(non_snake_case)]
pub struct Aligner<F> where F: Fn(u8, u8) -> i32 {
    S: [Vec<i32>; 2],
    I: [Vec<i32>; 2],
    D: [Vec<i32>; 2],
    traceback: Traceback,
    gap_open: i32,
    gap_extend: i32,
    score: F
}

impl<F> Aligner<F> where F: Fn(u8, u8) -> i32 {
    /// Create new aligner instance. The size hints help to
    /// avoid unnecessary memory allocations.
    ///
    /// # Arguments
    ///
    /// * `m` - the expected size of x
    /// * `n` - the expected size of y
    /// * `gap_open` - the score for opening a gap (should be negative)
    /// * `gap_extend` - the score for extending a gap (should be negative)
    /// * `score` - function that returns the score for substitutions
    ///
    pub fn with_capacity(m: usize, n: usize, gap_open: i32, gap_extend: i32, score: F) -> Self {
        let get_vec = |&:| Vec::with_capacity(m + 1);
        Aligner {
            S: [get_vec(), get_vec()],
            I: [get_vec(), get_vec()],
            D: [get_vec(), get_vec()],
            traceback: Traceback::with_capacity(m, n),
            gap_open: gap_open,
            gap_extend: gap_extend,
            score: score
        }
    }

    fn init(&mut self, m: usize, alignment_type: AlignmentType) {
        // set minimum score to -inf, and allow to add gap_extend
        // without overflow
        let min_score = i32::MIN - self.gap_extend;
        for k in 0..2us {
            self.S[k].clear();
            self.I[k].clear();
            self.D[k].clear();
            self.I[k].extend(repeat(min_score).take(m + 1));
            self.D[k].extend(repeat(min_score).take(m + 1));
            match alignment_type {
                AlignmentType::Global => {
                    let ref mut s = self.S[k];
                    let mut score = self.gap_open;
                    for _ in 0..m+1 {
                        s.push(score);
                        score += self.gap_extend;
                    }
                },
                _ => self.S[k].extend(repeat(0).take(m + 1))
            }
        }
    }

    /// Calculate global alignment.
    pub fn global(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Global)
    }

    /// Calculate semiglobal alignment.
    pub fn semiglobal(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Semiglobal)
    }

    /// Calculate local alignment.
    pub fn local(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Local)
    }

    fn align(&mut self, x: &[u8], y: &[u8], alignment_type: AlignmentType) -> Alignment {
        let (m, n) = (x.len(), y.len());

        self.init(m, alignment_type);
        self.traceback.init(n, alignment_type);

        let (mut best, mut best_i, mut best_j) = (0, 0, 0);
        let mut col = 0;

        for i in 1..n+1 {
            col = i % 2;
            let prev = 1 - col;

            match alignment_type {
                AlignmentType::Global => {
                    self.S[col][0] = self.gap_open + (i as i32 - 1) * self.gap_extend;
                    self.traceback.del(i, 0);
                },
                _ => {
                    // with local and semiglobal, allow to begin anywhere in y
                    self.S[col][0] = 0;
                }
            }

            let b = y[i - 1];
            let mut score = 0i32;
            for j in 1..m+1 {
                let a = x[j - 1];

                let d_score = max(
                    self.S[prev][j] + self.gap_open,
                    self.D[prev][j] + self.gap_extend
                );
                let i_score = max(
                    self.S[col][j-1] + self.gap_open,
                    self.I[col][j-1] + self.gap_extend
                );
                score = self.S[prev][j-1] + (self.score)(a, b);

                if d_score > score {
                    score = d_score;
                    self.traceback.del(i, j);
                }
                else if i_score > score {
                    score = i_score;
                    self.traceback.ins(i, j);
                }
                else {
                    self.traceback.subst(i, j);
                }

                match alignment_type {
                    AlignmentType::Local => {
                        if score < 0 {
                            self.traceback.start(i, j);
                            score = 0;
                        }
                        else if score > best {
                            best = score;
                            best_i = i;
                            best_j = j;
                        }
                    },
                    _ => ()
                }

                self.S[col][j] = score;
                self.D[col][j] = d_score;
                self.I[col][j] = i_score;
            }

            match alignment_type {
                AlignmentType::Semiglobal => {
                    if score > best {
                        best = score;
                        best_i = i;
                        best_j = m;
                    }
                },
                _ => ()
            }
        }
        match alignment_type {
            AlignmentType::Global => {
                let score = self.S[col][m];
                self.traceback.get_alignment(n, m, x, y, score)
            },
            _ => self.traceback.get_alignment(best_i, best_j, x, y, best)
        }

    }
}

struct Traceback {
    subst: Vec<Bitv>,
    del: Vec<Bitv>,
    ins: Vec<Bitv>
}

impl Traceback {
    fn with_capacity(m: usize, n: usize) -> Self {
        let get_vec = |&:| repeat(Bitv::from_elem(m + 1, false)).take(n + 1).collect::<Vec<Bitv>>();
        Traceback {
            subst: get_vec(),
            del: get_vec(),
            ins: get_vec()
        }
    }

    fn init(&mut self, n: usize, alignment_type: AlignmentType) {
        match alignment_type {
            AlignmentType::Global => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
                // set the first cell to start, the rest to deletions
                self.del[0].set(0, false);
            },
            _ => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.del[i].negate();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
            }
        }
    }

    fn start(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, false);
        self.del[i].set(j, false);
        self.ins[i].set(j, false);
    }

    fn subst(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, true);
    }

    fn del(&mut self, i: usize, j: usize) {
        self.del[i].set(j, true);
    }

    fn ins(&mut self, i: usize, j: usize) {
        self.ins[i].set(j, true);
    }

    fn is_subst(&self, i: usize, j: usize) -> bool {
        self.subst[i].get(j).unwrap()
    }

    fn is_del(&self, i: usize, j: usize) -> bool {
        self.del[i].get(j).unwrap()
    }

    fn is_ins(&self, i: usize, j: usize) -> bool {
        self.ins[i].get(j).unwrap()
    }

    fn get_alignment(&self, mut i: usize, mut j: usize, x: &[u8], y: &[u8], score: i32) -> Alignment {
        let mut ops = Vec::with_capacity(x.len());

        loop {
            let (ii, jj, op) = if self.is_subst(i, j) {
                let op = if y[i-1] == x[j-1] {
                    AlignmentOperation::Match
                }
                else {
                    AlignmentOperation::Subst
                };
                (i - 1, j - 1, op)
            }
            else if self.is_del(i, j) {
                (i - 1, j, AlignmentOperation::Del)
            }
            else if self.is_ins(i, j) {
                (i, j - 1, AlignmentOperation::Ins)
            } else {
                // reached alignment start
                break;
            };
            ops.push(op);
            i = ii;
            j = jj;
        }

        ops.reverse();
        Alignment { i: i, j: j, operations: ops, score: score}
    }
}

#[cfg(test)]
mod tests {
    use super::Aligner;
    use alignment::AlignmentOperation::{Match, Subst, Del};

    #[test]
    fn test_semiglobal() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.semiglobal(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_local() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.local(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_global() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.global(x, y);
        assert_eq!(alignment.i, 0);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Del, Del, Del, Del, Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }
}
<commit_msg>Docs.<commit_after>use std::i32;
use std::iter::repeat;
use std::cmp::max;
use std::collections::Bitv;

use alignment::{Alignment, AlignmentOperation};

#[derive(Copy)]
enum AlignmentType {
    Global,
    Semiglobal,
    Local
}

/// Calculate alignments with a generalized variant of the Smith Waterman algorithm.
/// Complexity: O(n * m) for strings of length m and n.
///
/// # Example
///
/// ```
/// use bio::alignment::pairwise::Aligner;
/// use bio::alignment::AlignmentOperation::{Match, Subst, Ins, Del};
/// let x = b"ACCGTGGAT";
/// let y = b"AAAAACCGTTGAT";
/// let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
/// let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
/// let alignment = aligner.semiglobal(x, y);
/// assert_eq!(alignment.i, 4);
/// assert_eq!(alignment.j, 0);
/// assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
/// ```
#[allow(non_snake_case)]
pub struct Aligner<F> where F: Fn(u8, u8) -> i32 {
    S: [Vec<i32>; 2],
    I: [Vec<i32>; 2],
    D: [Vec<i32>; 2],
    traceback: Traceback,
    gap_open: i32,
    gap_extend: i32,
    score: F
}

impl<F> Aligner<F> where F: Fn(u8, u8) -> i32 {
    /// Create new aligner instance. The size hints help to
    /// avoid unnecessary memory allocations.
    ///
    /// # Arguments
    ///
    /// * `m` - the expected size of x
    /// * `n` - the expected size of y
    /// * `gap_open` - the score for opening a gap (should be negative)
    /// * `gap_extend` - the score for extending a gap (should be negative)
    /// * `score` - function that returns the score for substitutions
    ///
    pub fn with_capacity(m: usize, n: usize, gap_open: i32, gap_extend: i32, score: F) -> Self {
        let get_vec = |&:| Vec::with_capacity(m + 1);
        Aligner {
            S: [get_vec(), get_vec()],
            I: [get_vec(), get_vec()],
            D: [get_vec(), get_vec()],
            traceback: Traceback::with_capacity(m, n),
            gap_open: gap_open,
            gap_extend: gap_extend,
            score: score
        }
    }

    fn init(&mut self, m: usize, alignment_type: AlignmentType) {
        // set minimum score to -inf, and allow to add gap_extend
        // without overflow
        let min_score = i32::MIN - self.gap_extend;
        for k in 0..2us {
            self.S[k].clear();
            self.I[k].clear();
            self.D[k].clear();
            self.I[k].extend(repeat(min_score).take(m + 1));
            self.D[k].extend(repeat(min_score).take(m + 1));
            match alignment_type {
                AlignmentType::Global => {
                    let ref mut s = self.S[k];
                    let mut score = self.gap_open;
                    for _ in 0..m+1 {
                        s.push(score);
                        score += self.gap_extend;
                    }
                },
                _ => self.S[k].extend(repeat(0).take(m + 1))
            }
        }
    }

    /// Calculate global alignment.
    pub fn global(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Global)
    }

    /// Calculate semiglobal alignment.
    pub fn semiglobal(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Semiglobal)
    }

    /// Calculate local alignment.
    pub fn local(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Local)
    }

    fn align(&mut self, x: &[u8], y: &[u8], alignment_type: AlignmentType) -> Alignment {
        let (m, n) = (x.len(), y.len());

        self.init(m, alignment_type);
        self.traceback.init(n, alignment_type);

        let (mut best, mut best_i, mut best_j) = (0, 0, 0);
        let mut col = 0;

        for i in 1..n+1 {
            col = i % 2;
            let prev = 1 - col;

            match alignment_type {
                AlignmentType::Global => {
                    self.S[col][0] = self.gap_open + (i as i32 - 1) * self.gap_extend;
                    self.traceback.del(i, 0);
                },
                _ => {
                    // with local and semiglobal, allow to begin anywhere in y
                    self.S[col][0] = 0;
                }
            }

            let b = y[i - 1];
            let mut score = 0i32;
            for j in 1..m+1 {
                let a = x[j - 1];

                // score for deletion
                let d_score = max(
                    self.S[prev][j] + self.gap_open,
                    self.D[prev][j] + self.gap_extend
                );
                // score for insertion
                let i_score = max(
                    self.S[col][j-1] + self.gap_open,
                    self.I[col][j-1] + self.gap_extend
                );
                // score for substitution
                score = self.S[prev][j-1] + (self.score)(a, b);

                if d_score > score {
                    score = d_score;
                    self.traceback.del(i, j);
                }
                else if i_score > score {
                    score = i_score;
                    self.traceback.ins(i, j);
                }
                else {
                    self.traceback.subst(i, j);
                }

                match alignment_type {
                    AlignmentType::Local => {
                        if score < 0 {
                            self.traceback.start(i, j);
                            score = 0;
                        }
                        else if score > best {
                            best = score;
                            best_i = i;
                            best_j = j;
                        }
                    },
                    _ => ()
                }

                self.S[col][j] = score;
                self.D[col][j] = d_score;
                self.I[col][j] = i_score;
            }

            match alignment_type {
                AlignmentType::Semiglobal => {
                    if score > best {
                        best = score;
                        best_i = i;
                        best_j = m;
                    }
                },
                _ => ()
            }
        }
        match alignment_type {
            AlignmentType::Global => {
                let score = self.S[col][m];
                self.traceback.get_alignment(n, m, x, y, score)
            },
            _ => self.traceback.get_alignment(best_i, best_j, x, y, best)
        }

    }
}

struct Traceback {
    subst: Vec<Bitv>,
    del: Vec<Bitv>,
    ins: Vec<Bitv>
}

impl Traceback {
    fn with_capacity(m: usize, n: usize) -> Self {
        let get_vec = |&:| repeat(Bitv::from_elem(m + 1, false)).take(n + 1).collect::<Vec<Bitv>>();
        Traceback {
            subst: get_vec(),
            del: get_vec(),
            ins: get_vec()
        }
    }

    fn init(&mut self, n: usize, alignment_type: AlignmentType) {
        match alignment_type {
            AlignmentType::Global => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
                // set the first cell to start, the rest to deletions
                self.del[0].set(0, false);
            },
            _ => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.del[i].negate();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
            }
        }
    }

    fn start(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, false);
        self.del[i].set(j, false);
        self.ins[i].set(j, false);
    }

    fn subst(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, true);
    }

    fn del(&mut self, i: usize, j: usize) {
        self.del[i].set(j, true);
    }

    fn ins(&mut self, i: usize, j: usize) {
        self.ins[i].set(j, true);
    }

    fn is_subst(&self, i: usize, j: usize) -> bool {
        self.subst[i].get(j).unwrap()
    }

    fn is_del(&self, i: usize, j: usize) -> bool {
        self.del[i].get(j).unwrap()
    }

    fn is_ins(&self, i: usize, j: usize) -> bool {
        self.ins[i].get(j).unwrap()
    }

    fn get_alignment(&self, mut i: usize, mut j: usize, x: &[u8], y: &[u8], score: i32) -> Alignment {
        let mut ops = Vec::with_capacity(x.len());

        loop {
            let (ii, jj, op) = if self.is_subst(i, j) {
                let op = if y[i-1] == x[j-1] {
                    AlignmentOperation::Match
                }
                else {
                    AlignmentOperation::Subst
                };
                (i - 1, j - 1, op)
            }
            else if self.is_del(i, j) {
                (i - 1, j, AlignmentOperation::Del)
            }
            else if self.is_ins(i, j) {
                (i, j - 1, AlignmentOperation::Ins)
            } else {
                // reached alignment start
                break;
            };
            ops.push(op);
            i = ii;
            j = jj;
        }

        ops.reverse();
        Alignment { i: i, j: j, operations: ops, score: score}
    }
}

#[cfg(test)]
mod tests {
    use super::Aligner;
    use alignment::AlignmentOperation::{Match, Subst, Del};

    #[test]
    fn test_semiglobal() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.semiglobal(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_local() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.local(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_global() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.global(x, y);
        assert_eq!(alignment.i, 0);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Del, Del, Del, Del, Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }
}
<|endoftext|>


<commit_before>//! AwesomeWM Keygrabber interface

use ::lua::LUA;
use rlua::{self, Lua, Table, Function, Value};
use rustwlc::*;
#[allow(deprecated)]
use rustwlc::xkb::Keysym;

pub const KEYGRABBER_TABLE: &str = "keygrabber";
const SECRET_CALLBACK: &str = "__callback";

/// Init the methods defined on this interface.
pub fn init(lua: &Lua) -> rlua::Result<()> {
    let keygrabber_table = lua.create_table();
    keygrabber_table.set("run", lua.create_function(run))?;
    keygrabber_table.set("stop", lua.create_function(stop))?;
    keygrabber_table.set("isrunning", lua.create_function(isrunning))?;
    let globals = lua.globals();
    globals.set(KEYGRABBER_TABLE, keygrabber_table)
}

#[allow(deprecated)]
/// Given the current input, handle calling the Lua defined callback if it is
/// defined with the input.
pub fn keygrabber_handle(mods: KeyboardModifiers, sym: Keysym, state: KeyState)
                         -> rlua::Result<()> {
    let lua = LUA.lock().expect("LUA was poisoned");
    let lua_state = if state == KeyState::Pressed {
        "press"
    } else {
        "release"
    }.into();
    let lua_sym = sym.get_name().expect("Key symbol did not have a defined name");
    let lua_mods = ::lua::mods_to_lua(&lua.0, mods.mods)
        .expect("Could not convert mods to lua representation");
    let res = call_keygrabber(&lua.0, (lua_mods, lua_sym, lua_state));
    match res {
        Ok(_) | Err(rlua::Error::FromLuaConversionError { .. }) => {Ok(())},
        err => {
            err
        }
    }

}

/// Call the Lua callback function for when a key is pressed.
fn call_keygrabber(lua: &Lua,
                   (mods, key, event): (Table, String, String))
                   -> rlua::Result<()> {
    let globals = lua.globals();
    let lua_callback = globals
        .get::<_, Table>(KEYGRABBER_TABLE).expect("keygrabber table not defined")
        .get::<_, Function>(SECRET_CALLBACK)?;
    lua_callback.call((mods, key, event))
}

fn run(lua: &Lua, function: rlua::Function) -> rlua::Result<()> {
    let keygrabber_table = lua.globals().get::<_, Table>(KEYGRABBER_TABLE)?;
    match keygrabber_table.get::<_, Value>(SECRET_CALLBACK)? {
        Value::Function(_) =>
            Err(rlua::Error::RuntimeError("keygrabber callback already set!"
                                          .into())),
        _ => keygrabber_table.set(SECRET_CALLBACK, function)
    }
}

fn stop(lua: &Lua, _: ()) -> rlua::Result<()> {
    let keygrabber_table = lua.globals().get::<_, Table>(KEYGRABBER_TABLE)?;
    keygrabber_table.set(SECRET_CALLBACK, Value::Nil)
}

fn isrunning(lua: &Lua, _: ()) -> rlua::Result<bool> {
    let keygrabber_table = lua.globals().get::<_, Table>(KEYGRABBER_TABLE)?;
    match keygrabber_table.get::<_, Value>(SECRET_CALLBACK)? {
        Value::Function(_) => Ok(true),
        _ => Ok(false)
    }
}
<commit_msg>keygrabber_handler cannot panic now<commit_after>//! AwesomeWM Keygrabber interface

use ::lua::LUA;
use rlua::{self, Lua, Table, Function, Value};
use rustwlc::*;
#[allow(deprecated)]
use rustwlc::xkb::Keysym;

pub const KEYGRABBER_TABLE: &str = "keygrabber";
const SECRET_CALLBACK: &str = "__callback";

/// Init the methods defined on this interface.
pub fn init(lua: &Lua) -> rlua::Result<()> {
    let keygrabber_table = lua.create_table();
    keygrabber_table.set("run", lua.create_function(run))?;
    keygrabber_table.set("stop", lua.create_function(stop))?;
    keygrabber_table.set("isrunning", lua.create_function(isrunning))?;
    let globals = lua.globals();
    globals.set(KEYGRABBER_TABLE, keygrabber_table)
}

#[allow(deprecated)]
/// Given the current input, handle calling the Lua defined callback if it is
/// defined with the input.
pub fn keygrabber_handle(mods: KeyboardModifiers, sym: Keysym, state: KeyState)
                         -> rlua::Result<()> {
    let lua = LUA.lock()
        .map_err(|err| rlua::Error::RuntimeError(
            format!("Lua lock was poisoned {:#?}", err)))?;
    let lua_state = if state == KeyState::Pressed {
        "press"
    } else {
        "release"
    }.into();
    let lua_sym = sym.get_name()
        .ok_or_else(|| rlua::Error::RuntimeError(
                 format!("Symbol did not have a name: {:#?}", sym)))?;
    let lua_mods = ::lua::mods_to_lua(&lua.0, mods.mods)?;
    let res = call_keygrabber(&lua.0, (lua_mods, lua_sym, lua_state));
    match res {
        Ok(_) | Err(rlua::Error::FromLuaConversionError { .. }) => {Ok(())},
        err => {
            err
        }
    }

}

/// Call the Lua callback function for when a key is pressed.
fn call_keygrabber(lua: &Lua,
                   (mods, key, event): (Table, String, String))
                   -> rlua::Result<()> {
    let globals = lua.globals();
    let lua_callback = globals
        .get::<_, Table>(KEYGRABBER_TABLE).expect("keygrabber table not defined")
        .get::<_, Function>(SECRET_CALLBACK)?;
    lua_callback.call((mods, key, event))
}

fn run(lua: &Lua, function: rlua::Function) -> rlua::Result<()> {
    let keygrabber_table = lua.globals().get::<_, Table>(KEYGRABBER_TABLE)?;
    match keygrabber_table.get::<_, Value>(SECRET_CALLBACK)? {
        Value::Function(_) =>
            Err(rlua::Error::RuntimeError("keygrabber callback already set!"
                                          .into())),
        _ => keygrabber_table.set(SECRET_CALLBACK, function)
    }
}

fn stop(lua: &Lua, _: ()) -> rlua::Result<()> {
    let keygrabber_table = lua.globals().get::<_, Table>(KEYGRABBER_TABLE)?;
    keygrabber_table.set(SECRET_CALLBACK, Value::Nil)
}

fn isrunning(lua: &Lua, _: ()) -> rlua::Result<bool> {
    let keygrabber_table = lua.globals().get::<_, Table>(KEYGRABBER_TABLE)?;
    match keygrabber_table.get::<_, Value>(SECRET_CALLBACK)? {
        Value::Function(_) => Ok(true),
        _ => Ok(false)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! rustbuild, the Rust build system
//!
//! This is the entry point for the build system used to compile the `rustc`
//! compiler. Lots of documentation can be found in the `README.md` file next to
//! this file, and otherwise documentation can be found throughout the `build`
//! directory in each respective module.

#![deny(warnings)]

extern crate bootstrap;

use std::env;

use bootstrap::{Flags, Config, Build};

fn main() {
    let args = env::args().skip(1).collect::<Vec<_>>();
    let flags = Flags::parse(&args);
    let mut config = Config::parse(&flags.build, flags.config.clone());

    // compat with `./configure` while we're still using that
    if std::fs::metadata("config.mk").is_ok() {
        config.update_with_config_mk();
    }

    Build::new(flags, config).build();
}
<commit_msg>Rollup merge of #39527 - king6cong:bootstrap-doc, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! rustbuild, the Rust build system
//!
//! This is the entry point for the build system used to compile the `rustc`
//! compiler. Lots of documentation can be found in the `README.md` file in the
//! parent directory, and otherwise documentation can be found throughout the `build`
//! directory in each respective module.

#![deny(warnings)]

extern crate bootstrap;

use std::env;

use bootstrap::{Flags, Config, Build};

fn main() {
    let args = env::args().skip(1).collect::<Vec<_>>();
    let flags = Flags::parse(&args);
    let mut config = Config::parse(&flags.build, flags.config.clone());

    // compat with `./configure` while we're still using that
    if std::fs::metadata("config.mk").is_ok() {
        config.update_with_config_mk();
    }

    Build::new(flags, config).build();
}
<|endoftext|>


<commit_before>use std::io;
use std::io::{Read, Write};
use std::sync::mpsc::{Receiver, RecvError, Sender, SyncSender, SendError};

use super::{ConduitM, produce, consume, defer, leftover, Flush};

fn read<R: Read>(r: &mut R, z: usize) -> io::Result<Vec<u8>> {
    let mut v = Vec::with_capacity(z);
    unsafe { v.set_len(z); }
    match r.read(&mut v) {
        Err(e) => Err(e),
        Ok(n) => {
            unsafe { v.set_len(n); }
            Ok(v)
        }
    }
}

/// A conduit that produces bytes it reads from the given `Read`.
pub fn reader<'a, R: 'a + Read>(mut r: R, z: usize) -> ConduitM<'a, (), Vec<u8>, io::Result<()>> {
    defer().and_then(move |_| {
        match read(&mut r, z) {
            Err(e) => Err(e).into(),
            Ok(v) => {
                if v.len() == 0 {
                    Ok(()).into()
                } else {
                    produce(v).and_then(move |_| reader(r, z))
                }
            }
        }
    })
}

/// A conduit that consumes bytes and writes them to the given `Write`.
pub fn writer<'a, W: 'a + Write>(mut w: W) -> ConduitM<'a, Vec<u8>, (), io::Result<()>> {
    consume().and_then(|vo: Option<Vec<u8>>| {
        match vo {
            None => Ok(()).into(),
            Some(v) => match w.write_all(&v) {
                Err(e) => Err(e).into(),
                Ok(_) => writer(w)
            }
        }
    })
}

fn write_flush<W: Write>(w: &mut W, f: Flush<Vec<u8>>) -> io::Result<()> {
    match f {
        Flush::Chunk(v) => w.write_all(&v),
        Flush::Flush => w.flush()
    }
}

/// A conduit that consumes bytes and writes them to the given `Write`,
/// while also providing flushing capabilities.
pub fn writer_flush<'a, W: 'a + Write>(mut w: W) -> ConduitM<'a, Flush<Vec<u8>>, (), io::Result<()>> {
    consume().and_then(|fo| {
        match fo {
            None => Ok(()).into(),
            Some(f) => match write_flush(&mut w, f) {
                Err(e) => Err(e).into(),
                Ok(_) => writer_flush(w)
            }
        }
    })
}

pub fn receiver<'a, T: 'a>(r: Receiver<T>) -> ConduitM<'a, (), T, ()> {
    defer().and_then(|_| {
        match r.recv() {
            Err(RecvError) => ().into(),
            Ok(x) => produce(x).and(receiver(r))
        }
    })
}

pub fn sender<'a, T: 'a>(s: Sender<T>) -> ConduitM<'a, T, (), ()> {
    consume().and_then(|xo| {
        match xo {
            None => ().into(),
            Some(x) => match s.send(x) {
                Err(SendError(x)) => leftover(x),
                Ok(_) => sender(s)
            }
        }
    })
}

pub fn sync_sender<'a, T: 'a>(s: SyncSender<T>) -> ConduitM<'a, T, (), ()> {
    consume().and_then(|xo| {
        match xo {
            None => ().into(),
            Some(x) => match s.send(x) {
                Err(SendError(x)) => leftover(x),
                Ok(_) => sync_sender(s)
            }
        }
    })
}
<commit_msg>add doco for receiver/sender/sync_sender<commit_after>use std::io;
use std::io::{Read, Write};
use std::sync::mpsc::{Receiver, RecvError, Sender, SyncSender, SendError};

use super::{ConduitM, produce, consume, defer, leftover, Flush};

fn read<R: Read>(r: &mut R, z: usize) -> io::Result<Vec<u8>> {
    let mut v = Vec::with_capacity(z);
    unsafe { v.set_len(z); }
    match r.read(&mut v) {
        Err(e) => Err(e),
        Ok(n) => {
            unsafe { v.set_len(n); }
            Ok(v)
        }
    }
}

/// A conduit that produces bytes it reads from the given `Read`.
pub fn reader<'a, R: 'a + Read>(mut r: R, z: usize) -> ConduitM<'a, (), Vec<u8>, io::Result<()>> {
    defer().and_then(move |_| {
        match read(&mut r, z) {
            Err(e) => Err(e).into(),
            Ok(v) => {
                if v.len() == 0 {
                    Ok(()).into()
                } else {
                    produce(v).and_then(move |_| reader(r, z))
                }
            }
        }
    })
}

/// A conduit that consumes bytes and writes them to the given `Write`.
pub fn writer<'a, W: 'a + Write>(mut w: W) -> ConduitM<'a, Vec<u8>, (), io::Result<()>> {
    consume().and_then(|vo: Option<Vec<u8>>| {
        match vo {
            None => Ok(()).into(),
            Some(v) => match w.write_all(&v) {
                Err(e) => Err(e).into(),
                Ok(_) => writer(w)
            }
        }
    })
}

fn write_flush<W: Write>(w: &mut W, f: Flush<Vec<u8>>) -> io::Result<()> {
    match f {
        Flush::Chunk(v) => w.write_all(&v),
        Flush::Flush => w.flush()
    }
}

/// A conduit that consumes bytes and writes them to the given `Write`,
/// while also providing flushing capabilities.
pub fn writer_flush<'a, W: 'a + Write>(mut w: W) -> ConduitM<'a, Flush<Vec<u8>>, (), io::Result<()>> {
    consume().and_then(|fo| {
        match fo {
            None => Ok(()).into(),
            Some(f) => match write_flush(&mut w, f) {
                Err(e) => Err(e).into(),
                Ok(_) => writer_flush(w)
            }
        }
    })
}

/// A conduit that produces values it receives from the given `Receiver`.
pub fn receiver<'a, T: 'a>(r: Receiver<T>) -> ConduitM<'a, (), T, ()> {
    defer().and_then(|_| {
        match r.recv() {
            Err(RecvError) => ().into(),
            Ok(x) => produce(x).and(receiver(r))
        }
    })
}

/// A conduit that consumes values and writes them to the given `Sender`.
pub fn sender<'a, T: 'a>(s: Sender<T>) -> ConduitM<'a, T, (), ()> {
    consume().and_then(|xo| {
        match xo {
            None => ().into(),
            Some(x) => match s.send(x) {
                Err(SendError(x)) => leftover(x),
                Ok(_) => sender(s)
            }
        }
    })
}

/// A conduit that consumes values and writes them to the given `SyncSender`.
pub fn sync_sender<'a, T: 'a>(s: SyncSender<T>) -> ConduitM<'a, T, (), ()> {
    consume().and_then(|xo| {
        match xo {
            None => ().into(),
            Some(x) => match s.send(x) {
                Err(SendError(x)) => leftover(x),
                Ok(_) => sync_sender(s)
            }
        }
    })
}
<|endoftext|>