<commit_before>use serde_json;
use std::collections::BTreeSet;
use rocket::State;
use lib::blockchain::*;
use lib::transaction::*;
use std::sync::{RwLock};

mod converters;

pub struct BlockchainState {
    pub blockchain: RwLock<Blockchain>
}

impl BlockchainState {
    pub fn new() -> BlockchainState {
        BlockchainState {
            blockchain: RwLock::new(Blockchain::new())
        }
    }
}

#[derive(Serialize)]
struct MineResult {
    message: String,
    index: usize,
    transactions: BTreeSet<Transaction>,
    proof: u64,
    previous_hash: String
}

//todo: respone as JSON - https://github.com/SergioBenitez/Rocket/blob/v0.3.3/examples/json/src/main.rs
#[get("/mine", format = "application/json")]
pub fn mine(state: State<BlockchainState>) -> Result<String, u32> {
    return blockchain_op(&state, |b| {

        let mined_block = b.mine();

        let response = MineResult {
            message: "New Block Forged".into(),
            index: mined_block.index,
            transactions: mined_block.transactions.clone(),
            proof: mined_block.proof,
            previous_hash: mined_block.previous_hash.clone()
        };

        serde_json::to_string(&response).unwrap_or_else(|e| {
            error!("serialize errro: {:?}", e);
            return String::from("Block mined, but details not available")
        })
    });
}

//todo: post
#[post("/transaction/new", format = "application/json", data = "<transaction>")]
pub fn new_transaction(transaction: Transaction, state: State<BlockchainState>) -> Result<String, u32> {
    blockchain_op(&state, |b| {
        let index = b.new_transaction(transaction.clone());
        return format!("Transaction added at block {}", index);
    })
}

///
/// Retrieves the blockchain from state, unlocks and executions the closure
///
fn blockchain_op<F>(state: &State<BlockchainState>, blockchain_op: F) -> Result<String, u32>
    where F: Fn(&mut Blockchain) -> String {
    let guard = state.blockchain.write();
    if guard.is_ok() {
        let mut blockchain = guard.unwrap();
        let result = blockchain_op(&mut blockchain);
        return Ok(result);
    }
    Err(500)
}

<commit_msg>lock erro<commit_after>use serde_json;
use std::collections::BTreeSet;
use rocket::State;
use lib::blockchain::*;
use lib::transaction::*;
use std::sync::{RwLock};

mod converters;

pub struct BlockchainState {
    pub blockchain: RwLock<Blockchain>
}

impl BlockchainState {
    pub fn new() -> BlockchainState {
        BlockchainState {
            blockchain: RwLock::new(Blockchain::new())
        }
    }
}

#[derive(Serialize)]
struct MineResult {
    message: String,
    index: usize,
    transactions: BTreeSet<Transaction>,
    proof: u64,
    previous_hash: String
}

//todo: respone as JSON - https://github.com/SergioBenitez/Rocket/blob/v0.3.3/examples/json/src/main.rs
#[get("/mine", format = "application/json")]
pub fn mine(state: State<BlockchainState>) -> Result<String, u32> {
    return blockchain_op(&state, |b| {

        let mined_block = b.mine();
        let response = MineResult {
            message: "New Block Forged".into(),
            index: mined_block.index,
            transactions: mined_block.transactions.clone(),
            proof: mined_block.proof,
            previous_hash: mined_block.previous_hash.clone()
        };

        serde_json::to_string(&response).unwrap_or_else(|e| {
            error!("serialize errro: {:?}", e);
            return String::from("Block mined, but details not available")
        })
    });
}

//todo: post
#[post("/transaction/new", format = "application/json", data = "<transaction>")]
pub fn new_transaction(transaction: Transaction, state: State<BlockchainState>) -> Result<String, u32> {
    blockchain_op(&state, |b| {
        let index = b.new_transaction(transaction.clone());
        return format!("Transaction added at block {}", index);
    })
}

///
/// Retrieves the blockchain from state, unlocks and executions the closure
///
fn blockchain_op<F>(state: &State<BlockchainState>, blockchain_op: F) -> Result<String, u32>
    where F: Fn(&mut Blockchain) -> String {
    let guard = state.blockchain.write();
    if guard.is_ok() {
        let mut blockchain = guard.unwrap();
        let result = blockchain_op(&mut blockchain);
        return Ok(result);
    }
    error!("Couldn't acquire lock");
    Err(500)
}

<|endoftext|>


<commit_before>extern crate systray;

pub use ::TStatusBar;
pub use ::NSCallback;

use self::systray::api::api::MenuEnableFlag;

use std::collections::BTreeMap;
use std::sync::mpsc::Sender;

//pub type Object = objc::runtime::Object;
pub type Object = u32;

use std::cell::Cell;
pub struct WindowsStatusBar {
    app: systray::Application,
    idx: Cell<u32>,
    tx: Sender<String>,
    items: BTreeMap<u64, u32>,
}

impl TStatusBar for WindowsStatusBar {
    type S = WindowsStatusBar;
    fn new(tx: Sender<String>) -> WindowsStatusBar {
        let mut bar = WindowsStatusBar {
            app: systray::Application::new().unwrap(),
            idx: Cell::new(0),
            tx: tx,
            items: BTreeMap::<u64, u32>::new(),
        };
        {
            let ref mut win = &mut bar.app.window;
            win.set_icon_from_file(&"spotify.ico".to_string());
        }
        bar
    }
    fn can_redraw(&mut self) -> bool {
        let ref mut win = &mut self.app.window;
        !win.menu_displayed()
    }
    fn clear_items(&mut self) {
        let ref mut win = &mut self.app.window;
        win.clear_menu();
        self.items.clear();
    }
    fn set_tooltip(&mut self, text: &str) {
        let ref mut win = &mut self.app.window;
        win.set_tooltip(&text.to_string());
    }
    fn add_label(&mut self, label: &str) {
        let ref mut win = &mut self.app.window;
        let idx = win.add_menu_item(&label.to_string(), false, |window| {});
        win.enable_menu_item(idx.unwrap(), MenuEnableFlag::Disabled);
    }
    fn add_quit(&mut self, label: &str) {
        let ref mut win = &mut self.app.window;
        win.add_menu_item(&"Quit".to_string(), false, |window| { window.quit(); panic!("goodness."); });
    }
    fn add_separator(&mut self) {
        let ref mut win = &mut self.app.window;
        win.add_menu_separator();
    }
    fn add_item(&mut self, item: &str, callback: NSCallback, selected: bool) -> *mut Object {
        let ref mut win = &mut self.app.window;
        let idx = self.idx.get();
        self.idx.set(idx+1);
        let tx = self.tx.clone();
        let item = win.add_menu_item(&item.to_string(), selected, move |window| {
            callback(idx as u64, &tx);
        }).unwrap();
        self.items.insert(idx as u64, item);
        idx as *mut Object
    }
    fn update_item(&mut self, item: *mut Object, label: &str) {
    }
    fn sel_item(&mut self, sender: u64) {
        let ref mut win = &mut self.app.window;
        let obj = self.items.get(&sender).unwrap();
        win.select_menu_item(*obj);
    }
    fn unsel_item(&mut self, sender: u64) {
        let ref mut win = &mut self.app.window;
        let obj = self.items.get(&sender).unwrap();
        win.unselect_menu_item(*obj);
    }
    fn run(&mut self, block: bool) {
        let ref mut win = &mut self.app.window;
        win.wait_for_message(block);
    }
}
<commit_msg>Fix Win32 crash on long track names.  Fix all Win32 build warnings.<commit_after>extern crate systray;

pub use ::TStatusBar;
pub use ::NSCallback;

use self::systray::api::api::MenuEnableFlag;

use std::collections::BTreeMap;
use std::sync::mpsc::Sender;

//pub type Object = objc::runtime::Object;
pub type Object = u32;

use std::cell::Cell;
pub struct WindowsStatusBar {
    app: systray::Application,
    idx: Cell<u32>,
    tx: Sender<String>,
    items: BTreeMap<u64, u32>,
}

