163 lines
6.0 KiB
C
163 lines
6.0 KiB
C
/*
|
|
* @Author : stark1898y 1658608470@qq.com
|
|
* @Date : 2024-12-12 13:35:45
|
|
* @LastEditors : stark1898y 1658608470@qq.com
|
|
* @LastEditTime : 2024-12-12 13:35:45
|
|
* @FilePath : \BLE_TYQ_CH584M\common\lwrb-3.2.0\lwrb_ex.c
|
|
* @Description :
|
|
*
|
|
* Copyright (c) 2024 by yzy, All Rights Reserved.
|
|
*/
|
|
/**
|
|
* \file lwrb_ex.c
|
|
* \brief Lightweight ring buffer - extended functions
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2024 Tilen MAJERLE
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without restriction,
|
|
* including without limitation the rights to use, copy, modify, merge,
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
|
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* This file is part of LwRB - Lightweight ring buffer library.
|
|
*
|
|
* Author: Tilen MAJERLE <tilen@majerle.eu>
|
|
* Version: v3.2.0
|
|
*/
|
|
#include "lwrb.h"
|
|
|
|
#if defined(LWRB_DEV)
|
|
|
|
/* Do not build if development mode isn't enabled */
|
|
|
|
#define BUF_IS_VALID(b) ((b) != NULL && (b)->buff != NULL && (b)->size > 0)
|
|
#define BUF_MIN(x, y) ((x) < (y) ? (x) : (y))
|
|
|
|
/**
|
|
* \brief Writes data to buffer with overwrite function, if no enough space to hold
|
|
* complete input data object.
|
|
* \note Similar to \ref lwrb_write but overwrites
|
|
* \param[in] buff: Buffer handle
|
|
* \param[in] data: Data to write to ring buffer
|
|
* \param[in] btw: Bytes To Write, length
|
|
* \return Number of bytes written to buffer, will always return btw
|
|
* \note Functionality is primary two parts, always writes some linear region, then
|
|
* writes the wrap region if there is more data to write. The r indicator is advanced if w overtakes
|
|
* it. This operation is a read op as well as a write op. For thread-safety mutexes may be desired,
|
|
* see documentation.
|
|
*/
|
|
lwrb_sz_t
|
|
lwrb_overwrite(lwrb_t* buff, const void* data, lwrb_sz_t btw) {
|
|
lwrb_sz_t orig_btw = btw, max_cap;
|
|
const uint8_t* d = data;
|
|
|
|
if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) {
|
|
return 0;
|
|
}
|
|
|
|
/* Process complete input array */
|
|
max_cap = buff->size - 1; /* Maximum capacity buffer can hold */
|
|
if (btw > max_cap) {
|
|
/*
|
|
* When data to write is larger than max buffer capacity,
|
|
* we can reset the buffer and simply write last part of
|
|
* the input buffer.
|
|
*
|
|
* This is done here, by calculating remaining
|
|
* length and then advancing to the end of input buffer
|
|
*/
|
|
d += btw - max_cap; /* Advance data */
|
|
btw = max_cap; /* Limit data to write */
|
|
lwrb_reset(buff); /* Reset buffer */
|
|
} else {
|
|
/*
|
|
* Bytes to write is less than capacity
|
|
* We have to perform max one skip operation,
|
|
* but only if free memory is less than
|
|
* btw, otherwise we skip the operation
|
|
* and only write the data.
|
|
*/
|
|
lwrb_sz_t f = lwrb_get_free(buff);
|
|
if (f < btw) {
|
|
lwrb_skip(buff, btw - f);
|
|
}
|
|
}
|
|
lwrb_write(buff, d, btw);
|
|
return orig_btw;
|
|
}
|
|
|
|
/**
|
|
* \brief Move one ring buffer to another, up to the amount of data in the source, or amount
|
|
* of data free in the destination.
|
|
* \param[in] dest: Buffer handle that the copied data will be written to
|
|
* \param[in] src: Buffer handle that the copied data will come from.
|
|
* Source buffer will be effectively read upon operation.
|
|
* \return Number of bytes written to destination buffer
|
|
* \note This operation is a read op to the source, on success it will update the r index.
|
|
* As well as a write op to the destination, and may update the w index.
|
|
* For thread-safety mutexes may be desired, see documentation.
|
|
*/
|
|
lwrb_sz_t
|
|
lwrb_move(lwrb_t* dest, lwrb_t* src) {
|
|
lwrb_sz_t len_to_copy, len_to_copy_orig, src_full, dest_free;
|
|
|
|
if (!BUF_IS_VALID(dest) || !BUF_IS_VALID(src)) {
|
|
return 0;
|
|
}
|
|
src_full = lwrb_get_full(src);
|
|
dest_free = lwrb_get_free(dest);
|
|
len_to_copy = BUF_MIN(src_full, dest_free);
|
|
len_to_copy_orig = len_to_copy;
|
|
|
|
/* Calculations for available length to copy is done above.
|
|
We safely assume operations inside loop will properly complete. */
|
|
while (len_to_copy > 0) {
|
|
lwrb_sz_t max_seq_read, max_seq_write, op_len;
|
|
const uint8_t* d_src;
|
|
uint8_t* d_dst;
|
|
|
|
/* Calculate data */
|
|
max_seq_read = lwrb_get_linear_block_read_length(src);
|
|
max_seq_write = lwrb_get_linear_block_write_length(dest);
|
|
op_len = BUF_MIN(max_seq_read, max_seq_write);
|
|
op_len = BUF_MIN(len_to_copy, op_len);
|
|
|
|
/* Get addresses */
|
|
d_src = lwrb_get_linear_block_read_address(src);
|
|
d_dst = lwrb_get_linear_block_write_address(dest);
|
|
|
|
/* Byte by byte copy */
|
|
for (lwrb_sz_t i = 0; i < op_len; ++i) {
|
|
*d_dst++ = *d_src++;
|
|
}
|
|
|
|
lwrb_advance(dest, op_len);
|
|
lwrb_skip(src, op_len);
|
|
len_to_copy -= op_len;
|
|
if (op_len == 0) {
|
|
/* Hard error... */
|
|
return 0;
|
|
}
|
|
}
|
|
return len_to_copy_orig;
|
|
}
|
|
|
|
#endif /* defined(LWRB_DEV) */
|