/* * Copyright (c) 2018, Sam Kumar * 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 #include #include #include 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