impl TStatusBar for WindowsStatusBar {
    type S = WindowsStatusBar;
    fn new(tx: Sender<String>) -> WindowsStatusBar {
        let mut bar = WindowsStatusBar {
            app: systray::Application::new().unwrap(),
            idx: Cell::new(0),
            tx: tx,
            items: BTreeMap::<u64, u32>::new(),
        };
        {
            let ref mut win = &mut bar.app.window;
            let _ = win.set_icon_from_file(&"spotify.ico".to_string());
        }
        bar
    }
    fn can_redraw(&mut self) -> bool {
        let ref mut win = &mut self.app.window;
        !win.menu_displayed()
    }
    fn clear_items(&mut self) {
        let ref mut win = &mut self.app.window;
        let _ = win.clear_menu();
        self.items.clear();
    }
    fn set_tooltip(&mut self, text: &str) {
        let ref mut win = &mut self.app.window;
        // Truncate to 128 (including NUL) for stupid W32 API
        let tooltip = match text.len() {
            len @ _ if len > 127 => format!("{}...", &text[0..124]),
            _ => text.to_string(),
        };
        let _ = win.set_tooltip(&tooltip);
    }
    fn add_label(&mut self, label: &str) {
        let ref mut win = &mut self.app.window;
        let idx = win.add_menu_item(&label.to_string(), false, |_| {});
        let _ = win.enable_menu_item(idx.unwrap(), MenuEnableFlag::Disabled);
    }
    fn add_quit(&mut self, label: &str) {
        let ref mut win = &mut self.app.window;
        // TODO: shutdown without a panic
        let _ = win.add_menu_item(&label.to_string(), false,
                                  |window| { window.quit(); panic!(""); });
    }
    fn add_separator(&mut self) {
        let ref mut win = &mut self.app.window;
        let _ = win.add_menu_separator();
    }
    fn add_item(&mut self, item: &str, callback: NSCallback, selected: bool) -> *mut Object {
        let ref mut win = &mut self.app.window;
        let idx = self.idx.get();
        self.idx.set(idx+1);
        let tx = self.tx.clone();
        let item = win.add_menu_item(&item.to_string(), selected, move |_| {
            callback(idx as u64, &tx);
        }).unwrap();
        self.items.insert(idx as u64, item);
        idx as *mut Object
    }
    fn update_item(&mut self, _item: *mut Object, _label: &str) {
    }
    fn sel_item(&mut self, sender: u64) {
        let ref mut win = &mut self.app.window;
        let obj = self.items.get(&sender).unwrap();
        let _ = win.select_menu_item(*obj);
    }
    fn unsel_item(&mut self, sender: u64) {
        let ref mut win = &mut self.app.window;
        let obj = self.items.get(&sender).unwrap();
        let _ = win.unselect_menu_item(*obj);
    }
    fn run(&mut self, block: bool) {
        let ref mut win = &mut self.app.window;
        win.wait_for_message(block);
    }
}
<|endoftext|>


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

use std::io::{self, Read};
use std::ptr;
use std::cmp;

use super::StreamProducer;

/// Represent the different kinds of errors.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ErrorKind {
  /// Error from I/O.
  IO(io::ErrorKind),
  /// A parser stopped midway and need more bytes to consume.
  Incomplete(usize),
  /// A parser has completes and there is still more bytes to consume.
  Continue,
  /// A parser has completes and there is no more bytes to consume.
  EndOfInput,
  /// A non-specified error.
  Unknown,
  // Parser Error
  /// Failed parsing the "fLaC" header token.
  HeaderParser,
  /// Failed parsing a metadata header.
  MetadataHeaderParser,
  /// Failed parsing the metadata block `StreamInfo`.
  StreamInfoParser,
  /// Failed parsing the metadata block `Padding`.
  PaddingParser,
  /// Failed parsing the metadata block `Application`.
  ApplicationParser,
  /// Failed parsing the metadata block `SeekTable`.
  SeekTableParser,
  /// Failed parsing the metadata block `VorbisComment`.
  VorbisCommentParser,
  /// Failed parsing the metadata block `CueSheet`.
  CueSheetParser,
  /// Failed parsing the metadata block `Picture`.
  PictureParser,
  /// Failed parsing the metadata block `Unknown`.
  UnknownParser,
  /// Failed parsing the blocking strategy inside the frame header.
  BlockingStrategyParser,
  /// Failed parsing the blocking sample inside the frame header.
  BlockingSampleParser,
  /// Failed parsing the channel bits inside the frame header.
  ChannelBitsParser,
  /// Failed parsing the UTF-8 header inside the frame header.
  UTF8HeaderParser,
  /// Failed parsing the UTF-8 body inside the frame header.
  UTF8BodyParser,
  /// Failed parsing the CRC-8 inside the frame header.
  CRC8Parser,
  /// Failed parsing the frame footer, also known as the CRC-16.
  FrameFooterParser,
  /// Failed parsing the subframe header.
  SubframeHeaderParser,
  /// Failed parsing the leading zero for a unary value.
  LeadingZerosParser,
  /// Failed parsing a Constant subframe data.
  ConstantParser,
  /// Failed parsing a Verbatim subframe data.
  VerbatimParser,
  /// Failed parsing a Fixed subframe data.
  FixedParser,
  /// Failed parsing a LPC subframe data.
  LPCParser,
  // Invalid Error
  /// A block type, base on the number, that is outside the range (0-126).
  InvalidBlockType,
  /// An incorrect sync code with the frame header.
  InvalidSyncCode,
  /// A block sample that could cause sync-fooling.
  InvalidBlockSample,
  /// One or more bits are reserved values.
  InvalidChannelBits,
  /// An error occurred in building the UTF-8 value.
  InvalidUTF8,
  /// The stored CRC-8 doesn't match the one generated from the bytes within
  /// the frame header.
  InvalidCRC8,
  /// The stored CRC-16 doesn't match the one generated from the bytes
  /// within the entire frame.
  InvalidCRC16,
  InvalidSubframeHeader,
  // Not Found
  /// Some metadata block was not found with a specific filter.
  NotFound,
}

/// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  /// Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  /// Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  /// Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        match e {
          nom::Err::Code(k)               |
          nom::Err::Node(k, _)            |
          nom::Err::Position(k, _)        |
          nom::Err::NodePosition(k, _, _) => {
            if let nom::ErrorKind::Custom(kind) = k {
              Err(kind)
            } else {
              Err(ErrorKind::Unknown)
            }
          }
        }
      },
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

/// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  /// Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T, ErrorKind>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity() + 1024;

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      match e {
        nom::Err::Code(k)               |
        nom::Err::Node(k, _)            |
        nom::Err::Position(k, _)        |
        nom::Err::NodePosition(k, _, _) => {
          if let nom::ErrorKind::Custom(kind) = k {
            Err(kind)
          } else {
            Err(ErrorKind::Unknown)
          }
        }
      }
    },
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(|e| ErrorKind::IO(e.kind())));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;

          Err(ErrorKind::Continue)
        } else {
          Err(kind)
        }
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::{self, IResult};

  #[inline]
  fn be_u32(input: &[u8]) -> IResult<&[u8], u32, ErrorKind> {
    nom::be_u32(input).map_err(to_custom_error!(Unknown))
  }

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<commit_msg>Add documentation for subframe invalidity<commit_after>use nom::{self, IResult, Needed};

use std::io::{self, Read};
use std::ptr;
use std::cmp;

use super::StreamProducer;

/// Represent the different kinds of errors.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ErrorKind {
  /// Error from I/O.
  IO(io::ErrorKind),
  /// A parser stopped midway and need more bytes to consume.
  Incomplete(usize),
  /// A parser has completes and there is still more bytes to consume.
  Continue,
  /// A parser has completes and there is no more bytes to consume.
  EndOfInput,
  /// A non-specified error.
  Unknown,
  // Parser Error
  /// Failed parsing the "fLaC" header token.
  HeaderParser,
  /// Failed parsing a metadata header.
  MetadataHeaderParser,
  /// Failed parsing the metadata block `StreamInfo`.
  StreamInfoParser,
  /// Failed parsing the metadata block `Padding`.
  PaddingParser,
  /// Failed parsing the metadata block `Application`.
  ApplicationParser,
  /// Failed parsing the metadata block `SeekTable`.
  SeekTableParser,
  /// Failed parsing the metadata block `VorbisComment`.
  VorbisCommentParser,
  /// Failed parsing the metadata block `CueSheet`.
  CueSheetParser,
  /// Failed parsing the metadata block `Picture`.
  PictureParser,
  /// Failed parsing the metadata block `Unknown`.
  UnknownParser,
  /// Failed parsing the blocking strategy inside the frame header.
  BlockingStrategyParser,
  /// Failed parsing the blocking sample inside the frame header.
  BlockingSampleParser,
  /// Failed parsing the channel bits inside the frame header.
  ChannelBitsParser,
  /// Failed parsing the UTF-8 header inside the frame header.
  UTF8HeaderParser,
  /// Failed parsing the UTF-8 body inside the frame header.
  UTF8BodyParser,
  /// Failed parsing the CRC-8 inside the frame header.
  CRC8Parser,
  /// Failed parsing the frame footer, also known as the CRC-16.
  FrameFooterParser,
  /// Failed parsing the subframe header.
  SubframeHeaderParser,
  /// Failed parsing the leading zero for a unary value.
  LeadingZerosParser,
  /// Failed parsing a Constant subframe data.
  ConstantParser,
  /// Failed parsing a Verbatim subframe data.
  VerbatimParser,
  /// Failed parsing a Fixed subframe data.
  FixedParser,
  /// Failed parsing a LPC subframe data.
  LPCParser,
  // Invalid Error
  /// A block type, base on the number, that is outside the range (0-126).
  InvalidBlockType,
  /// An incorrect sync code with the frame header.
  InvalidSyncCode,
  /// A block sample that could cause sync-fooling.
  InvalidBlockSample,
  /// One or more bits are reserved values.
  InvalidChannelBits,
  /// An error occurred in building the UTF-8 value.
  InvalidUTF8,
  /// The stored CRC-8 doesn't match the one generated from the bytes within
  /// the frame header.
  InvalidCRC8,
  /// The stored CRC-16 doesn't match the one generated from the bytes
  /// within the entire frame.
  InvalidCRC16,
  /// A subframe header that could cause sync-fooling.
  InvalidSubframeHeader,
  // Not Found
  /// Some metadata block was not found with a specific filter.
  NotFound,
}

