1 /* 2 * Copyright (c) 2018, Sam Kumar <samkumar@cs.berkeley.edu> 3 * Copyright (c) 2018, University of California, Berkeley 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the 14 * names of its contributors may be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef CBUF_H_ 31 #define CBUF_H_ 32 33 /* CIRCULAR BUFFER */ 34 35 #include <stdbool.h> 36 #include <stdint.h> 37 #include <stdlib.h> 38 #include <sys/types.h> 39 40 struct otLinkedBuffer; 41 42 /* Represents a circular buffer. */ 43 struct cbufhead { 44 size_t r_index; 45 size_t w_index; 46 size_t size; 47 uint8_t* buf; 48 }; 49 50 /* Initializes a circular buffer (chdr is the header storing metadata). */ 51 void cbuf_init(struct cbufhead* chdr, uint8_t* buf, size_t len); 52 53 /* Function type for copying data into or out of a circular buffer. */ 54 typedef void(*cbuf_copier_t)(void*, size_t, const void*, size_t, size_t); 55 56 /* Instantiations of cbuf_copier_t, for copying data between circular buffers and regular buffers. */ 57 void cbuf_copy_into_buffer(void* buffer, size_t buffer_offset, const void* arr, size_t arr_offset, size_t num_bytes); 58 void cbuf_copy_from_buffer(void* arr, size_t arr_offset, const void* buffer, size_t buffer_offset, size_t num_bytes); 59 60 /* Instantiations of cbuf_copier_t, for copying data between circular buffers and otMessages. */ 61 void cbuf_copy_into_message(void* buffer, size_t buffer_offset, const void* arr, size_t arr_offset, size_t num_bytes); 62 void cbuf_copy_from_message(void* arr, size_t arr_offset, const void* buffer, size_t buffer_offset, size_t num_bytes); 63 64 /* Writes data to the back of the circular buffer using the specified copier. */ 65 size_t cbuf_write(struct cbufhead* chdr, const void* data, size_t data_offset, size_t data_len, cbuf_copier_t copy_from); 66 67 /* Reads data from the front ofthe circular buffer using the specified copier. */ 68 size_t cbuf_read(struct cbufhead* chdr, void* data, size_t data_offset, size_t numbytes, int pop, cbuf_copier_t copy_into); 69 70 /* Reads data at the specified offset, in bytes, from the front of the circular buffer using the specified copier. */ 71 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); 72 73 /* Drops bytes from the front of the circular buffer. */ 74 size_t cbuf_pop(struct cbufhead* chdr, size_t numbytes); 75 76 /* Returns the number of bytes available for reading from the circular buffer. */ 77 size_t cbuf_used_space(struct cbufhead* chdr); 78 79 /* Returns the number of bytes that can be written to the circular buffer before it is full. */ 80 size_t cbuf_free_space(struct cbufhead* chdr); 81 82 /* Returns the total capacity of the circular buffer, in bytes. */ 83 size_t cbuf_size(struct cbufhead* chdr); 84 85 /* Returns true if the circular buffer is empty, and false if it is not empty. */ 86 bool cbuf_empty(struct cbufhead* chdr); 87 88 /* Populates the provided otLinkedBuffers to reference the data currently in the circular buffer. */ 89 void cbuf_reference(const struct cbufhead* chdr, struct otLinkedBuffer* first, struct otLinkedBuffer* second); 90 91 /* Writes DATA at the end of the circular buffer without making it available for 92 reading. This data is said to be "out-of-sequence". OFFSET is position at 93 which to write these bytes, relative to the positoin where cbuf_write would 94 write them. Each bit in the BITMAP corresponds to a byte in the circular 95 buffer; the bits corresponding to the bytes containing the newly written 96 data are set. The index of the first byte written is stored into FIRSTINDEX, 97 if it is not NULL. */ 98 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); 99 100 /* Makes NUMBYTES out-of-seqence bytes available for reading in the circular 101 buffer. No data is copied; the out-of-sequence bytes made available are the 102 bytes currently at the position where cbuf_write would write them. The bytes 103 are taken from the unused space of the buffer, and can be set using 104 cbuf_reass_write. */ 105 size_t cbuf_reass_merge(struct cbufhead* chdr, size_t numbytes, uint8_t* bitmap); 106 107 /* Counts the number of contiguous out-of-sequence bytes at the specified 108 OFFSET, until the count reaches the specified LIMIT. */ 109 size_t cbuf_reass_count_set(struct cbufhead* chdr, size_t offset, uint8_t* bitmap, size_t limit); 110 111 /* Returns a true value iff INDEX is the index of a byte within OFFSET bytes 112 past the end of the buffer. */ 113 int cbuf_reass_within_offset(struct cbufhead* chdr, size_t offset, size_t index); 114 115 #endif 116