<commit_before>use ll;
use pa;
use pa::{PaError, PaResult};
use device::DeviceIndex;
use util::{to_pa_result, pa_time_to_duration};
use std::raw::Slice;
use std::mem;
use std::time::duration::Duration;

#[repr(u32)]
pub enum StreamCallbackResult
{
    Continue = ll::paContinue,
    Complete = ll::paComplete,
    Abort = ll::paAbort,
}

pub type StreamCallback<'a, T> = |input: &[T], output: &mut [T], timeinfo: StreamTimeInfo, StreamCallbackFlags|:'a -> StreamCallbackResult;
pub type StreamFinishedCallback<'a> = ||:'a;

struct StreamUserData<'a, T>
{
    num_input: uint,
    num_output: uint,
    callback: Option<StreamCallback<'a, T>>,
    finished_callback: Option<StreamFinishedCallback<'a>>,
}

pub struct StreamTimeInfo
{
    pub input_adc_time: Duration,
    pub current_time: Duration,
    pub output_dac_time: Duration,
}

bitflags!(
    flags StreamCallbackFlags: u64 {
        static inputUnderflow = 0x01,
        static inputOverflow = 0x02,
        static outputUnderflow = 0x04,
        static outputOverflow = 0x08,
        static primingOutput = 0x10
    }
)

bitflags!(
    flags StreamFlags: u64 {
        static ClipOff                               = 0x00000001,
        static DitherOff                             = 0x00000002,
        static NeverDropInput                        = 0x00000004,
        static PrimeOutputBuffersUsingStreamCallback = 0x00000008,
        static PlatformSpecific                      = 0xFFFF0000
    }
)

extern "C" fn stream_callback<T>(input: *const ::libc::c_void,
                                 output: *mut ::libc::c_void,
                                 frame_count: ::libc::c_ulong,
                                 time_info: *const ll::PaStreamCallbackTimeInfo,
                                 status_flags: ll::PaStreamCallbackFlags,
                                 user_data: *mut ::libc::c_void) -> ::libc::c_int
{
    let mut stream_data: Box<StreamUserData<T>> = unsafe { mem::transmute(user_data) };

    let input_buffer: &[T] = unsafe
    {
        mem::transmute(
            Slice { data: input as *const T, len: frame_count as uint * stream_data.num_input }
        )
    };
    let output_buffer: &mut [T] = unsafe
    {
        mem::transmute(
            Slice { data: output as *const T, len: frame_count as uint * stream_data.num_output }
        )
    };

    let flags = StreamCallbackFlags::from_bits_truncate(status_flags);

    let timeinfo = match unsafe { time_info.to_option() }
    {
        Some(ref info) => StreamTimeInfo { input_adc_time: pa_time_to_duration(info.inputBufferAdcTime),
                                           current_time: pa_time_to_duration(info.currentTime),
                                           output_dac_time: pa_time_to_duration(info.outputBufferDacTime) },
        None => StreamTimeInfo { input_adc_time: Duration::seconds(0),
                                 current_time: Duration::seconds(0),
                                 output_dac_time: Duration::seconds(0), },
    };

    let result = match stream_data.callback
    {
        Some(ref mut f) => (*f)(input_buffer, output_buffer, timeinfo, flags),
        None => Abort,
    };

    unsafe { mem::forget(stream_data); }

    result as i32
}

extern "C" fn stream_finished_callback<T>(user_data: *mut ::libc::c_void)
{
    let mut stream_data: Box<StreamUserData<T>> = unsafe { mem::transmute(user_data) };
    match stream_data.finished_callback
    {
        Some(ref mut f) => (*f)(),
        None => {},
    };

    unsafe { mem::forget(stream_data); }
}

trait SampleType
{
    fn sample_format(_: Option<Self>) -> u64;
}
impl SampleType for f32 { fn sample_format(_: Option<f32>) -> u64 { 0x00000001 } }
impl SampleType for i32 { fn sample_format(_: Option<i32>) -> u64 { 0x00000002 } }
impl SampleType for i16 { fn sample_format(_: Option<i16>) -> u64 { 0x00000008 } }
impl SampleType for i8 { fn sample_format(_: Option<i8>) -> u64 { 0x00000010 } }
impl SampleType for u8 { fn sample_format(_: Option<u8>) -> u64 { 0x00000020 } }

fn get_sample_format<T: SampleType>() -> u64
{
    SampleType::sample_format(None::<T>)
}

pub fn get_sample_size<T: SampleType>() -> Result<uint, PaError>
{
    match unsafe { ll::Pa_GetSampleSize(get_sample_format::<T>()) }
    {
        n if n >= 0 => Ok(n as uint),
        m => to_pa_result(m).map(|_| 0),
    }
}

pub struct Stream<'a, T>
{
    pa_stream: *mut ll::PaStream,
    inputs: uint,
    outputs: uint,
    user_data: Box<StreamUserData<'a, T>>,
}

impl<'a, T: SampleType> Stream<'a, T>
{
    pub fn open_default(num_input_channels: uint,
                        num_output_channels: uint,
                        sample_rate: f64,
                        frames_per_buffer: u64,
                        callback: Option<StreamCallback<'a, T>>)
                       -> Result<Stream<'a, T>, PaError>
    {
        unsafe
        {
            let callback_pointer = match callback
            {
                Some(_) => Some(stream_callback::<T>),
                None => None,
            };
            let userdata = box StreamUserData
            {
                num_input: num_input_channels,
                num_output: num_output_channels,
                callback: callback,
                finished_callback: None,
            };
            let mut pa_stream = ::std::ptr::mut_null();

            let ud_pointer: *mut ::libc::c_void = ::std::mem::transmute(userdata);
            let ud_pointer_2 = ud_pointer.clone();
            let code = ll::Pa_OpenDefaultStream(&mut pa_stream as *mut *mut ll::PaStream,
                                                num_input_channels as i32,
                                                num_output_channels as i32,
                                                get_sample_format::<T>(),
                                                sample_rate,
                                                frames_per_buffer,
                                                callback_pointer,
                                                ud_pointer);
            match to_pa_result(code)
            {
                Ok(()) => Ok(Stream { pa_stream: pa_stream,
                                      user_data: ::std::mem::transmute(ud_pointer_2),
                                      inputs: num_input_channels,
                                      outputs: num_output_channels,
                             }),
                Err(v) => Err(v),
            }
        }
    }

    pub fn open(input: StreamParameters<T>,
                output: StreamParameters<T>,
                sample_rate: f64,
                frames_per_buffer: u64,
                flags: StreamFlags,
                callback: Option<StreamCallback<'a, T>>)
               -> Result<Stream<'a, T>, PaError>
    {
        unsafe
        {
            let callback_pointer = match callback
            {
                Some(_) => Some(stream_callback::<T>),
                None => None,
            };

            let user_data = box StreamUserData
            {
                num_input: input.channel_count,
                num_output: output.channel_count,
                callback: callback,
                finished_callback: None,
            };

            let mut pa_stream = ::std::ptr::mut_null();
            let ud_pointer: *mut ::libc::c_void = mem::transmute(user_data);
            let ud_pointer_2 = ud_pointer.clone();

            let result = ll::Pa_OpenStream(&mut pa_stream,
                                                  &input.to_ll(),
                                                  &output.to_ll(),
                                                  sample_rate,
                                                  frames_per_buffer,
                                                  flags.bits,
                                                  callback_pointer,
                                                  ud_pointer);
            match to_pa_result(result)
            {
                Ok(()) => Ok(Stream { pa_stream: pa_stream,
                                      user_data: mem::transmute(ud_pointer_2),
                                      inputs: input.channel_count,
                                      outputs: output.channel_count,
                          }),
                Err(v) => Err(v),
            }
        }
    }

    pub fn start(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_StartStream(self.pa_stream) })
    }

