Remove CircularFileStream / replace it with CallSessionFileRotatingStream.

BUG=4838, 4839

Review URL: https://codereview.webrtc.org/1245143005

Cr-Commit-Position: refs/heads/master@{#9628}
diff --git a/webrtc/base/filerotatingstream.cc b/webrtc/base/filerotatingstream.cc
index 3fd60ac..f2a6def 100644
--- a/webrtc/base/filerotatingstream.cc
+++ b/webrtc/base/filerotatingstream.cc
@@ -177,6 +177,26 @@
   return file_stream_->Flush();
 }
 
+bool FileRotatingStream::GetSize(size_t* size) const {
+  if (mode_ != kRead) {
+    // Not possible to get accurate size on disk when writing because of
+    // potential buffering.
+    return false;
+  }
+  DCHECK(size);
+  *size = 0;
+  size_t total_size = 0;
+  for (auto file_name : file_names_) {
+    Pathname pathname(file_name);
+    size_t file_size = 0;
+    if (Filesystem::GetFileSize(file_name, &file_size)) {
+      total_size += file_size;
+    }
+  }
+  *size = total_size;
+  return true;
+}
+
 void FileRotatingStream::Close() {
   CloseCurrentFile();
 }
diff --git a/webrtc/base/filerotatingstream.h b/webrtc/base/filerotatingstream.h
index 7f6bc50..f3de14e 100644
--- a/webrtc/base/filerotatingstream.h
+++ b/webrtc/base/filerotatingstream.h
@@ -50,6 +50,8 @@
                      size_t* written,
                      int* error) override;
   bool Flush() override;
+  // Returns the total file size currently used on disk.
+  bool GetSize(size_t* size) const override;
   void Close() override;
 
   // Opens the appropriate file(s). Call this before using the stream.
diff --git a/webrtc/base/filerotatingstream_unittest.cc b/webrtc/base/filerotatingstream_unittest.cc
index 084c612..09438f8 100644
--- a/webrtc/base/filerotatingstream_unittest.cc
+++ b/webrtc/base/filerotatingstream_unittest.cc
@@ -60,11 +60,15 @@
     scoped_ptr<FileRotatingStream> stream;
     stream.reset(new FileRotatingStream(dir_path, file_prefix));
     ASSERT_TRUE(stream->Open());
+    size_t read = 0;
+    size_t stream_size = 0;
+    EXPECT_TRUE(stream->GetSize(&stream_size));
     scoped_ptr<uint8_t[]> buffer(new uint8_t[expected_length]);
     EXPECT_EQ(SR_SUCCESS,
-              stream->ReadAll(buffer.get(), expected_length, nullptr, nullptr));
+              stream->ReadAll(buffer.get(), expected_length, &read, nullptr));
     EXPECT_EQ(0, memcmp(expected_contents, buffer.get(), expected_length));
     EXPECT_EQ(SR_EOS, stream->ReadAll(buffer.get(), 1, nullptr, nullptr));
+    EXPECT_EQ(stream_size, read);
   }
 
   void VerifyFileContents(const char* expected_contents,
@@ -214,11 +218,15 @@
     scoped_ptr<CallSessionFileRotatingStream> stream(
         new CallSessionFileRotatingStream(dir_path));
     ASSERT_TRUE(stream->Open());
+    size_t read = 0;
+    size_t stream_size = 0;
+    EXPECT_TRUE(stream->GetSize(&stream_size));
     scoped_ptr<uint8_t[]> buffer(new uint8_t[expected_length]);
     EXPECT_EQ(SR_SUCCESS,
-              stream->ReadAll(buffer.get(), expected_length, nullptr, nullptr));
+              stream->ReadAll(buffer.get(), expected_length, &read, nullptr));
     EXPECT_EQ(0, memcmp(expected_contents, buffer.get(), expected_length));
     EXPECT_EQ(SR_EOS, stream->ReadAll(buffer.get(), 1, nullptr, nullptr));
