| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/tools/flip_server/ring_buffer.h" | 5 #include "net/tools/flip_server/ring_buffer.h" |
| 6 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 | 7 |
| 8 namespace net { | 8 namespace net { |
| 9 | 9 |
| 10 RingBuffer::RingBuffer(int buffer_size) | 10 RingBuffer::RingBuffer(int buffer_size) |
| 11 : buffer_(new char[buffer_size]), | 11 : buffer_(new char[buffer_size]), |
| 12 buffer_size_(buffer_size), | 12 buffer_size_(buffer_size), |
| 13 bytes_used_(0), | 13 bytes_used_(0), |
| 14 read_idx_(0), | 14 read_idx_(0), |
| 15 write_idx_(0) { | 15 write_idx_(0) {} |
| 16 } | |
| 17 | 16 |
| 18 RingBuffer::~RingBuffer() {} | 17 RingBuffer::~RingBuffer() {} |
| 19 | 18 |
| 20 //////////////////////////////////////////////////////////////////////////////// | 19 int RingBuffer::ReadableBytes() const { return bytes_used_; } |
| 21 | 20 |
| 22 int RingBuffer::ReadableBytes() const { | 21 int RingBuffer::BufferSize() const { return buffer_size_; } |
| 23 return bytes_used_; | |
| 24 } | |
| 25 | 22 |
| 26 //////////////////////////////////////////////////////////////////////////////// | 23 int RingBuffer::BytesFree() const { return BufferSize() - ReadableBytes(); } |
| 27 | 24 |
| 28 int RingBuffer::BufferSize() const { | 25 bool RingBuffer::Empty() const { return ReadableBytes() == 0; } |
| 29 return buffer_size_; | |
| 30 } | |
| 31 | 26 |
| 32 //////////////////////////////////////////////////////////////////////////////// | 27 bool RingBuffer::Full() const { return ReadableBytes() == BufferSize(); } |
| 33 | |
| 34 int RingBuffer::BytesFree() const { | |
| 35 return BufferSize() - ReadableBytes(); | |
| 36 } | |
| 37 | |
| 38 //////////////////////////////////////////////////////////////////////////////// | |
| 39 | |
| 40 bool RingBuffer::Empty() const { | |
| 41 return ReadableBytes() == 0; | |
| 42 } | |
| 43 | |
| 44 //////////////////////////////////////////////////////////////////////////////// | |
| 45 | |
| 46 bool RingBuffer::Full() const { | |
| 47 return ReadableBytes() == BufferSize(); | |
| 48 } | |
| 49 | |
| 50 //////////////////////////////////////////////////////////////////////////////// | |
| 51 | 28 |
| 52 // Returns the number of characters written. | 29 // Returns the number of characters written. |
| 53 // Appends up-to-'size' bytes to the ringbuffer. | 30 // Appends up-to-'size' bytes to the ringbuffer. |
| 54 int RingBuffer::Write(const char* bytes, int size) { | 31 int RingBuffer::Write(const char* bytes, int size) { |
| 55 CHECK_GE(size, 0); | 32 CHECK_GE(size, 0); |
| 56 #if 1 | 33 #if 1 |
| 57 char* wptr; | 34 char* wptr; |
| 58 int wsize; | 35 int wsize; |
| 59 GetWritablePtr(&wptr, &wsize); | 36 GetWritablePtr(&wptr, &wsize); |
| 60 int bytes_remaining = size; | 37 int bytes_remaining = size; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 87 ++this->write_idx_; | 64 ++this->write_idx_; |
| 88 if (this->write_idx_ >= this->buffer_size_) { | 65 if (this->write_idx_ >= this->buffer_size_) { |
| 89 this->write_idx_ = 0; | 66 this->write_idx_ = 0; |
| 90 } | 67 } |
| 91 } | 68 } |
| 92 bytes_used_ += bytes_to_write; | 69 bytes_used_ += bytes_to_write; |
| 93 return bytes_to_write; | 70 return bytes_to_write; |
| 94 #endif | 71 #endif |
| 95 } | 72 } |
| 96 | 73 |
| 97 //////////////////////////////////////////////////////////////////////////////// | |
| 98 | |
| 99 // Sets *ptr to the beginning of writable memory, and sets *size to the size | 74 // Sets *ptr to the beginning of writable memory, and sets *size to the size |
| 100 // available for writing using this pointer. | 75 // available for writing using this pointer. |
| 101 void RingBuffer::GetWritablePtr(char** ptr, int* size) const { | 76 void RingBuffer::GetWritablePtr(char** ptr, int* size) const { |
| 102 *ptr = buffer_.get() + write_idx_; | 77 *ptr = buffer_.get() + write_idx_; |
| 103 | 78 |
| 104 if (bytes_used_ == buffer_size_) { | 79 if (bytes_used_ == buffer_size_) { |
| 105 *size = 0; | 80 *size = 0; |
| 106 } else if (read_idx_ > write_idx_) { | 81 } else if (read_idx_ > write_idx_) { |
| 107 *size = read_idx_ - write_idx_; | 82 *size = read_idx_ - write_idx_; |
| 108 } else { | 83 } else { |
| 109 *size = buffer_size_ - write_idx_; | 84 *size = buffer_size_ - write_idx_; |
| 110 } | 85 } |
| 111 } | 86 } |
| 112 | 87 |
| 113 //////////////////////////////////////////////////////////////////////////////// | |
| 114 | |
| 115 // Sets *ptr to the beginning of readable memory, and sets *size to the size | 88 // Sets *ptr to the beginning of readable memory, and sets *size to the size |
| 116 // available for reading using this pointer. | 89 // available for reading using this pointer. |
| 117 void RingBuffer::GetReadablePtr(char** ptr, int* size) const { | 90 void RingBuffer::GetReadablePtr(char** ptr, int* size) const { |
| 118 *ptr = buffer_.get() + read_idx_; | 91 *ptr = buffer_.get() + read_idx_; |
| 119 | 92 |
| 120 if (bytes_used_ == 0) { | 93 if (bytes_used_ == 0) { |
| 121 *size = 0; | 94 *size = 0; |
| 122 } else if (write_idx_ > read_idx_) { | 95 } else if (write_idx_ > read_idx_) { |
| 123 *size = write_idx_ - read_idx_; | 96 *size = write_idx_ - read_idx_; |
| 124 } else { | 97 } else { |
| 125 *size = buffer_size_ - read_idx_; | 98 *size = buffer_size_ - read_idx_; |
| 126 } | 99 } |
| 127 } | 100 } |
| 128 | 101 |
| 129 //////////////////////////////////////////////////////////////////////////////// | |
| 130 | |
| 131 // returns the number of bytes read into | 102 // returns the number of bytes read into |
| 132 int RingBuffer::Read(char* bytes, int size) { | 103 int RingBuffer::Read(char* bytes, int size) { |
| 133 CHECK_GE(size, 0); | 104 CHECK_GE(size, 0); |
| 134 #if 1 | 105 #if 1 |
| 135 char* rptr; | 106 char* rptr; |
| 136 int rsize; | 107 int rsize; |
| 137 GetReadablePtr(&rptr, &rsize); | 108 GetReadablePtr(&rptr, &rsize); |
| 138 int bytes_remaining = size; | 109 int bytes_remaining = size; |
| 139 int bytes_read = 0; | 110 int bytes_read = 0; |
| 140 | 111 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 164 ++this->read_idx_; | 135 ++this->read_idx_; |
| 165 if (this->read_idx_ >= this->buffer_size_) { | 136 if (this->read_idx_ >= this->buffer_size_) { |
| 166 this->read_idx_ = 0; | 137 this->read_idx_ = 0; |
| 167 } | 138 } |
| 168 } | 139 } |
| 169 this->bytes_used_ -= bytes_to_read; | 140 this->bytes_used_ -= bytes_to_read; |
| 170 return bytes_to_read; | 141 return bytes_to_read; |
| 171 #endif | 142 #endif |
| 172 } | 143 } |
| 173 | 144 |
| 174 //////////////////////////////////////////////////////////////////////////////// | |
| 175 | |
| 176 void RingBuffer::Clear() { | 145 void RingBuffer::Clear() { |
| 177 bytes_used_ = 0; | 146 bytes_used_ = 0; |
| 178 write_idx_ = 0; | 147 write_idx_ = 0; |
| 179 read_idx_ = 0; | 148 read_idx_ = 0; |
| 180 } | 149 } |
| 181 | 150 |
| 182 //////////////////////////////////////////////////////////////////////////////// | |
| 183 | |
| 184 bool RingBuffer::Reserve(int size) { | 151 bool RingBuffer::Reserve(int size) { |
| 185 DCHECK(size > 0); | 152 DCHECK_GT(size, 0); |
| 186 char* write_ptr = NULL; | 153 char* write_ptr = NULL; |
| 187 int write_size = 0; | 154 int write_size = 0; |
| 188 GetWritablePtr(&write_ptr, &write_size); | 155 GetWritablePtr(&write_ptr, &write_size); |
| 189 | 156 |
| 190 if (write_size < size) { | 157 if (write_size < size) { |
| 191 char* read_ptr = NULL; | 158 char* read_ptr = NULL; |
| 192 int read_size = 0; | 159 int read_size = 0; |
| 193 GetReadablePtr(&read_ptr, &read_size); | 160 GetReadablePtr(&read_ptr, &read_size); |
| 194 if (size <= BytesFree()) { | 161 if (size <= BytesFree()) { |
| 195 // The fact that the total Free size is big enough but writable size is | 162 // The fact that the total Free size is big enough but writable size is |
| 196 // not means that the writeable region is broken into two pieces: only | 163 // not means that the writeable region is broken into two pieces: only |
| 197 // possible if the read_idx < write_idx. If write_idx < read_idx, then | 164 // possible if the read_idx < write_idx. If write_idx < read_idx, then |
| 198 // the writeable region must be contiguous: [write_idx, read_idx). There | 165 // the writeable region must be contiguous: [write_idx, read_idx). There |
| 199 // is no work to be done for the latter. | 166 // is no work to be done for the latter. |
| 200 DCHECK(read_idx_ <= write_idx_); | 167 DCHECK_LE(read_idx_, write_idx_); |
| 201 DCHECK(read_size == ReadableBytes()); | 168 DCHECK_EQ(read_size, ReadableBytes()); |
| 202 if (read_idx_ < write_idx_) { | 169 if (read_idx_ < write_idx_) { |
| 203 // Writeable area fragmented, consolidate it. | 170 // Writeable area fragmented, consolidate it. |
| 204 memmove(buffer_.get(), read_ptr, read_size); | 171 memmove(buffer_.get(), read_ptr, read_size); |
| 205 read_idx_ = 0; | 172 read_idx_ = 0; |
| 206 write_idx_ = read_size; | 173 write_idx_ = read_size; |
| 207 } else if (read_idx_ == write_idx_) { | 174 } else if (read_idx_ == write_idx_) { |
| 208 // No unconsumed data in the buffer, simply reset the indexes. | 175 // No unconsumed data in the buffer, simply reset the indexes. |
| 209 DCHECK(ReadableBytes() == 0); | 176 DCHECK_EQ(ReadableBytes(), 0); |
| 210 read_idx_ = 0; | 177 read_idx_ = 0; |
| 211 write_idx_ = 0; | 178 write_idx_ = 0; |
| 212 } | 179 } |
| 213 } else { | 180 } else { |
| 214 Resize(ReadableBytes() + size); | 181 Resize(ReadableBytes() + size); |
| 215 } | 182 } |
| 216 } | 183 } |
| 217 DCHECK_LE(size, buffer_size_ - write_idx_); | 184 DCHECK_LE(size, buffer_size_ - write_idx_); |
| 218 return true; | 185 return true; |
| 219 } | 186 } |
| 220 | 187 |
| 221 //////////////////////////////////////////////////////////////////////////////// | |
| 222 | |
| 223 void RingBuffer::AdvanceReadablePtr(int amount_to_consume) { | 188 void RingBuffer::AdvanceReadablePtr(int amount_to_consume) { |
| 224 CHECK_GE(amount_to_consume, 0); | 189 CHECK_GE(amount_to_consume, 0); |
| 225 if (amount_to_consume >= bytes_used_) { | 190 if (amount_to_consume >= bytes_used_) { |
| 226 Clear(); | 191 Clear(); |
| 227 return; | 192 return; |
| 228 } | 193 } |
| 229 read_idx_ += amount_to_consume; | 194 read_idx_ += amount_to_consume; |
| 230 read_idx_ %= buffer_size_; | 195 read_idx_ %= buffer_size_; |
| 231 bytes_used_ -= amount_to_consume; | 196 bytes_used_ -= amount_to_consume; |
| 232 } | 197 } |
| 233 | 198 |
| 234 //////////////////////////////////////////////////////////////////////////////// | |
| 235 | |
| 236 void RingBuffer::AdvanceWritablePtr(int amount_to_produce) { | 199 void RingBuffer::AdvanceWritablePtr(int amount_to_produce) { |
| 237 CHECK_GE(amount_to_produce, 0); | 200 CHECK_GE(amount_to_produce, 0); |
| 238 CHECK_LE(amount_to_produce, BytesFree()); | 201 CHECK_LE(amount_to_produce, BytesFree()); |
| 239 write_idx_ += amount_to_produce; | 202 write_idx_ += amount_to_produce; |
| 240 write_idx_ %= buffer_size_; | 203 write_idx_ %= buffer_size_; |
| 241 bytes_used_ += amount_to_produce; | 204 bytes_used_ += amount_to_produce; |
| 242 } | 205 } |
| 243 | 206 |
| 244 //////////////////////////////////////////////////////////////////////////////// | |
| 245 | |
| 246 void RingBuffer::Resize(int buffer_size) { | 207 void RingBuffer::Resize(int buffer_size) { |
| 247 CHECK_GE(buffer_size, 0); | 208 CHECK_GE(buffer_size, 0); |
| 248 if (buffer_size == buffer_size_) return; | 209 if (buffer_size == buffer_size_) |
| 210 return; |
| 249 | 211 |
| 250 char* new_buffer = new char[buffer_size]; | 212 char* new_buffer = new char[buffer_size]; |
| 251 if (buffer_size < bytes_used_) { | 213 if (buffer_size < bytes_used_) { |
| 252 // consume the oldest data. | 214 // consume the oldest data. |
| 253 AdvanceReadablePtr(bytes_used_ - buffer_size); | 215 AdvanceReadablePtr(bytes_used_ - buffer_size); |
| 254 } | 216 } |
| 255 | 217 |
| 256 int bytes_written = 0; | 218 int bytes_written = 0; |
| 257 int bytes_used = bytes_used_; | 219 int bytes_used = bytes_used_; |
| 258 while (true) { | 220 while (true) { |
| 259 int size; | 221 int size; |
| 260 char* ptr; | 222 char* ptr; |
| 261 GetReadablePtr(&ptr, &size); | 223 GetReadablePtr(&ptr, &size); |
| 262 if (size == 0) break; | 224 if (size == 0) |
| 225 break; |
| 263 if (size > buffer_size) { | 226 if (size > buffer_size) { |
| 264 size = buffer_size; | 227 size = buffer_size; |
| 265 } | 228 } |
| 266 memcpy(new_buffer + bytes_written, ptr, size); | 229 memcpy(new_buffer + bytes_written, ptr, size); |
| 267 bytes_written += size; | 230 bytes_written += size; |
| 268 AdvanceReadablePtr(size); | 231 AdvanceReadablePtr(size); |
| 269 } | 232 } |
| 270 buffer_.reset(new_buffer); | 233 buffer_.reset(new_buffer); |
| 271 | 234 |
| 272 buffer_size_ = buffer_size; | 235 buffer_size_ = buffer_size; |
| 273 bytes_used_ = bytes_used; | 236 bytes_used_ = bytes_used; |
| 274 read_idx_ = 0; | 237 read_idx_ = 0; |
| 275 write_idx_ = bytes_used_ % buffer_size_; | 238 write_idx_ = bytes_used_ % buffer_size_; |
| 276 } | 239 } |
| 277 | 240 |
| 278 } // namespace net | 241 } // namespace net |
| 279 | |
| OLD | NEW |