    pub fn stop(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_StopStream(self.pa_stream) })
    }

    pub fn abort(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_AbortStream(self.pa_stream) })
    }

    fn close(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_CloseStream(self.pa_stream) })
    }

    pub fn is_stopped(&self) -> Result<bool, PaError>
    {
        match unsafe { ll::Pa_IsStreamStopped(self.pa_stream) }
        {
            1 => Ok(true),
            n => to_pa_result(n).map(|_| false),
        }
    }

    pub fn is_active(&self) -> Result<bool, PaError>
    {
        match unsafe { ll::Pa_IsStreamActive(self.pa_stream) }
        {
            1 => Ok(true),
            n => to_pa_result(n).map(|_| false),
        }
    }

    pub fn read_available(&self) -> Result<uint, PaError>
    {
        match unsafe { ll::Pa_GetStreamReadAvailable(self.pa_stream) }
        {
            n if n >= 0 => { Ok(n as uint) },
            n => to_pa_result(n as i32).map(|_| 0),
        }
    }

    pub fn write_available(&self) -> Result<uint, PaError>
    {
        match unsafe { ll::Pa_GetStreamWriteAvailable(self.pa_stream) }
        {
            n if n >= 0 => { Ok(n as uint) },
            n => to_pa_result(n as i32).map(|_| 0),
        }
    }

    pub fn write(&self, buffer: &[T]) -> PaResult
    {
        if self.outputs == 0 { return Err(pa::CanNotWriteToAnInputOnlyStream) }

        let pointer = buffer.as_ptr() as *const ::libc::c_void;
        let frames = (buffer.len() / self.outputs) as u64;

        to_pa_result(unsafe { ll::Pa_WriteStream(self.pa_stream, pointer, frames) })
    }

    pub fn read(&self, buffer: &mut [T]) -> PaResult
    {
        if self.inputs == 0 { return Err(pa::CanNotReadFromAnOutputOnlyStream) }

        let pointer = buffer.as_mut_ptr() as *mut ::libc::c_void;
        let frames = (buffer.len() / self.inputs) as u64;

        to_pa_result(unsafe { ll::Pa_ReadStream(self.pa_stream, pointer, frames) })
    }

    pub fn cpu_load(&self) -> f64
    {
        unsafe { ll::Pa_GetStreamCpuLoad(self.pa_stream) }
    }

    pub fn time(&self) -> Duration
    {
        let time = unsafe { ll::Pa_GetStreamTime(self.pa_stream) };
        pa_time_to_duration(time)
    }

    pub fn info(&self) -> Option<StreamInfo>
    {
        unsafe
        {
            ll::Pa_GetStreamInfo(self.pa_stream)
                .to_option()
                .map(|s| StreamInfo::from_ll(s))
        }
    }

    pub fn set_finished_callback(&mut self, finished_callback: StreamFinishedCallback<'a>) -> PaResult
    {
        self.user_data.finished_callback = Some(finished_callback);
        let callback_pointer = Some(stream_finished_callback::<T>);
        to_pa_result(unsafe { ll::Pa_SetStreamFinishedCallback(self.pa_stream, callback_pointer) })
    }

    pub fn unset_finished_callback(&mut self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_SetStreamFinishedCallback(self.pa_stream, None) })
    }
}

#[unsafe_destructor]
impl<'a, T: SampleType> Drop for Stream<'a, T>
{
    fn drop(&mut self)
    {
        match self.close()
        {
            Err(v) => error!("Error: {}", v),
            Ok(_) => {},
        };
    }
}

pub struct StreamParameters<T>
{
    pub device: DeviceIndex,
    pub channel_count: uint,
    pub suggested_latency: Duration,
}

impl<T: SampleType> StreamParameters<T>
{
    fn to_ll(&self) -> ll::Struct_PaStreamParameters
    {
        ll::Struct_PaStreamParameters
        {
            device: self.device as i32,
            channelCount: self.channel_count as i32,
            sampleFormat: get_sample_format::<T>(),
            suggestedLatency: self.suggested_latency.num_milliseconds() as f64 / 1000.0,
            hostApiSpecificStreamInfo: ::std::ptr::mut_null(),
        }
    }
}

pub fn is_format_supported<I: SampleType, O: SampleType>(input: StreamParameters<I>, output: StreamParameters<O>, sample_rate: f64) -> PaResult
{
    to_pa_result(unsafe { ll::Pa_IsFormatSupported(&input.to_ll(), &output.to_ll(), sample_rate) })
}

pub struct StreamInfo
{
    pub input_latency: Duration,
    pub output_latency: Duration,
    pub sample_rate: f64,
}

impl StreamInfo
{
    fn from_ll(data: &ll::PaStreamInfo) -> StreamInfo
    {
        StreamInfo
        {
            input_latency: pa_time_to_duration(data.inputLatency),
            output_latency: pa_time_to_duration(data.outputLatency),
            sample_rate: data.sampleRate,
        }
    }
}

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

    // This test asserts that the sizes used by PortAudio are the same as
    // those used by Rust
    #[test]
    fn sample_sizes()
    {
        test_sample_size::<f32>();
        test_sample_size::<i32>();
        test_sample_size::<i16>();
        test_sample_size::<i8>();
        test_sample_size::<u8>();
    }

    fn test_sample_size<T: SampleType>()
    {
        use std::mem;

        let pa_size = super::get_sample_size::<T>();
        let rs_size = Ok(mem::size_of::<T>());
        assert_eq!(rs_size, pa_size);
    }

    // In the FFI some assumptions are made as to how Some(p) and None are
    // represented when used as function pointers. This test asserts these
    // assumptions.
    #[test]
    fn option_pointer()
    {
        use std::{mem, ptr};
        use libc;

        unsafe
        {
            assert!   (mem::transmute::<Option<extern "C" fn()>, *const libc::c_void>(Some(external_function)) != ptr::null());
            assert_eq!(mem::transmute::<Option<extern "C" fn()>, *const libc::c_void>(None)                    ,  ptr::null());
        }
    }

    extern "C" fn external_function() {}
}
<commit_msg>Change some use statements<commit_after>use ll;
use pa::{PaError, PaResult};
use device::DeviceIndex;
use util::{to_pa_result, pa_time_to_duration};
use std::raw::Slice;
use std::mem;
use std::time::duration::Duration;
use libc::c_void;

#[repr(u32)]
pub enum StreamCallbackResult
{
    Continue = ll::paContinue,
    Complete = ll::paComplete,
    Abort = ll::paAbort,
}

pub type StreamCallback<'a, T> = |input: &[T], output: &mut [T], timeinfo: StreamTimeInfo, StreamCallbackFlags|:'a -> StreamCallbackResult;
pub type StreamFinishedCallback<'a> = ||:'a;

struct StreamUserData<'a, T>
{
    num_input: uint,
    num_output: uint,
    callback: Option<StreamCallback<'a, T>>,
    finished_callback: Option<StreamFinishedCallback<'a>>,
}

pub struct StreamTimeInfo
{
    pub input_adc_time: Duration,
    pub current_time: Duration,
    pub output_dac_time: Duration,
}

bitflags!(
    flags StreamCallbackFlags: u64 {
        static inputUnderflow = 0x01,
        static inputOverflow = 0x02,
        static outputUnderflow = 0x04,
        static outputOverflow = 0x08,
        static primingOutput = 0x10
    }
)

bitflags!(
    flags StreamFlags: u64 {
        static ClipOff                               = 0x00000001,
        static DitherOff                             = 0x00000002,
        static NeverDropInput                        = 0x00000004,
        static PrimeOutputBuffersUsingStreamCallback = 0x00000008,
        static PlatformSpecific                      = 0xFFFF0000
    }
)

extern "C" fn stream_callback<T>(input: *const c_void,
                                 output: *mut c_void,
                                 frame_count: ::libc::c_ulong,
                                 time_info: *const ll::PaStreamCallbackTimeInfo,
                                 status_flags: ll::PaStreamCallbackFlags,
                                 user_data: *mut c_void) -> ::libc::c_int
{
    let mut stream_data: Box<StreamUserData<T>> = unsafe { mem::transmute(user_data) };

    let input_buffer: &[T] = unsafe
    {
        mem::transmute(
            Slice { data: input as *const T, len: frame_count as uint * stream_data.num_input }
        )
    };
    let output_buffer: &mut [T] = unsafe
    {
        mem::transmute(
            Slice { data: output as *const T, len: frame_count as uint * stream_data.num_output }
        )
    };

    let flags = StreamCallbackFlags::from_bits_truncate(status_flags);

    let timeinfo = match unsafe { time_info.to_option() }
    {
        Some(ref info) => StreamTimeInfo { input_adc_time: pa_time_to_duration(info.inputBufferAdcTime),
                                           current_time: pa_time_to_duration(info.currentTime),
                                           output_dac_time: pa_time_to_duration(info.outputBufferDacTime) },
        None => StreamTimeInfo { input_adc_time: Duration::seconds(0),
                                 current_time: Duration::seconds(0),
                                 output_dac_time: Duration::seconds(0), },
    };

    let result = match stream_data.callback
    {
        Some(ref mut f) => (*f)(input_buffer, output_buffer, timeinfo, flags),
        None => Abort,
    };

    unsafe { mem::forget(stream_data); }

    result as i32
}

extern "C" fn stream_finished_callback<T>(user_data: *mut c_void)
{
    let mut stream_data: Box<StreamUserData<T>> = unsafe { mem::transmute(user_data) };
    match stream_data.finished_callback
    {
        Some(ref mut f) => (*f)(),
        None => {},
    };

    unsafe { mem::forget(stream_data); }
}

trait SampleType
{
    fn sample_format(_: Option<Self>) -> u64;
}
impl SampleType for f32 { fn sample_format(_: Option<f32>) -> u64 { 0x00000001 } }
impl SampleType for i32 { fn sample_format(_: Option<i32>) -> u64 { 0x00000002 } }
impl SampleType for i16 { fn sample_format(_: Option<i16>) -> u64 { 0x00000008 } }
impl SampleType for i8 { fn sample_format(_: Option<i8>) -> u64 { 0x00000010 } }
impl SampleType for u8 { fn sample_format(_: Option<u8>) -> u64 { 0x00000020 } }