+    EXPECT_EQ(stream_size, read);
   }
 
   scoped_ptr<CallSessionFileRotatingStream> stream_;
diff --git a/webrtc/base/logsinks.cc b/webrtc/base/logsinks.cc
index e202a81..4968339 100644
--- a/webrtc/base/logsinks.cc
+++ b/webrtc/base/logsinks.cc
@@ -10,8 +10,11 @@
 
 #include "webrtc/base/logsinks.h"
 
+#include <iostream>
 #include <string>
 
+#include "webrtc/base/checks.h"
+
 namespace rtc {
 
 FileRotatingLogSink::FileRotatingLogSink(const std::string& log_dir_path,
@@ -26,14 +29,15 @@
 
 FileRotatingLogSink::FileRotatingLogSink(FileRotatingStream* stream)
     : stream_(stream) {
+  DCHECK(stream);
 }
 
 FileRotatingLogSink::~FileRotatingLogSink() {
 }
 
 void FileRotatingLogSink::OnLogMessage(const std::string& message) {
-  if (!stream_ || stream_->GetState() != SS_OPEN) {
-    LOG(LS_WARNING) << "Init() must be called before adding this sink.";
+  if (stream_->GetState() != SS_OPEN) {
+    std::cerr << "Init() must be called before adding this sink." << std::endl;
     return;
   }
   stream_->WriteAll(message.c_str(), message.size(), nullptr, nullptr);
@@ -43,6 +47,10 @@
   return stream_->Open();
 }
 
+bool FileRotatingLogSink::DisableBuffering() {
+  return stream_->DisableBuffering();
+}
+
 CallSessionFileRotatingLogSink::CallSessionFileRotatingLogSink(
     const std::string& log_dir_path,
     size_t max_total_log_size)
diff --git a/webrtc/base/logsinks.h b/webrtc/base/logsinks.h
index f86bdd0..849e1dc 100644
--- a/webrtc/base/logsinks.h
+++ b/webrtc/base/logsinks.h
@@ -39,6 +39,9 @@
   // Deletes any existing files in the directory and creates a new log file.
   virtual bool Init();
 
+  // Disables buffering on the underlying stream.
+  bool DisableBuffering();
+
  protected:
   explicit FileRotatingLogSink(FileRotatingStream* stream);
 
@@ -57,8 +60,6 @@
   ~CallSessionFileRotatingLogSink() override;
 
  private:
-  scoped_ptr<CallSessionFileRotatingStream> stream_;
-
   DISALLOW_COPY_AND_ASSIGN(CallSessionFileRotatingLogSink);
 };
 
diff --git a/webrtc/base/stream.cc b/webrtc/base/stream.cc
index 3e3afa0..e22c3d8 100644
--- a/webrtc/base/stream.cc
+++ b/webrtc/base/stream.cc
@@ -517,113 +517,6 @@
   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_;
-    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
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/webrtc/base/stream.h b/webrtc/base/stream.h
index f67c704..b331766 100644
--- a/webrtc/base/stream.h
+++ b/webrtc/base/stream.h
@@ -418,39 +418,6 @@
   DISALLOW_COPY_AND_ASSIGN(FileStream);
 };
 
-// A stream that caps the output at a certain size, dropping content from the
-// middle of the logical stream and maintaining equal parts of the start/end of
-// the logical stream.
-class CircularFileStream : public FileStream {
- public:
-  explicit CircularFileStream(size_t max_size);
-
-  bool Open(const std::string& filename, const char* mode, int* error) override;
-  StreamResult Read(void* buffer,
-                    size_t buffer_len,
-                    size_t* read,
-                    int* error) override;
-  StreamResult Write(const void* data,
-                     size_t data_len,
-                     size_t* written,
-                     int* error) override;
-
- private:
-  enum ReadSegment {
-    READ_MARKED,  // Read 0 .. marked_position_
-    READ_MIDDLE,  // Read position_ .. file_size
-    READ_LATEST,  // Read marked_position_ .. position_ if the buffer was
-                  // overwritten or 0 .. position_ otherwise.
-  };
-
-  size_t max_write_size_;
-  size_t position_;
-  size_t marked_position_;
-  size_t last_write_position_;
-  ReadSegment read_segment_;
-  size_t read_segment_available_;
-};
-
 ///////////////////////////////////////////////////////////////////////////////
 // MemoryStream is a simple implementation of a StreamInterface over in-memory
 // data.  Data is read and written at the current seek position.  Reads return
diff --git a/webrtc/base/stream_unittest.cc b/webrtc/base/stream_unittest.cc
index 4d5066a..4172a97 100644
--- a/webrtc/base/stream_unittest.cc
+++ b/webrtc/base/stream_unittest.cc
@@ -372,162 +372,4 @@
   EXPECT_EQ(SR_BLOCK, buf.ReadOffset(out, 10, 16, NULL));
 }
 