/// Structure that hold a slice of bytes.
pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  /// Construct a `ByteStream` based on the passed in byte slice.
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  /// Return the number of bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  /// Return true if the stream contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        match e {
          nom::Err::Code(k)               |
          nom::Err::Node(k, _)            |
          nom::Err::Position(k, _)        |
          nom::Err::NodePosition(k, _, _) => {
            if let nom::ErrorKind::Custom(kind) = k {
              Err(kind)
            } else {
              Err(ErrorKind::Unknown)
            }
          }
        }
      },
    }
  }
}

// Growable buffer of bytes.
//
// Mainly used to the `ReadStream` structure but can be used seperately for
// manually filling with some `Read` source.
pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  // Default constructor for `Buffer`
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  // Explicitly set the buffer capacity.
  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  // Return the number of read bytes that haven't been consumed yet.
  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  // Return true if buffer contains no more bytes.
  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  // The set length of the unlining buffer.
  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  // Return a reference to the slice of unread bytes.
  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  // Fill the buffer with bytes from a `Read` source.
  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  // Resize the current buffer
  //
  // This will only allocate data when the size requests is larger than the
  // current capacity of the buffer, otherwise it moves the currently filled
  // data to the beginning of the buffer.
  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length  = self.filled - self.offset;
      let mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  // Move the offset by the amount of consumed bytes.
  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

/// Structure that hold a reader for a source of bytes.
pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  /// Constructor for `ReadStream` based on a `Read` source.
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  // Fill the stream with bytes from a `Read` source.
  fn fill(&mut self) -> io::Result<usize> {
    let needed = cmp::max(1, self.needed);

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T, ErrorKind>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity() + 1024;

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      match e {
        nom::Err::Code(k)               |
        nom::Err::Node(k, _)            |
        nom::Err::Position(k, _)        |
        nom::Err::NodePosition(k, _, _) => {
          if let nom::ErrorKind::Custom(kind) = k {
            Err(kind)
          } else {
            Err(ErrorKind::Unknown)
          }
        }
      }
    },
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T, ErrorKind> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(|e| ErrorKind::IO(e.kind())));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;

          Err(ErrorKind::Continue)
        } else {
          Err(kind)
        }
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use utility::StreamProducer;
  use nom::{self, IResult};

  #[inline]
  fn be_u32(input: &[u8]) -> IResult<&[u8], u32, ErrorKind> {
    nom::be_u32(input).map_err(to_custom_error!(Unknown))
  }

  #[test]
  fn test_buffer() {
    let mut buffer = Buffer::new();
    let bytes      = b"Hello World";
    let mut reader = &bytes[..];

    assert!(buffer.is_empty());
    assert_eq!(buffer.capacity(), 1024);

    let bytes_read = buffer.fill(&mut reader).unwrap_or(0);
    let bytes_len  = bytes.len();

    assert_eq!(bytes_read, bytes_len);
    assert_eq!(buffer.len(), bytes_len);
    assert_eq!(buffer.as_slice(), bytes);

    buffer.resize(512);
    assert_eq!(buffer.capacity(), 1024);
  }

  #[test]
  fn test_byte_stream() {
    let bytes      = b"Hello World";
    let mut stream = ByteStream::new(bytes);

    assert_eq!(stream.len(), bytes.len());

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444);
    assert_eq!(stream.len(), 7);
  }

  #[test]
  fn test_read_stream() {
    let bytes      = b"Hello World";
    let mut stream = ReadStream::new(&bytes[..]);

    let result = stream.parse(be_u32).unwrap_or(0);

    assert_eq!(result, 1214606444)
  }
}
<|endoftext|>


<commit_before>#![cfg(target_os = "windows")]

extern crate user32;
extern crate kernel32;
extern crate winapi;
extern crate gdi32;

use Scale;
use Vsync;
use Key;

use std::ptr;
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;
use std::mem;

use self::winapi::windef::HWND;
use self::winapi::windef::HDC;
use self::winapi::winuser::WS_OVERLAPPEDWINDOW;
use self::winapi::winuser::WNDCLASSW;
use self::winapi::wingdi::BITMAPINFOHEADER;
use self::winapi::wingdi::RGBQUAD;

// Wrap this so we can have a proper numbef of bmiColors to write in
#[repr(C)]
struct BitmapInfo {
    pub bmi_header: BITMAPINFOHEADER,
    pub bmi_colors: [RGBQUAD; 3],
}

fn update_key_state(window: &mut Window, wparam: u32, state: bool) {
    match wparam & 0x1ff {
        0x00B => window.keys[Key::Key0 as usize] = state,
        0x002 => window.keys[Key::Key1 as usize] = state,
        0x003 => window.keys[Key::Key2 as usize] = state,
        0x004 => window.keys[Key::Key3 as usize] = state,
        0x005 => window.keys[Key::Key4 as usize] = state,
        0x006 => window.keys[Key::Key5 as usize] = state,
        0x007 => window.keys[Key::Key6 as usize] = state,
        0x008 => window.keys[Key::Key7 as usize] = state,
        0x009 => window.keys[Key::Key8 as usize] = state,
        0x00A => window.keys[Key::Key9 as usize] = state,
        0x01E => window.keys[Key::A as usize] = state,
        0x030 => window.keys[Key::B as usize] = state,
        0x02E => window.keys[Key::C as usize] = state,
        0x020 => window.keys[Key::D as usize] = state,
        0x012 => window.keys[Key::E as usize] = state,
        0x021 => window.keys[Key::F as usize] = state,
        0x022 => window.keys[Key::G as usize] = state,
        0x023 => window.keys[Key::H as usize] = state,
        0x017 => window.keys[Key::I as usize] = state,
        0x024 => window.keys[Key::J as usize] = state,
        0x025 => window.keys[Key::K as usize] = state,
        0x026 => window.keys[Key::L as usize] = state,
        0x032 => window.keys[Key::M as usize] = state,
        0x031 => window.keys[Key::N as usize] = state,
        0x018 => window.keys[Key::O as usize] = state,
        0x019 => window.keys[Key::P as usize] = state,
        0x010 => window.keys[Key::Q as usize] = state,
        0x013 => window.keys[Key::R as usize] = state,
        0x01F => window.keys[Key::S as usize] = state,
        0x014 => window.keys[Key::T as usize] = state,
        0x016 => window.keys[Key::U as usize] = state,
        0x02F => window.keys[Key::V as usize] = state,
        0x011 => window.keys[Key::W as usize] = state,
        0x02D => window.keys[Key::X as usize] = state,
        0x015 => window.keys[Key::Y as usize] = state,
        0x02C => window.keys[Key::Z as usize] = state,
        0x03B => window.keys[Key::F1 as usize] = state,
        0x03C => window.keys[Key::F2 as usize] = state,
        0x03D => window.keys[Key::F3 as usize] = state,
        0x03E => window.keys[Key::F4 as usize] = state,
        0x03F => window.keys[Key::F5 as usize] = state,
        0x040 => window.keys[Key::F6 as usize] = state,
        0x041 => window.keys[Key::F7 as usize] = state,
        0x042 => window.keys[Key::F8 as usize] = state,
        0x043 => window.keys[Key::F9 as usize] = state,
        0x044 => window.keys[Key::F10 as usize] = state,
        0x057 => window.keys[Key::F11 as usize] = state,
        0x058 => window.keys[Key::F12 as usize] = state,
        0x150 => window.keys[Key::Down as usize] = state,
        0x14B => window.keys[Key::Left as usize] = state,
        0x14D => window.keys[Key::Right as usize] = state,
        0x148 => window.keys[Key::Up as usize] = state,
        0x028 => window.keys[Key::Apostrophe as usize] = state,
        0x02B => window.keys[Key::Backslash as usize] = state,
        0x033 => window.keys[Key::Comma as usize] = state,
        0x00D => window.keys[Key::Equal as usize] = state,
        0x01A => window.keys[Key::LeftBracket as usize] = state,
        0x00C => window.keys[Key::Minus as usize] = state,
        0x034 => window.keys[Key::Period as usize] = state,
        0x01B => window.keys[Key::RightBracket as usize] = state,
        0x027 => window.keys[Key::Semicolon as usize] = state,
        0x035 => window.keys[Key::Slash as usize] = state,
        0x00E => window.keys[Key::Backspace as usize] = state,
        0x153 => window.keys[Key::Delete as usize] = state,
        0x14F => window.keys[Key::End as usize] = state,
        0x01C => window.keys[Key::Enter as usize] = state,
        0x001 => window.keys[Key::Escape as usize] = state,
        0x147 => window.keys[Key::Home as usize] = state,
        0x152 => window.keys[Key::Insert as usize] = state,
        0x15D => window.keys[Key::Menu as usize] = state,
        0x151 => window.keys[Key::PageDown as usize] = state,
        0x149 => window.keys[Key::PageUp as usize] = state,
        0x045 => window.keys[Key::Pause as usize] = state,
        0x039 => window.keys[Key::Space as usize] = state,
        0x00F => window.keys[Key::Tab as usize] = state,
        0x03A => window.keys[Key::CapsLock as usize] = state,
        _ => (),
    }
}

