MessageBuffer: add CanFitEver()

The CanFitEver() method will be used to determine
whether the MessageBuffer can host an incoming
message, or if the incoming message requires
compression.

Bug: 31653003
Test: ./runtests.sh (on bullhead)
Change-Id: If09ae5bc6c7c80a71e490e945187bd6fc25529b1
diff --git a/message_buffer.cpp b/message_buffer.cpp
index 49902bf..12b41be 100644
--- a/message_buffer.cpp
+++ b/message_buffer.cpp
@@ -41,6 +41,11 @@
   return true;
 }
 
+bool MessageBuffer::CanFitEver(uint16_t length) const {
+  // This unusual formulation is intended to avoid overflow.
+  return capacity_ - GetHeaderSize() >= length;
+}
+
 bool MessageBuffer::CanFitNow(uint16_t length) const {
   // This unusual formulation is intended to avoid overflow/underflow.
   return GetFreeSize() >= GetHeaderSize() &&
diff --git a/message_buffer.h b/message_buffer.h
index 6058813..1a1932b 100644
--- a/message_buffer.h
+++ b/message_buffer.h
@@ -39,6 +39,10 @@
   // true if the message was added to the buffer.
   bool Append(NONNULL const uint8_t* data, uint16_t data_len);
 
+  // Returns true if the buffer is large enough to hold |length| bytes of user
+  // data, when the buffer is empty.
+  bool CanFitEver(uint16_t length) const;
+
   // Returns true if the buffer currently has enough free space to hold |length|
   // bytes of user data.
   bool CanFitNow(uint16_t length) const;
diff --git a/tests/message_buffer_unittest.cpp b/tests/message_buffer_unittest.cpp
index a4883b6..b183b98 100644
--- a/tests/message_buffer_unittest.cpp
+++ b/tests/message_buffer_unittest.cpp
@@ -142,6 +142,37 @@
   EXPECT_TRUE(buffer_.CanFitNow(kLargestMessage.size()));
 }
 
+TEST_F(MessageBufferTest, CanFitEverIsCorrectOnFreshBuffer) {
+  EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
+  EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
+}
+
+TEST_F(MessageBufferTest, CanFitEverIsCorrectAfterSmallWrite) {
+  ASSERT_TRUE(buffer_.Append(kSmallestMessage.data(), kSmallestMessage.size()));
+  EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
+  EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
+}
+
+TEST_F(MessageBufferTest, CanFitEverIsCorrectOnFullBuffer) {
+  ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
+  EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
+  EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
+}
+
+TEST_F(MessageBufferTest, CanFitEverIsCorrectAfterRewind) {
+  ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
+  buffer_.Rewind();
+  EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
+  EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
+}
+
+TEST_F(MessageBufferTest, CanFitEverIsCorrectAfterClear) {
+  ASSERT_TRUE(buffer_.Append(kLargestMessage.data(), kLargestMessage.size()));
+  buffer_.Clear();
+  EXPECT_TRUE(buffer_.CanFitEver(kLargestMessage.size()));
+  EXPECT_FALSE(buffer_.CanFitEver(kLargestMessage.size() + 1));
+}
+
 TEST_F(MessageBufferTest, ConsumeNextMessageReturnsNullOnFreshBuffer) {
   const std::tuple<const uint8_t*, size_t> expected{nullptr, 0};
   EXPECT_EQ(expected, buffer_.ConsumeNextMessage());