| 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 | 
|---|