-class CircularFileStreamTest : public ::testing::Test {
- protected:
-  static size_t const kMaxSize = 12;
-
-  CircularFileStreamTest() : is_open_(false), stream_(kMaxSize) {
-    Pathname temp_dir;
-    if (Filesystem::GetAppTempFolder(&temp_dir)) {
-      logfile_name_ =
-          Filesystem::TempFilename(temp_dir, "CircularFileStreamTest");
-    }
-  }
-
-  virtual void SetUp() {
-    int error = -1;
-    is_open_ = stream_.Open(logfile_name_, "wb", &error);
-  }
-
-  virtual void TearDown() {
-    if (!Filesystem::IsAbsent(logfile_name_)) {
-      Filesystem::DeleteFile(logfile_name_);
-    }
-  }
-
-  bool is_open_;
-  CircularFileStream stream_;
-  std::string logfile_name_;
-};
-
-TEST_F(CircularFileStreamTest, ReadWriteWithinCapacity) {
-  EXPECT_TRUE(is_open_);
-  // Write contents.
-  const uint8_t bytes[] = {1, 2, 3, 4, 5, 6};
-  size_t written = 0;
-  int error = 0;
-  EXPECT_EQ(SR_SUCCESS, stream_.Write(bytes, sizeof(bytes), &written, &error));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(written, sizeof(bytes));
-  stream_.Close();
-
-  // Check file contents.
-  uint8_t content_bytes[sizeof(bytes)] = {};
-  scoped_ptr<FileStream> content_stream(
-      Filesystem::OpenFile(logfile_name_, "r"));
-  size_t num_content_bytes_read = 0;
-  EXPECT_TRUE(content_stream);
-  error = 0;
-  EXPECT_EQ(SR_SUCCESS,
-            content_stream->Read(content_bytes, sizeof(content_bytes),
-                                 &num_content_bytes_read, &error));
-  EXPECT_EQ(sizeof(content_bytes), num_content_bytes_read);
-  ASSERT_EQ(sizeof(content_bytes), sizeof(bytes));
-  EXPECT_EQ(0, memcmp(content_bytes, bytes, sizeof(content_bytes)));
-
-  // Check read result.
-  error = 0;
-  size_t file_size = 0;
-  EXPECT_TRUE(stream_.Open(logfile_name_, "r", &error));
-  EXPECT_TRUE(stream_.GetSize(&file_size));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(sizeof(bytes), file_size);
-  scoped_ptr<uint8_t[]> read_bytes(new uint8_t[file_size]);
-  size_t num_read_bytes = 0;
-  error = 0;
-  EXPECT_EQ(SR_SUCCESS, stream_.ReadAll(read_bytes.get(), file_size,
-                                        &num_read_bytes, &error));
-  EXPECT_EQ(sizeof(bytes), num_read_bytes);
-  EXPECT_EQ(0, memcmp(bytes, read_bytes.get(), file_size));
-}
-
-TEST_F(CircularFileStreamTest, ReadWriteAtCapacity) {
-  EXPECT_TRUE(is_open_);
-  // Write contents.
-  const uint8_t bytes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
-  size_t written = 0;
-  int error = 0;
-  EXPECT_EQ(SR_SUCCESS, stream_.Write(bytes, sizeof(bytes), &written, &error));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(written, sizeof(bytes));
-  stream_.Close();
-
-  // Check file contents.
-  uint8_t content_bytes[sizeof(bytes)] = {};
-  scoped_ptr<FileStream> content_stream(
-      Filesystem::OpenFile(logfile_name_, "r"));
-  size_t num_content_bytes_read = 0;
-  EXPECT_TRUE(content_stream);
-  error = 0;
-  EXPECT_EQ(SR_SUCCESS,
-            content_stream->Read(content_bytes, sizeof(content_bytes),
-                                 &num_content_bytes_read, &error));
-  EXPECT_EQ(sizeof(content_bytes), num_content_bytes_read);
-  ASSERT_EQ(sizeof(content_bytes), sizeof(bytes));
-  EXPECT_EQ(0, memcmp(content_bytes, bytes, sizeof(content_bytes)));
-
-  // Check read result.
-  error = 0;
-  size_t file_size = 0;
-  EXPECT_TRUE(stream_.Open(logfile_name_, "r", &error));
-  EXPECT_TRUE(stream_.GetSize(&file_size));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(sizeof(bytes), file_size);
-  scoped_ptr<uint8_t[]> read_bytes(new uint8_t[file_size]);
-  size_t num_read_bytes = 0;
-  error = 0;
-  EXPECT_EQ(SR_SUCCESS, stream_.ReadAll(read_bytes.get(), file_size,
-                                        &num_read_bytes, &error));
-  EXPECT_EQ(sizeof(bytes), num_read_bytes);
-  EXPECT_EQ(0, memcmp(bytes, read_bytes.get(), file_size));
-}
-
-TEST_F(CircularFileStreamTest, ReadWriteOverCapacity) {
-  EXPECT_TRUE(is_open_);
-  // Write contents.
-  const uint8_t bytes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-  size_t written = 0;
-  int error = 0;
-  EXPECT_EQ(SR_SUCCESS,
-            stream_.WriteAll(bytes, sizeof(bytes), &written, &error));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(written, sizeof(bytes));
-  stream_.Close();
-
-  // Check file contents.
-  uint8_t content_bytes[kMaxSize] = {};
-  scoped_ptr<FileStream> content_stream(
-      Filesystem::OpenFile(logfile_name_, "r"));
-  size_t num_content_bytes_read = 0;
-  EXPECT_TRUE(content_stream);
-  error = 0;
-  EXPECT_EQ(SR_SUCCESS,
-            content_stream->Read(content_bytes, sizeof(content_bytes),
-                                 &num_content_bytes_read, &error));
-  EXPECT_EQ(sizeof(content_bytes), num_content_bytes_read);
-  const uint8_t expected_content_bytes[] = {
-      1, 2, 3, 4, 5, 6, 13, 14, 15, 10, 11, 12};
-  ASSERT_EQ(sizeof(content_bytes), sizeof(expected_content_bytes));
-  EXPECT_EQ(
-      0, memcmp(expected_content_bytes, content_bytes, sizeof(content_bytes)));
-
-  // Check read result.
-  error = 0;
-  size_t file_size = 0;
-  EXPECT_TRUE(stream_.Open(logfile_name_, "r", &error));
-  EXPECT_TRUE(stream_.GetSize(&file_size));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(sizeof(content_bytes), file_size);
-  scoped_ptr<uint8_t[]> read_bytes(new uint8_t[file_size]);
-  size_t num_read_bytes = 0;
-  error = 0;
-  EXPECT_EQ(SR_SUCCESS, stream_.ReadAll(read_bytes.get(), file_size,
-                                        &num_read_bytes, &error));
-
-  const uint8_t expected_read_bytes[] = {
-      1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 15};
-  EXPECT_EQ(sizeof(expected_read_bytes), num_read_bytes);
-  EXPECT_EQ(0, memcmp(expected_read_bytes, read_bytes.get(), file_size));
-}
-
 }  // namespace rtc