Chromium Code Reviews| Index: webrtc/base/stream.cc |
| diff --git a/webrtc/base/stream.cc b/webrtc/base/stream.cc |
| index e22c3d8aa4ef567ea656183cedb500af5623a539..3e3afa040dae9e0bf75531bc39f28a18acabaffe 100644 |
| --- a/webrtc/base/stream.cc |
| +++ b/webrtc/base/stream.cc |
| @@ -517,6 +517,113 @@ void FileStream::DoClose() { |
| fclose(file_); |
| } |
| +CircularFileStream::CircularFileStream(size_t max_size) |
| + : max_write_size_(max_size), |
| + position_(0), |
| + marked_position_(max_size / 2), |
| + last_write_position_(0), |
| + read_segment_(READ_LATEST), |
| + read_segment_available_(0) { |
| +} |
| + |
| +bool CircularFileStream::Open(const std::string& filename, |
| + const char* mode, |
| + int* error) { |
| + if (!FileStream::Open(filename.c_str(), mode, error)) |
| + return false; |
| + |
| + if (strchr(mode, "r") != NULL) { // Opened in read mode. |
| + // Check if the buffer has been overwritten and determine how to read the |
| + // log in time sequence. |
| + size_t file_size; |
| + GetSize(&file_size); |
| + if (file_size == position_) { |
| + // The buffer has not been overwritten yet. Read 0 .. file_size |
| + read_segment_ = READ_LATEST; |
| + read_segment_available_ = file_size; |
| + } else { |
| + // The buffer has been over written. There are three segments: The first |
| + // one is 0 .. marked_position_, which is the marked earliest log. The |
| + // second one is position_ .. file_size, which is the middle log. The |
| + // last one is marked_position_ .. position_, which is the latest log. |
| + read_segment_ = READ_MARKED; |
| + read_segment_available_ = marked_position_; |
| + last_write_position_ = position_; |
| + } |
| + |
| + // Read from the beginning. |
| + position_ = 0; |
| + SetPosition(position_); |
| + } |
| + |
| + return true; |
| +} |
| + |
| +StreamResult CircularFileStream::Read(void* buffer, |
| + size_t buffer_len, |
| + size_t* read, |
| + int* error) { |
| + if (read_segment_available_ == 0) { |
| + size_t file_size; |
| + switch (read_segment_) { |
| + case READ_MARKED: // Finished READ_MARKED and start READ_MIDDLE. |
| + read_segment_ = READ_MIDDLE; |
| + position_ = last_write_position_; |
| + SetPosition(position_); |
| + GetSize(&file_size); |
| + read_segment_available_ = file_size - position_; |
| + break; |
| + |
| + case READ_MIDDLE: // Finished READ_MIDDLE and start READ_LATEST. |
| + read_segment_ = READ_LATEST; |
| + position_ = marked_position_; |
| + SetPosition(position_); |
| + read_segment_available_ = last_write_position_ - position_; |
| + break; |
| + |
| + default: // Finished READ_LATEST and return EOS. |
| + return rtc::SR_EOS; |
| + } |
| + } |
| + |
| + size_t local_read; |
| + if (!read) |
| + read = &local_read; |
| + |
| + size_t to_read = std::min(buffer_len, read_segment_available_); |
| + rtc::StreamResult result = |
| + rtc::FileStream::Read(buffer, to_read, read, error); |
| + if (result == rtc::SR_SUCCESS) { |
| + read_segment_available_ -= *read; |
| + position_ += *read; |
| + } |
| + return result; |
| +} |
| + |
| +StreamResult CircularFileStream::Write(const void* data, |
| + size_t data_len, |
| + size_t* written, |
| + int* error) { |
| + if (position_ >= max_write_size_) { |
| + ASSERT(position_ == max_write_size_); |
| + position_ = marked_position_; |
|
jiayl2
2015/07/06 18:18:14
I'm not sure this is what we want IIUC. If the max
tkchin
2015/07/06 20:36:50
Hmm I should've looked closer at this, I just unde
jiayl2
2015/07/06 20:55:22
The log uploaded should have the messages in the r
|
| + SetPosition(position_); |
| + } |
| + |
| + size_t local_written; |
| + if (!written) |
| + written = &local_written; |
| + |
| + size_t to_eof = max_write_size_ - position_; |
| + size_t to_write = std::min(data_len, to_eof); |
| + rtc::StreamResult result = |
| + rtc::FileStream::Write(data, to_write, written, error); |
| + if (result == rtc::SR_SUCCESS) { |
| + position_ += *written; |
| + } |
| + return result; |
| +} |
| + |
| /////////////////////////////////////////////////////////////////////////////// |
| // MemoryStream |
| /////////////////////////////////////////////////////////////////////////////// |