fn get_sample_format<T: SampleType>() -> u64
{
    SampleType::sample_format(None::<T>)
}

pub fn get_sample_size<T: SampleType>() -> Result<uint, PaError>
{
    match unsafe { ll::Pa_GetSampleSize(get_sample_format::<T>()) }
    {
        n if n >= 0 => Ok(n as uint),
        m => to_pa_result(m).map(|_| 0),
    }
}

pub struct Stream<'a, T>
{
    pa_stream: *mut ll::PaStream,
    inputs: uint,
    outputs: uint,
    user_data: Box<StreamUserData<'a, T>>,
}

impl<'a, T: SampleType> Stream<'a, T>
{
    pub fn open_default(num_input_channels: uint,
                        num_output_channels: uint,
                        sample_rate: f64,
                        frames_per_buffer: u64,
                        callback: Option<StreamCallback<'a, T>>)
                       -> Result<Stream<'a, T>, PaError>
    {
        unsafe
        {
            let callback_pointer = match callback
            {
                Some(_) => Some(stream_callback::<T>),
                None => None,
            };
            let userdata = box StreamUserData
            {
                num_input: num_input_channels,
                num_output: num_output_channels,
                callback: callback,
                finished_callback: None,
            };
            let mut pa_stream = ::std::ptr::mut_null();

            let ud_pointer: *mut c_void = mem::transmute(userdata);
            let ud_pointer_2 = ud_pointer.clone();
            let code = ll::Pa_OpenDefaultStream(&mut pa_stream as *mut *mut ll::PaStream,
                                                num_input_channels as i32,
                                                num_output_channels as i32,
                                                get_sample_format::<T>(),
                                                sample_rate,
                                                frames_per_buffer,
                                                callback_pointer,
                                                ud_pointer);
            match to_pa_result(code)
            {
                Ok(()) => Ok(Stream { pa_stream: pa_stream,
                                      user_data: mem::transmute(ud_pointer_2),
                                      inputs: num_input_channels,
                                      outputs: num_output_channels,
                             }),
                Err(v) => Err(v),
            }
        }
    }

    pub fn open(input: StreamParameters<T>,
                output: StreamParameters<T>,
                sample_rate: f64,
                frames_per_buffer: u64,
                flags: StreamFlags,
                callback: Option<StreamCallback<'a, T>>)
               -> Result<Stream<'a, T>, PaError>
    {
        unsafe
        {
            let callback_pointer = match callback
            {
                Some(_) => Some(stream_callback::<T>),
                None => None,
            };

            let user_data = box StreamUserData
            {
                num_input: input.channel_count,
                num_output: output.channel_count,
                callback: callback,
                finished_callback: None,
            };

            let mut pa_stream = ::std::ptr::mut_null();
            let ud_pointer: *mut c_void = mem::transmute(user_data);
            let ud_pointer_2 = ud_pointer.clone();

            let result = ll::Pa_OpenStream(&mut pa_stream,
                                                  &input.to_ll(),
                                                  &output.to_ll(),
                                                  sample_rate,
                                                  frames_per_buffer,
                                                  flags.bits,
                                                  callback_pointer,
                                                  ud_pointer);
            match to_pa_result(result)
            {
                Ok(()) => Ok(Stream { pa_stream: pa_stream,
                                      user_data: mem::transmute(ud_pointer_2),
                                      inputs: input.channel_count,
                                      outputs: output.channel_count,
                          }),
                Err(v) => Err(v),
            }
        }
    }

    pub fn start(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_StartStream(self.pa_stream) })
    }

    pub fn stop(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_StopStream(self.pa_stream) })
    }

    pub fn abort(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_AbortStream(self.pa_stream) })
    }

    fn close(&self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_CloseStream(self.pa_stream) })
    }

    pub fn is_stopped(&self) -> Result<bool, PaError>
    {
        match unsafe { ll::Pa_IsStreamStopped(self.pa_stream) }
        {
            1 => Ok(true),
            n => to_pa_result(n).map(|_| false),
        }
    }

    pub fn is_active(&self) -> Result<bool, PaError>
    {
        match unsafe { ll::Pa_IsStreamActive(self.pa_stream) }
        {
            1 => Ok(true),
            n => to_pa_result(n).map(|_| false),
        }
    }

    pub fn read_available(&self) -> Result<uint, PaError>
    {
        match unsafe { ll::Pa_GetStreamReadAvailable(self.pa_stream) }
        {
            n if n >= 0 => { Ok(n as uint) },
            n => to_pa_result(n as i32).map(|_| 0),
        }
    }

    pub fn write_available(&self) -> Result<uint, PaError>
    {
        match unsafe { ll::Pa_GetStreamWriteAvailable(self.pa_stream) }
        {
            n if n >= 0 => { Ok(n as uint) },
            n => to_pa_result(n as i32).map(|_| 0),
        }
    }

    pub fn write(&self, buffer: &[T]) -> PaResult
    {
        if self.outputs == 0 { return Err(::pa::CanNotWriteToAnInputOnlyStream) }

        let pointer = buffer.as_ptr() as *const c_void;
        let frames = (buffer.len() / self.outputs) as u64;

        to_pa_result(unsafe { ll::Pa_WriteStream(self.pa_stream, pointer, frames) })
    }

    pub fn read(&self, buffer: &mut [T]) -> PaResult
    {
        if self.inputs == 0 { return Err(::pa::CanNotReadFromAnOutputOnlyStream) }

        let pointer = buffer.as_mut_ptr() as *mut c_void;
        let frames = (buffer.len() / self.inputs) as u64;

        to_pa_result(unsafe { ll::Pa_ReadStream(self.pa_stream, pointer, frames) })
    }

    pub fn cpu_load(&self) -> f64
    {
        unsafe { ll::Pa_GetStreamCpuLoad(self.pa_stream) }
    }

    pub fn time(&self) -> Duration
    {
        let time = unsafe { ll::Pa_GetStreamTime(self.pa_stream) };
        pa_time_to_duration(time)
    }

    pub fn info(&self) -> Option<StreamInfo>
    {
        unsafe
        {
            ll::Pa_GetStreamInfo(self.pa_stream)
                .to_option()
                .map(|s| StreamInfo::from_ll(s))
        }
    }

    pub fn set_finished_callback(&mut self, finished_callback: StreamFinishedCallback<'a>) -> PaResult
    {
        self.user_data.finished_callback = Some(finished_callback);
        let callback_pointer = Some(stream_finished_callback::<T>);
        to_pa_result(unsafe { ll::Pa_SetStreamFinishedCallback(self.pa_stream, callback_pointer) })
    }

    pub fn unset_finished_callback(&mut self) -> PaResult
    {
        to_pa_result(unsafe { ll::Pa_SetStreamFinishedCallback(self.pa_stream, None) })
    }
}

#[unsafe_destructor]
impl<'a, T: SampleType> Drop for Stream<'a, T>
{
    fn drop(&mut self)
    {
        match self.close()
        {
            Err(v) => error!("Error: {}", v),
            Ok(_) => {},
        };
    }
}

pub struct StreamParameters<T>
{
    pub device: DeviceIndex,
    pub channel_count: uint,
    pub suggested_latency: Duration,
}

impl<T: SampleType> StreamParameters<T>
{
    fn to_ll(&self) -> ll::Struct_PaStreamParameters
    {
        ll::Struct_PaStreamParameters
        {
            device: self.device as i32,
            channelCount: self.channel_count as i32,
            sampleFormat: get_sample_format::<T>(),
            suggestedLatency: self.suggested_latency.num_milliseconds() as f64 / 1000.0,
            hostApiSpecificStreamInfo: ::std::ptr::mut_null(),
        }
    }
}

pub fn is_format_supported<I: SampleType, O: SampleType>(input: StreamParameters<I>, output: StreamParameters<O>, sample_rate: f64) -> PaResult
{
    to_pa_result(unsafe { ll::Pa_IsFormatSupported(&input.to_ll(), &output.to_ll(), sample_rate) })
}

pub struct StreamInfo
{
    pub input_latency: Duration,
    pub output_latency: Duration,
    pub sample_rate: f64,
}

impl StreamInfo
{
    fn from_ll(data: &ll::PaStreamInfo) -> StreamInfo
    {
        StreamInfo
        {
            input_latency: pa_time_to_duration(data.inputLatency),
            output_latency: pa_time_to_duration(data.outputLatency),
            sample_rate: data.sampleRate,
        }
    }
}

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

    // This test asserts that the sizes used by PortAudio are the same as
    // those used by Rust
    #[test]
    fn sample_sizes()
    {
        test_sample_size::<f32>();
        test_sample_size::<i32>();
        test_sample_size::<i16>();
        test_sample_size::<i8>();
        test_sample_size::<u8>();
    }

    fn test_sample_size<T: SampleType>()
    {
        use std::mem;

        let pa_size = super::get_sample_size::<T>();
        let rs_size = Ok(mem::size_of::<T>());
        assert_eq!(rs_size, pa_size);
    }

    // In the FFI some assumptions are made as to how Some(p) and None are
    // represented when used as function pointers. This test asserts these
    // assumptions.
    #[test]
    fn option_pointer()
    {
        use std::{mem, ptr};
        use libc::c_void;

        unsafe
        {
            assert!   (mem::transmute::<Option<extern "C" fn()>, *const c_void>(Some(external_function)) != ptr::null());
            assert_eq!(mem::transmute::<Option<extern "C" fn()>, *const c_void>(None)                    ,  ptr::null());
        }
    }

    extern "C" fn external_function() {}
}
<|endoftext|>


