116 lines
5.8 KiB
C
116 lines
5.8 KiB
C
/*
|
|
* 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
|