unsafe extern "system" fn wnd_proc(window: winapi::HWND,
                                   msg: winapi::UINT,
                                   wparam: winapi::WPARAM,
                                   lparam: winapi::LPARAM)
                                   -> winapi::LRESULT {
    // This make sure we actually don't do anything before the user data has been setup for the
    // window

    let user_data = user32::GetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA);

    if user_data == 0 {
        return user32::DefWindowProcW(window, msg, wparam, lparam);
    }

    let mut wnd: &mut Window = mem::transmute(user_data);

    match msg {
        winapi::winuser::WM_KEYDOWN => {
            update_key_state(wnd, (lparam as u32) >> 16, true);
        }

        winapi::winuser::WM_CLOSE => {
            wnd.is_open = false;
        }

        winapi::winuser::WM_KEYUP => {
            update_key_state(wnd, (lparam as u32) >> 16, false);
        }

        winapi::winuser::WM_PAINT => {
            let mut rect: winapi::RECT = mem::uninitialized();

            user32::GetClientRect(window, &mut rect);

            let mut bitmap_info: BitmapInfo = mem::zeroed();
            let width = rect.right - rect.left;
            let height = rect.bottom - rect.top;

            bitmap_info.bmi_header.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
            bitmap_info.bmi_header.biPlanes = 1;
            bitmap_info.bmi_header.biBitCount = 32;
            bitmap_info.bmi_header.biCompression = winapi::wingdi::BI_BITFIELDS;
            bitmap_info.bmi_header.biWidth = width;
            bitmap_info.bmi_header.biHeight = -height;
            bitmap_info.bmi_colors[0].rgbRed = 0xff;
            bitmap_info.bmi_colors[1].rgbGreen = 0xff;
            bitmap_info.bmi_colors[2].rgbBlue = 0xff;

            gdi32::StretchDIBits(wnd.dc.unwrap(),
                                 0,
                                 0,
                                 width,
                                 height,
                                 0,
                                 0,
                                 width,
                                 height,
                                 mem::transmute(wnd.buffer.as_ptr()),
                                 mem::transmute(&bitmap_info),
                                 winapi::wingdi::DIB_RGB_COLORS,
                                 winapi::wingdi::SRCCOPY);

            user32::ValidateRect(window, ptr::null_mut());
        }

        _ => (),
    }

    return user32::DefWindowProcW(window, msg, wparam, lparam);
}

pub enum MinifbError {
    UnableToCreateWindow,
}

fn to_wstring(str: &str) -> *const u16 {
    let mut v: Vec<u16> = OsStr::new(str).encode_wide().chain(Some(0).into_iter()).collect();
    v.push(0u16);
    v.as_ptr()
}

pub struct Window {
    dc: Option<HDC>,
    window: Option<HWND>,
    keys: [bool; 512],
    buffer: Vec<u32>,
    is_open : bool,
}

impl Window {
    fn open_window(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> Option<HWND> {
        unsafe {
            let class_name = to_wstring("minifb_window");
            let class = WNDCLASSW {
                style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC,
                lpfnWndProc: Some(wnd_proc),
                cbClsExtra: 0,
                cbWndExtra: 0,
                hInstance: kernel32::GetModuleHandleA(ptr::null()),
                hIcon: ptr::null_mut(),
                hCursor: ptr::null_mut(),
                hbrBackground: ptr::null_mut(),
                lpszMenuName: ptr::null(),
                lpszClassName: class_name,
            };

            if user32::RegisterClassW(&class) == 0 {
                println!("Unable to register class, error {}", kernel32::GetLastError() as u32);
                return None;
            }

            let mut rect = winapi::RECT {
                left: 0,
                right: width as winapi::LONG,
                top: 0,
                bottom: height as winapi::LONG,
            };

            user32::AdjustWindowRect(&mut rect,
                                     winapi::WS_POPUP | winapi::WS_SYSMENU | winapi::WS_CAPTION,
                                     0);

            rect.right -= rect.left;
            rect.bottom -= rect.top;

            let handle = user32::CreateWindowExW(0,
                                                 class_name,
                                                 to_wstring(name),
                                                 winapi::WS_OVERLAPPEDWINDOW &
                                                 !winapi::WS_MAXIMIZEBOX &
                                                 !winapi::WS_THICKFRAME,
                                                 winapi::CW_USEDEFAULT,
                                                 winapi::CW_USEDEFAULT,
                                                 rect.right,
                                                 rect.bottom,
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut());
            if handle.is_null() {
                println!("Unable to create window, error {}", kernel32::GetLastError() as u32);
                return None;
            }

            user32::ShowWindow(handle, winapi::SW_NORMAL);

            return Some(handle);
        }
    }

    pub fn new(name: &str,
               width: usize,
               height: usize,
               scale: Scale,
               vsync: Vsync)
               -> Result<Window, &str> {
        unsafe {
            let handle = Self::open_window(name, width, height, scale, vsync);

            if handle.is_none() {
                return Err("Unable to create Window");
            }

            let window = Window {
                dc: Some(user32::GetDC(handle.unwrap())),
                window: Some(handle.unwrap()),
                keys: [false; 512],
                buffer: Vec::new(),
                is_open: true,
            };

            Ok(window)
        }
    }

    #[inline]
    pub fn is_key_down(&self, key: Key) -> bool {
        return self.keys[key as usize];
    }

    #[inline]
    pub fn is_open(&self) -> bool {
        return self.is_open
    }

    pub fn update(&mut self, buffer: &[u32]) {
        unsafe {
            let mut msg = mem::uninitialized();
            let window = self.window.unwrap();

            // TODO: Optimize

            self.buffer = buffer.iter().cloned().collect();

            user32::SetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA, mem::transmute(self));
            user32::InvalidateRect(window, ptr::null_mut(), winapi::TRUE);

            while user32::PeekMessageW(&mut msg, window, 0, 0, winapi::winuser::PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }
        }
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            if self.dc.is_some() {
                user32::ReleaseDC(self.window.unwrap(), self.dc.unwrap());
            }

            if self.window.is_some() {
                user32::CloseWindow(self.window.unwrap());
            }
        }
    }
}
<commit_msg>Make sure to keep wchars alive<commit_after>#![cfg(target_os = "windows")]

extern crate user32;
extern crate kernel32;
extern crate winapi;
extern crate gdi32;

use Scale;
use Vsync;
use Key;

use std::ptr;
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;
use std::mem;

use self::winapi::windef::HWND;
use self::winapi::windef::HDC;
use self::winapi::winuser::WS_OVERLAPPEDWINDOW;
use self::winapi::winuser::WNDCLASSW;
use self::winapi::wingdi::BITMAPINFOHEADER;
use self::winapi::wingdi::RGBQUAD;

// Wrap this so we can have a proper numbef of bmiColors to write in
#[repr(C)]
struct BitmapInfo {
    pub bmi_header: BITMAPINFOHEADER,
    pub bmi_colors: [RGBQUAD; 3],
}

