// Copyright 2016 Google Inc. All Rights Reserved. #include "circular_buffer.h" #include "log.h" namespace wvcdm { namespace oemprofiler { CircularBuffer::CircularBuffer(size_t memory_budget) : buffer_(memory_budget) { buffer_.resize(memory_budget, 0x00); fill_ = head_ = tail_ = 0; } size_t CircularBuffer::GetFreeSpace() const { return buffer_.size() - fill_; } size_t CircularBuffer::GetUsedSpace() const { return fill_; } bool CircularBuffer::AddU8(uint8_t value) { return AddU8s(&value, 1); } bool CircularBuffer::AddU8s(const uint8_t* values, size_t values_length) { if (GetFreeSpace() < values_length) { return false; } for (size_t i = 0; i < values_length; i++) { buffer_[head_] = values[i]; head_ = (head_ + 1) % buffer_.size(); } fill_ += values_length; return true; } bool CircularBuffer::PeekU8s( size_t offset, uint8_t* out, size_t read_length) const { if (out == NULL) { LOGE("Cannot read to null output"); return false; } if (offset >= GetUsedSpace()) { LOGE("Cannot read past end of data - %zu >= %zu", offset, GetUsedSpace()); return false; } if (read_length > GetUsedSpace() - offset) { LOGE("Cannot read when there is not enough data - %zu >= %zu", GetUsedSpace() - offset, sizeof(uint8_t)); return false; } for (size_t i = 0; i < read_length; i++) { const size_t safe_index = (tail_ + offset + i) % buffer_.size(); out[i] = buffer_[safe_index]; } return true; } bool CircularBuffer::PeekU8(size_t offset, uint8_t* out) const { return PeekU8s(offset, out, 1); } bool CircularBuffer::Remove(size_t count) { if (count > GetUsedSpace()) { // can't remove more than there is return false; } fill_ -= count; tail_ = (tail_ + count) % buffer_.size(); return true; } } // namespace oemprofiler } // namespace wvcdm