<commit_before>use std::io::{Read, Write, Result};
use std::net::{ToSocketAddrs, SocketAddr};
use socket::UtpSocket;

/// A structure that represents a uTP (Micro Transport Protocol) stream between a local socket and a
/// remote socket.
///
/// The connection will be closed when the value is dropped (either explicitly or when it goes out of
/// scope).
///
/// # Examples
///
/// ```no_run
/// use utp::UtpStream;
/// use std::io::{Read, Write};
///
/// let mut stream = UtpStream::bind("127.0.0.1:1234").unwrap();
/// let _ = stream.write(&[1]);
/// let _ = stream.read(&mut [0; 1000]);
/// ```
pub struct UtpStream {
    socket: UtpSocket,
}

impl UtpStream {
    /// Creates a uTP stream listening on the given address.
    ///
    /// The address type can be any implementor of the `ToSocketAddr` trait. See its documentation
    /// for concrete examples.
    ///
    /// If more than one valid address is specified, only the first will be used.
    pub fn bind<A: ToSocketAddrs>(addr: A) -> Result<UtpStream> {
        UtpSocket::bind(addr).and_then(|s| Ok(UtpStream { socket: s }))
    }

    /// Opens a uTP connection to a remote host by hostname or IP address.
    ///
    /// The address type can be any implementor of the `ToSocketAddr` trait. See its documentation
    /// for concrete examples.
    ///
    /// If more than one valid address is specified, only the first will be used.
    pub fn connect<A: ToSocketAddrs>(dst: A) -> Result<UtpStream> {
        // Port 0 means the operating system gets to choose it
        let my_addr = match dst.to_socket_addrs().unwrap().next().unwrap() {
            SocketAddr::V4(_) => "0.0.0.0:0",
            SocketAddr::V6(_) => ":::0",
        };
        UtpSocket::bind(my_addr)
            .and_then(|s| s.connect(dst))
            .and_then(|s| Ok(UtpStream { socket: s }))
    }

    /// Gracefully closes connection to peer.
    ///
    /// This method allows both peers to receive all packets still in
    /// flight.
    pub fn close(&mut self) -> Result<()> {
        self.socket.close()
    }

    /// Returns the socket address of the local half of this uTP connection.
    pub fn local_addr(&self) -> Result<SocketAddr> {
        self.socket.local_addr()
    }
}

impl Read for UtpStream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        self.socket.recv_from(buf).map(|(read, _src)| read)
    }
}

impl Write for UtpStream {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.socket.send_to(buf)
    }

    fn flush(&mut self) -> Result<()> {
        self.socket.flush()
    }
}

impl Into<UtpStream> for UtpSocket {
    fn into(self) -> UtpStream {
        UtpStream { socket: self }
    }
}
<commit_msg>Implement `Deref` for UtpStream into UtpSocket.<commit_after>use std::io::{Read, Write, Result};
use std::net::{ToSocketAddrs, SocketAddr};
use std::ops::Deref;
use socket::UtpSocket;

/// A structure that represents a uTP (Micro Transport Protocol) stream between a local socket and a
/// remote socket.
///
/// The connection will be closed when the value is dropped (either explicitly or when it goes out of
/// scope).
///
/// # Examples
///
/// ```no_run
/// use utp::UtpStream;
/// use std::io::{Read, Write};
///
/// let mut stream = UtpStream::bind("127.0.0.1:1234").unwrap();
/// let _ = stream.write(&[1]);
/// let _ = stream.read(&mut [0; 1000]);
/// ```
pub struct UtpStream {
    socket: UtpSocket,
}

impl UtpStream {
    /// Creates a uTP stream listening on the given address.
    ///
    /// The address type can be any implementor of the `ToSocketAddr` trait. See its documentation
    /// for concrete examples.
    ///
    /// If more than one valid address is specified, only the first will be used.
    pub fn bind<A: ToSocketAddrs>(addr: A) -> Result<UtpStream> {
        UtpSocket::bind(addr).and_then(|s| Ok(UtpStream { socket: s }))
    }

    /// Opens a uTP connection to a remote host by hostname or IP address.
    ///
    /// The address type can be any implementor of the `ToSocketAddr` trait. See its documentation
    /// for concrete examples.
    ///
    /// If more than one valid address is specified, only the first will be used.
    pub fn connect<A: ToSocketAddrs>(dst: A) -> Result<UtpStream> {
        // Port 0 means the operating system gets to choose it
        let my_addr = match dst.to_socket_addrs().unwrap().next().unwrap() {
            SocketAddr::V4(_) => "0.0.0.0:0",
            SocketAddr::V6(_) => ":::0",
        };
        UtpSocket::bind(my_addr)
            .and_then(|s| s.connect(dst))
            .and_then(|s| Ok(UtpStream { socket: s }))
    }

    /// Gracefully closes connection to peer.
    ///
    /// This method allows both peers to receive all packets still in
    /// flight.
    pub fn close(&mut self) -> Result<()> {
        self.socket.close()
    }

    /// Returns the socket address of the local half of this uTP connection.
    pub fn local_addr(&self) -> Result<SocketAddr> {
        self.socket.local_addr()
    }
}

impl Read for UtpStream {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        self.socket.recv_from(buf).map(|(read, _src)| read)
    }
}

impl Write for UtpStream {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.socket.send_to(buf)
    }

    fn flush(&mut self) -> Result<()> {
        self.socket.flush()
    }
}

impl Into<UtpStream> for UtpSocket {
    fn into(self) -> UtpStream {
        UtpStream { socket: self }
    }
}

impl Deref for UtpStream {
    type Target = UtpSocket;

    fn deref(&self) -> &UtpSocket {
        &self.socket
    }
}
<|endoftext|>


<commit_before>use std;
use libc::size_t;
use mdb::types::MDB_val;

pub trait MDBIncomingValue {
    fn to_mdb_value(&self) -> MDB_val;
}

pub trait MDBOutgoingValue {
    fn from_mdb_value(value: &MDB_val) -> Self;
}

impl MDBIncomingValue for ~[u8] {
    fn to_mdb_value(&self) -> MDB_val {
        unsafe {
            MDB_val {
                mv_data: std::cast::transmute(self.as_ptr()),
                mv_size: self.len() as size_t
            }
        }
    }
}

impl MDBOutgoingValue for ~[u8] {
    fn from_mdb_value(value: &MDB_val) -> ~[u8] {
        unsafe {
            std::slice::raw::from_buf_raw(value.mv_data as *u8, value.mv_size as uint)
        }
    }
}

impl MDBIncomingValue for ~str {
    fn to_mdb_value(&self) -> MDB_val {
        unsafe {
            let t = self.as_slice();
            MDB_val {
                mv_data: std::cast::transmute(t.as_ptr()),
                mv_size: t.len() as size_t
            }
        }
    }
}

impl MDBOutgoingValue for ~str {
    fn from_mdb_value(value: &MDB_val) -> ~str {
        unsafe {
            std::str::raw::from_buf_len(std::cast::transmute(value.mv_data), value.mv_size as uint)
        }
    }
}

impl MDBOutgoingValue for () {
    fn from_mdb_value(_: &MDB_val) {
    }
}

pub trait StateError {
    fn new_state_error(msg: ~str) -> Self;
}<commit_msg>Allowing static strs to be used as incoming value<commit_after>use std;
use libc::size_t;
use mdb::types::MDB_val;

pub trait MDBIncomingValue {
    fn to_mdb_value(&self) -> MDB_val;
}

pub trait MDBOutgoingValue {
    fn from_mdb_value(value: &MDB_val) -> Self;
}

impl MDBIncomingValue for ~[u8] {
    fn to_mdb_value(&self) -> MDB_val {
        unsafe {
            MDB_val {
                mv_data: std::cast::transmute(self.as_ptr()),
                mv_size: self.len() as size_t
            }
        }
    }
}

impl MDBOutgoingValue for ~[u8] {
    fn from_mdb_value(value: &MDB_val) -> ~[u8] {
        unsafe {
            std::slice::raw::from_buf_raw(value.mv_data as *u8, value.mv_size as uint)
        }
    }
}

impl MDBIncomingValue for ~str {
    fn to_mdb_value(&self) -> MDB_val {
        unsafe {
            let t = self.as_slice();
            MDB_val {
                mv_data: std::cast::transmute(t.as_ptr()),
                mv_size: t.len() as size_t
            }
        }
    }
}

