CircularBuffer.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include "CircularBuffer.h"
  2. #include <algorithm> // for min
  3. using namespace bell;
  4. CircularBuffer::CircularBuffer(size_t dataCapacity) {
  5. this->dataCapacity = dataCapacity;
  6. buffer = std::vector<uint8_t>(dataCapacity);
  7. this->dataSemaphore = std::make_unique<bell::WrappedSemaphore>(5);
  8. };
  9. size_t CircularBuffer::write(const uint8_t* data, size_t bytes) {
  10. if (bytes == 0)
  11. return 0;
  12. std::lock_guard<std::mutex> guard(bufferMutex);
  13. size_t bytesToWrite = std::min(bytes, dataCapacity - dataSize);
  14. // Write in a single step
  15. if (bytesToWrite <= dataCapacity - endIndex) {
  16. memcpy(buffer.data() + endIndex, data, bytesToWrite);
  17. endIndex += bytesToWrite;
  18. if (endIndex == dataCapacity)
  19. endIndex = 0;
  20. }
  21. // Write in two steps
  22. else {
  23. size_t firstChunkSize = dataCapacity - endIndex;
  24. memcpy(buffer.data() + endIndex, data, firstChunkSize);
  25. size_t secondChunkSize = bytesToWrite - firstChunkSize;
  26. memcpy(buffer.data(), data + firstChunkSize, secondChunkSize);
  27. endIndex = secondChunkSize;
  28. }
  29. dataSize += bytesToWrite;
  30. // this->dataSemaphore->give();
  31. return bytesToWrite;
  32. }
  33. void CircularBuffer::emptyBuffer() {
  34. std::lock_guard<std::mutex> guard(bufferMutex);
  35. begIndex = 0;
  36. dataSize = 0;
  37. endIndex = 0;
  38. }
  39. void CircularBuffer::emptyExcept(size_t sizeToSet) {
  40. std::lock_guard<std::mutex> guard(bufferMutex);
  41. if (sizeToSet > dataSize)
  42. sizeToSet = dataSize;
  43. dataSize = sizeToSet;
  44. endIndex = begIndex + sizeToSet;
  45. if (endIndex > dataCapacity) {
  46. endIndex -= dataCapacity;
  47. }
  48. }
  49. size_t CircularBuffer::read(uint8_t* data, size_t bytes) {
  50. if (bytes == 0)
  51. return 0;
  52. std::lock_guard<std::mutex> guard(bufferMutex);
  53. size_t bytesToRead = std::min(bytes, dataSize);
  54. // Read in a single step
  55. if (bytesToRead <= dataCapacity - begIndex) {
  56. memcpy(data, buffer.data() + begIndex, bytesToRead);
  57. begIndex += bytesToRead;
  58. if (begIndex == dataCapacity)
  59. begIndex = 0;
  60. }
  61. // Read in two steps
  62. else {
  63. size_t firstChunkSize = dataCapacity - begIndex;
  64. memcpy(data, buffer.data() + begIndex, firstChunkSize);
  65. size_t secondChunkSize = bytesToRead - firstChunkSize;
  66. memcpy(data + firstChunkSize, buffer.data(), secondChunkSize);
  67. begIndex = secondChunkSize;
  68. }
  69. dataSize -= bytesToRead;
  70. return bytesToRead;
  71. }