buffer Algorithm

The buffer algorithm is a technique used in computer science and programming to manage and optimize the flow of data between different processing units or storage devices. It is a fundamental concept used in various applications such as communication systems, operating systems, and data processing workflows. By creating a temporary storage space called a buffer, the algorithm ensures that data can be effectively held and managed before being transmitted or processed. This approach helps to balance the differences in data processing speeds between different components of a system and ensures smooth and efficient data transfer. Buffers can be implemented in various forms, such as circular buffers, FIFO (First-In-First-Out) queues, and priority queues, depending on the requirements of a particular application. The buffer algorithm manages the data input and output operations by adding new data to the buffer when there is available space and removing or processing data from the buffer when needed. This process helps to prevent data loss, reduce latency, and improve overall system performance. By acting as an intermediary between different processing components, the buffer algorithm plays a critical role in managing the flow of data and ensuring that systems function efficiently and seamlessly.
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cmp;

use cryptoutil;

#[derive(Clone,Copy)]
pub enum BufferResult {
    BufferUnderflow,
    BufferOverflow
}

pub trait ReadBuffer {
    fn is_empty(&self) -> bool;
    fn is_full(&self) -> bool;
    fn remaining(&self) -> usize;
    fn capacity(&self) -> usize;
    fn position(&self) -> usize { self.capacity() - self.remaining() }

    fn rewind(&mut self, distance: usize);
    fn truncate(&mut self, amount: usize);
    fn reset(&mut self);

    fn peek_next(&self, count: usize) -> &[u8];
    fn peek_remaining(&self) -> &[u8] {
        self.peek_next(self.remaining())
    }

    fn take_next(&mut self, count: usize) -> &[u8];
    fn take_remaining(&mut self) -> &[u8] {
        let rem = self.remaining();
        self.take_next(rem)
    }

    fn push_to<W: WriteBuffer>(&mut self, output: &mut W) {
        let count = cmp::min(output.remaining(), self.remaining());
        cryptoutil::copy_memory(self.take_next(count), output.take_next(count));
    }
}

pub trait WriteBuffer {
    fn is_empty(&self) -> bool;
    fn is_full(&self) -> bool;
    fn remaining(&self) -> usize;
    fn capacity(&self) -> usize;
    fn position(&self) -> usize { self.capacity() - self.remaining() }

    fn rewind(&mut self, distance: usize);
    fn reset(&mut self);

    // FIXME - Shouldn't need mut self
    fn peek_read_buffer(&mut self) -> RefReadBuffer;

    fn take_next(&mut self, count: usize) -> &mut [u8];
    fn take_remaining(&mut self) -> &mut [u8] {
        let rem = self.remaining();
        self.take_next(rem)
    }
    fn take_read_buffer(&mut self) -> RefReadBuffer;
}

pub struct RefReadBuffer<'a> {
    buff: &'a [u8],
    pos: usize
}

impl <'a> RefReadBuffer<'a> {
    pub fn new(buff: &[u8]) -> RefReadBuffer {
        RefReadBuffer {
            buff: buff,
            pos: 0
        }
    }
}

impl <'a> ReadBuffer for RefReadBuffer<'a> {
    fn is_empty(&self) -> bool { self.pos == self.buff.len() }
    fn is_full(&self) -> bool { self.pos == 0 }
    fn remaining(&self) -> usize { self.buff.len() - self.pos }
    fn capacity(&self) -> usize { self.buff.len() }

    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
    fn truncate(&mut self, amount: usize) {
        self.buff = &self.buff[..self.buff.len() - amount];
    }
    fn reset(&mut self) { self.pos = 0; }

    fn peek_next(&self, count: usize) -> &[u8] { &self.buff[self.pos..count] }

    fn take_next(&mut self, count: usize) -> &[u8] {
        let r = &self.buff[self.pos..self.pos + count];
        self.pos += count;
        r
    }
}

pub struct OwnedReadBuffer {
    buff: Vec<u8>,
    len: usize,
    pos: usize
}

impl OwnedReadBuffer {
    pub fn new(buff: Vec<u8>) -> OwnedReadBuffer {
        let len = buff.len();
        OwnedReadBuffer {
            buff: buff,
            len: len,
            pos: 0
        }
    }
    pub fn new_with_len<'a>(buff: Vec<u8>, len: usize) -> OwnedReadBuffer {
        OwnedReadBuffer {
            buff: buff,
            len: len,
            pos: 0
        }
    }
    pub fn into_write_buffer(self) -> OwnedWriteBuffer {
        OwnedWriteBuffer::new(self.buff)
    }
    pub fn borrow_write_buffer(&mut self) -> BorrowedWriteBuffer {
        self.pos = 0;
        self.len = 0;
        BorrowedWriteBuffer::new(self)
    }
}