impl MDBIncomingValue for &'static str {
    fn to_mdb_value(&self) -> MDB_val {
        unsafe {
            let t = self.as_slice();
            MDB_val {
                mv_data: std::cast::transmute(t.as_ptr()),
                mv_size: t.len() as size_t
            }
        }
    }
}

impl MDBOutgoingValue for ~str {
    fn from_mdb_value(value: &MDB_val) -> ~str {
        unsafe {
            std::str::raw::from_buf_len(std::cast::transmute(value.mv_data), value.mv_size as uint)
        }
    }
}

impl MDBOutgoingValue for () {
    fn from_mdb_value(_: &MDB_val) {
    }
}

pub trait StateError {
    fn new_state_error(msg: ~str) -> Self;
}
<|endoftext|>


<commit_before>use rustc::hir::def_id::DefId;
use rustc::traits::{self, Reveal, SelectionContext};
use rustc::ty::subst::Substs;
use rustc::ty;

use error::EvalResult;
use eval_context::EvalContext;
use memory::Pointer;
use terminator::{get_impl_method, ImplMethod};

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
    /// objects.
    ///
    /// The `trait_ref` encodes the erased self type. Hence if we are
    /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
    /// `trait_ref` would map `T:Trait`.
    pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'tcx, Pointer> {
        let tcx = self.tcx;

        debug!("get_vtable(trait_ref={:?})", trait_ref);

        let methods: Vec<_> = traits::supertraits(tcx, trait_ref).flat_map(|trait_ref| {
            match self.fulfill_obligation(trait_ref) {
                // Should default trait error here?
                traits::VtableDefaultImpl(_) |
                traits::VtableBuiltin(_) => {
                    Vec::new().into_iter()
                }

                traits::VtableImpl(traits::VtableImplData { impl_def_id: id, substs, .. }) => {
                    self.get_vtable_methods(id, substs)
                        .into_iter()
                        .map(|opt_mth| opt_mth.map(|mth| {
                            let fn_ty = self.tcx.item_type(mth.method.def_id);
                            let fn_ty = match fn_ty.sty {
                                ty::TyFnDef(_, _, fn_ty) => fn_ty,
                                _ => bug!("bad function type: {}", fn_ty),
                            };
                            let fn_ty = self.tcx.erase_regions(&fn_ty);
                            self.memory.create_fn_ptr(self.tcx, mth.method.def_id, mth.substs, fn_ty)
                        }))
                        .collect::<Vec<_>>()
                        .into_iter()
                }

                traits::VtableClosure(
                    traits::VtableClosureData {
                        closure_def_id,
                        substs,
                        ..
                    }
                ) => {
                    let closure_type = self.tcx.closure_type(closure_def_id, substs);
                    vec![Some(self.memory.create_closure_ptr(self.tcx, closure_def_id, substs, closure_type))].into_iter()
                }

                // turn a function definition into a Fn trait object
                traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, .. }) => {
                    match fn_ty.sty {
                        ty::TyFnDef(did, substs, bare_fn_ty) => {
                            vec![Some(self.memory.create_fn_as_trait_glue(self.tcx, did, substs, bare_fn_ty))].into_iter()
                        },
                        ty::TyFnPtr(bare_fn_ty) => {
                            vec![Some(self.memory.create_fn_ptr_as_trait_glue(bare_fn_ty))].into_iter()
                        },
                        _ => bug!("bad VtableFnPointer fn_ty: {:#?}", fn_ty.sty),
                    }
                }

                traits::VtableObject(ref data) => {
                    // this would imply that the Self type being erased is
                    // an object type; this cannot happen because we
                    // cannot cast an unsized type into a trait object
                    bug!("cannot get vtable for an object type: {:?}",
                         data);
                }

                vtable @ traits::VtableParam(..) => {
                    bug!("resolved vtable for {:?} to bad vtable {:?} in trans",
                         trait_ref,
                         vtable);
                }
            }
        }).collect();

        let size = self.type_size(trait_ref.self_ty())?.expect("can't create a vtable for an unsized type");
        let align = self.type_align(trait_ref.self_ty())?;

        let ptr_size = self.memory.pointer_size();
        let vtable = self.memory.allocate(ptr_size * (3 + methods.len() as u64), ptr_size)?;

        // in case there is no drop function to be called, this still needs to be initialized
        self.memory.write_usize(vtable, 0)?;
        if let ty::TyAdt(adt_def, substs) = trait_ref.self_ty().sty {
            if let Some(drop_def_id) = adt_def.destructor() {
                let fn_ty = match  self.tcx.item_type(drop_def_id).sty {
                    ty::TyFnDef(_, _, fn_ty) => self.tcx.erase_regions(&fn_ty),
                    _ => bug!("drop method is not a TyFnDef"),
                };
                let fn_ptr = self.memory.create_drop_glue(self.tcx, drop_def_id, substs, fn_ty);
                self.memory.write_ptr(vtable, fn_ptr)?;
            }
        }

        self.memory.write_usize(vtable.offset(ptr_size), size)?;
        self.memory.write_usize(vtable.offset(ptr_size * 2), align)?;

        for (i, method) in methods.into_iter().enumerate() {
            if let Some(method) = method {
                self.memory.write_ptr(vtable.offset(ptr_size * (3 + i as u64)), method)?;
            }
        }

        self.memory.mark_static_initalized(vtable.alloc_id, false)?;

        Ok(vtable)
    }

    fn get_vtable_methods(&mut self, impl_id: DefId, substs: &'tcx Substs<'tcx>) -> Vec<Option<ImplMethod<'tcx>>> {
        debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);

        let trait_id = match self.tcx.impl_trait_ref(impl_id) {
            Some(t_id) => t_id.def_id,
            None       => bug!("make_impl_vtable: don't know how to \
                                make a vtable for a type impl!")
        };

        self.tcx.populate_implementations_for_trait_if_necessary(trait_id);

        self.tcx
            .associated_items(trait_id)
            // Filter out non-method items.
            .filter_map(|trait_method_type| {
                if trait_method_type.kind != ty::AssociatedKind::Method {
                    return None;
                }
                debug!("get_vtable_methods: trait_method_type={:?}",
                       trait_method_type);

                let name = trait_method_type.name;

                // Some methods cannot be called on an object; skip those.
                if !self.tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
                    debug!("get_vtable_methods: not vtable safe");
                    return Some(None);
                }

                debug!("get_vtable_methods: trait_method_type={:?}",
                       trait_method_type);

                // the method may have some early-bound lifetimes, add
                // regions for those
                let method_substs = Substs::for_item(self.tcx, trait_method_type.def_id,
                                                     |_, _| self.tcx.mk_region(ty::ReErased),
                                                     |_, _| self.tcx.types.err);

                // The substitutions we have are on the impl, so we grab
                // the method type from the impl to substitute into.
                let mth = get_impl_method(self.tcx, method_substs, impl_id, substs, name);

                debug!("get_vtable_methods: mth={:?}", mth);

                // If this is a default method, it's possible that it
                // relies on where clauses that do not hold for this
                // particular set of type parameters. Note that this
                // method could then never be called, so we do not want to
                // try and trans it, in that case. Issue #23435.
                if mth.is_provided {
                    let predicates = self.tcx.item_predicates(trait_method_type.def_id).instantiate_own(self.tcx, mth.substs);
                    if !self.normalize_and_test_predicates(predicates.predicates) {
                        debug!("get_vtable_methods: predicates do not hold");
                        return Some(None);
                    }
                }

                Some(Some(mth))
            })
            .collect()
    }

    /// Normalizes the predicates and checks whether they hold.  If this
    /// returns false, then either normalize encountered an error or one
    /// of the predicates did not hold. Used when creating vtables to
    /// check for unsatisfiable methods.
    fn normalize_and_test_predicates(&mut self, predicates: Vec<ty::Predicate<'tcx>>) -> bool {
        debug!("normalize_and_test_predicates(predicates={:?})",
               predicates);

        self.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
            let mut selcx = SelectionContext::new(&infcx);
            let mut fulfill_cx = traits::FulfillmentContext::new();
            let cause = traits::ObligationCause::dummy();
            let traits::Normalized { value: predicates, obligations } =
                traits::normalize(&mut selcx, cause.clone(), &predicates);
            for obligation in obligations {
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }
            for predicate in predicates {
                let obligation = traits::Obligation::new(cause.clone(), predicate);
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }

            fulfill_cx.select_all_or_error(&infcx).is_ok()
        })
    }
}
<commit_msg>double space<commit_after>use rustc::hir::def_id::DefId;
use rustc::traits::{self, Reveal, SelectionContext};
use rustc::ty::subst::Substs;
use rustc::ty;

