<commit_before>//! AccReader is like a BufReader, but supports partial consumption
//! import new data with `fill_buf`, get the current buffer with
//! `current_slice`, and indicate with `consume` how many bytes
//! were used

use crate::buffer::Buffered;
use std::cmp;
use std::io;
use std::io::{BufRead, Read, Result, Seek, SeekFrom};
use std::iter;
use std::iter::Iterator;

pub struct AccReader<R> {
    inner: R,
    buf: Vec<u8>,
    pos: usize,
    end: usize,
    // position in the stream of the buffer's beginning
    index: usize,
}

impl<R: Read + Seek> AccReader<R> {
    pub fn new(inner: R) -> AccReader<R> {
        AccReader::with_capacity(4096, inner)
    }

    pub fn with_capacity(cap: usize, inner: R) -> AccReader<R> {
        let mut buf = vec![0; cap];
        buf.extend(iter::repeat(0).take(cap));
        AccReader {
            inner,
            buf,
            pos: 0,
            end: 0,
            index: 0,
        }
    }

    /// Gets a reference to the underlying reader.
    pub fn get_ref(&self) -> &R {
        &self.inner
    }

    /// Gets a mutable reference to the underlying reader.
    pub fn get_mut(&mut self) -> &mut R {
        &mut self.inner
    }

    /// Unwraps this `AccReader`, returning the underlying reader.
    ///
    /// Note that any leftover data in the internal buffer is lost.
    pub fn into_inner(self) -> R {
        self.inner
    }

    pub fn reset_buffer_position(&mut self) {
        trace!(
            "resetting buffer at pos: {} capacity: {}",
            self.pos,
            self.end
        );
        if self.end - self.pos > 0 {
            for i in 0..(self.end - self.pos) {
                trace!("buf[{}] = buf[{}]", i, self.pos + i);
                self.buf[i] = self.buf[self.pos + i];
            }
        }
        self.end -= self.pos;
        self.pos = 0;
    }

    pub fn current_slice(&self) -> &[u8] {
        trace!("current slice pos: {}, cap: {}", self.pos, self.end);
        &self.buf[self.pos..self.end]
    }

    pub fn capacity(&self) -> usize {
        self.end - self.pos
    }
}

impl<R: Read + Seek + Send> Buffered for AccReader<R> {
    fn data(&self) -> &[u8] {
        &self.buf[self.pos..self.end]
    }
    fn grow(&mut self, len: usize) {
        let l = self.buf.len() + len;
        self.buf.resize(l, 0);
    }
}

impl<R: Read + Seek> Read for AccReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        trace!(
            "read pos: {} cap: {} buflen: {}",
            self.pos,
            self.end,
            buf.len()
        );
        if buf.len() < self.end - self.pos {
            match (&self.buf[self.pos..(self.pos + buf.len())]).read(buf) {
                Ok(len) => {
                    self.consume(len);
                    Ok(len)
                }
                Err(e) => Err(e),
            }
        } else {
            // If we don't have any buffered data and we're doing a massive read
            // (larger than our internal buffer), bypass our internal buffer
            // entirely.
            if buf.len() > self.buf.len() {
                match (&self.buf[self.pos..self.end]).read(buf) {
                    Ok(len) => {
                        self.consume(len);
                        self.inner.read(&mut buf[self.end..])
                    }
                    Err(e) => Err(e),
                }
            } else {
                let nread = {
                    let mut rem = self.fill_buf()?;
                    rem.read(buf)?
                };
                self.consume(nread);
                Ok(nread)
            }
        }
    }
}

impl<R: Read + Seek> BufRead for AccReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        // trace!("fillbuf current: {:?}", str::from_utf8(&self.buf[self.pos..self.end]).unwrap());
        if self.pos != 0 || self.end != self.buf.len() {
            self.reset_buffer_position();
            trace!("buffer reset ended");
            let read = self.inner.read(&mut self.buf[self.end..])?;
            self.end += read;
            trace!(
                "new pos: {} and cap: {} -> current: {:?}",
                self.pos,
                self.end,
                &self.buf[self.pos..self.end]
            );
        }
        Ok(&self.buf[self.pos..self.end])
    }

    fn consume(&mut self, amt: usize) {
        trace!("consumed {} bytes", amt);
        self.pos = cmp::min(self.pos + amt, self.end);
        self.index += amt;
    }
}

impl<R: Read + Seek> Seek for AccReader<R> {
    fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
        match pos {
            SeekFrom::Start(sz) => {
                let mv = sz as usize;
                if mv >= self.index && mv < self.index + self.end - self.pos {
                    self.pos += mv - self.index;
                    self.index = mv;

                    return Ok(mv as u64);
                }
            }
            SeekFrom::End(_) => {}
            SeekFrom::Current(sz) => {
                if sz >= 0 && sz as usize <= self.end - self.pos {
                    self.index = sz as usize;
                    self.pos += sz as usize;
                    return Ok(sz as u64);
                }
            }
        };

        match self.inner.seek(pos) {
            Ok(sz) => {
                self.index = sz as usize;
                self.pos = 0;
                self.end = 0;
                self.fill_buf()?;
                Ok(sz)
            }
            Err(e) => Err(e),
        }
    }
}
// impl<R> fmt::Debug for AccReader<R> where R: fmt::Debug {
// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
// fmt.debug_struct("AccReader")
// .field("reader", &self.inner)
// .field("buffer", &format_args!("{}/{}", self.end - self.pos, self.buf.len()))
// .finish()
// }
// }

#[cfg(test)]
mod tests {
    use super::*;
    use crate::buffer::Buffered;
    use std::io::{BufRead, Cursor};

    #[test]
    fn acc_reader_test() {
        let buf = b"AAAA\nAAAB\nAAACAAADAAAEAAAF\ndabcdEEEE";
        let c = Cursor::new(&buf[..]);

        let acc = AccReader::with_capacity(20, c);

        assert_eq!(4, acc.lines().count());
    }

    #[test]
    fn grow() {
        let buf = b"abcdefghilmnopqrst";
        let c = Cursor::new(&buf[..]);

        let mut acc = AccReader::with_capacity(4, c);
        acc.fill_buf().unwrap();
        acc.consume(2);
        acc.grow(4);
        assert_eq!(b"cd", acc.data());
        acc.fill_buf().unwrap();
        assert_eq!(b"cdefghil", acc.data());
    }
}
<commit_msg>vec![] might allocate a buffer with a different capacity<commit_after>//! AccReader is like a BufReader, but supports partial consumption
//! import new data with `fill_buf`, get the current buffer with
//! `current_slice`, and indicate with `consume` how many bytes
//! were used

use crate::buffer::Buffered;
use std::cmp;
use std::io;
use std::io::{BufRead, Read, Result, Seek, SeekFrom};
use std::iter;
use std::iter::Iterator;

pub struct AccReader<R> {
    inner: R,
    buf: Vec<u8>,
    pos: usize,
    end: usize,
    // position in the stream of the buffer's beginning
    index: usize,
}

impl<R: Read + Seek> AccReader<R> {
    pub fn new(inner: R) -> AccReader<R> {
        AccReader::with_capacity(4096, inner)
    }

    pub fn with_capacity(cap: usize, inner: R) -> AccReader<R> {
        AccReader {
            inner,
            buf: iter::repeat(0).take(cap).collect::<Vec<_>>(),
            pos: 0,
            end: 0,
            index: 0,
        }
    }

    /// Gets a reference to the underlying reader.
    pub fn get_ref(&self) -> &R {
        &self.inner
    }

    /// Gets a mutable reference to the underlying reader.
    pub fn get_mut(&mut self) -> &mut R {
        &mut self.inner
    }

    /// Unwraps this `AccReader`, returning the underlying reader.
    ///
    /// Note that any leftover data in the internal buffer is lost.
    pub fn into_inner(self) -> R {
        self.inner
    }

    pub fn reset_buffer_position(&mut self) {
        trace!(
            "resetting buffer at pos: {} capacity: {}",
            self.pos,
            self.end
        );
        if self.end - self.pos > 0 {
            for i in 0..(self.end - self.pos) {
                trace!("buf[{}] = buf[{}]", i, self.pos + i);
                self.buf[i] = self.buf[self.pos + i];
            }
        }
        self.end -= self.pos;
        self.pos = 0;
    }

    pub fn current_slice(&self) -> &[u8] {
        trace!("current slice pos: {}, cap: {}", self.pos, self.end);
        &self.buf[self.pos..self.end]
    }

    pub fn capacity(&self) -> usize {
        self.end - self.pos
    }
}

impl<R: Read + Seek + Send> Buffered for AccReader<R> {
    fn data(&self) -> &[u8] {
        &self.buf[self.pos..self.end]
    }
    fn grow(&mut self, len: usize) {
        let l = self.buf.len() + len;
        self.buf.resize(l, 0);
    }
}