fn update_key_state(window: &mut Window, wparam: u32, state: bool) {
    match wparam & 0x1ff {
        0x00B => window.keys[Key::Key0 as usize] = state,
        0x002 => window.keys[Key::Key1 as usize] = state,
        0x003 => window.keys[Key::Key2 as usize] = state,
        0x004 => window.keys[Key::Key3 as usize] = state,
        0x005 => window.keys[Key::Key4 as usize] = state,
        0x006 => window.keys[Key::Key5 as usize] = state,
        0x007 => window.keys[Key::Key6 as usize] = state,
        0x008 => window.keys[Key::Key7 as usize] = state,
        0x009 => window.keys[Key::Key8 as usize] = state,
        0x00A => window.keys[Key::Key9 as usize] = state,
        0x01E => window.keys[Key::A as usize] = state,
        0x030 => window.keys[Key::B as usize] = state,
        0x02E => window.keys[Key::C as usize] = state,
        0x020 => window.keys[Key::D as usize] = state,
        0x012 => window.keys[Key::E as usize] = state,
        0x021 => window.keys[Key::F as usize] = state,
        0x022 => window.keys[Key::G as usize] = state,
        0x023 => window.keys[Key::H as usize] = state,
        0x017 => window.keys[Key::I as usize] = state,
        0x024 => window.keys[Key::J as usize] = state,
        0x025 => window.keys[Key::K as usize] = state,
        0x026 => window.keys[Key::L as usize] = state,
        0x032 => window.keys[Key::M as usize] = state,
        0x031 => window.keys[Key::N as usize] = state,
        0x018 => window.keys[Key::O as usize] = state,
        0x019 => window.keys[Key::P as usize] = state,
        0x010 => window.keys[Key::Q as usize] = state,
        0x013 => window.keys[Key::R as usize] = state,
        0x01F => window.keys[Key::S as usize] = state,
        0x014 => window.keys[Key::T as usize] = state,
        0x016 => window.keys[Key::U as usize] = state,
        0x02F => window.keys[Key::V as usize] = state,
        0x011 => window.keys[Key::W as usize] = state,
        0x02D => window.keys[Key::X as usize] = state,
        0x015 => window.keys[Key::Y as usize] = state,
        0x02C => window.keys[Key::Z as usize] = state,
        0x03B => window.keys[Key::F1 as usize] = state,
        0x03C => window.keys[Key::F2 as usize] = state,
        0x03D => window.keys[Key::F3 as usize] = state,
        0x03E => window.keys[Key::F4 as usize] = state,
        0x03F => window.keys[Key::F5 as usize] = state,
        0x040 => window.keys[Key::F6 as usize] = state,
        0x041 => window.keys[Key::F7 as usize] = state,
        0x042 => window.keys[Key::F8 as usize] = state,
        0x043 => window.keys[Key::F9 as usize] = state,
        0x044 => window.keys[Key::F10 as usize] = state,
        0x057 => window.keys[Key::F11 as usize] = state,
        0x058 => window.keys[Key::F12 as usize] = state,
        0x150 => window.keys[Key::Down as usize] = state,
        0x14B => window.keys[Key::Left as usize] = state,
        0x14D => window.keys[Key::Right as usize] = state,
        0x148 => window.keys[Key::Up as usize] = state,
        0x028 => window.keys[Key::Apostrophe as usize] = state,
        0x02B => window.keys[Key::Backslash as usize] = state,
        0x033 => window.keys[Key::Comma as usize] = state,
        0x00D => window.keys[Key::Equal as usize] = state,
        0x01A => window.keys[Key::LeftBracket as usize] = state,
        0x00C => window.keys[Key::Minus as usize] = state,
        0x034 => window.keys[Key::Period as usize] = state,
        0x01B => window.keys[Key::RightBracket as usize] = state,
        0x027 => window.keys[Key::Semicolon as usize] = state,
        0x035 => window.keys[Key::Slash as usize] = state,
        0x00E => window.keys[Key::Backspace as usize] = state,
        0x153 => window.keys[Key::Delete as usize] = state,
        0x14F => window.keys[Key::End as usize] = state,
        0x01C => window.keys[Key::Enter as usize] = state,
        0x001 => window.keys[Key::Escape as usize] = state,
        0x147 => window.keys[Key::Home as usize] = state,
        0x152 => window.keys[Key::Insert as usize] = state,
        0x15D => window.keys[Key::Menu as usize] = state,
        0x151 => window.keys[Key::PageDown as usize] = state,
        0x149 => window.keys[Key::PageUp as usize] = state,
        0x045 => window.keys[Key::Pause as usize] = state,
        0x039 => window.keys[Key::Space as usize] = state,
        0x00F => window.keys[Key::Tab as usize] = state,
        0x03A => window.keys[Key::CapsLock as usize] = state,
        _ => (),
    }
}

unsafe extern "system" fn wnd_proc(window: winapi::HWND,
                                   msg: winapi::UINT,
                                   wparam: winapi::WPARAM,
                                   lparam: winapi::LPARAM)
                                   -> winapi::LRESULT {
    // This make sure we actually don't do anything before the user data has been setup for the
    // window

    let user_data = user32::GetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA);

    if user_data == 0 {
        return user32::DefWindowProcW(window, msg, wparam, lparam);
    }

    let mut wnd: &mut Window = mem::transmute(user_data);

    match msg {
        winapi::winuser::WM_KEYDOWN => {
            update_key_state(wnd, (lparam as u32) >> 16, true);
        }

        winapi::winuser::WM_CLOSE => {
            wnd.is_open = false;
        }

        winapi::winuser::WM_KEYUP => {
            update_key_state(wnd, (lparam as u32) >> 16, false);
        }

        winapi::winuser::WM_PAINT => {
            let mut rect: winapi::RECT = mem::uninitialized();

            user32::GetClientRect(window, &mut rect);

            let mut bitmap_info: BitmapInfo = mem::zeroed();
            let width = rect.right - rect.left;
            let height = rect.bottom - rect.top;

            bitmap_info.bmi_header.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
            bitmap_info.bmi_header.biPlanes = 1;
            bitmap_info.bmi_header.biBitCount = 32;
            bitmap_info.bmi_header.biCompression = winapi::wingdi::BI_BITFIELDS;
            bitmap_info.bmi_header.biWidth = width;
            bitmap_info.bmi_header.biHeight = -height;
            bitmap_info.bmi_colors[0].rgbRed = 0xff;
            bitmap_info.bmi_colors[1].rgbGreen = 0xff;
            bitmap_info.bmi_colors[2].rgbBlue = 0xff;

            gdi32::StretchDIBits(wnd.dc.unwrap(),
                                 0,
                                 0,
                                 width,
                                 height,
                                 0,
                                 0,
                                 width,
                                 height,
                                 mem::transmute(wnd.buffer.as_ptr()),
                                 mem::transmute(&bitmap_info),
                                 winapi::wingdi::DIB_RGB_COLORS,
                                 winapi::wingdi::SRCCOPY);

            user32::ValidateRect(window, ptr::null_mut());
        }

        _ => (),
    }

    return user32::DefWindowProcW(window, msg, wparam, lparam);
}

pub enum MinifbError {
    UnableToCreateWindow,
}

fn to_wstring(str: &str) -> Vec<u16> {
    let mut v: Vec<u16> = OsStr::new(str).encode_wide().chain(Some(0).into_iter()).collect();
    v.push(0u16);
    v
}

pub struct Window {
    dc: Option<HDC>,
    window: Option<HWND>,
    keys: [bool; 512],
    buffer: Vec<u32>,
    is_open : bool,
}

impl Window {
    fn open_window(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> Option<HWND> {
        unsafe {
            let class_name = to_wstring("minifb_window");
            let class = WNDCLASSW {
                style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC,
                lpfnWndProc: Some(wnd_proc),
                cbClsExtra: 0,
                cbWndExtra: 0,
                hInstance: kernel32::GetModuleHandleA(ptr::null()),
                hIcon: ptr::null_mut(),
                hCursor: ptr::null_mut(),
                hbrBackground: ptr::null_mut(),
                lpszMenuName: ptr::null(),
                lpszClassName: class_name.as_ptr(),
            };

            if user32::RegisterClassW(&class) == 0 {
                println!("Unable to register class, error {}", kernel32::GetLastError() as u32);
                return None;
            }

            let mut rect = winapi::RECT {
                left: 0,
                right: width as winapi::LONG,
                top: 0,
                bottom: height as winapi::LONG,
            };

            user32::AdjustWindowRect(&mut rect,
                                     winapi::WS_POPUP | winapi::WS_SYSMENU | winapi::WS_CAPTION,
                                     0);

            rect.right -= rect.left;
            rect.bottom -= rect.top;

            let window_name = to_wstring(name);

            let handle = user32::CreateWindowExW(0,
                                                 class_name.as_ptr(),
                                                 window_name.as_ptr(),
                                                 winapi::WS_OVERLAPPEDWINDOW &
                                                 !winapi::WS_MAXIMIZEBOX &
                                                 !winapi::WS_THICKFRAME,
                                                 winapi::CW_USEDEFAULT,
                                                 winapi::CW_USEDEFAULT,
                                                 rect.right,
                                                 rect.bottom,
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut());
            if handle.is_null() {
                println!("Unable to create window, error {}", kernel32::GetLastError() as u32);
                return None;
            }

            user32::ShowWindow(handle, winapi::SW_NORMAL);

            return Some(handle);
        }
    }

    pub fn new(name: &str,
               width: usize,
               height: usize,
               scale: Scale,
               vsync: Vsync)
               -> Result<Window, &str> {
        unsafe {
            let handle = Self::open_window(name, width, height, scale, vsync);

            if handle.is_none() {
                return Err("Unable to create Window");
            }

            let window = Window {
                dc: Some(user32::GetDC(handle.unwrap())),
                window: Some(handle.unwrap()),
                keys: [false; 512],
                buffer: Vec::new(),
                is_open: true,
            };

            Ok(window)
        }
    }

    #[inline]
    pub fn is_key_down(&self, key: Key) -> bool {
        return self.keys[key as usize];
    }

    #[inline]
    pub fn is_open(&self) -> bool {
        return self.is_open
    }

    pub fn update(&mut self, buffer: &[u32]) {
        unsafe {
            let mut msg = mem::uninitialized();
            let window = self.window.unwrap();

            // TODO: Optimize

            self.buffer = buffer.iter().cloned().collect();

            user32::SetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA, mem::transmute(self));
            user32::InvalidateRect(window, ptr::null_mut(), winapi::TRUE);

            while user32::PeekMessageW(&mut msg, window, 0, 0, winapi::winuser::PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }
        }
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            if self.dc.is_some() {
                user32::ReleaseDC(self.window.unwrap(), self.dc.unwrap());
            }

            if self.window.is_some() {
                user32::CloseWindow(self.window.unwrap());
            }
        }
    }
}
<|endoftext|>


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

use std::io;
use std::io::Read;
use std::ptr;

pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  EndOfInput,
  Unknown,
}

pub trait StreamProducer {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T>;
}

pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(_)      => Err(ErrorKind::Unknown),
    }
  }
}

pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length      = self.filled - self.offset;
      let mut mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  fn fill(&mut self) -> io::Result<usize> {
    let needed = self.needed;

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(_)      => Err(ErrorKind::Unknown),
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        if let ErrorKind::Incomplete(needed) = kind {
          self.needed = needed;
        }

        Err(kind)
      }
    }
  }
}
<commit_msg>Add handle for when slice has been consumed<commit_after>use nom::{Err, IResult, Needed};

use std::io;
use std::io::Read;
use std::ptr;

pub enum ErrorKind {
  IO(io::Error),
  Incomplete(usize),
  Consumed(usize),
  EndOfInput,
  Unknown,
}

pub trait StreamProducer {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T>;
}

pub struct ByteStream<'a> {
  offset: usize,
  bytes: &'a [u8],
}

impl<'a> ByteStream<'a> {
  pub fn new(bytes: &'a [u8]) -> Self {
    ByteStream {
      offset: 0,
      bytes: bytes,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.bytes.len() - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }
}

impl<'a> StreamProducer for ByteStream<'a> {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.is_empty() {
      return Err(ErrorKind::EndOfInput);
    }

    match f(&self.bytes[self.offset..]) {
      IResult::Done(i, o)    => {
        self.offset += self.len() - i.len();

        Ok(o)
      }
      IResult::Incomplete(n) => {
        let mut needed = self.len();

        if let Needed::Size(size) = n {
          needed = size;
        }

        Err(ErrorKind::Incomplete(needed))
      }
      IResult::Error(e)      => {
        if let Err::Position(_, i) = e {
          self.offset += self.len() - i.len();
        }

        Err(ErrorKind::Unknown)
      }
    }
  }
}

pub struct Buffer {
  data: Vec<u8>,
  filled: usize,
  offset: usize,
}

impl Buffer {
  pub fn new() -> Self {
    Self::with_capacity(1024)
  }

  pub fn with_capacity(capacity: usize) -> Self {
    let mut buffer = Vec::with_capacity(capacity);

    unsafe {
      buffer.set_len(capacity);
    }

    Buffer {
      data: buffer,
      filled: 0,
      offset: 0,
    }
  }

  #[inline]
  pub fn len(&self) -> usize {
    self.filled - self.offset
  }

  #[inline]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  #[inline]
  pub fn capacity(&self) -> usize {
    self.data.len()
  }

  pub fn as_slice(&self) -> &[u8] {
    &self.data[self.offset..self.filled]
  }

  pub fn fill<R: Read>(&mut self, reader: &mut R) -> io::Result<usize> {
    reader.read(&mut self.data[self.filled..]).map(|consumed| {
      self.filled += consumed;

      consumed
    })
  }

  pub fn resize(&mut self, size: usize) {
    if size > self.data.capacity() {
      self.data.reserve(size);

      let capacity = self.data.capacity();

      unsafe {
        self.data.set_len(capacity);
      }
    }

    if self.data.len() - self.filled < size  {
      let length      = self.filled - self.offset;
      let mut mut_ptr = self.data.as_mut_ptr();

      unsafe {
        let offset_ptr  = self.data.as_ptr().offset(self.offset as isize);

        ptr::copy(offset_ptr, mut_ptr, length);
      }

      self.filled -= self.offset;
      self.offset  = 0;
    }
  }

  pub fn consume(&mut self, consumed: usize) {
    self.offset += consumed;
  }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ParserState {
  Incomplete,
  EndOfInput,
}

fn fill<R: Read>(buffer: &mut Buffer, reader: &mut R, needed: usize)
                 -> io::Result<usize> {
  let mut read = 0;

  if buffer.len() < needed {
    buffer.resize(needed);

    while buffer.len() < needed {
      let size_read = try!(buffer.fill(reader));

      if size_read > 0 {
        read += size_read;
      } else {
        break;
      }
    }
  }

  Ok(read)
}

pub struct ReadStream<R: Read> {
  reader: R,
  buffer: Buffer,
  needed: usize,
  state: ParserState,
}

impl<R> ReadStream<R> where R: Read {
  pub fn new(reader: R) -> Self {
    ReadStream {
      reader: reader,
      buffer: Buffer::new(),
      needed: 0,
      state: ParserState::Incomplete,
    }
  }

  fn fill(&mut self) -> io::Result<usize> {
    let needed = self.needed;

    fill(&mut self.buffer, &mut self.reader, needed).map(|consumed| {
      if self.buffer.len() < needed {
        self.state = ParserState::EndOfInput;
      }

      consumed
    })
  }
}

fn from_iresult<T>(buffer: &Buffer, result: IResult<&[u8], T>)
                   -> Result<(usize, T), ErrorKind> {
  match result {
    IResult::Done(i, o)    => Ok((buffer.len() - i.len(), o)),
    IResult::Incomplete(n) => {
      let mut needed = buffer.capacity();

      if let Needed::Size(size) = n {
        needed = size;
      }

      Err(ErrorKind::Incomplete(needed))
    }
    IResult::Error(e)      => {
      if let Err::Position(_, i) = e {
        Err(ErrorKind::Consumed(buffer.len() - i.len()))
      } else {
        Err(ErrorKind::Unknown)
      }
    }
  }
}

impl<R> StreamProducer for ReadStream<R> where R: Read {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T> {
    if self.state != ParserState::EndOfInput {
      try!(self.fill().map_err(ErrorKind::IO));
    }

    let mut buffer = &mut self.buffer;

    if buffer.is_empty() {
      self.state = ParserState::EndOfInput;

      return Err(ErrorKind::EndOfInput);
    }

    let result = {
      let iresult = f(buffer.as_slice());

      from_iresult(&buffer, iresult)
    };

    match result {
      Ok((consumed, o)) => {
        buffer.consume(consumed);

        Ok(o)
      }
      Err(kind)         => {
        match kind {
          ErrorKind::Incomplete(needed) => self.needed = needed,
          ErrorKind::Consumed(consumed) => buffer.consume(consumed),
          _                             => (),
        }

        Err(kind)
      }
    }
  }
}
<|endoftext|>


<commit_before>#![cfg(target_os = "windows")]

extern crate user32;
extern crate kernel32;
extern crate winapi;
extern crate gdi32;

use Scale;
use Vsync;
use Key;

use std::ffi::CString;
use std::ptr;
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;
use std::mem;

use self::winapi::windef::HWND;
use self::winapi::winuser::WS_OVERLAPPEDWINDOW;
use self::winapi::winuser::WNDCLASSW;
use self::winapi::wingdi::BITMAPINFOHEADER;
use self::winapi::wingdi::RGBQUAD;

static mut CLOSE_APP: bool = false;

// Wrap this so we can have a proper numbef of bmiColors to write in
#[repr(C)]
struct BitmapInfo {
    pub bmi_header: BITMAPINFOHEADER,
    pub bmi_colors: [RGBQUAD; 3],
}

fn update_key_state(window: &mut Window, wparam: u32, bool state) {
    match wparam & 0x1ff {
        0x00B => window.keys[Key::Key0] = state,
        0x00B => window.keys[Key::Key0] = state,
        0x002 => window.keys[Key::Key1] = state,
        0x003 => window.keys[Key::Key2] = state,
        0x004 => window.keys[Key::Key3] = state,
        0x005 => window.keys[Key::Key4] = state,
        0x006 => window.keys[Key::Key5] = state,
        0x007 => window.keys[Key::Key6] = state,
        0x008 => window.keys[Key::Key7] = state,
        0x009 => window.keys[Key::Key8] = state,
        0x00A => window.keys[Key::Key9] = state,
        0x01E => window.keys[Key::A] = state,
        0x030 => window.keys[Key::B] = state,
        0x02E => window.keys[Key::C] = state,
        0x020 => window.keys[Key::D] = state,
        0x012 => window.keys[Key::E] = state,
        0x021 => window.keys[Key::F] = state,
        0x022 => window.keys[Key::G] = state,
        0x023 => window.keys[Key::H] = state,
        0x017 => window.keys[Key::I] = state,
        0x024 => window.keys[Key::J] = state,
        0x025 => window.keys[Key::K] = state,
        0x026 => window.keys[Key::L] = state,
        0x032 => window.keys[Key::M] = state,
        0x031 => window.keys[Key::N] = state,
        0x018 => window.keys[Key::O] = state,
        0x019 => window.keys[Key::P] = state,
        0x010 => window.keys[Key::Q] = state,
        0x013 => window.keys[Key::R] = state,
        0x01F => window.keys[Key::S] = state,
        0x014 => window.keys[Key::T] = state,
        0x016 => window.keys[Key::U] = state,
        0x02F => window.keys[Key::V] = state,
        0x011 => window.keys[Key::W] = state,
        0x02D => window.keys[Key::X] = state,
        0x015 => window.keys[Key::Y] = state,
        0x02C => window.keys[Key::Z] = state,
        0x03B => window.keys[Key::F1] = state,
        0x03C => window.keys[Key::F2] = state,
        0x03D => window.keys[Key::F3] = state,
        0x03E => window.keys[Key::F4] = state,
        0x03F => window.keys[Key::F5] = state,
        0x040 => window.keys[Key::F6] = state,
        0x041 => window.keys[Key::F7] = state,
        0x042 => window.keys[Key::F8] = state,
        0x043 => window.keys[Key::F9] = state,
        0x042 => window.keys[Key::F8] = state,
        0x043 => window.keys[Key::F9] = state,
        0x044 => window.keys[Key::F10] = state,
        0x057 => window.keys[Key::F11] = state,
        0x058 => window.keys[Key::F12] = state,
        0x150 => window.keys[Key::Down] = state,
        0x14B => window.keys[Key::Left] = state,
        0x14D => window.keys[Key::Right] = state,
        0x148 => window.keys[Key::Up] = state,
        0x028 => window.keys[Key::Apostrophe] = state,
        0x02B => window.keys[Key::Backslash] = state,
        0x033 => window.keys[Key::Comma] = state,
        0x00D => window.keys[Key::Equal] = state,
        0x01A => window.keys[Key::LeftBracket] = state,
        0x00C => window.keys[Key::Minus] = state,
        0x034 => window.keys[Key::Period] = state,
        0x01B => window.keys[Key::RightBracket] = state,
        0x027 => window.keys[Key::Semicolon] = state,
        0x035 => window.keys[Key::Slash] = state,
        0x00E => window.keys[Key::Backspace] = state,
        0x153 => window.keys[Key::Delete] = state,
        0x14F => window.keys[Key::End] = state,
        0x01C => window.keys[Key::Enter] = state,
        0x001 => window.keys[Key::Escape] = state,
        0x147 => window.keys[Key::Home] = state,
        0x152 => window.keys[Key::Insert] = state,
        0x15D => window.keys[Key::Menu] = state,
        0x151 => window.keys[Key::PageDown] = state,
        0x149 => window.keys[Key::PageUp] = state,
        0x045 => window.keys[Key::Pause] = state,
        0x039 => window.keys[Key::Space] = state,
        0x00F => window.keys[Key::Tab] = state,
        0x03A => window.keys[Key::CapsLock] = state,
    }
}

unsafe extern "system" fn wnd_proc(window: winapi::HWND,
                                   msg: winapi::UINT,
                                   wparam: winapi::WPARAM,
                                   lparam: winapi::LPARAM)
                                   -> winapi::LRESULT {
    // This make sure we actually don't do anything before the user data has been setup for the
    // window

    let user_data = user32::GetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA);

    if user_data == 0
        return user32::DefWindowProcW(window, msg, wparam, lparam);

    let mut self = user_data as &mut Window;

    match msg {
        winapi::winuser::WM_KEYDOWN => {
            update_key_state(self, wparam as u32, true);
            if (wparam & 0x1ff) == 27 {
                CLOSE_APP = true;
            }
        }

        winapi::winuser::WM_KEYUP => {
            update_key_state(self, wparam as u32, false);
        }

        winapi::winuser::WM_PAINT => {
            let mut rect: winapi::RECT = mem::uninitialized();

            user32::GetClientRect(window, &mut rect);

            let mut bitmap_info: BitmapInfo = mem::zeroed();
            let width = rect.right - rect.left;
            let height = rect.bottom - rect.top;

            bitmap_info.bmi_header.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
            bitmap_info.bmi_header.biPlanes = 1;
            bitmap_info.bmi_header.biBitCount = 32;
            bitmap_info.bmi_header.biCompression = winapi::wingdi::BI_BITFIELDS;
            bitmap_info.bmi_header.biWidth = width;
            bitmap_info.bmi_header.biHeight = -height;
            bitmap_info.bmi_colors[0].rgbRed = 0xff;
            bitmap_info.bmi_colors[1].rgbGreen = 0xff;
            bitmap_info.bmi_colors[2].rgbBlue = 0xff;

            gdi32::StretchDIBits(self.dc,
                                 0,
                                 0,
                                 width,
                                 height,
                                 0,
                                 0,
                                 width,
                                 height,
                                 mem::transmute(self.buffer),
                                 mem::transmute(&bitmap_info),
                                 winapi::wingdi::DIB_RGB_COLORS,
                                 winapi::wingdi::SRCCOPY);

            user32::ValidateRect(window, ptr::null_mut());
        }

        _ => (),
    }

    return user32::DefWindowProcW(window, msg, wparam, lparam);
}

pub enum MinifbError {
    UnableToCreateWindow,
}

fn to_wstring(str: &str) -> *const u16 {
    let v: Vec<u16> = OsStr::new(str).encode_wide().chain(Some(0).into_iter()).collect();
    v.as_ptr()
}

pub struct Window {
    dc: DC,
    window: HWND,
    bool keys_down: [bool; 512],
    buffer: &[u32],
}