use error::EvalResult;
use eval_context::EvalContext;
use memory::Pointer;
use terminator::{get_impl_method, ImplMethod};

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
    /// objects.
    ///
    /// The `trait_ref` encodes the erased self type. Hence if we are
    /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
    /// `trait_ref` would map `T:Trait`.
    pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'tcx, Pointer> {
        let tcx = self.tcx;

        debug!("get_vtable(trait_ref={:?})", trait_ref);

        let methods: Vec<_> = traits::supertraits(tcx, trait_ref).flat_map(|trait_ref| {
            match self.fulfill_obligation(trait_ref) {
                // Should default trait error here?
                traits::VtableDefaultImpl(_) |
                traits::VtableBuiltin(_) => {
                    Vec::new().into_iter()
                }

                traits::VtableImpl(traits::VtableImplData { impl_def_id: id, substs, .. }) => {
                    self.get_vtable_methods(id, substs)
                        .into_iter()
                        .map(|opt_mth| opt_mth.map(|mth| {
                            let fn_ty = self.tcx.item_type(mth.method.def_id);
                            let fn_ty = match fn_ty.sty {
                                ty::TyFnDef(_, _, fn_ty) => fn_ty,
                                _ => bug!("bad function type: {}", fn_ty),
                            };
                            let fn_ty = self.tcx.erase_regions(&fn_ty);
                            self.memory.create_fn_ptr(self.tcx, mth.method.def_id, mth.substs, fn_ty)
                        }))
                        .collect::<Vec<_>>()
                        .into_iter()
                }

                traits::VtableClosure(
                    traits::VtableClosureData {
                        closure_def_id,
                        substs,
                        ..
                    }
                ) => {
                    let closure_type = self.tcx.closure_type(closure_def_id, substs);
                    vec![Some(self.memory.create_closure_ptr(self.tcx, closure_def_id, substs, closure_type))].into_iter()
                }

                // turn a function definition into a Fn trait object
                traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, .. }) => {
                    match fn_ty.sty {
                        ty::TyFnDef(did, substs, bare_fn_ty) => {
                            vec![Some(self.memory.create_fn_as_trait_glue(self.tcx, did, substs, bare_fn_ty))].into_iter()
                        },
                        ty::TyFnPtr(bare_fn_ty) => {
                            vec![Some(self.memory.create_fn_ptr_as_trait_glue(bare_fn_ty))].into_iter()
                        },
                        _ => bug!("bad VtableFnPointer fn_ty: {:#?}", fn_ty.sty),
                    }
                }

                traits::VtableObject(ref data) => {
                    // this would imply that the Self type being erased is
                    // an object type; this cannot happen because we
                    // cannot cast an unsized type into a trait object
                    bug!("cannot get vtable for an object type: {:?}",
                         data);
                }

                vtable @ traits::VtableParam(..) => {
                    bug!("resolved vtable for {:?} to bad vtable {:?} in trans",
                         trait_ref,
                         vtable);
                }
            }
        }).collect();

        let size = self.type_size(trait_ref.self_ty())?.expect("can't create a vtable for an unsized type");
        let align = self.type_align(trait_ref.self_ty())?;

        let ptr_size = self.memory.pointer_size();
        let vtable = self.memory.allocate(ptr_size * (3 + methods.len() as u64), ptr_size)?;

        // in case there is no drop function to be called, this still needs to be initialized
        self.memory.write_usize(vtable, 0)?;
        if let ty::TyAdt(adt_def, substs) = trait_ref.self_ty().sty {
            if let Some(drop_def_id) = adt_def.destructor() {
                let fn_ty = match self.tcx.item_type(drop_def_id).sty {
                    ty::TyFnDef(_, _, fn_ty) => self.tcx.erase_regions(&fn_ty),
                    _ => bug!("drop method is not a TyFnDef"),
                };
                let fn_ptr = self.memory.create_drop_glue(self.tcx, drop_def_id, substs, fn_ty);
                self.memory.write_ptr(vtable, fn_ptr)?;
            }
        }

        self.memory.write_usize(vtable.offset(ptr_size), size)?;
        self.memory.write_usize(vtable.offset(ptr_size * 2), align)?;

        for (i, method) in methods.into_iter().enumerate() {
            if let Some(method) = method {
                self.memory.write_ptr(vtable.offset(ptr_size * (3 + i as u64)), method)?;
            }
        }

        self.memory.mark_static_initalized(vtable.alloc_id, false)?;

        Ok(vtable)
    }

    fn get_vtable_methods(&mut self, impl_id: DefId, substs: &'tcx Substs<'tcx>) -> Vec<Option<ImplMethod<'tcx>>> {
        debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);

        let trait_id = match self.tcx.impl_trait_ref(impl_id) {
            Some(t_id) => t_id.def_id,
            None       => bug!("make_impl_vtable: don't know how to \
                                make a vtable for a type impl!")
        };

        self.tcx.populate_implementations_for_trait_if_necessary(trait_id);

        self.tcx
            .associated_items(trait_id)
            // Filter out non-method items.
            .filter_map(|trait_method_type| {
                if trait_method_type.kind != ty::AssociatedKind::Method {
                    return None;
                }
                debug!("get_vtable_methods: trait_method_type={:?}",
                       trait_method_type);

                let name = trait_method_type.name;

                // Some methods cannot be called on an object; skip those.
                if !self.tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
                    debug!("get_vtable_methods: not vtable safe");
                    return Some(None);
                }

                debug!("get_vtable_methods: trait_method_type={:?}",
                       trait_method_type);

                // the method may have some early-bound lifetimes, add
                // regions for those
                let method_substs = Substs::for_item(self.tcx, trait_method_type.def_id,
                                                     |_, _| self.tcx.mk_region(ty::ReErased),
                                                     |_, _| self.tcx.types.err);

                // The substitutions we have are on the impl, so we grab
                // the method type from the impl to substitute into.
                let mth = get_impl_method(self.tcx, method_substs, impl_id, substs, name);

                debug!("get_vtable_methods: mth={:?}", mth);

                // If this is a default method, it's possible that it
                // relies on where clauses that do not hold for this
                // particular set of type parameters. Note that this
                // method could then never be called, so we do not want to
                // try and trans it, in that case. Issue #23435.
                if mth.is_provided {
                    let predicates = self.tcx.item_predicates(trait_method_type.def_id).instantiate_own(self.tcx, mth.substs);
                    if !self.normalize_and_test_predicates(predicates.predicates) {
                        debug!("get_vtable_methods: predicates do not hold");
                        return Some(None);
                    }
                }

                Some(Some(mth))
            })
            .collect()
    }

    /// Normalizes the predicates and checks whether they hold.  If this
    /// returns false, then either normalize encountered an error or one
    /// of the predicates did not hold. Used when creating vtables to
    /// check for unsatisfiable methods.
    fn normalize_and_test_predicates(&mut self, predicates: Vec<ty::Predicate<'tcx>>) -> bool {
        debug!("normalize_and_test_predicates(predicates={:?})",
               predicates);

        self.tcx.infer_ctxt((), Reveal::All).enter(|infcx| {
            let mut selcx = SelectionContext::new(&infcx);
            let mut fulfill_cx = traits::FulfillmentContext::new();
            let cause = traits::ObligationCause::dummy();
            let traits::Normalized { value: predicates, obligations } =
                traits::normalize(&mut selcx, cause.clone(), &predicates);
            for obligation in obligations {
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }
            for predicate in predicates {
                let obligation = traits::Obligation::new(cause.clone(), predicate);
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }

            fulfill_cx.select_all_or_error(&infcx).is_ok()
        })
    }
}
<|endoftext|>


<commit_before>// Copyright © 2015, Peter Atashian
// Licensed under the MIT License <LICENSE.md>
//! GDI procedure declarations, constant definitions and macros
//1438
pub const LF_FACESIZE: usize = 32;

// this type is weird because it's a hacky "unsized type"
#[repr(C)]
pub struct RGNDATA;

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PALETTEENTRY {
    peRed: ::BYTE,
    peGreen: ::BYTE,
    peBlue: ::BYTE,
    peFlags: ::BYTE
}<commit_msg>Added 'RGB' from 'wingdi.h'.<commit_after>// Copyright © 2015, Peter Atashian
// Licensed under the MIT License <LICENSE.md>
//! GDI procedure declarations, constant definitions and macros
//1438
pub const LF_FACESIZE: usize = 32;
//1595
#[inline]
pub fn RGB (r: ::BYTE, g: ::BYTE, b: ::BYTE) -> ::COLORREF {
  r as ::COLORREF | ((g as ::COLORREF) << 8) | ((b as ::COLORREF) << 16)
}

// this type is weird because it's a hacky "unsized type"
#[repr(C)]
pub struct RGNDATA;

#[repr(C)]
#[derive(Copy, Clone)]
pub struct PALETTEENTRY {
    peRed: ::BYTE,
    peGreen: ::BYTE,
    peBlue: ::BYTE,
    peFlags: ::BYTE
}
<|endoftext|>


<commit_before>use std::io::{Writer, IoError, IoResult};
use std::num::Int;

use rustc_serialize::Encoder;

use super::SizeLimit;

type EwResult = IoResult<()>;

pub struct EncoderWriter<'a, W: 'a> {
    writer: &'a mut W,
    size_limit: SizeLimit
}

impl <'a, W: Writer> EncoderWriter<'a, W> {
    pub fn new(w: &'a mut W, size_limit: SizeLimit) -> EncoderWriter<'a, W> {
        EncoderWriter {
            writer: w,
            size_limit: size_limit
        }
    }
}

impl<'a, W: Writer> Encoder for EncoderWriter<'a, W> {
    type Error = IoError;