impl<R: Read + Seek> Read for AccReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        trace!(
            "read pos: {} cap: {} buflen: {}",
            self.pos,
            self.end,
            buf.len()
        );
        if buf.len() < self.end - self.pos {
            match (&self.buf[self.pos..(self.pos + buf.len())]).read(buf) {
                Ok(len) => {
                    self.consume(len);
                    Ok(len)
                }
                Err(e) => Err(e),
            }
        } else {
            // If we don't have any buffered data and we're doing a massive read
            // (larger than our internal buffer), bypass our internal buffer
            // entirely.
            if buf.len() > self.buf.len() {
                match (&self.buf[self.pos..self.end]).read(buf) {
                    Ok(len) => {
                        self.consume(len);
                        self.inner.read(&mut buf[self.end..])
                    }
                    Err(e) => Err(e),
                }
            } else {
                let nread = {
                    let mut rem = self.fill_buf()?;
                    rem.read(buf)?
                };
                self.consume(nread);
                Ok(nread)
            }
        }
    }
}

impl<R: Read + Seek> BufRead for AccReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        // trace!("fillbuf current: {:?}", str::from_utf8(&self.buf[self.pos..self.end]).unwrap());
        if self.pos != 0 || self.end != self.buf.len() {
            self.reset_buffer_position();
            trace!("buffer reset ended");
            let read = self.inner.read(&mut self.buf[self.end..])?;
            self.end += read;
            trace!(
                "new pos: {} and cap: {} -> current: {:?}",
                self.pos,
                self.end,
                &self.buf[self.pos..self.end]
            );
        }
        Ok(&self.buf[self.pos..self.end])
    }

    fn consume(&mut self, amt: usize) {
        trace!("consumed {} bytes", amt);
        self.pos = cmp::min(self.pos + amt, self.end);
        self.index += amt;
    }
}

impl<R: Read + Seek> Seek for AccReader<R> {
    fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
        match pos {
            SeekFrom::Start(sz) => {
                let mv = sz as usize;
                if mv >= self.index && mv < self.index + self.end - self.pos {
                    self.pos += mv - self.index;
                    self.index = mv;

                    return Ok(mv as u64);
                }
            }
            SeekFrom::End(_) => {}
            SeekFrom::Current(sz) => {
                if sz >= 0 && sz as usize <= self.end - self.pos {
                    self.index = sz as usize;
                    self.pos += sz as usize;
                    return Ok(sz as u64);
                }
            }
        };

        match self.inner.seek(pos) {
            Ok(sz) => {
                self.index = sz as usize;
                self.pos = 0;
                self.end = 0;
                self.fill_buf()?;
                Ok(sz)
            }
            Err(e) => Err(e),
        }
    }
}
// impl<R> fmt::Debug for AccReader<R> where R: fmt::Debug {
// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
// fmt.debug_struct("AccReader")
// .field("reader", &self.inner)
// .field("buffer", &format_args!("{}/{}", self.end - self.pos, self.buf.len()))
// .finish()
// }
// }

#[cfg(test)]
mod tests {
    use super::*;
    use crate::buffer::Buffered;
    use std::io::{BufRead, Cursor};

    #[test]
    fn acc_reader_test() {
        let buf = b"AAAA\nAAAB\nAAACAAADAAAEAAAF\ndabcdEEEE";
        let c = Cursor::new(&buf[..]);

        let acc = AccReader::with_capacity(20, c);

        assert_eq!(4, acc.lines().count());
    }

    #[test]
    fn grow() {
        let buf = b"abcdefghilmnopqrst";
        let c = Cursor::new(&buf[..]);

        let mut acc = AccReader::with_capacity(4, c);
        acc.fill_buf().unwrap();
        assert_eq!(b"abcd", acc.data());
        acc.consume(2);
        assert_eq!(b"cd", acc.data());
        acc.grow(4);
        assert_eq!(b"cd", acc.data());
        acc.fill_buf().unwrap();
        assert_eq!(b"cdefghil", acc.data());
    }
}
<|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/. */

use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf8_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf16_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_wide_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}
<commit_msg>implement cef_string_utf8_to_utf16()<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/. */

use encoding::{Encoding, EncodeStrict};
use encoding::all::{UTF_16LE};
use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::string;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf8_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    unsafe {
       let result = UTF_16LE.encode(string::raw::from_buf_len(src, src_len as uint).as_slice(), EncodeStrict);
       if result.is_err() { return 0; }
       cef_string_utf16_set(mem::transmute(result.unwrap().as_slice().as_ptr()), (src_len * 2) as size_t, output, 1);
    }
    1
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf16_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_wide_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}
<|endoftext|>


<commit_before>//! A synchronous client for the PostgreSQL database.
//!
//! # Example
//!
//! ```no_run
//! use postgres::{Client, NoTls};
//!
//! # fn main() -> Result<(), postgres::Error> {
//! let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
//!
//! client.simple_query("
//!     CREATE TABLE person (
//!         id      SERIAL PRIMARY KEY,
//!         name    TEXT NOT NULL,
//!         data    BYTEA
//!     )
//! ")?;
//!
//! let name = "Ferris";
//! let data = None::<&[u8]>;
//! client.execute(
//!     "INSERT INTO person (name, data) VALUES ($1, $2)",
//!     &[&name, &data],
//! )?;
//!
//! for row in client.query("SELECT id, name, data FROM person", &[])? {
//!     let id: i32 = row.get(0);
//!     let name: &str = row.get(1);
//!     let data: Option<&[u8]> = row.get(2);
//!
//!     println!("found person: {} {} {:?}", id, name, data);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Implementation
//!
//! This crate is a lightweight wrapper over tokio-postgres. The `postgres::Client` is simply a wrapper around a
//! `tokio_postgres::Client` along side a tokio `Runtime`. The client simply blocks on the futures provided by the async
//! client.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
//! crates, respectively.
#![doc(html_root_url = "https://docs.rs/postgres/0.17")]
#![warn(clippy::all, rust_2018_idioms, missing_docs)]

pub use fallible_iterator;
pub use tokio_postgres::{
    error, row, tls, types, Column, Portal, SimpleQueryMessage, Socket, Statement, ToStatement,
};

pub use crate::client::*;
pub use crate::config::Config;
pub use crate::copy_in_writer::CopyInWriter;
pub use crate::copy_out_reader::CopyOutReader;
#[doc(no_inline)]
pub use crate::error::Error;
#[doc(no_inline)]
pub use crate::row::{Row, SimpleQueryRow};
pub use crate::row_iter::RowIter;
#[doc(no_inline)]
pub use crate::tls::NoTls;
pub use crate::transaction::*;

pub mod binary_copy;
mod client;
pub mod config;
mod copy_in_writer;
mod copy_out_reader;
mod lazy_pin;
mod row_iter;
mod transaction;

#[cfg(test)]
mod test;
<commit_msg>Use batch_execute in example<commit_after>//! A synchronous client for the PostgreSQL database.
//!
//! # Example
//!
//! ```no_run
//! use postgres::{Client, NoTls};
//!
//! # fn main() -> Result<(), postgres::Error> {
//! let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
//!
//! client.batch_execute("
//!     CREATE TABLE person (
//!         id      SERIAL PRIMARY KEY,
//!         name    TEXT NOT NULL,
//!         data    BYTEA
//!     )
//! ")?;
//!
//! let name = "Ferris";
//! let data = None::<&[u8]>;
//! client.execute(
//!     "INSERT INTO person (name, data) VALUES ($1, $2)",
//!     &[&name, &data],
//! )?;
//!
//! for row in client.query("SELECT id, name, data FROM person", &[])? {
//!     let id: i32 = row.get(0);
//!     let name: &str = row.get(1);
//!     let data: Option<&[u8]> = row.get(2);
//!
//!     println!("found person: {} {} {:?}", id, name, data);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Implementation
//!
//! This crate is a lightweight wrapper over tokio-postgres. The `postgres::Client` is simply a wrapper around a
//! `tokio_postgres::Client` along side a tokio `Runtime`. The client simply blocks on the futures provided by the async
//! client.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
//! crates, respectively.
#![doc(html_root_url = "https://docs.rs/postgres/0.17")]
#![warn(clippy::all, rust_2018_idioms, missing_docs)]

pub use fallible_iterator;
pub use tokio_postgres::{
    error, row, tls, types, Column, Portal, SimpleQueryMessage, Socket, Statement, ToStatement,
};

pub use crate::client::*;
pub use crate::config::Config;
pub use crate::copy_in_writer::CopyInWriter;
pub use crate::copy_out_reader::CopyOutReader;
#[doc(no_inline)]
pub use crate::error::Error;
#[doc(no_inline)]
pub use crate::row::{Row, SimpleQueryRow};
pub use crate::row_iter::RowIter;
#[doc(no_inline)]
pub use crate::tls::NoTls;
pub use crate::transaction::*;

pub mod binary_copy;
mod client;
pub mod config;
mod copy_in_writer;
mod copy_out_reader;
mod lazy_pin;
mod row_iter;
mod transaction;

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>use env_logger::{Env, DEFAULT_FILTER_ENV};
use godcoin::prelude::*;
use log::info;
use std::{
    env,
    path::{Path, PathBuf},
};

