<commit_before>use std::io;

use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use cast;

use quic::errors::{Error, Result};
use quic::utils::map_unexpected_eof;


pub const FRAME_FLAG_STREAM: u8 = 0b10000000;

#[derive(Clone, Debug, Default, PartialEq)]
pub struct StreamFrame {
    pub stream_id: u32,
    pub offset: u64,
    pub stream_data: Vec<u8>,
    pub fin: bool,
}

impl StreamFrame {
    pub fn encode(&self, write: &mut io::Write, last_frame: bool) -> Result<()> {
        // construct the type octet
        let mut frame_type = FRAME_FLAG_STREAM;

        if self.fin {
            frame_type |= 0b01000000
        }

        if !last_frame {
            frame_type |= 0b00100000;
        }

        // TODO: calculate this more intelligently
        let offset_size = 8;
        frame_type |= 0b00011100;

        // TODO: calculate this more intelligently
        let stream_id_size = 4;
        frame_type |= 0b00000011;

        write.write_u8(frame_type)?;

        // other fields
        assert!(self.stream_data.len() != 0 || self.fin);

        if !last_frame {
            write.write_u16::<BigEndian>(
                cast::u16(self.stream_data.len())
                .expect("Stream data too big, size has to fit in 16 bits")
            )?;
        }
        write.write_uint::<BigEndian>(self.stream_id as u64, stream_id_size)?;
        write.write_uint::<BigEndian>(self.offset, offset_size)?;
        write.write_all(&self.stream_data[..])?;

        Ok(())
    }

    pub fn decode(read: &mut io::Read) -> Result<StreamFrame> {
        // extract type octet data
        let frame_type = read.read_u8().map_err(map_unexpected_eof)?;
        assert!((frame_type & FRAME_FLAG_STREAM) != 0);

        let fin = (frame_type & 0b01000000) != 0;

        let last_frame = (frame_type & 0b00100000) == 0;

        let offset_size = match (frame_type & 0b00011100) >> 2 {
            0b000 => 0,
            bit_value => bit_value + 1,
        } as usize;

        let stream_id_size = ((frame_type & 0b00000011) + 1) as usize;

        // other fields
        let data_length = if !last_frame {
            Some(read.read_u16::<BigEndian>().map_err(map_unexpected_eof)? as usize)
        } else {
            None
        };

        let stream_id = 
            read.read_uint::<BigEndian>(stream_id_size)
            .map_err(map_unexpected_eof)?
            as u32;
        
        let offset = if offset_size != 0 {
            read.read_uint::<BigEndian>(offset_size)
            .map_err(map_unexpected_eof)?
        } else {
            0
        };

        let stream_data = match data_length {
            Some(data_length) => {
                let mut buffer = vec![0; data_length];
                read.read_exact(&mut buffer).map_err(map_unexpected_eof)?;
                buffer
            },
            None => {
                let mut buffer = Vec::new();
                read.read_to_end(&mut buffer).map_err(map_unexpected_eof)?;
                buffer
            },
        };

        if stream_data.len() == 0 && !fin {
            return Err(Error::Decoding(String::from("Must have either non-zero data length or the FIN bit set")));
        }

        Ok(StreamFrame {
            stream_id: stream_id,
            offset: offset,
            stream_data: stream_data,
            fin: fin,
        })
    }
}<commit_msg>Formatting<commit_after>use std::io;

use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use cast;

use quic::errors::{Error, Result};
use quic::utils::map_unexpected_eof;


pub const FRAME_FLAG_STREAM: u8 = 0b10000000;

#[derive(Clone, Debug, Default, PartialEq)]
pub struct StreamFrame {
    pub stream_id: u32,
    pub offset: u64,
    pub stream_data: Vec<u8>,
    pub fin: bool,
}

impl StreamFrame {
    pub fn encode(&self, write: &mut io::Write, last_frame: bool) -> Result<()> {
        // construct the type octet
        let mut frame_type = FRAME_FLAG_STREAM;

        if self.fin {
            frame_type |= 0b01000000
        }

        if !last_frame {
            frame_type |= 0b00100000;
        }

        // TODO: calculate this more intelligently
        let offset_size = 8;
        frame_type |= 0b00011100;

        // TODO: calculate this more intelligently
        let stream_id_size = 4;
        frame_type |= 0b00000011;

        write.write_u8(frame_type)?;

        // other fields
        assert!(self.stream_data.len() != 0 || self.fin);

        if !last_frame {
            write.write_u16::<BigEndian>(
                cast::u16(self.stream_data.len())
                .expect("Stream data too big, size has to fit in 16 bits")
            )?;
        }
        write.write_uint::<BigEndian>(self.stream_id as u64, stream_id_size)?;
        write.write_uint::<BigEndian>(self.offset, offset_size)?;
        write.write_all(&self.stream_data[..])?;

        Ok(())
    }

    pub fn decode(read: &mut io::Read) -> Result<StreamFrame> {
        // extract type octet data
        let frame_type = read.read_u8().map_err(map_unexpected_eof)?;
        assert!((frame_type & FRAME_FLAG_STREAM) != 0);

        let fin = (frame_type & 0b01000000) != 0;

        let last_frame = (frame_type & 0b00100000) == 0;

        let offset_size = match (frame_type & 0b00011100) >> 2 {
            0b000 => 0,
            bit_value => bit_value + 1,
        } as usize;

        let stream_id_size = ((frame_type & 0b00000011) + 1) as usize;

        // other fields
        let data_length = if !last_frame {
            Some(read.read_u16::<BigEndian>().map_err(map_unexpected_eof)? as usize)
        } else {
            None
        };

        let stream_id = 
            read.read_uint::<BigEndian>(stream_id_size)
            .map_err(map_unexpected_eof)?
            as u32;
        
        let offset = if offset_size != 0 {
            read.read_uint::<BigEndian>(offset_size)
            .map_err(map_unexpected_eof)?
        } else {
            0
        };

        let stream_data = match data_length {
            Some(data_length) => {
                let mut buffer = vec![0; data_length];
                read.read_exact(&mut buffer).map_err(map_unexpected_eof)?;
                buffer
            },
            None => {
                let mut buffer = Vec::new();
                read.read_to_end(&mut buffer).map_err(map_unexpected_eof)?;
                buffer
            },
        };

        if stream_data.len() == 0 && !fin {
            return Err(
                Error::Decoding(
                    String::from("Must have either non-zero data length or the FIN bit set")
                )
            );
        }

        Ok(StreamFrame {
            stream_id: stream_id,
            offset: offset,
            stream_data: stream_data,
            fin: fin,
        })
    }
}
{'fraction_non_alphanumeric': 0.11428571428571428, 'fraction_numerical': 0.03487179487179487, 'mean_word_length': 1.8311903774367482, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4521800', 'n_tokens_mistral': 2301, 'n_tokens_neox': 2101, 'n_words': 464}