    fn emit_nil(&mut self) -> EwResult { Ok(()) }
    fn emit_uint(&mut self, v: uint) -> EwResult {
        self.emit_u64(v as u64)
    }
    fn emit_u64(&mut self, v: u64) -> EwResult {
        self.writer.write_be_u64(v)
    }
    fn emit_u32(&mut self, v: u32) -> EwResult {
        self.writer.write_be_u32(v)
    }
    fn emit_u16(&mut self, v: u16) -> EwResult {
        self.writer.write_be_u16(v)
    }
    fn emit_u8(&mut self, v: u8) -> EwResult {
        self.writer.write_u8(v)
    }
    fn emit_int(&mut self, v: int) -> EwResult {
        self.emit_i64(v as i64)
    }
    fn emit_i64(&mut self, v: i64) -> EwResult {
        self.writer.write_be_i64(v)
    }
    fn emit_i32(&mut self, v: i32) -> EwResult {
        self.writer.write_be_i32(v)
    }
    fn emit_i16(&mut self, v: i16) -> EwResult {
        self.writer.write_be_i16(v)
    }
    fn emit_i8(&mut self, v: i8) -> EwResult {
        self.writer.write_i8(v)
    }
    fn emit_bool(&mut self, v: bool) -> EwResult {
        self.writer.write_u8(if v {1} else {0})
    }
    fn emit_f64(&mut self, v: f64) -> EwResult {
        self.writer.write_be_f64(v)
    }
    fn emit_f32(&mut self, v: f32) -> EwResult {
        self.writer.write_be_f32(v)
    }
    fn emit_char(&mut self, v: char) -> EwResult {
        self.writer.write_char(v)
    }
    fn emit_str(&mut self, v: &str) -> EwResult {
        try!(self.emit_uint(v.len()));
        self.writer.write_str(v)
    }
    fn emit_enum<F>(&mut self, __: &str, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_enum_variant<F>(&mut self, _: &str,
                            v_id: uint,
                            _: uint,
                            f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            let max_u32: u32 = Int::max_value();
            if v_id > (max_u32 as uint) {
                panic!("Variant tag doesn't fit in a u32")
            }
            try!(self.emit_u32(v_id as u32));
            f(self)
        }
    fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_enum_struct_variant<F>(&mut self, _: &str,
                                   _: uint,
                                   _: uint,
                                   f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_enum_struct_variant_field<F>(&mut self,
                                         _: &str,
                                         _: uint,
                                         f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_struct<F>(&mut self, _: &str, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_struct_field<F>(&mut self, _: &str, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_tuple<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_tuple_arg<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            self.emit_tuple(len, f)
        }
    fn emit_tuple_struct_arg<F>(&mut self, f_idx: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            self.emit_tuple_arg(f_idx, f)
        }
    fn emit_option<F>(&mut self, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_option_none(&mut self) -> EwResult {
        self.writer.write_u8(0)
    }
    fn emit_option_some<F>(&mut self, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            try!(self.writer.write_u8(1));
            f(self)
        }
    fn emit_seq<F>(&mut self, len: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            try!(self.emit_uint(len));
            f(self)
        }
    fn emit_seq_elt<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_map<F>(&mut self, len: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            try!(self.emit_uint(len));
            f(self)
        }
    fn emit_map_elt_key<F>(&mut self, _: uint, mut f: F) -> EwResult where
        F: FnMut(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_map_elt_val<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
}
<commit_msg>Silence unused variable warning for EncoderWriter.<commit_after>use std::io::{Writer, IoError, IoResult};
use std::num::Int;

use rustc_serialize::Encoder;

use super::SizeLimit;

type EwResult = IoResult<()>;

pub struct EncoderWriter<'a, W: 'a> {
    writer: &'a mut W,
    _size_limit: SizeLimit
}

impl <'a, W: Writer> EncoderWriter<'a, W> {
    pub fn new(w: &'a mut W, size_limit: SizeLimit) -> EncoderWriter<'a, W> {
        EncoderWriter {
            writer: w,
            _size_limit: size_limit
        }
    }
}

impl<'a, W: Writer> Encoder for EncoderWriter<'a, W> {
    type Error = IoError;

    fn emit_nil(&mut self) -> EwResult { Ok(()) }
    fn emit_uint(&mut self, v: uint) -> EwResult {
        self.emit_u64(v as u64)
    }
    fn emit_u64(&mut self, v: u64) -> EwResult {
        self.writer.write_be_u64(v)
    }
    fn emit_u32(&mut self, v: u32) -> EwResult {
        self.writer.write_be_u32(v)
    }
    fn emit_u16(&mut self, v: u16) -> EwResult {
        self.writer.write_be_u16(v)
    }
    fn emit_u8(&mut self, v: u8) -> EwResult {
        self.writer.write_u8(v)
    }
    fn emit_int(&mut self, v: int) -> EwResult {
        self.emit_i64(v as i64)
    }
    fn emit_i64(&mut self, v: i64) -> EwResult {
        self.writer.write_be_i64(v)
    }
    fn emit_i32(&mut self, v: i32) -> EwResult {
        self.writer.write_be_i32(v)
    }
    fn emit_i16(&mut self, v: i16) -> EwResult {
        self.writer.write_be_i16(v)
    }
    fn emit_i8(&mut self, v: i8) -> EwResult {
        self.writer.write_i8(v)
    }
    fn emit_bool(&mut self, v: bool) -> EwResult {
        self.writer.write_u8(if v {1} else {0})
    }
    fn emit_f64(&mut self, v: f64) -> EwResult {
        self.writer.write_be_f64(v)
    }
    fn emit_f32(&mut self, v: f32) -> EwResult {
        self.writer.write_be_f32(v)
    }
    fn emit_char(&mut self, v: char) -> EwResult {
        self.writer.write_char(v)
    }
    fn emit_str(&mut self, v: &str) -> EwResult {
        try!(self.emit_uint(v.len()));
        self.writer.write_str(v)
    }
    fn emit_enum<F>(&mut self, __: &str, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_enum_variant<F>(&mut self, _: &str,
                            v_id: uint,
                            _: uint,
                            f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            let max_u32: u32 = Int::max_value();
            if v_id > (max_u32 as uint) {
                panic!("Variant tag doesn't fit in a u32")
            }
            try!(self.emit_u32(v_id as u32));
            f(self)
        }
    fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_enum_struct_variant<F>(&mut self, _: &str,
                                   _: uint,
                                   _: uint,
                                   f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_enum_struct_variant_field<F>(&mut self,
                                         _: &str,
                                         _: uint,
                                         f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_struct<F>(&mut self, _: &str, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_struct_field<F>(&mut self, _: &str, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_tuple<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_tuple_arg<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            self.emit_tuple(len, f)
        }
    fn emit_tuple_struct_arg<F>(&mut self, f_idx: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            self.emit_tuple_arg(f_idx, f)
        }
    fn emit_option<F>(&mut self, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_option_none(&mut self) -> EwResult {
        self.writer.write_u8(0)
    }
    fn emit_option_some<F>(&mut self, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            try!(self.writer.write_u8(1));
            f(self)
        }
    fn emit_seq<F>(&mut self, len: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            try!(self.emit_uint(len));
            f(self)
        }
    fn emit_seq_elt<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_map<F>(&mut self, len: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            try!(self.emit_uint(len));
            f(self)
        }
    fn emit_map_elt_key<F>(&mut self, _: uint, mut f: F) -> EwResult where
        F: FnMut(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
    fn emit_map_elt_val<F>(&mut self, _: uint, f: F) -> EwResult where
        F: FnOnce(&mut EncoderWriter<'a, W>) -> EwResult {
            f(self)
        }
}
<|endoftext|>


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

use kite::{Document, TermRef};
use kite::schema::FieldRef;
use byteorder::{BigEndian, WriteBytesExt};

use key_builder::KeyBuilder;

#[derive(Debug)]
pub struct SegmentBuilder {
    current_doc: u16,
    pub term_dictionary: HashMap<Vec<u8>, TermRef>,
    current_term_ref: u32,
    pub term_directories: HashMap<(FieldRef, TermRef), Vec<u16>>,
    pub statistics: HashMap<Vec<u8>, i64>,
    pub stored_field_values: HashMap<(FieldRef, u16, Vec<u8>), Vec<u8>>,
}

#[derive(Debug)]
pub enum DocumentInsertError {
    /// Segment couldn't hold any more docs
    SegmentFull,
}

impl SegmentBuilder {
    pub fn new() -> SegmentBuilder {
        SegmentBuilder {
            current_doc: 0,
            term_dictionary: HashMap::new(),
            current_term_ref: 0,
            term_directories: HashMap::new(),
            statistics: HashMap::new(),
            stored_field_values: HashMap::new(),
        }
    }

    // TODO: Need to translate field names to field refs and terms to term refs
    pub fn add_document(&mut self, doc: Document) -> Result<(), DocumentInsertError> {
        // Get document ord
        let doc_id = self.current_doc;
        self.current_doc += 1;
        try!(self.current_doc.checked_add(1).ok_or(DocumentInsertError::SegmentFull));

        // Insert indexed fields
        let mut term_frequencies = HashMap::new();
        for (field, tokens) in doc.indexed_fields.iter() {
            let mut field_token_count = 0;

            for token in tokens.iter() {
                field_token_count += 1;

                // Get term ref
                let term_bytes = token.term.to_bytes();
                let mut current_term_ref = self.current_term_ref;
                let term_ref = self.term_dictionary.entry(term_bytes).or_insert_with(|| {
                    let term_ref = TermRef::new(current_term_ref);
                    current_term_ref += 1;
                    term_ref
                });
                self.current_term_ref = current_term_ref;

                // Term frequency
                let mut term_frequency = term_frequencies.entry(*term_ref).or_insert(0);
                *term_frequency += 1;

                // Write directory list
                self.term_directories.entry((*field, *term_ref)).or_insert_with(Vec::new).push(doc_id);
            }

            // Term frequencies
            for (term_ref, frequency) in term_frequencies.drain() {
                // Write term frequency
                // 1 is by far the most common frequency. At search time, we interpret a missing
                // key as meaning there is a term frequency of 1
                if frequency != 1 {
                    let mut value_type = vec![b't', b'f'];
                    value_type.extend(term_ref.ord().to_string().as_bytes());

                    let mut frequency_bytes: Vec<u8> = Vec::new();
                    frequency_bytes.write_i64::<BigEndian>(frequency).unwrap();

                    self.stored_field_values.insert((*field, doc_id, value_type), frequency_bytes);
                }

                // Increment term document frequency
                let stat_name = KeyBuilder::segment_stat_term_doc_frequency_stat_name(field.ord(), term_ref.ord());
                let mut stat = self.statistics.entry(stat_name).or_insert(0);
                *stat += 1;
            }

            // Field length
            // Used by the BM25 similarity model
            let length = ((field_token_count as f64).sqrt() - 1.0) * 3.0;
            let length = if length > 255.0 { 255.0 } else { length } as u8;
            if length != 0 {
                self.stored_field_values.insert((*field, doc_id, b"len".to_vec()), vec![length]);
            }

            // Increment total field docs
            {
                let stat_name = KeyBuilder::segment_stat_total_field_docs_stat_name(field.ord());
                let mut stat = self.statistics.entry(stat_name).or_insert(0);
                *stat += 1;
            }

            // Increment total field tokens
            {
                let stat_name = KeyBuilder::segment_stat_total_field_tokens_stat_name(field.ord());
                let mut stat = self.statistics.entry(stat_name).or_insert(0);
                *stat += field_token_count;
            }
        }

        // Insert stored fields
        for (field, value) in doc.stored_fields.iter() {
            self.stored_field_values.insert((*field, doc_id, b"val".to_vec()), value.to_bytes());
        }

        // Increment total docs
        {
            let mut stat = self.statistics.entry(b"total_docs".to_vec()).or_insert(0);
            *stat += 1;
        }

        Ok(())
    }
}
<commit_msg>SegmentBuilder.add_document now returns id<commit_after>use std::collections::HashMap;

use kite::{Document, TermRef};
use kite::schema::FieldRef;
use byteorder::{BigEndian, WriteBytesExt};

use key_builder::KeyBuilder;

#[derive(Debug)]
pub struct SegmentBuilder {
    current_doc: u16,
    pub term_dictionary: HashMap<Vec<u8>, TermRef>,
    current_term_ref: u32,
    pub term_directories: HashMap<(FieldRef, TermRef), Vec<u16>>,
    pub statistics: HashMap<Vec<u8>, i64>,
    pub stored_field_values: HashMap<(FieldRef, u16, Vec<u8>), Vec<u8>>,
}

#[derive(Debug)]
pub enum DocumentInsertError {
    /// Segment couldn't hold any more docs
    SegmentFull,
}

impl SegmentBuilder {
    pub fn new() -> SegmentBuilder {
        SegmentBuilder {
            current_doc: 0,
            term_dictionary: HashMap::new(),
            current_term_ref: 0,
            term_directories: HashMap::new(),
            statistics: HashMap::new(),
            stored_field_values: HashMap::new(),
        }
    }

    // TODO: Need to translate field names to field refs and terms to term refs
    pub fn add_document(&mut self, doc: Document) -> Result<u16, DocumentInsertError> {
        // Get document ord
        let doc_id = self.current_doc;
        self.current_doc += 1;
        try!(self.current_doc.checked_add(1).ok_or(DocumentInsertError::SegmentFull));

        // Insert indexed fields
        let mut term_frequencies = HashMap::new();
        for (field, tokens) in doc.indexed_fields.iter() {
            let mut field_token_count = 0;

            for token in tokens.iter() {
                field_token_count += 1;

                // Get term ref
                let term_bytes = token.term.to_bytes();
                let mut current_term_ref = self.current_term_ref;
                let term_ref = self.term_dictionary.entry(term_bytes).or_insert_with(|| {
                    let term_ref = TermRef::new(current_term_ref);
                    current_term_ref += 1;
                    term_ref
                });
                self.current_term_ref = current_term_ref;

                // Term frequency
                let mut term_frequency = term_frequencies.entry(*term_ref).or_insert(0);
                *term_frequency += 1;

                // Write directory list
                self.term_directories.entry((*field, *term_ref)).or_insert_with(Vec::new).push(doc_id);
            }

            // Term frequencies
            for (term_ref, frequency) in term_frequencies.drain() {
                // Write term frequency
                // 1 is by far the most common frequency. At search time, we interpret a missing
                // key as meaning there is a term frequency of 1
                if frequency != 1 {
                    let mut value_type = vec![b't', b'f'];
                    value_type.extend(term_ref.ord().to_string().as_bytes());

                    let mut frequency_bytes: Vec<u8> = Vec::new();
                    frequency_bytes.write_i64::<BigEndian>(frequency).unwrap();

                    self.stored_field_values.insert((*field, doc_id, value_type), frequency_bytes);
                }

                // Increment term document frequency
                let stat_name = KeyBuilder::segment_stat_term_doc_frequency_stat_name(field.ord(), term_ref.ord());
                let mut stat = self.statistics.entry(stat_name).or_insert(0);
                *stat += 1;
            }

            // Field length
            // Used by the BM25 similarity model
            let length = ((field_token_count as f64).sqrt() - 1.0) * 3.0;
            let length = if length > 255.0 { 255.0 } else { length } as u8;
            if length != 0 {
                self.stored_field_values.insert((*field, doc_id, b"len".to_vec()), vec![length]);
            }

            // Increment total field docs
            {
                let stat_name = KeyBuilder::segment_stat_total_field_docs_stat_name(field.ord());
                let mut stat = self.statistics.entry(stat_name).or_insert(0);
                *stat += 1;
            }

            // Increment total field tokens
            {
                let stat_name = KeyBuilder::segment_stat_total_field_tokens_stat_name(field.ord());
                let mut stat = self.statistics.entry(stat_name).or_insert(0);
                *stat += field_token_count;
            }
        }

        // Insert stored fields
        for (field, value) in doc.stored_fields.iter() {
            self.stored_field_values.insert((*field, doc_id, b"val".to_vec()), value.to_bytes());
        }

        // Increment total docs
        {
            let mut stat = self.statistics.entry(b"total_docs".to_vec()).or_insert(0);
            *stat += 1;
        }

        Ok(doc_id)
    }
}
<|endoftext|>


<commit_before>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.85")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless,
        const_static_lifetime,
        doc_markdown,
        needless_pass_by_value,
        redundant_field_names,
        type_complexity,
        zero_prefixed_literal
    )
)]
// Ignored clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_precision_loss,
        cast_sign_loss,
        // things are often more readable this way
        module_name_repetitions,
        single_match_else,
        use_self,
        // not practical
        similar_names,
        // alternative is not stable
        empty_enum,
    )
)]
// Blacklisted Rust lints.
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::String;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<commit_msg>Combine the two clippy lists<commit_after>//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//!   definition.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//!   Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.85")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        // not available in our oldest supported compiler
        const_static_lifetime,
        empty_enum,
        redundant_field_names,
        // integer and float ser/de requires these sorts of casts
        cast_possible_truncation,
        cast_possible_wrap,
        cast_precision_loss,
        cast_sign_loss,
        // things are often more readable this way
        cast_lossless,
        module_name_repetitions,
        single_match_else,
        type_complexity,
        use_self,
        zero_prefixed_literal,
        // not practical
        needless_pass_by_value,
        similar_names,
        // preference
        doc_markdown,
    )
)]
// Blacklisted Rust lints.
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::ops::Range;
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::String;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::sync::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(any(core_duration, feature = "std"))]
    pub use self::core::time::Duration;

    #[cfg(range_inclusive)]
    pub use self::core::ops::RangeInclusive;
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<|endoftext|>