fn main() {
    env_logger::init_from_env(Env::new().filter_or(DEFAULT_FILTER_ENV, "godcoin=info,actix=info"));
    godcoin::init().unwrap();
    let sys = actix::System::new("godcoin-server");

    let home: PathBuf = {
        let home = {
            use dirs;
            match env::var("GODCOIN_HOME") {
                Ok(s) => PathBuf::from(s),
                Err(_) => Path::join(&dirs::data_local_dir().unwrap(), "godcoin"),
            }
        };
        if !Path::is_dir(&home) {
            let res = std::fs::create_dir(&home);
            res.unwrap_or_else(|_| panic!("Failed to create dir at {:?}", &home));
            info!("Created GODcoin home at {:?}", &home);
        } else {
            info!("Found GODcoin home at {:?}", &home);
        }
        home
    };

    let minter_key = {
        let key =
            env::var("GODCOIN_MINTER_KEY").expect("GODCOIN_MINTER_KEY is required to init server");
        PrivateKey::from_wif(&key).expect("GODCOIN_MINTER_KEY is invalid")
    };

    let bind_addr = env::var("GODCOIN_BIND_ADDR").unwrap_or_else(|_| "127.0.0.1:7777".to_owned());

    godcoin_server::start(godcoin_server::ServerConfig {
        home,
        minter_key,
        bind_addr,
    });

    sys.run().unwrap();
}
<commit_msg>Remove unnecessary import<commit_after>use env_logger::{Env, DEFAULT_FILTER_ENV};
use godcoin::prelude::*;
use log::info;
use std::{
    env,
    path::{Path, PathBuf},
};

fn main() {
    env_logger::init_from_env(Env::new().filter_or(DEFAULT_FILTER_ENV, "godcoin=info,actix=info"));
    godcoin::init().unwrap();
    let sys = actix::System::new("godcoin-server");

    let home: PathBuf = {
        let home = {
            match env::var("GODCOIN_HOME") {
                Ok(s) => PathBuf::from(s),
                Err(_) => Path::join(&dirs::data_local_dir().unwrap(), "godcoin"),
            }
        };
        if !Path::is_dir(&home) {
            let res = std::fs::create_dir(&home);
            res.unwrap_or_else(|_| panic!("Failed to create dir at {:?}", &home));
            info!("Created GODcoin home at {:?}", &home);
        } else {
            info!("Found GODcoin home at {:?}", &home);
        }
        home
    };

    let minter_key = {
        let key =
            env::var("GODCOIN_MINTER_KEY").expect("GODCOIN_MINTER_KEY is required to init server");
        PrivateKey::from_wif(&key).expect("GODCOIN_MINTER_KEY is invalid")
    };

    let bind_addr = env::var("GODCOIN_BIND_ADDR").unwrap_or_else(|_| "127.0.0.1:7777".to_owned());

    godcoin_server::start(godcoin_server::ServerConfig {
        home,
        minter_key,
        bind_addr,
    });

    sys.run().unwrap();
}
<|endoftext|>


<commit_before>//! Parsing interface for parsing a token stream into a syntax tree node.

use std::cell::Cell;
use std::fmt::Display;
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::rc::Rc;

use proc_macro2::{Ident, Span};

use buffer::Cursor;
use error;

pub use error::{Error, Result};
pub use lookahead::{Lookahead1, Peek};

/// Parsing interface implemented by all types that can be parsed in a default
/// way from a token stream.
pub trait Parse: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

/// Input to a Syn parser function.
pub type ParseStream<'a> = &'a ParseBuffer<'a>;

/// Cursor position within a buffered token stream.
#[derive(Clone)]
pub struct ParseBuffer<'a> {
    scope: Span,
    cell: Cell<Cursor<'static>>,
    marker: PhantomData<Cursor<'a>>,
    unexpected: Rc<Cell<Option<Span>>>,
}

impl<'a> Drop for ParseBuffer<'a> {
    fn drop(&mut self) {
        if !self.is_empty() && self.unexpected.get().is_none() {
            self.unexpected.set(Some(self.cursor().span()));
        }
    }
}

// Not public API.
#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct StepCursor<'c, 'a> {
    scope: Span,
    cursor: Cursor<'c>,
    marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
}

impl<'c, 'a> Deref for StepCursor<'c, 'a> {
    type Target = Cursor<'c>;

    fn deref(&self) -> &Self::Target {
        &self.cursor
    }
}

impl<'c, 'a> StepCursor<'c, 'a> {
    // Not public API.
    #[doc(hidden)]
    pub fn advance(self, other: Cursor<'c>) -> Cursor<'a> {
        unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(other) }
    }

    // Not public API.
    #[doc(hidden)]
    pub fn error<T: Display>(self, message: T) -> Error {
        error::new_at(self.scope, self.cursor, message)
    }
}

impl<'a> ParseBuffer<'a> {
    // Not public API.
    #[doc(hidden)]
    pub fn new(scope: Span, cursor: Cursor<'a>, unexpected: Rc<Cell<Option<Span>>>) -> Self {
        let extend = unsafe { mem::transmute::<Cursor<'a>, Cursor<'static>>(cursor) };
        ParseBuffer {
            scope: scope,
            cell: Cell::new(extend),
            marker: PhantomData,
            unexpected: unexpected,
        }
    }

    pub fn cursor(&self) -> Cursor<'a> {
        self.cell.get()
    }

    pub fn is_empty(&self) -> bool {
        self.cursor().eof()
    }

    pub fn lookahead1(&self) -> Lookahead1<'a> {
        Lookahead1::new(self.scope, self.cursor())
    }

    pub fn parse<T: Parse>(&self) -> Result<T> {
        self.check_unexpected()?;
        T::parse(self)
    }

    // Not public API.
    #[doc(hidden)]
    pub fn step_cursor<F, R>(&self, function: F) -> Result<R>
    where
        F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
    {
        self.check_unexpected()?;
        match function(StepCursor {
            scope: self.scope,
            cursor: self.cell.get(),
            marker: PhantomData,
        }) {
            Ok((ret, cursor)) => {
                self.cell.set(cursor);
                Ok(ret)
            }
            Err(err) => Err(err),
        }
    }

    // Not public API.
    #[doc(hidden)]
    pub fn get_unexpected(&self) -> Rc<Cell<Option<Span>>> {
        self.unexpected.clone()
    }

    // Not public API.
    #[doc(hidden)]
    pub fn check_unexpected(&self) -> Result<()> {
        match self.unexpected.get() {
            Some(span) => Err(Error::new(span, "unexpected token")),
            None => Ok(()),
        }
    }
}

impl Parse for Ident {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step_cursor(|cursor| {
            if let Some((ident, rest)) = cursor.ident() {
                match ident.to_string().as_str() {
                    "_"
                    // Based on https://doc.rust-lang.org/grammar.html#keywords
                    // and https://github.com/rust-lang/rfcs/blob/master/text/2421-unreservations-2018.md
                    | "abstract" | "as" | "become" | "box" | "break" | "const"
                    | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
                    | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
                    | "mod" | "move" | "mut" | "override" | "priv" | "proc" | "pub"
                    | "ref" | "return" | "Self" | "self" | "static" | "struct"
                    | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
                    | "virtual" | "where" | "while" | "yield" => {}
                    _ => return Ok((ident, rest)),
                }
            }
            Err(cursor.error("expected identifier"))
        })
    }
}

// In reality the impl would be for Punctuated.
impl<T: Parse> Parse for Vec<T> {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut vec = Vec::new();
        while !input.is_empty() {
            let t = input.parse::<T>()?;
            vec.push(t);
        }
        Ok(vec)
    }
}
<commit_msg>Add some ParseBuffer utilities<commit_after>//! Parsing interface for parsing a token stream into a syntax tree node.

use std::cell::Cell;
use std::fmt::Display;
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::rc::Rc;

use proc_macro2::{Ident, Span};

use buffer::Cursor;
use error;
use synom::PResult;

pub use error::{Error, Result};
pub use lookahead::{Lookahead1, Peek};

/// Parsing interface implemented by all types that can be parsed in a default
/// way from a token stream.
pub trait Parse: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

/// Input to a Syn parser function.
pub type ParseStream<'a> = &'a ParseBuffer<'a>;

/// Cursor position within a buffered token stream.
#[derive(Clone)]
pub struct ParseBuffer<'a> {
    scope: Span,
    cell: Cell<Cursor<'static>>,
    marker: PhantomData<Cursor<'a>>,
    unexpected: Rc<Cell<Option<Span>>>,
}

impl<'a> Drop for ParseBuffer<'a> {
    fn drop(&mut self) {
        if !self.is_empty() && self.unexpected.get().is_none() {
            self.unexpected.set(Some(self.cursor().span()));
        }
    }
}

// Not public API.
#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct StepCursor<'c, 'a> {
    scope: Span,
    cursor: Cursor<'c>,
    marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
}

impl<'c, 'a> Deref for StepCursor<'c, 'a> {
    type Target = Cursor<'c>;

    fn deref(&self) -> &Self::Target {
        &self.cursor
    }
}

