2015-06-02 15:11:59 +00:00
|
|
|
/**
|
2015-07-20 01:32:48 +00:00
|
|
|
******************************************************************************
|
|
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
|
|
******************************************************************************
|
|
|
|
* Copyright 2015 Ben Vanik. All rights reserved. *
|
|
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
2015-06-02 15:11:59 +00:00
|
|
|
|
|
|
|
#include "xenia/base/ring_buffer.h"
|
|
|
|
|
2015-06-19 14:50:54 +00:00
|
|
|
#include <algorithm>
|
2015-06-17 05:08:05 +00:00
|
|
|
#include <cstring>
|
|
|
|
|
2015-06-02 15:11:59 +00:00
|
|
|
namespace xe {
|
|
|
|
|
2015-06-20 02:48:51 +00:00
|
|
|
RingBuffer::RingBuffer(uint8_t* buffer, size_t capacity)
|
2015-08-30 01:06:30 +00:00
|
|
|
: buffer_(buffer), capacity_(capacity) {}
|
2015-06-20 02:48:51 +00:00
|
|
|
|
2015-09-06 17:28:17 +00:00
|
|
|
RingBuffer::ReadRange RingBuffer::BeginRead(size_t count) {
|
|
|
|
count = std::min(count, capacity_);
|
|
|
|
if (!count) {
|
|
|
|
return {0};
|
|
|
|
}
|
|
|
|
if (read_offset_ + count < capacity_) {
|
|
|
|
return {buffer_ + read_offset_, count, nullptr, 0};
|
|
|
|
} else {
|
|
|
|
size_t left_half = capacity_ - read_offset_;
|
|
|
|
size_t right_half = count - left_half;
|
|
|
|
return {buffer_ + read_offset_, left_half, buffer_, right_half};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RingBuffer::EndRead(ReadRange read_range) {
|
|
|
|
if (read_range.second_length) {
|
|
|
|
read_offset_ = read_range.second_length;
|
|
|
|
} else {
|
|
|
|
read_offset_ += read_range.first_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-20 02:48:51 +00:00
|
|
|
size_t RingBuffer::Read(uint8_t* buffer, size_t count) {
|
|
|
|
count = std::min(count, capacity_);
|
|
|
|
if (!count) {
|
2015-06-19 14:50:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2015-06-03 16:12:55 +00:00
|
|
|
|
2015-06-20 02:48:51 +00:00
|
|
|
if (read_offset_ + count < capacity_) {
|
|
|
|
std::memcpy(buffer, buffer_ + read_offset_, count);
|
|
|
|
read_offset_ += count;
|
2015-06-19 14:50:54 +00:00
|
|
|
} else {
|
2015-06-20 02:48:51 +00:00
|
|
|
size_t left_half = capacity_ - read_offset_;
|
|
|
|
size_t right_half = count - left_half;
|
|
|
|
std::memcpy(buffer, buffer_ + read_offset_, left_half);
|
|
|
|
std::memcpy(buffer + left_half, buffer_, right_half);
|
2015-06-19 14:50:54 +00:00
|
|
|
read_offset_ = right_half;
|
2015-06-02 15:11:59 +00:00
|
|
|
}
|
|
|
|
|
2015-06-20 02:48:51 +00:00
|
|
|
return count;
|
2015-06-02 15:11:59 +00:00
|
|
|
}
|
|
|
|
|
2015-08-30 01:06:30 +00:00
|
|
|
size_t RingBuffer::Write(const uint8_t* buffer, size_t count) {
|
2015-06-20 02:48:51 +00:00
|
|
|
count = std::min(count, capacity_);
|
|
|
|
if (!count) {
|
2015-06-19 14:50:54 +00:00
|
|
|
return 0;
|
2015-06-03 16:12:55 +00:00
|
|
|
}
|
|
|
|
|
2015-06-20 02:48:51 +00:00
|
|
|
if (write_offset_ + count < capacity_) {
|
|
|
|
std::memcpy(buffer_ + write_offset_, buffer, count);
|
|
|
|
write_offset_ += count;
|
2015-06-02 15:11:59 +00:00
|
|
|
} else {
|
2015-06-20 02:48:51 +00:00
|
|
|
size_t left_half = capacity_ - write_offset_;
|
|
|
|
size_t right_half = count - left_half;
|
|
|
|
std::memcpy(buffer_ + write_offset_, buffer, left_half);
|
|
|
|
std::memcpy(buffer_, buffer + left_half, right_half);
|
2015-06-19 14:50:54 +00:00
|
|
|
write_offset_ = right_half;
|
2015-06-02 15:11:59 +00:00
|
|
|
}
|
2015-06-19 14:50:54 +00:00
|
|
|
|
2015-06-20 02:48:51 +00:00
|
|
|
return count;
|
2015-06-02 15:11:59 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 05:26:51 +00:00
|
|
|
} // namespace xe
|