Add ReadExactBinary and WriteAllBinary methods.

These are hopefully more user-friendly for reading and writing binary
data.

Bug: 156286088
Test: launch_cvd
Change-Id: Ia035237dee3fed0de8d3d66dd7d903920cb1cf8a
Merged-In: Ia035237dee3fed0de8d3d66dd7d903920cb1cf8a
diff --git a/common/libs/fs/shared_buf.cc b/common/libs/fs/shared_buf.cc
index 7400f03..5ae1aa2 100644
--- a/common/libs/fs/shared_buf.cc
+++ b/common/libs/fs/shared_buf.cc
@@ -22,13 +22,15 @@
 #include "common/libs/fs/shared_buf.h"
 #include "common/libs/fs/shared_fd.h"
 
-namespace cvd {
-
 namespace {
 
 const size_t BUFF_SIZE = 1 << 14;
 
-static ssize_t WriteAll(SharedFD fd, const char* buf, size_t size) {
+} // namespace
+
+namespace cvd {
+
+ssize_t WriteAll(SharedFD fd, const char* buf, size_t size) {
   size_t total_written = 0;
   ssize_t written = 0;
   while ((written = fd->Write((void*)&(buf[total_written]), size - total_written)) > 0) {
@@ -44,7 +46,21 @@
   return total_written;
 }
 
-} // namespace
+ssize_t ReadExact(SharedFD fd, char* buf, size_t size) {
+  size_t total_read = 0;
+  ssize_t read = 0;
+  while ((read = fd->Read((void*)&(buf[total_read]), size - total_read)) > 0) {
+    if (read < 0) {
+      errno = fd->GetErrno();
+      return read;
+    }
+    total_read += read;
+    if (total_read == size) {
+      break;
+    }
+  }
+  return total_read;
+}
 
 ssize_t ReadAll(SharedFD fd, std::string* buf) {
   char buff[BUFF_SIZE];
@@ -63,19 +79,11 @@
 }
 
 ssize_t ReadExact(SharedFD fd, std::string* buf) {
-  size_t total_read = 0;
-  ssize_t read = 0;
-  while ((read = fd->Read((void*)&((*buf)[total_read]), buf->size() - total_read)) > 0) {
-    if (read < 0) {
-      errno = fd->GetErrno();
-      return read;
-    }
-    total_read += read;
-    if (total_read == buf->size()) {
-      break;
-    }
-  }
-  return total_read;
+  return ReadExact(fd, buf->data(), buf->size());
+}
+
+ssize_t ReadExact(SharedFD fd, std::vector<char>* buf) {
+  return ReadExact(fd, buf->data(), buf->size());
 }
 
 ssize_t WriteAll(SharedFD fd, const std::string& buf) {
diff --git a/common/libs/fs/shared_buf.h b/common/libs/fs/shared_buf.h
index bebb5bc..f8f86b7 100644
--- a/common/libs/fs/shared_buf.h
+++ b/common/libs/fs/shared_buf.h
@@ -43,6 +43,39 @@
 ssize_t ReadExact(SharedFD fd, std::string* buf);
 
 /**
+ * Reads from fd until reading buf->size() bytes or errors.
+ *
+ * On a successful read, returns buf->size().
+ *
+ * If a read error is encountered, returns -1. buf will contain any data read
+ * up until that point and errno will be set.
+ */
+ssize_t ReadExact(SharedFD fd, std::vector<char>* buf);
+
+/**
+ * Reads from fd until reading `size` bytes or errors.
+ *
+ * On a successful read, returns buf->size().
+ *
+ * If a read error is encountered, returns -1. buf will contain any data read
+ * up until that point and errno will be set.
+ */
+ssize_t ReadExact(SharedFD fd, char* buf, size_t size);
+
+/*
+ * Reads from fd until reading `sizeof(T)` bytes or errors.
+ *
+ * On a successful read, returns `sizeof(T)`.
+ *
+ * If a read error is encountered, returns -1. buf will contain any data read
+ * up until that point and errno will be set.
+ */
+template<typename T>
+ssize_t ReadExactBinary(SharedFD fd, T* binary_data) {
+  return ReadExact(fd, (char*) binary_data, sizeof(*binary_data));
+}
+
+/**
  * Writes to fd until writing all bytes in buf.
  *
  * On a successful write, returns buf.size().
@@ -62,4 +95,27 @@
  */
 ssize_t WriteAll(SharedFD fd, const std::vector<char>& buf);
 
+/**
+ * Writes to fd until `size` bytes are written from `buf`.
+ *
+ * On a successful write, returns `size`.
+ *
+ * If a write error is encountered, returns -1. Some data may have already been
+ * written to fd at that point.
+ */
+ssize_t WriteAll(SharedFD fd, const char* buf, size_t size);
+
+/**
+ * Writes to fd until `sizeof(T)` bytes are written from binary_data.
+ *
+ * On a successful write, returns `sizeof(T)`.
+ *
+ * If a write error is encountered, returns -1. Some data may have already been
+ * written to fd at that point.
+ */
+template<typename T>
+ssize_t WriteAllBinary(SharedFD fd, const T* binary_data) {
+  return WriteAll(fd, (const char*) binary_data, sizeof(*binary_data));
+}
+
 } // namespace cvd