impl Window {
    fn open_window(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> Result<Window, &str> {
        unsafe {
            let class_name = to_wstring("minifb_window");
            let s = CString::new(name).unwrap();

            let class = WNDCLASSW {
                style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC,
                lpfnWndProc: Some(wnd_proc),
                cbClsExtra: 0,
                cbWndExtra: 0,
                hInstance: kernel32::GetModuleHandleA(ptr::null()),
                hIcon: ptr::null_mut(),
                hCursor: ptr::null_mut(),
                hbrBackground: ptr::null_mut(),
                lpszMenuName: ptr::null(),
                lpszClassName: class_name,
            };

            user32::RegisterClassW(&class);

            let mut rect = winapi::RECT {
                left: 0,
                right: width as winapi::LONG,
                top: 0,
                bottom: height as winapi::LONG,
            };

            user32::AdjustWindowRect(&mut rect,
                                     winapi::WS_POPUP | winapi::WS_SYSMENU | winapi::WS_CAPTION,
                                     0);

            rect.right -= rect.left;
            rect.bottom -= rect.top;

            let handle = user32::CreateWindowExA(0,
                                                 "minifb_window".as_ptr() as *mut _,
                                                 s.as_ptr(),
                                                 winapi::WS_OVERLAPPEDWINDOW &
                                                 !winapi::WS_MAXIMIZEBOX &
                                                 !winapi::WS_THICKFRAME,
                                                 winapi::CW_USEDEFAULT,
                                                 winapi::CW_USEDEFAULT,
                                                 rect.right,
                                                 rect.bottom,
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut());

            if !handle.is_null() {
                user32::ShowWindow(handle, winapi::SW_NORMAL);
            }

            return handle;
        }
    }

    pub fn new(name: &str, width: usize, height: usize) -> Option<Minifb> {
        let handle = Minifb::open_window(name, width, height);

        match handle.is_null() {
            true => None,
            false => Some(Minifb { window: handle }),
        }
    }

    pub fn get_keys(&self -> Vec<Key> {
        let index = 0;
        let mut keys: Vec<Key> = Vec::new();

        for i in self.keys {
            if *i {
                keys.push(index as Key);
            }

            index += 1;
        }

        keys
    }

    pub fn update(&mut self, buffer: &[u32]) -> bool {
        unsafe {
            let mut msg = mem::uninitialized();

            user32::SetWindowLongPtrW(self.window, winapi::winuser::GWLP_USERDATA, self as i64);
            user32::InvalidateRect(self.window, ptr::null_mut(), winapi::TRUE);

            while user32::PeekMessageW(&mut msg, self.window, 0, 0, winapi::winuser::PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }
        }

        unsafe {
            return !CLOSE_APP;
        }
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            if self.dc.is_valid() {
                user32::ReleaseDC(self.window, self.dc);
            }

            if self.hwnd.is_valid() {
                user32::CloseWindow(self.hwnd);
            }
        }
    }
}
<commit_msg>Removed double Key0<commit_after>#![cfg(target_os = "windows")]

extern crate user32;
extern crate kernel32;
extern crate winapi;
extern crate gdi32;

use Scale;
use Vsync;
use Key;

use std::ffi::CString;
use std::ptr;
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;
use std::mem;

use self::winapi::windef::HWND;
use self::winapi::winuser::WS_OVERLAPPEDWINDOW;
use self::winapi::winuser::WNDCLASSW;
use self::winapi::wingdi::BITMAPINFOHEADER;
use self::winapi::wingdi::RGBQUAD;

static mut CLOSE_APP: bool = false;

// Wrap this so we can have a proper numbef of bmiColors to write in
#[repr(C)]
struct BitmapInfo {
    pub bmi_header: BITMAPINFOHEADER,
    pub bmi_colors: [RGBQUAD; 3],
}

fn update_key_state(window: &mut Window, wparam: u32, bool state) {
    match wparam & 0x1ff {
        0x00B => window.keys[Key::Key0] = state,
        0x002 => window.keys[Key::Key1] = state,
        0x003 => window.keys[Key::Key2] = state,
        0x004 => window.keys[Key::Key3] = state,
        0x005 => window.keys[Key::Key4] = state,
        0x006 => window.keys[Key::Key5] = state,
        0x007 => window.keys[Key::Key6] = state,
        0x008 => window.keys[Key::Key7] = state,
        0x009 => window.keys[Key::Key8] = state,
        0x00A => window.keys[Key::Key9] = state,
        0x01E => window.keys[Key::A] = state,
        0x030 => window.keys[Key::B] = state,
        0x02E => window.keys[Key::C] = state,
        0x020 => window.keys[Key::D] = state,
        0x012 => window.keys[Key::E] = state,
        0x021 => window.keys[Key::F] = state,
        0x022 => window.keys[Key::G] = state,
        0x023 => window.keys[Key::H] = state,
        0x017 => window.keys[Key::I] = state,
        0x024 => window.keys[Key::J] = state,
        0x025 => window.keys[Key::K] = state,
        0x026 => window.keys[Key::L] = state,
        0x032 => window.keys[Key::M] = state,
        0x031 => window.keys[Key::N] = state,
        0x018 => window.keys[Key::O] = state,
        0x019 => window.keys[Key::P] = state,
        0x010 => window.keys[Key::Q] = state,
        0x013 => window.keys[Key::R] = state,
        0x01F => window.keys[Key::S] = state,
        0x014 => window.keys[Key::T] = state,
        0x016 => window.keys[Key::U] = state,
        0x02F => window.keys[Key::V] = state,
        0x011 => window.keys[Key::W] = state,
        0x02D => window.keys[Key::X] = state,
        0x015 => window.keys[Key::Y] = state,
        0x02C => window.keys[Key::Z] = state,
        0x03B => window.keys[Key::F1] = state,
        0x03C => window.keys[Key::F2] = state,
        0x03D => window.keys[Key::F3] = state,
        0x03E => window.keys[Key::F4] = state,
        0x03F => window.keys[Key::F5] = state,
        0x040 => window.keys[Key::F6] = state,
        0x041 => window.keys[Key::F7] = state,
        0x042 => window.keys[Key::F8] = state,
        0x043 => window.keys[Key::F9] = state,
        0x042 => window.keys[Key::F8] = state,
        0x043 => window.keys[Key::F9] = state,
        0x044 => window.keys[Key::F10] = state,
        0x057 => window.keys[Key::F11] = state,
        0x058 => window.keys[Key::F12] = state,
        0x150 => window.keys[Key::Down] = state,
        0x14B => window.keys[Key::Left] = state,
        0x14D => window.keys[Key::Right] = state,
        0x148 => window.keys[Key::Up] = state,
        0x028 => window.keys[Key::Apostrophe] = state,
        0x02B => window.keys[Key::Backslash] = state,
        0x033 => window.keys[Key::Comma] = state,
        0x00D => window.keys[Key::Equal] = state,
        0x01A => window.keys[Key::LeftBracket] = state,
        0x00C => window.keys[Key::Minus] = state,
        0x034 => window.keys[Key::Period] = state,
        0x01B => window.keys[Key::RightBracket] = state,
        0x027 => window.keys[Key::Semicolon] = state,
        0x035 => window.keys[Key::Slash] = state,
        0x00E => window.keys[Key::Backspace] = state,
        0x153 => window.keys[Key::Delete] = state,
        0x14F => window.keys[Key::End] = state,
        0x01C => window.keys[Key::Enter] = state,
        0x001 => window.keys[Key::Escape] = state,
        0x147 => window.keys[Key::Home] = state,
        0x152 => window.keys[Key::Insert] = state,
        0x15D => window.keys[Key::Menu] = state,
        0x151 => window.keys[Key::PageDown] = state,
        0x149 => window.keys[Key::PageUp] = state,
        0x045 => window.keys[Key::Pause] = state,
        0x039 => window.keys[Key::Space] = state,
        0x00F => window.keys[Key::Tab] = state,
        0x03A => window.keys[Key::CapsLock] = state,
    }
}

unsafe extern "system" fn wnd_proc(window: winapi::HWND,
                                   msg: winapi::UINT,
                                   wparam: winapi::WPARAM,
                                   lparam: winapi::LPARAM)
                                   -> winapi::LRESULT {
    // This make sure we actually don't do anything before the user data has been setup for the
    // window

    let user_data = user32::GetWindowLongPtrW(window, winapi::winuser::GWLP_USERDATA);

    if user_data == 0
        return user32::DefWindowProcW(window, msg, wparam, lparam);

    let mut self = user_data as &mut Window;

    match msg {
        winapi::winuser::WM_KEYDOWN => {
            update_key_state(self, wparam as u32, true);
            if (wparam & 0x1ff) == 27 {
                CLOSE_APP = true;
            }
        }

        winapi::winuser::WM_KEYUP => {
            update_key_state(self, wparam as u32, false);
        }

        winapi::winuser::WM_PAINT => {
            let mut rect: winapi::RECT = mem::uninitialized();

            user32::GetClientRect(window, &mut rect);

            let mut bitmap_info: BitmapInfo = mem::zeroed();
            let width = rect.right - rect.left;
            let height = rect.bottom - rect.top;

            bitmap_info.bmi_header.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
            bitmap_info.bmi_header.biPlanes = 1;
            bitmap_info.bmi_header.biBitCount = 32;
            bitmap_info.bmi_header.biCompression = winapi::wingdi::BI_BITFIELDS;
            bitmap_info.bmi_header.biWidth = width;
            bitmap_info.bmi_header.biHeight = -height;
            bitmap_info.bmi_colors[0].rgbRed = 0xff;
            bitmap_info.bmi_colors[1].rgbGreen = 0xff;
            bitmap_info.bmi_colors[2].rgbBlue = 0xff;

            gdi32::StretchDIBits(self.dc,
                                 0,
                                 0,
                                 width,
                                 height,
                                 0,
                                 0,
                                 width,
                                 height,
                                 mem::transmute(self.buffer),
                                 mem::transmute(&bitmap_info),
                                 winapi::wingdi::DIB_RGB_COLORS,
                                 winapi::wingdi::SRCCOPY);

            user32::ValidateRect(window, ptr::null_mut());
        }

        _ => (),
    }

    return user32::DefWindowProcW(window, msg, wparam, lparam);
}

pub enum MinifbError {
    UnableToCreateWindow,
}

fn to_wstring(str: &str) -> *const u16 {
    let v: Vec<u16> = OsStr::new(str).encode_wide().chain(Some(0).into_iter()).collect();
    v.as_ptr()
}

pub struct Window {
    dc: DC,
    window: HWND,
    bool keys_down: [bool; 512],
    buffer: &[u32],
}

impl Window {
    fn open_window(name: &str, width: usize, height: usize, _: Scale, _: Vsync) -> Result<Window, &str> {
        unsafe {
            let class_name = to_wstring("minifb_window");
            let s = CString::new(name).unwrap();

            let class = WNDCLASSW {
                style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC,
                lpfnWndProc: Some(wnd_proc),
                cbClsExtra: 0,
                cbWndExtra: 0,
                hInstance: kernel32::GetModuleHandleA(ptr::null()),
                hIcon: ptr::null_mut(),
                hCursor: ptr::null_mut(),
                hbrBackground: ptr::null_mut(),
                lpszMenuName: ptr::null(),
                lpszClassName: class_name,
            };

            user32::RegisterClassW(&class);

            let mut rect = winapi::RECT {
                left: 0,
                right: width as winapi::LONG,
                top: 0,
                bottom: height as winapi::LONG,
            };

            user32::AdjustWindowRect(&mut rect,
                                     winapi::WS_POPUP | winapi::WS_SYSMENU | winapi::WS_CAPTION,
                                     0);

            rect.right -= rect.left;
            rect.bottom -= rect.top;

            let handle = user32::CreateWindowExA(0,
                                                 "minifb_window".as_ptr() as *mut _,
                                                 s.as_ptr(),
                                                 winapi::WS_OVERLAPPEDWINDOW &
                                                 !winapi::WS_MAXIMIZEBOX &
                                                 !winapi::WS_THICKFRAME,
                                                 winapi::CW_USEDEFAULT,
                                                 winapi::CW_USEDEFAULT,
                                                 rect.right,
                                                 rect.bottom,
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut(),
                                                 ptr::null_mut());

            if !handle.is_null() {
                user32::ShowWindow(handle, winapi::SW_NORMAL);
            }

            return handle;
        }
    }

    pub fn new(name: &str, width: usize, height: usize) -> Option<Minifb> {
        let handle = Minifb::open_window(name, width, height);

        match handle.is_null() {
            true => None,
            false => Some(Minifb { window: handle }),
        }
    }

    pub fn get_keys(&self -> Vec<Key> {
        let index = 0;
        let mut keys: Vec<Key> = Vec::new();

        for i in self.keys {
            if *i {
                keys.push(index as Key);
            }

            index += 1;
        }

        keys
    }

    pub fn update(&mut self, buffer: &[u32]) -> bool {
        unsafe {
            let mut msg = mem::uninitialized();

            user32::SetWindowLongPtrW(self.window, winapi::winuser::GWLP_USERDATA, self as i64);
            user32::InvalidateRect(self.window, ptr::null_mut(), winapi::TRUE);

            while user32::PeekMessageW(&mut msg, self.window, 0, 0, winapi::winuser::PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }
        }

        unsafe {
            return !CLOSE_APP;
        }
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        unsafe {
            if self.dc.is_valid() {
                user32::ReleaseDC(self.window, self.dc);
            }

            if self.hwnd.is_valid() {
                user32::CloseWindow(self.hwnd);
            }
        }
    }
}
<|endoftext|>