// Copyright (c) 2011 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 "net/curvecp/circular_buffer.h" #include #include "base/logging.h" namespace net { CircularBuffer::CircularBuffer(int capacity) : capacity_(capacity), head_(0), length_(0) { buffer_ = new char[capacity_]; } CircularBuffer::~CircularBuffer() { delete [] buffer_; } int CircularBuffer::write(const char* data, int length) { int bytes_written = 0; // We can't write more bytes than we have space for. if (length > capacity_ - length_) length = capacity_ - length_; // Check for space at end of buffer. if (head_ + length_ < capacity_) { bytes_written = std::min(capacity_ - head_ - length_, length); int end_pos = head_ + length_; memcpy(buffer_ + end_pos, data, bytes_written); length_ += bytes_written; length -= bytes_written; } if (!length) return bytes_written; DCHECK_LT(length_, capacity_); // Buffer still has space. DCHECK_GE(head_ + length_, capacity_); // Space is at the beginning. int start_pos = (head_ + length_) % capacity_; memcpy(&buffer_[start_pos], &data[bytes_written], length); bytes_written += length; length_ += length; return bytes_written; } int CircularBuffer::read(char* data, int length) { int bytes_read = 0; // We can't read more bytes than are in the buffer. if (length > length_) length = length_; while (length) { DCHECK_LE(length, length_); int span_end = std::min(capacity_, head_ + length); int len = span_end - head_; DCHECK_LE(len, length_); memcpy(&data[bytes_read], &buffer_[head_], len); bytes_read += len; length -= len; length_ -= len; head_ += len; DCHECK_LE(head_, capacity_); if (head_ == capacity_) head_ = 0; } return bytes_read; } } // namespace net