impl<'c, 'a> StepCursor<'c, 'a> {
    // Not public API.
    #[doc(hidden)]
    pub fn advance(self, other: Cursor<'c>) -> Cursor<'a> {
        unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(other) }
    }

    // Not public API.
    #[doc(hidden)]
    pub fn error<T: Display>(self, message: T) -> Error {
        error::new_at(self.scope, self.cursor, message)
    }
}

impl<'a> ParseBuffer<'a> {
    // Not public API.
    #[doc(hidden)]
    pub fn new(scope: Span, cursor: Cursor<'a>, unexpected: Rc<Cell<Option<Span>>>) -> Self {
        let extend = unsafe { mem::transmute::<Cursor<'a>, Cursor<'static>>(cursor) };
        ParseBuffer {
            scope: scope,
            cell: Cell::new(extend),
            marker: PhantomData,
            unexpected: unexpected,
        }
    }

    pub fn cursor(&self) -> Cursor<'a> {
        self.cell.get()
    }

    pub fn is_empty(&self) -> bool {
        self.cursor().eof()
    }

    pub fn lookahead1(&self) -> Lookahead1<'a> {
        Lookahead1::new(self.scope, self.cursor())
    }

    pub fn parse<T: Parse>(&self) -> Result<T> {
        self.check_unexpected()?;
        T::parse(self)
    }

    pub fn peek<T: Peek>(&self, token: T) -> bool {
        self.lookahead1().peek(token)
    }

    pub fn fork(&self) -> Self {
        self.clone()
    }

    // Not public API.
    #[doc(hidden)]
    pub fn step_cursor<F, R>(&self, function: F) -> Result<R>
    where
        F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
    {
        self.check_unexpected()?;
        match function(StepCursor {
            scope: self.scope,
            cursor: self.cell.get(),
            marker: PhantomData,
        }) {
            Ok((ret, cursor)) => {
                self.cell.set(cursor);
                Ok(ret)
            }
            Err(err) => Err(err),
        }
    }

    // Not public API.
    #[doc(hidden)]
    pub fn parse_synom<T>(&self, parse: fn(Cursor) -> PResult<T>) -> Result<T> {
        self.step_cursor(|step| parse(step.cursor))
    }

    // Not public API.
    #[doc(hidden)]
    pub fn get_unexpected(&self) -> Rc<Cell<Option<Span>>> {
        self.unexpected.clone()
    }

    // Not public API.
    #[doc(hidden)]
    pub fn check_unexpected(&self) -> Result<()> {
        match self.unexpected.get() {
            Some(span) => Err(Error::new(span, "unexpected token")),
            None => Ok(()),
        }
    }
}

impl Parse for Ident {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step_cursor(|cursor| {
            if let Some((ident, rest)) = cursor.ident() {
                match ident.to_string().as_str() {
                    "_"
                    // Based on https://doc.rust-lang.org/grammar.html#keywords
                    // and https://github.com/rust-lang/rfcs/blob/master/text/2421-unreservations-2018.md
                    | "abstract" | "as" | "become" | "box" | "break" | "const"
                    | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final"
                    | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match"
                    | "mod" | "move" | "mut" | "override" | "priv" | "proc" | "pub"
                    | "ref" | "return" | "Self" | "self" | "static" | "struct"
                    | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use"
                    | "virtual" | "where" | "while" | "yield" => {}
                    _ => return Ok((ident, rest)),
                }
            }
            Err(cursor.error("expected identifier"))
        })
    }
}

// In reality the impl would be for Punctuated.
impl<T: Parse> Parse for Vec<T> {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut vec = Vec::new();
        while !input.is_empty() {
            let t = input.parse::<T>()?;
            vec.push(t);
        }
        Ok(vec)
    }
}
<|endoftext|>


<commit_before>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use pci::PciInterruptPin;

// The number of 32bit registers in the config space, 256 bytes.
const NUM_CONFIGURATION_REGISTERS: usize = 64;

const BAR0_REG: usize = 4;
const BAR_IO_ADDR_MASK: u32 = 0xffff_fffc;
const BAR_IO_BIT: u32 = 0x0000_0001;
const BAR_MEM_ADDR_MASK: u32 = 0xffff_fff0;
const NUM_BAR_REGS: usize = 6;

const INTERRUPT_LINE_PIN_REG: usize = 15;

/// Represents the types of PCI headers allowed in the configuration registers.
#[derive(Copy, Clone)]
pub enum PciHeaderType {
    Device,
    Bridge,
}

/// Classes of PCI nodes.
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciClassCode {
    TooOld,
    MassStorage,
    NetworkController,
    DisplayController,
    MultimediaController,
    MemoryController,
    BridgeDevice,
    SimpleCommunicationController,
    BaseSystemPeripheral,
    InputDevice,
    DockingStation,
    Processor,
    SerialBusController,
    WirelessController,
    IntelligentIoController,
    EncryptionController,
    DataAcquisitionSignalProcessing,
    Other = 0xff,
}

impl PciClassCode {
    pub fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// A PCI sublcass. Each class in `PciClassCode` can specify a unique set of subclasses. This trait
/// is implemented by each subclass. It allows use of a trait object to generate configurations.
pub trait PciSubclass {
    /// Convert this subclass to the value used in the PCI specification.
    fn get_register_value(&self) -> u8;
}

/// Subclasses of the MultimediaController class.
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciMultimediaSubclass {
    VideoController = 0x00,
    AudioController = 0x01,
    TelephonyDevice = 0x02,
    AudioDevice = 0x03,
    Other = 0x80,
}

impl PciSubclass for PciMultimediaSubclass {
    fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// Subclasses of the BridgeDevice
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciBridgeSubclass {
    HostBridge = 0x00,
    IsaBridge = 0x01,
    EisaBridge = 0x02,
    McaBridge = 0x03,
    PciToPciBridge = 0x04,
    PcmciaBridge = 0x05,
    NuBusBridge = 0x06,
    CardBusBridge = 0x07,
    RACEwayBridge = 0x08,
    PciToPciSemiTransparentBridge = 0x09,
    InfiniBrandToPciHostBridge = 0x0a,
    OtherBridgeDevice = 0x80,
}

impl PciSubclass for PciBridgeSubclass {
    fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// Contains the configuration space of a PCI node.
/// See the [specification](https://en.wikipedia.org/wiki/PCI_configuration_space).
/// The configuration space is accessed with DWORD reads and writes from the guest.
pub struct PciConfiguration {
    registers: [u32; NUM_CONFIGURATION_REGISTERS],
    writable_bits: [u32; NUM_CONFIGURATION_REGISTERS], // writable bits for each register.
    num_bars: usize,
}

impl PciConfiguration {
    pub fn new(
        vendor_id: u16,
        device_id: u16,
        class_code: PciClassCode,
        subclass: &PciSubclass,
        header_type: PciHeaderType,
    ) -> Self {
        let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
        registers[0] = u32::from(device_id) << 16 | u32::from(vendor_id);
        registers[2] = u32::from(class_code.get_register_value()) << 24
            | u32::from(subclass.get_register_value()) << 16;
        match header_type {
            PciHeaderType::Device => (),
            PciHeaderType::Bridge => registers[3] = 0x0001_0000,
        };
        PciConfiguration {
            registers,
            writable_bits: [0xffff_ffff; NUM_CONFIGURATION_REGISTERS],
            num_bars: 0,
        }
    }

    /// Reads a 32bit register from `reg_idx` in the register map.
    pub fn read_reg(&self, reg_idx: usize) -> u32 {
        *(self.registers.get(reg_idx).unwrap_or(&0xffff_ffff))
    }

    /// Writes a 32bit register to `reg_idx` in the register map.
    pub fn write_reg(&mut self, reg_idx: usize, value: u32) {
        if let Some(r) = self.registers.get_mut(reg_idx) {
            *r = value & self.writable_bits[reg_idx];
        } else {
            warn!("bad PCI register write {}", reg_idx);
        }
    }

    /// Writes a 16bit word to `offset`. `offset` must be 16bit aligned.
    pub fn write_word(&mut self, offset: usize, value: u16) {
        let shift = match offset % 4 {
            0 => 0,
            2 => 16,
            _ => {
                warn!("bad PCI config write offset {}", offset);
                return;
            }
        };
        let reg_idx = offset / 4;

        if let Some(r) = self.registers.get_mut(reg_idx) {
            let writable_mask = self.writable_bits[reg_idx];
            let mask = (0xffffu32 << shift) & writable_mask;
            let shifted_value = (u32::from(value) << shift) & writable_mask;
            *r = *r & !mask | shifted_value;
        } else {
            warn!("bad PCI config write offset {}", offset);
        }
    }

    /// Writes a byte to `offset`.
    pub fn write_byte(&mut self, offset: usize, value: u8) {
        let shift = (offset % 4) * 8;
        let reg_idx = offset / 4;

        if let Some(r) = self.registers.get_mut(reg_idx) {
            let writable_mask = self.writable_bits[reg_idx];
            let mask = (0xffu32 << shift) & writable_mask;
            let shifted_value = (u32::from(value) << shift) & writable_mask;
            *r = *r & !mask | shifted_value;
        } else {
            warn!("bad PCI config write offset {}", offset);
        }
    }