impl ReadBuffer for OwnedReadBuffer {
    fn is_empty(&self) -> bool { self.pos == self.len }
    fn is_full(&self) -> bool { self.pos == 0 }
    fn remaining(&self) -> usize { self.len - self.pos }
    fn capacity(&self) -> usize { self.len }

    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
    fn truncate(&mut self, amount: usize) { self.len -= amount; }
    fn reset(&mut self) { self.pos = 0; }

    fn peek_next(&self, count: usize) -> &[u8] { &self.buff[self.pos..count] }

    fn take_next(&mut self, count: usize) -> &[u8] {
        let r = &self.buff[self.pos..self.pos + count];
        self.pos += count;
        r
    }
}

pub struct RefWriteBuffer<'a> {
    buff: &'a mut [u8],
    len: usize,
    pos: usize
}

impl <'a> RefWriteBuffer<'a> {
    pub fn new(buff: &mut [u8]) -> RefWriteBuffer {
        let len = buff.len();
        RefWriteBuffer {
            buff: buff,
            len: len,
            pos: 0
        }
    }
}

impl <'a> WriteBuffer for RefWriteBuffer<'a> {
    fn is_empty(&self) -> bool { self.pos == 0 }
    fn is_full(&self) -> bool { self.pos == self.len }
    fn remaining(&self) -> usize { self.len - self.pos }
    fn capacity(&self) -> usize { self.len }

    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
    fn reset(&mut self) { self.pos = 0; }

    fn peek_read_buffer(&mut self) -> RefReadBuffer {
        RefReadBuffer::new(&mut self.buff[..self.pos])
    }

    fn take_next(&mut self, count: usize) -> &mut [u8] {
        let r = &mut self.buff[self.pos..self.pos + count];
        self.pos += count;
        r
    }
    fn take_read_buffer(&mut self) -> RefReadBuffer {
        let r = RefReadBuffer::new(&mut self.buff[..self.pos]);
        self.pos = 0;
        r
    }
}

pub struct BorrowedWriteBuffer<'a> {
    parent: &'a mut OwnedReadBuffer,
    pos: usize,
    len: usize
}

impl <'a> BorrowedWriteBuffer<'a> {
    fn new(parent: &mut OwnedReadBuffer) -> BorrowedWriteBuffer {
        let buff_len = parent.buff.len();
        BorrowedWriteBuffer {
            parent: parent,
            pos: 0,
            len: buff_len
        }
    }
}

impl <'a> WriteBuffer for BorrowedWriteBuffer<'a> {
    fn is_empty(&self) -> bool { self.pos == 0 }
    fn is_full(&self) -> bool { self.pos == self.len }
    fn remaining(&self) -> usize { self.len - self.pos }
    fn capacity(&self) -> usize { self.len }

    fn rewind(&mut self, distance: usize) {
        self.pos -= distance;
        self.parent.len -= distance;
    }
    fn reset(&mut self) {
        self.pos = 0;
        self.parent.len = 0;
    }

    fn peek_read_buffer(&mut self) -> RefReadBuffer {
        RefReadBuffer::new(&self.parent.buff[..self.pos])
    }

    fn take_next<>(&mut self, count: usize) -> &mut [u8] {
        let r = &mut self.parent.buff[self.pos..self.pos + count];
        self.pos += count;
        self.parent.len += count;
        r
    }
    fn take_read_buffer(&mut self) -> RefReadBuffer {
        let r = RefReadBuffer::new(&self.parent.buff[..self.pos]);
        self.pos = 0;
        self.parent.len = 0;
        r
    }
}

pub struct OwnedWriteBuffer {
    buff: Vec<u8>,
    len: usize,
    pos: usize
}

impl OwnedWriteBuffer {
    pub fn new(buff: Vec<u8>) -> OwnedWriteBuffer {
        let len = buff.len();
        OwnedWriteBuffer {
            buff: buff,
            len: len,
            pos: 0
        }
    }
    pub fn into_read_buffer(self) -> OwnedReadBuffer {
        let pos = self.pos;
        OwnedReadBuffer::new_with_len(self.buff, pos)
    }
}

impl WriteBuffer for OwnedWriteBuffer {
    fn is_empty(&self) -> bool { self.pos == 0 }
    fn is_full(&self) -> bool { self.pos == self.len }
    fn remaining(&self) -> usize { self.len - self.pos }
    fn capacity(&self) -> usize { self.len }

    fn rewind(&mut self, distance: usize) { self.pos -= distance; }
    fn reset(&mut self) { self.pos = 0; }

    fn peek_read_buffer<'a>(&'a mut self) -> RefReadBuffer<'a> {
        RefReadBuffer::new(&self.buff[..self.pos])
    }

    fn take_next<'a>(&'a mut self, count: usize) -> &'a mut [u8] {
        let r = &mut self.buff[self.pos..self.pos + count];
        self.pos += count;
        r
    }
    fn take_read_buffer<'a>(&'a mut self) -> RefReadBuffer<'a> {
        let r = RefReadBuffer::new(&self.buff[..self.pos]);
        self.pos = 0;
        r
    }
}

LANGUAGE:

DARK MODE: