MessageBuffer: add Append()

Add the ability to write to a MessageBuffer, and
unit tests for the same.

(Read functionality will come later.)

Bug: 31653003
Test: ./runtests.sh (on bullhead)
Change-Id: I5d43922364c29710676fd10187d9722a46dfb0db
diff --git a/message_buffer.cpp b/message_buffer.cpp
index f89210f..bb509ed 100644
--- a/message_buffer.cpp
+++ b/message_buffer.cpp
@@ -14,16 +14,51 @@
  * limitations under the License.
  */
 
-#include <android-base/logging.h>
+#include <cinttypes>
+#include <cstring>
+
+#include "android-base/logging.h"
 
 #include "wifilogd/message_buffer.h"
 
 namespace android {
 namespace wifilogd {
 
-MessageBuffer::MessageBuffer(size_t size) : data_(new uint8_t[size]) {
+MessageBuffer::MessageBuffer(size_t size)
+    : data_(new uint8_t[size]), capacity_(size), write_pos_(0) {
   CHECK(size > GetHeaderSize());
 }
 
+bool MessageBuffer::Append(const uint8_t* message, uint16_t message_len) {
+  CHECK(message_len);
+
+  if (!CanFitNow(message_len)) {
+    return false;
+  }
+
+  AppendHeader(message_len);
+  AppendRawBytes(message, message_len);
+  return true;
+}
+
+bool MessageBuffer::CanFitNow(uint16_t length) const {
+  // This unusual formulation is intended to avoid overflow/underflow.
+  return GetFreeSize() >= GetHeaderSize() &&
+         GetFreeSize() - GetHeaderSize() >= length;
+}
+
+// Private methods below.
+
+void MessageBuffer::AppendHeader(uint16_t message_len) {
+  LengthHeader header;
+  header.payload_len = message_len;
+  AppendRawBytes(&header, sizeof(header));
+}
+
+void MessageBuffer::AppendRawBytes(const void* data_start, size_t data_len) {
+  std::memcpy(data_.get() + write_pos_, data_start, data_len);
+  write_pos_ += data_len;
+}
+
 }  // namespace wifilogd
 }  // namespace android