blob: 7ba6b6d0f444f25b5a74a5cc126796fca8d4492d [file] [log] [blame]
/*
* Copyright (c) 2018, Sam Kumar <samkumar@cs.berkeley.edu>
* Copyright (c) 2018, University of California, Berkeley
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CBUF_H_
#define CBUF_H_
/* CIRCULAR BUFFER */
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
struct otLinkedBuffer;
/* Represents a circular buffer. */
struct cbufhead {
size_t r_index;
size_t w_index;
size_t size;
uint8_t* buf;
};
/* Initializes a circular buffer (chdr is the header storing metadata). */
void cbuf_init(struct cbufhead* chdr, uint8_t* buf, size_t len);
/* Function type for copying data into or out of a circular buffer. */
typedef void(*cbuf_copier_t)(void*, size_t, const void*, size_t, size_t);
/* Instantiations of cbuf_copier_t, for copying data between circular buffers and regular buffers. */
void cbuf_copy_into_buffer(void* buffer, size_t buffer_offset, const void* arr, size_t arr_offset, size_t num_bytes);
void cbuf_copy_from_buffer(void* arr, size_t arr_offset, const void* buffer, size_t buffer_offset, size_t num_bytes);
/* Instantiations of cbuf_copier_t, for copying data between circular buffers and otMessages. */
void cbuf_copy_into_message(void* buffer, size_t buffer_offset, const void* arr, size_t arr_offset, size_t num_bytes);
void cbuf_copy_from_message(void* arr, size_t arr_offset, const void* buffer, size_t buffer_offset, size_t num_bytes);
/* Writes data to the back of the circular buffer using the specified copier. */
size_t cbuf_write(struct cbufhead* chdr, const void* data, size_t data_offset, size_t data_len, cbuf_copier_t copy_from);
/* Reads data from the front ofthe circular buffer using the specified copier. */
size_t cbuf_read(struct cbufhead* chdr, void* data, size_t data_offset, size_t numbytes, int pop, cbuf_copier_t copy_into);
/* Reads data at the specified offset, in bytes, from the front of the circular buffer using the specified copier. */
size_t cbuf_read_offset(struct cbufhead* chdr, void* data, size_t data_offset, size_t numbytes, size_t offset, cbuf_copier_t copy_into);
/* Drops bytes from the front of the circular buffer. */
size_t cbuf_pop(struct cbufhead* chdr, size_t numbytes);
/* Returns the number of bytes available for reading from the circular buffer. */
size_t cbuf_used_space(struct cbufhead* chdr);
/* Returns the number of bytes that can be written to the circular buffer before it is full. */
size_t cbuf_free_space(struct cbufhead* chdr);
/* Returns the total capacity of the circular buffer, in bytes. */
size_t cbuf_size(struct cbufhead* chdr);
/* Returns true if the circular buffer is empty, and false if it is not empty. */
bool cbuf_empty(struct cbufhead* chdr);
/* Populates the provided otLinkedBuffers to reference the data currently in the circular buffer. */
void cbuf_reference(const struct cbufhead* chdr, struct otLinkedBuffer* first, struct otLinkedBuffer* second);
/* Writes DATA at the end of the circular buffer without making it available for
reading. This data is said to be "out-of-sequence". OFFSET is position at
which to write these bytes, relative to the positoin where cbuf_write would
write them. Each bit in the BITMAP corresponds to a byte in the circular
buffer; the bits corresponding to the bytes containing the newly written
data are set. The index of the first byte written is stored into FIRSTINDEX,
if it is not NULL. */
size_t cbuf_reass_write(struct cbufhead* chdr, size_t offset, const void* data, size_t data_offset, size_t numbytes, uint8_t* bitmap, size_t* firstindex, cbuf_copier_t copy_from);
/* Makes NUMBYTES out-of-seqence bytes available for reading in the circular
buffer. No data is copied; the out-of-sequence bytes made available are the
bytes currently at the position where cbuf_write would write them. The bytes
are taken from the unused space of the buffer, and can be set using
cbuf_reass_write. */
size_t cbuf_reass_merge(struct cbufhead* chdr, size_t numbytes, uint8_t* bitmap);
/* Counts the number of contiguous out-of-sequence bytes at the specified
OFFSET, until the count reaches the specified LIMIT. */
size_t cbuf_reass_count_set(struct cbufhead* chdr, size_t offset, uint8_t* bitmap, size_t limit);
/* Returns a true value iff INDEX is the index of a byte within OFFSET bytes
past the end of the buffer. */
int cbuf_reass_within_offset(struct cbufhead* chdr, size_t offset, size_t index);
#endif