    // Add either an IO or memory region, depending on `mem_type` mask, which is ORed in to the
    // value before saving it.
    fn add_bar(&mut self, addr: u64, size: u64, addr_mask: u32, mem_type: u32) -> Option<usize> {
        if self.num_bars >= NUM_BAR_REGS {
            return None;
        }
        if size.count_ones() != 1 {
            return None;
        }

        // TODO(dgreid) Allow 64 bit address and size.
        if addr.checked_add(size)? > u64::from(u32::max_value()) {
                return None;
        }

        let bar_idx = BAR0_REG + self.num_bars;

        self.registers[bar_idx] = addr as u32 & addr_mask | mem_type;
        // The first writable bit represents the size of the region.
        self.writable_bits[bar_idx] = !(size - 1) as u32;

        self.num_bars += 1;
        Some(bar_idx)
    }

    /// Adds a memory region of `size` at `addr`. Configures the next available BAR register to
    /// report this region and size to the guest kernel. Returns 'None' if all BARs are full, or
    /// `Some(BarIndex)` on success. `size` must be a power of 2.
    pub fn add_memory_region(&mut self, addr: u64, size: u64) -> Option<usize> {
        self.add_bar(addr, size, BAR_MEM_ADDR_MASK, 0)
    }

    /// Adds an IO region of `size` at `addr`. Configures the next available BAR register to
    /// report this region and size to the guest kernel. Returns 'None' if all BARs are full, or
    /// `Some(BarIndex)` on success. `size` must be a power of 2.
    pub fn add_io_region(&mut self, addr: u64, size: u64) -> Option<usize> {
        self.add_bar(addr, size, BAR_IO_ADDR_MASK, BAR_IO_BIT)
    }

    /// Returns the address of the given BAR region.
    pub fn get_bar_addr(&self, bar_num: usize) -> u32 {
        let bar_idx = BAR0_REG + bar_num;

        self.registers[bar_idx] & BAR_MEM_ADDR_MASK
    }

    /// Configures the IRQ line and pin used by this device.
    pub fn set_irq(&mut self, line: u8, pin: PciInterruptPin) {
        // `pin` is 1-based in the pci config space.
        let pin_idx = (pin as u32) + 1;
        self.registers[INTERRUPT_LINE_PIN_REG] = (self.registers[INTERRUPT_LINE_PIN_REG]
            & 0xffff_0000) | (pin_idx << 8)
            | u32::from(line);
    }
}
<commit_msg>pci: Add serial bus subclass<commit_after>// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use pci::PciInterruptPin;

// The number of 32bit registers in the config space, 256 bytes.
const NUM_CONFIGURATION_REGISTERS: usize = 64;

const BAR0_REG: usize = 4;
const BAR_IO_ADDR_MASK: u32 = 0xffff_fffc;
const BAR_IO_BIT: u32 = 0x0000_0001;
const BAR_MEM_ADDR_MASK: u32 = 0xffff_fff0;
const NUM_BAR_REGS: usize = 6;

const INTERRUPT_LINE_PIN_REG: usize = 15;

/// Represents the types of PCI headers allowed in the configuration registers.
#[derive(Copy, Clone)]
pub enum PciHeaderType {
    Device,
    Bridge,
}

/// Classes of PCI nodes.
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciClassCode {
    TooOld,
    MassStorage,
    NetworkController,
    DisplayController,
    MultimediaController,
    MemoryController,
    BridgeDevice,
    SimpleCommunicationController,
    BaseSystemPeripheral,
    InputDevice,
    DockingStation,
    Processor,
    SerialBusController,
    WirelessController,
    IntelligentIoController,
    EncryptionController,
    DataAcquisitionSignalProcessing,
    Other = 0xff,
}

impl PciClassCode {
    pub fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// A PCI sublcass. Each class in `PciClassCode` can specify a unique set of subclasses. This trait
/// is implemented by each subclass. It allows use of a trait object to generate configurations.
pub trait PciSubclass {
    /// Convert this subclass to the value used in the PCI specification.
    fn get_register_value(&self) -> u8;
}

/// Subclasses of the MultimediaController class.
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciMultimediaSubclass {
    VideoController = 0x00,
    AudioController = 0x01,
    TelephonyDevice = 0x02,
    AudioDevice = 0x03,
    Other = 0x80,
}

impl PciSubclass for PciMultimediaSubclass {
    fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// Subclasses of the BridgeDevice
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciBridgeSubclass {
    HostBridge = 0x00,
    IsaBridge = 0x01,
    EisaBridge = 0x02,
    McaBridge = 0x03,
    PciToPciBridge = 0x04,
    PcmciaBridge = 0x05,
    NuBusBridge = 0x06,
    CardBusBridge = 0x07,
    RACEwayBridge = 0x08,
    PciToPciSemiTransparentBridge = 0x09,
    InfiniBrandToPciHostBridge = 0x0a,
    OtherBridgeDevice = 0x80,
}

impl PciSubclass for PciBridgeSubclass {
    fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// Subclass of the SerialBus
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum PciSerialBusSubClass {
    Firewire = 0x00,
    ACCESSbus = 0x01,
    SSA = 0x02,
    USB = 0x03,
}

impl PciSubclass for PciSerialBusSubClass {
    fn get_register_value(&self) -> u8 {
        *self as u8
    }
}

/// Contains the configuration space of a PCI node.
/// See the [specification](https://en.wikipedia.org/wiki/PCI_configuration_space).
/// The configuration space is accessed with DWORD reads and writes from the guest.
pub struct PciConfiguration {
    registers: [u32; NUM_CONFIGURATION_REGISTERS],
    writable_bits: [u32; NUM_CONFIGURATION_REGISTERS], // writable bits for each register.
    num_bars: usize,
}

impl PciConfiguration {
    pub fn new(
        vendor_id: u16,
        device_id: u16,
        class_code: PciClassCode,
        subclass: &PciSubclass,
        header_type: PciHeaderType,
    ) -> Self {
        let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
        registers[0] = u32::from(device_id) << 16 | u32::from(vendor_id);
        registers[2] = u32::from(class_code.get_register_value()) << 24
            | u32::from(subclass.get_register_value()) << 16;
        match header_type {
            PciHeaderType::Device => (),
            PciHeaderType::Bridge => registers[3] = 0x0001_0000,
        };
        PciConfiguration {
            registers,
            writable_bits: [0xffff_ffff; NUM_CONFIGURATION_REGISTERS],
            num_bars: 0,
        }
    }

    /// Reads a 32bit register from `reg_idx` in the register map.
    pub fn read_reg(&self, reg_idx: usize) -> u32 {
        *(self.registers.get(reg_idx).unwrap_or(&0xffff_ffff))
    }

    /// Writes a 32bit register to `reg_idx` in the register map.
    pub fn write_reg(&mut self, reg_idx: usize, value: u32) {
        if let Some(r) = self.registers.get_mut(reg_idx) {
            *r = value & self.writable_bits[reg_idx];
        } else {
            warn!("bad PCI register write {}", reg_idx);
        }
    }

    /// Writes a 16bit word to `offset`. `offset` must be 16bit aligned.
    pub fn write_word(&mut self, offset: usize, value: u16) {
        let shift = match offset % 4 {
            0 => 0,
            2 => 16,
            _ => {
                warn!("bad PCI config write offset {}", offset);
                return;
            }
        };
        let reg_idx = offset / 4;

        if let Some(r) = self.registers.get_mut(reg_idx) {
            let writable_mask = self.writable_bits[reg_idx];
            let mask = (0xffffu32 << shift) & writable_mask;
            let shifted_value = (u32::from(value) << shift) & writable_mask;
            *r = *r & !mask | shifted_value;
        } else {
            warn!("bad PCI config write offset {}", offset);
        }
    }

    /// Writes a byte to `offset`.
    pub fn write_byte(&mut self, offset: usize, value: u8) {
        let shift = (offset % 4) * 8;
        let reg_idx = offset / 4;

        if let Some(r) = self.registers.get_mut(reg_idx) {
            let writable_mask = self.writable_bits[reg_idx];
            let mask = (0xffu32 << shift) & writable_mask;
            let shifted_value = (u32::from(value) << shift) & writable_mask;
            *r = *r & !mask | shifted_value;
        } else {
            warn!("bad PCI config write offset {}", offset);
        }
    }

    // Add either an IO or memory region, depending on `mem_type` mask, which is ORed in to the
    // value before saving it.
    fn add_bar(&mut self, addr: u64, size: u64, addr_mask: u32, mem_type: u32) -> Option<usize> {
        if self.num_bars >= NUM_BAR_REGS {
            return None;
        }
        if size.count_ones() != 1 {
            return None;
        }

        // TODO(dgreid) Allow 64 bit address and size.
        if addr.checked_add(size)? > u64::from(u32::max_value()) {
                return None;
        }

        let bar_idx = BAR0_REG + self.num_bars;

        self.registers[bar_idx] = addr as u32 & addr_mask | mem_type;
        // The first writable bit represents the size of the region.
        self.writable_bits[bar_idx] = !(size - 1) as u32;

        self.num_bars += 1;
        Some(bar_idx)
    }

