File indexing completed on 2025-01-05 04:37:29

0001 /*
0002     SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "circularbuffer.h"
0008 #include "log.h"
0009 #include <string.h>
0010 #include <util/log.h>
0011 
0012 namespace bt
0013 {
0014 CircularBuffer::CircularBuffer(Uint32 cap)
0015     : data(nullptr)
0016     , buf_capacity(cap)
0017     , start(0)
0018     , buf_size(0)
0019 {
0020     data = new Uint8[cap];
0021 }
0022 
0023 CircularBuffer::~CircularBuffer()
0024 {
0025     delete[] data;
0026 }
0027 
0028 bt::Uint32 CircularBuffer::read(bt::Uint8 *ptr, bt::Uint32 max_len)
0029 {
0030     if (empty())
0031         return 0;
0032 
0033     bt::Uint32 to_read = buf_size < max_len ? buf_size : max_len;
0034 
0035     Range r = firstRange();
0036     bt::Uint32 s = r.second;
0037     if (s >= to_read) {
0038         memcpy(ptr, r.first, to_read);
0039     } else { // s < to_read
0040         memcpy(ptr, r.first, s);
0041         r = secondRange();
0042         memcpy(ptr + s, r.first, to_read - s);
0043     }
0044 
0045     start = (start + to_read) % buf_capacity;
0046     buf_size -= to_read;
0047     // Out(SYS_GEN|LOG_DEBUG) << "CircularBuffer::read 1 " << size() << " " << capacity() << endl;
0048     // Out(SYS_GEN|LOG_DEBUG) << "CircularBuffer::read 2 " << start << " " << to_read << endl;
0049     return to_read;
0050 }
0051 
0052 bt::Uint32 CircularBuffer::write(const bt::Uint8 *ptr, bt::Uint32 len)
0053 {
0054     if (full())
0055         return 0;
0056 
0057     bt::Uint32 free_space = buf_capacity - buf_size;
0058     bt::Uint32 to_write = free_space < len ? free_space : len;
0059 
0060     bt::Uint32 write_pos = (start + buf_size) % buf_capacity;
0061     if (write_pos + to_write > buf_capacity) {
0062         bt::Uint32 w = (buf_capacity - write_pos);
0063         memcpy(data + write_pos, ptr, w);
0064         memcpy(data, ptr + w, to_write - w);
0065     } else {
0066         memcpy(data + write_pos, ptr, to_write);
0067     }
0068 
0069     buf_size += to_write;
0070     // Out(SYS_GEN|LOG_DEBUG) << "CircularBuffer::write 1 " << size() << " " << capacity() << endl;
0071     // Out(SYS_GEN|LOG_DEBUG) << "CircularBuffer::write 2 " << start << " " << to_write << endl;
0072     return to_write;
0073 }
0074 
0075 CircularBuffer::Range CircularBuffer::firstRange()
0076 {
0077     if (start + buf_size > buf_capacity)
0078         return Range(data + start, buf_capacity - start);
0079     else
0080         return Range(data + start, buf_size);
0081 }
0082 
0083 CircularBuffer::Range CircularBuffer::secondRange()
0084 {
0085     if (start + buf_size > buf_capacity)
0086         return Range(data, buf_size - (buf_capacity - start));
0087     else
0088         return Range((bt::Uint8 *)nullptr, 0);
0089 }
0090 
0091 }