| Index: ppapi/shared_impl/circular_buffer.cc
|
| diff --git a/ppapi/shared_impl/circular_buffer.cc b/ppapi/shared_impl/circular_buffer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8623a82ffad3635db3be6c0d3d71f7ab5f9bb5e4
|
| --- /dev/null
|
| +++ b/ppapi/shared_impl/circular_buffer.cc
|
| @@ -0,0 +1,164 @@
|
| +// Copyright (c) 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ppapi/shared_impl/circular_buffer.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "base/logging.h"
|
| +#include "ppapi/c/pp_errors.h"
|
| +
|
| +namespace ppapi {
|
| +
|
| +CircularBuffer::CircularBuffer(void* buffer, uint32_t size)
|
| + : buffer_(static_cast<uint8_t*>(buffer)),
|
| + buffer_size_(size),
|
| + position_(0),
|
| + limit_(0),
|
| + remaining_(0),
|
| + locked_buffer_(NULL),
|
| + locked_buffer_size_(0) {
|
| +}
|
| +
|
| +CircularBuffer::~CircularBuffer() {
|
| +}
|
| +
|
| +void CircularBuffer::MovePosition(uint32_t offset) {
|
| + CHECK(offset);
|
| + CHECK(offset <= remaining_);
|
| +
|
| + position_ += offset;
|
| + remaining_ -= offset;
|
| + if (position_ >= buffer_size_)
|
| + position_ -= buffer_size_;
|
| +}
|
| +
|
| +void CircularBuffer::MoveLimit(uint32_t offset) {
|
| + CHECK(offset);
|
| + CHECK(offset <= (buffer_size_ - remaining_));
|
| +
|
| + limit_ += offset;
|
| + remaining_ += offset;
|
| + if (limit_ >= buffer_size_)
|
| + limit_ -= buffer_size_;
|
| +}
|
| +
|
| +int32_t CircularBuffer::Read(void* buffer, uint32_t size) {
|
| + // Buffer has been locked.
|
| + if (locked_buffer_)
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + size = std::min(size, remaining_);
|
| +
|
| + if (!size)
|
| + return 0;
|
| +
|
| + return ReadInternal(buffer, size);
|
| +}
|
| +
|
| +int32_t CircularBuffer::ReadAll(void* buffer, uint32_t size) {
|
| + // Buffer has been locked.
|
| + if (locked_buffer_)
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + if (size > buffer_size_)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + if (size > remaining_)
|
| + return PP_ERROR_NOSPACE;
|
| +
|
| + return ReadInternal(buffer, size);
|
| +
|
| +}
|
| +
|
| +int32_t CircularBuffer::ReadInternal(void* buffer, uint32_t size) {
|
| + uint32_t n = std::min(buffer_size_ - position_, size);
|
| + memcpy(buffer, buffer_ + position_, n);
|
| + if (n != size) {
|
| + memcpy(static_cast<uint8_t*>(buffer) + n, buffer_, size - n);
|
| + }
|
| + MovePosition(size);
|
| + return size;
|
| +}
|
| +
|
| +int32_t CircularBuffer::Write(const void* buffer, uint32_t size) {
|
| + // Buffer has been locked.
|
| + if (locked_buffer_)
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + size = std::min(size, remaining_);
|
| + if (!size)
|
| + return 0;
|
| +
|
| + return WriteInternal(buffer, size);
|
| +}
|
| +
|
| +int32_t CircularBuffer::WriteAll(const void* buffer, uint32_t size) {
|
| + // Buffer has been locked.
|
| + if (locked_buffer_)
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + if (size > buffer_size_)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + if (size > remaining_)
|
| + return PP_ERROR_NOSPACE;
|
| +
|
| + return WriteInternal(buffer, size);
|
| +}
|
| +
|
| +int32_t CircularBuffer::WriteInternal(const void* buffer, uint32_t size) {
|
| + uint32_t n = std::min(buffer_size_ - position_, size);
|
| + memcpy(buffer_ + position_, buffer, n);
|
| + if (n != size) {
|
| + memcpy(buffer_, static_cast<const uint8_t*>(buffer) + n, size - n);
|
| + }
|
| + MovePosition(size);
|
| + return size;
|
| +}
|
| +
|
| +int32_t CircularBuffer::Lock(void** buffer, uint32_t size) {
|
| + CHECK(buffer);
|
| + CHECK(size);
|
| +
|
| + if (locked_buffer_)
|
| + return PP_ERROR_INPROGRESS;
|
| +
|
| + // Request memory is not continuous.
|
| + if (position_ + size > buffer_size_)
|
| + return PP_ERROR_FAILED;
|
| +
|
| + // Do not have enough space for locking.
|
| + if (size > remaining_)
|
| + return PP_ERROR_NOSPACE;
|
| +
|
| + locked_buffer_ = buffer_ + position_;
|
| + *buffer = locked_buffer_;
|
| + locked_buffer_size_ = size;
|
| + return PP_OK;
|
| +}
|
| +
|
| +int32_t CircularBuffer::Relock(void* buffer, uint32_t size) {
|
| + if (locked_buffer_ != buffer)
|
| + return PP_ERROR_BADARGUMENT;
|
| + locked_buffer_size_ = size;
|
| + return PP_OK;
|
| +}
|
| +
|
| +int32_t CircularBuffer::Unlock(const void* buffer) {
|
| + if (!buffer)
|
| + return PP_ERROR_BADARGUMENT;
|
| + if (locked_buffer_ != buffer)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + int32_t size = locked_buffer_size_;
|
| +
|
| + locked_buffer_ = NULL;
|
| + locked_buffer_size_ = 0;
|
| +
|
| + MovePosition(size);
|
| + return size;
|
| +}
|
| +
|
| +} // namespace ppapi
|
|
|