    /// Adds a memory region of `size` at `addr`. Configures the next available BAR register to
    /// report this region and size to the guest kernel. Returns 'None' if all BARs are full, or
    /// `Some(BarIndex)` on success. `size` must be a power of 2.
    pub fn add_memory_region(&mut self, addr: u64, size: u64) -> Option<usize> {
        self.add_bar(addr, size, BAR_MEM_ADDR_MASK, 0)
    }

    /// Adds an IO region of `size` at `addr`. Configures the next available BAR register to
    /// report this region and size to the guest kernel. Returns 'None' if all BARs are full, or
    /// `Some(BarIndex)` on success. `size` must be a power of 2.
    pub fn add_io_region(&mut self, addr: u64, size: u64) -> Option<usize> {
        self.add_bar(addr, size, BAR_IO_ADDR_MASK, BAR_IO_BIT)
    }

    /// Returns the address of the given BAR region.
    pub fn get_bar_addr(&self, bar_num: usize) -> u32 {
        let bar_idx = BAR0_REG + bar_num;

        self.registers[bar_idx] & BAR_MEM_ADDR_MASK
    }

    /// Configures the IRQ line and pin used by this device.
    pub fn set_irq(&mut self, line: u8, pin: PciInterruptPin) {
        // `pin` is 1-based in the pci config space.
        let pin_idx = (pin as u32) + 1;
        self.registers[INTERRUPT_LINE_PIN_REG] = (self.registers[INTERRUPT_LINE_PIN_REG]
            & 0xffff_0000) | (pin_idx << 8)
            | u32::from(line);
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use backend::Backend;
use expression::*;
use query_builder::*;
use result::QueryResult;
use super::unchecked_bind::UncheckedBind;
use types::HasSqlType;

#[derive(Debug, Clone)]
/// Available for when you truly cannot represent something using the expression
/// DSL. You will need to provide the type of the expression, in addition to the
/// SQL. The compiler will be unable to verify the correctness of this type.
///
/// To get a SQL literal, use the [`sql()`] function.
///
/// [`sql()`]: fn.sql.html
pub struct SqlLiteral<ST> {
    sql: String,
    _marker: PhantomData<ST>,
}

impl<ST> SqlLiteral<ST> {
    #[doc(hidden)]
    pub fn new(sql: String) -> Self {
        SqlLiteral {
            sql: sql,
            _marker: PhantomData,
        }
    }

    /// Bind a value for use with this SQL query.
    ///
    /// # Safety
    ///
    /// This function should be used with care, as Diesel cannot validate that
    /// the value is of the right type nor can it validate that you have passed
    /// the correct number of parameters.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Integer,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     use self::users::dsl::*;
    /// #     use diesel::expression::dsl::sql;
    /// #     use diesel::types::{Integer, Text};
    /// #     let connection = establish_connection();
    /// #[cfg(feature="postgres")]
    /// let query = sql::<Integer>("SELECT id FROM users WHERE name = $1");
    /// #[cfg(not(feature="postgres"))]
    /// let query = sql::<Integer>("SELECT id FROM users WHERE name = ?");
    /// let seans_id = query.clone().bind::<Text, _>("Sean")
    ///     .get_result(&connection);
    /// assert_eq!(Ok(1), seans_id);
    /// let tess_id = query.bind::<Text, _>("Tess")
    ///     .get_result(&connection);
    /// assert_eq!(Ok(2), tess_id);
    /// # }
    /// ```
    ///
    /// ### Multiple Bind Params
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Integer,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     use self::users::dsl::*;
    /// #     use diesel::expression::dsl::sql;
    /// #     use diesel::types::{Integer, Text};
    /// #     let connection = establish_connection();
    /// #     diesel::insert(&NewUser::new("Jim")).into(users)
    /// #         .execute(&connection).unwrap();
    /// #[cfg(not(feature="postgres"))]
    /// let query = sql::<Text>("SELECT name FROM users WHERE id > ? AND name <> ?");
    /// #[cfg(feature="postgres")]
    /// let query = sql("SELECT name FROM users WHERE id > $1 AND name <> $2");
    /// let query = query
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Jim");
    /// let expected = vec!["Tess".to_string()];
    /// assert_eq!(Ok(expected), query.load(&connection));
    /// # }
    /// ```
    pub fn bind<BindST, T>(self, bind_value: T) -> UncheckedBind<Self, T, BindST> {
        UncheckedBind::new(self, bind_value)
    }
}

impl<ST> Expression for SqlLiteral<ST> {
    type SqlType = ST;
}

impl<ST, DB> QueryFragment<DB> for SqlLiteral<ST> where
    DB: Backend + HasSqlType<ST>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        out.push_sql(&self.sql);
        Ok(())
    }
}

impl_query_id!(noop: SqlLiteral<ST>);

impl<ST> Query for SqlLiteral<ST> {
    type SqlType = ST;
}

impl<QS, ST> SelectableExpression<QS> for SqlLiteral<ST> {
}

impl<QS, ST> AppearsOnTable<QS> for SqlLiteral<ST> {
}

impl<ST> NonAggregate for SqlLiteral<ST> {
}

/// Use literal SQL in the query builder
///
/// Available for when you truly cannot represent something using the expression
/// DSL. You will need to provide the SQL type of the expression, in addition to
/// the SQL.
///
/// # Safety
///
/// The compiler will be unable to verify the correctness of the annotated type.
/// If you give the wrong type, it'll either crash at runtime when deserializing
/// the query result or produce invalid values.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # #[macro_use] extern crate diesel_codegen;
/// use diesel::expression::sql;
/// use diesel::types::{Bool, Integer, Text};
/// # include!("src/doctest_setup.rs");
/// # table! {
/// #   users {
/// #       id -> Integer,
/// #       name -> VarChar,
/// #   }
/// # }
///
/// #[derive(PartialEq, Debug, Queryable)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// # fn main() {
/// # let connection = establish_connection();
/// #
/// let setup = sql::<Bool>("INSERT INTO users(name) VALUES('Ruby')");
/// setup.execute(&connection).expect("Can't insert in users");
///
/// let query = sql::<(Integer, Text)>("SELECT id, name FROM users WHERE name='Ruby';");
/// let users = query.load::<User>(&connection).expect("Can't query users");
/// assert_eq!(users, vec![User{id: 3, name: "Ruby".to_owned()}]);
///
/// let query = users::table.filter(sql::<Bool>("name='Ruby'")); // Same query as above
/// let users = query.load::<User>(&connection).expect("Can't query users");
/// assert_eq!(users, vec![User{id: 3, name: "Ruby".to_owned()}]);
/// # }
/// ```
pub fn sql<ST>(sql: &str) -> SqlLiteral<ST> {
    SqlLiteral::new(sql.into())
}
<commit_msg>Add a link to the bind method on the sql() function page<commit_after>use std::marker::PhantomData;

use backend::Backend;
use expression::*;
use query_builder::*;
use result::QueryResult;
use super::unchecked_bind::UncheckedBind;
use types::HasSqlType;

#[derive(Debug, Clone)]
/// Available for when you truly cannot represent something using the expression
/// DSL. You will need to provide the type of the expression, in addition to the
/// SQL. The compiler will be unable to verify the correctness of this type.
///
/// To get a SQL literal, use the [`sql()`] function.
///
/// [`sql()`]: fn.sql.html
pub struct SqlLiteral<ST> {
    sql: String,
    _marker: PhantomData<ST>,
}

impl<ST> SqlLiteral<ST> {
    #[doc(hidden)]
    pub fn new(sql: String) -> Self {
        SqlLiteral {
            sql: sql,
            _marker: PhantomData,
        }
    }

    /// Bind a value for use with this SQL query.
    ///
    /// # Safety
    ///
    /// This function should be used with care, as Diesel cannot validate that
    /// the value is of the right type nor can it validate that you have passed
    /// the correct number of parameters.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Integer,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     use self::users::dsl::*;
    /// #     use diesel::expression::dsl::sql;
    /// #     use diesel::types::{Integer, Text};
    /// #     let connection = establish_connection();
    /// #[cfg(feature="postgres")]
    /// let query = sql::<Integer>("SELECT id FROM users WHERE name = $1");
    /// #[cfg(not(feature="postgres"))]
    /// let query = sql::<Integer>("SELECT id FROM users WHERE name = ?");
    /// let seans_id = query.clone().bind::<Text, _>("Sean")
    ///     .get_result(&connection);
    /// assert_eq!(Ok(1), seans_id);
    /// let tess_id = query.bind::<Text, _>("Tess")
    ///     .get_result(&connection);
    /// assert_eq!(Ok(2), tess_id);
    /// # }
    /// ```
    ///
    /// ### Multiple Bind Params
    ///
    /// ```rust
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Integer,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    /// # fn main() {
    /// #     use self::users::dsl::*;
    /// #     use diesel::expression::dsl::sql;
    /// #     use diesel::types::{Integer, Text};
    /// #     let connection = establish_connection();
    /// #     diesel::insert(&NewUser::new("Jim")).into(users)
    /// #         .execute(&connection).unwrap();
    /// #[cfg(not(feature="postgres"))]
    /// let query = sql::<Text>("SELECT name FROM users WHERE id > ? AND name <> ?");
    /// #[cfg(feature="postgres")]
    /// let query = sql("SELECT name FROM users WHERE id > $1 AND name <> $2");
    /// let query = query
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Jim");
    /// let expected = vec!["Tess".to_string()];
    /// assert_eq!(Ok(expected), query.load(&connection));
    /// # }
    /// ```
    pub fn bind<BindST, T>(self, bind_value: T) -> UncheckedBind<Self, T, BindST> {
        UncheckedBind::new(self, bind_value)
    }
}

impl<ST> Expression for SqlLiteral<ST> {
    type SqlType = ST;
}

impl<ST, DB> QueryFragment<DB> for SqlLiteral<ST> where
    DB: Backend + HasSqlType<ST>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        out.push_sql(&self.sql);
        Ok(())
    }
}

impl_query_id!(noop: SqlLiteral<ST>);

impl<ST> Query for SqlLiteral<ST> {
    type SqlType = ST;
}

impl<QS, ST> SelectableExpression<QS> for SqlLiteral<ST> {
}

impl<QS, ST> AppearsOnTable<QS> for SqlLiteral<ST> {
}

impl<ST> NonAggregate for SqlLiteral<ST> {
}

/// Use literal SQL in the query builder
///
/// Available for when you truly cannot represent something using the expression
/// DSL. You will need to provide the SQL type of the expression, in addition to
/// the SQL.
///
/// # Bound parameters
///
/// If you need to pass arguments to your query, you should use [`.bind()`].
///
/// [`.bind()`]: ../sql_literal/struct.SqlLiteral.html#method.bind
///
/// # Safety
///
/// The compiler will be unable to verify the correctness of the annotated type.
/// If you give the wrong type, it'll either crash at runtime when deserializing
/// the query result or produce invalid values.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # #[macro_use] extern crate diesel_codegen;
/// use diesel::expression::sql;
/// use diesel::types::{Bool, Integer, Text};
/// # include!("src/doctest_setup.rs");
/// # table! {
/// #   users {
/// #       id -> Integer,
/// #       name -> VarChar,
/// #   }
/// # }
///
/// #[derive(PartialEq, Debug, Queryable)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// # fn main() {
/// # let connection = establish_connection();
/// #
/// let setup = sql::<Bool>("INSERT INTO users(name) VALUES('Ruby')");
/// setup.execute(&connection).expect("Can't insert in users");
///
/// let query = sql::<(Integer, Text)>("SELECT id, name FROM users WHERE name='Ruby';");
/// let users = query.load::<User>(&connection).expect("Can't query users");
/// assert_eq!(users, vec![User{id: 3, name: "Ruby".to_owned()}]);
///
/// let query = users::table.filter(sql::<Bool>("name='Ruby'")); // Same query as above
/// let users = query.load::<User>(&connection).expect("Can't query users");
/// assert_eq!(users, vec![User{id: 3, name: "Ruby".to_owned()}]);
/// # }
/// ```
pub fn sql<ST>(sql: &str) -> SqlLiteral<ST> {
    SqlLiteral::new(sql.into())
}
<|endoftext|>


<commit_before>use inflector::Inflector;
use linked_hash_map::LinkedHashMap;
use serde_json::{json, Value};

use crate::options::Options;
use crate::shape::{self, Shape};

#[allow(dead_code)]
pub struct Ctxt {
    options: Options,
}

pub type Ident = String;
pub type Code = String;

pub fn json_schema(name: &str, shape: &Shape, options: Options) -> (Ident, Option<Code>) {
    let mut ctxt = Ctxt { options };

    let ident = "".to_string();
    let value = type_from_shape(&mut ctxt, name, shape);

    let mut schema = json!({
        "$schema": "http://json-schema.org/schema#",
        "title": name
    });

    if let Value::Object(map) = value {
        for (key, val) in map.into_iter() {
            schema[key] = val;
        }
    }

    let code = ::serde_json::to_string_pretty(&schema);

    (ident, code.ok())
}

fn type_from_shape(ctxt: &mut Ctxt, path: &str, shape: &Shape) -> Value {
    use crate::shape::Shape::*;
    match shape {
        Null | Any | Bottom => json!({}),
        Bool => json!({ "type": "boolean" }),
        StringT => json!({ "type": "string" }),
        Integer => json!({ "type": "number" }),
        Floating => json!({ "type": "number" }),
        Tuple(shapes, _n) => {
            let folded = shape::fold_shapes(shapes.clone());
            if folded == Any && shapes.iter().any(|s| s != &Any) {
                generate_tuple_type(ctxt, path, &shapes)
            } else {
                generate_vec_type(ctxt, path, &folded)
            }
        }
        VecT { elem_type: e } => generate_vec_type(ctxt, path, &e),
        Struct { fields: map } => generate_struct_from_field_shapes(ctxt, path, &map),
        MapT { val_type: v } => generate_map_type(ctxt, path, &v),
        Opaque(t) => json!({ "type": t }),
        Optional(e) => type_from_shape(ctxt, path, &e),
    }
}

fn generate_vec_type(ctxt: &mut Ctxt, path: &str, shape: &Shape) -> Value {
    let singular = path.to_singular();
    let inner = type_from_shape(ctxt, &singular, shape);
    json!({
        "type": "array",
        "items": inner
    })
}

fn generate_map_type(ctxt: &mut Ctxt, path: &str, shape: &Shape) -> Value {
    let singular = path.to_singular();
    let inner = type_from_shape(ctxt, &singular, shape);
    json!({
        "type": "object",
        "additionalProperties": inner
    })
}

fn generate_tuple_type(ctxt: &mut Ctxt, path: &str, shapes: &[Shape]) -> Value {
    let mut types = Vec::new();

    for shape in shapes {
        let typ = type_from_shape(ctxt, path, shape);
        types.push(typ);
    }

    json!({
        "type": "array",
        "items": types,
        "additionalItems": false
    })
}

fn collapse_option(typ: &Shape) -> (bool, &Shape) {
    if let Shape::Optional(inner) = typ {
        return (true, &**inner);
    }
    (false, typ)
}

fn generate_struct_from_field_shapes(
    ctxt: &mut Ctxt,
    _path: &str,
    map: &LinkedHashMap<String, Shape>,
) -> Value {
    let mut required: Vec<String> = Vec::new();
    let mut properties = json!({});

    for (name, typ) in map.iter() {
        let (was_optional, collapsed) = collapse_option(typ);

        if !was_optional {
            required.push(name.clone());
        }

        let field_code = type_from_shape(ctxt, name, collapsed);

        properties[name] = field_code;
    }

    json!({
        "type": "object",
        "properties": properties,
        "required": required
    })
}
<commit_msg>shared: Use actual JSON Schema version.<commit_after>use inflector::Inflector;
use linked_hash_map::LinkedHashMap;
use serde_json::{json, Value};

use crate::options::Options;
use crate::shape::{self, Shape};

#[allow(dead_code)]
pub struct Ctxt {
    options: Options,
}

pub type Ident = String;
pub type Code = String;

pub fn json_schema(name: &str, shape: &Shape, options: Options) -> (Ident, Option<Code>) {
    let mut ctxt = Ctxt { options };

    let ident = "".to_string();
    let value = type_from_shape(&mut ctxt, name, shape);

    let mut schema = json!({
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": format!("Generated schema for {}", name)
    });

    if let Value::Object(map) = value {
        for (key, val) in map.into_iter() {
            schema[key] = val;
        }
    }

    let code = ::serde_json::to_string_pretty(&schema);

    (ident, code.ok())
}

fn type_from_shape(ctxt: &mut Ctxt, path: &str, shape: &Shape) -> Value {
    use crate::shape::Shape::*;
    match shape {
        Null | Any | Bottom => json!({}),
        Bool => json!({ "type": "boolean" }),
        StringT => json!({ "type": "string" }),
        Integer => json!({ "type": "number" }),
        Floating => json!({ "type": "number" }),
        Tuple(shapes, _n) => {
            let folded = shape::fold_shapes(shapes.clone());
            if folded == Any && shapes.iter().any(|s| s != &Any) {
                generate_tuple_type(ctxt, path, &shapes)
            } else {
                generate_vec_type(ctxt, path, &folded)
            }
        }
        VecT { elem_type: e } => generate_vec_type(ctxt, path, &e),
        Struct { fields: map } => generate_struct_from_field_shapes(ctxt, path, &map),
        MapT { val_type: v } => generate_map_type(ctxt, path, &v),
        Opaque(t) => json!({ "type": t }),
        Optional(e) => type_from_shape(ctxt, path, &e),
    }
}

fn generate_vec_type(ctxt: &mut Ctxt, path: &str, shape: &Shape) -> Value {
    let singular = path.to_singular();
    let inner = type_from_shape(ctxt, &singular, shape);
    json!({
        "type": "array",
        "items": inner
    })
}

fn generate_map_type(ctxt: &mut Ctxt, path: &str, shape: &Shape) -> Value {
    let singular = path.to_singular();
    let inner = type_from_shape(ctxt, &singular, shape);
    json!({
        "type": "object",
        "additionalProperties": inner
    })
}

fn generate_tuple_type(ctxt: &mut Ctxt, path: &str, shapes: &[Shape]) -> Value {
    let mut types = Vec::new();

    for shape in shapes {
        let typ = type_from_shape(ctxt, path, shape);
        types.push(typ);
    }

    json!({
        "type": "array",
        "items": types,
        "additionalItems": false
    })
}

fn collapse_option(typ: &Shape) -> (bool, &Shape) {
    if let Shape::Optional(inner) = typ {
        return (true, &**inner);
    }
    (false, typ)
}

fn generate_struct_from_field_shapes(
    ctxt: &mut Ctxt,
    _path: &str,
    map: &LinkedHashMap<String, Shape>,
) -> Value {
    let mut required: Vec<String> = Vec::new();
    let mut properties = json!({});

    for (name, typ) in map.iter() {
        let (was_optional, collapsed) = collapse_option(typ);

        if !was_optional {
            required.push(name.clone());
        }

        let field_code = type_from_shape(ctxt, name, collapsed);

        properties[name] = field_code;
    }

    json!({
        "type": "object",
        "properties": properties,
        "required": required
    })
}
<|endoftext|>


<commit_before>use bytes::{BufMut, BytesMut};

use std::io;
use std::str;

use tokio_core::net::TcpStream;
use tokio_io::codec::{Decoder, Encoder, Framed};
use tokio_tls::TlsStream;

pub type ImapTransport = Framed<TlsStream<TcpStream>, ImapCodec>;

pub struct ImapCodec;

impl Decoder for ImapCodec {
    type Item = Response;
    type Error = io::Error;
    fn decode(&mut self, buf: &mut BytesMut)
             -> Result<Option<Response>, io::Error> {
        if let Some(n) = buf.iter().position(|b| *b == b'\n') {
            let mut line = buf.split_to(n - 1);
            let request_id = if line[0] == b'*' {
                let _ = line.split_to(2);
                None
            } else {
                let pos = line.iter().position(|b| *b == b' ').unwrap();
                let tag = line.split_to(pos);
                let _ = line.split_to(1);
                Some(RequestId(str::from_utf8(&tag).unwrap().to_string()))
            };
            let rest = str::from_utf8(line.get(..).unwrap()).unwrap().to_string();
            buf.split_to(2);
            Ok(Some(Response::Status(request_id, rest)))
        } else {
            Ok(None)
        }
    }
}

impl Encoder for ImapCodec {
    type Item = Request;
    type Error = io::Error;
    fn encode(&mut self, msg: Self::Item, dst: &mut BytesMut)
             -> Result<(), io::Error> {
        dst.put(msg.0.as_bytes());
        dst.put(b' ');
        dst.put(msg.1.to_string().as_bytes());
        dst.put("\r\n");
        Ok(())
    }
}

#[derive(Debug)]
pub struct Request(pub RequestId, pub Command);

#[derive(Debug)]
pub enum Command {
    Check,
    Fetch(SequenceSet, MessageData),
    Login(String, String),
    Select(String),
}

impl ToString for Command {
    fn to_string(&self) -> String {
        match *self {
            Command::Check => {
                format!("CHECK")
            },
            Command::Fetch(ref set, ref items) => {
                format!("FETCH {} {}", &set.to_string(), &items.to_string())
            },
            Command::Login(ref user_name, ref password) => {
                format!("LOGIN {} {}", user_name, password)
            },
            Command::Select(ref mailbox) => {
                format!("SELECT {}", mailbox)
            },
        }
    }
}

#[derive(Debug)]
pub enum MessageData {
    All,
    Fast,
    Full,
}

impl ToString for MessageData {
    fn to_string(&self) -> String {
        use self::MessageData::*;
        match *self {
            All => "ALL".to_string(),
            Fast => "FAST".to_string(),
            Full => "FULL".to_string(),
        }
    }
}

#[derive(Debug)]
pub enum SequenceSet {
    Range(usize, usize),
}

impl ToString for SequenceSet {
    fn to_string(&self) -> String {
        use self::SequenceSet::*;
        match *self {
            Range(start, stop) => format!("{}:{}", start, stop),
        }
    }
}

#[derive(Debug)]
pub enum Response {
    Status(Option<RequestId>, String),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RequestId(String);

impl RequestId {
    fn as_bytes(&self) -> &[u8] {
        self.0.as_bytes()
    }
}

pub struct IdGenerator {
    next: u64,
}

impl IdGenerator {
    pub fn new() -> IdGenerator {
        IdGenerator { next: 0 }
    }
}

impl Iterator for IdGenerator {
    type Item = RequestId;
    fn next(&mut self) -> Option<Self::Item> {
        self.next += 1;
        Some(RequestId(format!("A{:04}", self.next % 10000)))
    }
}

#[allow(dead_code)]
pub enum State {
    NotAuthenticated,
    Authenticated,
    Selected,
    Logout,
}

enum Status {
    Ok,
    No,
    Bad,
    PreAuth,
    Bye,
}
<commit_msg>Silence warning about currently unused enum<commit_after>use bytes::{BufMut, BytesMut};

use std::io;
use std::str;

use tokio_core::net::TcpStream;
use tokio_io::codec::{Decoder, Encoder, Framed};
use tokio_tls::TlsStream;

pub type ImapTransport = Framed<TlsStream<TcpStream>, ImapCodec>;

pub struct ImapCodec;

impl Decoder for ImapCodec {
    type Item = Response;
    type Error = io::Error;
    fn decode(&mut self, buf: &mut BytesMut)
             -> Result<Option<Response>, io::Error> {
        if let Some(n) = buf.iter().position(|b| *b == b'\n') {
            let mut line = buf.split_to(n - 1);
            let request_id = if line[0] == b'*' {
                let _ = line.split_to(2);
                None
            } else {
                let pos = line.iter().position(|b| *b == b' ').unwrap();
                let tag = line.split_to(pos);
                let _ = line.split_to(1);
                Some(RequestId(str::from_utf8(&tag).unwrap().to_string()))
            };
            let rest = str::from_utf8(line.get(..).unwrap()).unwrap().to_string();
            buf.split_to(2);
            Ok(Some(Response::Status(request_id, rest)))
        } else {
            Ok(None)
        }
    }
}

impl Encoder for ImapCodec {
    type Item = Request;
    type Error = io::Error;
    fn encode(&mut self, msg: Self::Item, dst: &mut BytesMut)
             -> Result<(), io::Error> {
        dst.put(msg.0.as_bytes());
        dst.put(b' ');
        dst.put(msg.1.to_string().as_bytes());
        dst.put("\r\n");
        Ok(())
    }
}

#[derive(Debug)]
pub struct Request(pub RequestId, pub Command);

#[derive(Debug)]
pub enum Command {
    Check,
    Fetch(SequenceSet, MessageData),
    Login(String, String),
    Select(String),
}

impl ToString for Command {
    fn to_string(&self) -> String {
        match *self {
            Command::Check => {
                format!("CHECK")
            },
            Command::Fetch(ref set, ref items) => {
                format!("FETCH {} {}", &set.to_string(), &items.to_string())
            },
            Command::Login(ref user_name, ref password) => {
                format!("LOGIN {} {}", user_name, password)
            },
            Command::Select(ref mailbox) => {
                format!("SELECT {}", mailbox)
            },
        }
    }
}

#[derive(Debug)]
pub enum MessageData {
    All,
    Fast,
    Full,
}

impl ToString for MessageData {
    fn to_string(&self) -> String {
        use self::MessageData::*;
        match *self {
            All => "ALL".to_string(),
            Fast => "FAST".to_string(),
            Full => "FULL".to_string(),
        }
    }
}

#[derive(Debug)]
pub enum SequenceSet {
    Range(usize, usize),
}

impl ToString for SequenceSet {
    fn to_string(&self) -> String {
        use self::SequenceSet::*;
        match *self {
            Range(start, stop) => format!("{}:{}", start, stop),
        }
    }
}

#[derive(Debug)]
pub enum Response {
    Status(Option<RequestId>, String),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RequestId(String);

impl RequestId {
    fn as_bytes(&self) -> &[u8] {
        self.0.as_bytes()
    }
}

pub struct IdGenerator {
    next: u64,
}

impl IdGenerator {
    pub fn new() -> IdGenerator {
        IdGenerator { next: 0 }
    }
}

impl Iterator for IdGenerator {
    type Item = RequestId;
    fn next(&mut self) -> Option<Self::Item> {
        self.next += 1;
        Some(RequestId(format!("A{:04}", self.next % 10000)))
    }
}

#[allow(dead_code)]
pub enum State {
    NotAuthenticated,
    Authenticated,
    Selected,
    Logout,
}

#[allow(dead_code)]
enum Status {
    Ok,
    No,
    Bad,
    PreAuth,
    Bye,
}
<|endoftext|>