Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53552048 authored by Elliott Hughes's avatar Elliott Hughes Committed by android-build-merger
Browse files

Merge "Keep the ReadFileToString/ReadFdToString overhead down."

am: 2af784bf

Change-Id: I4c59280af2b5d3aad0911df7696e675a86cad701
parents f803be00 2af784bf
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -49,6 +49,14 @@ using namespace android::base::utf8;
bool ReadFdToString(int fd, std::string* content) {
  content->clear();

  // Although original we had small files in mind, this code gets used for
  // very large files too, where the std::string growth heuristics might not
  // be suitable. https://code.google.com/p/android/issues/detail?id=258500.
  struct stat sb;
  if (fstat(fd, &sb) != -1 && sb.st_size > 0) {
    content->reserve(sb.st_size);
  }

  char buf[BUFSIZ];
  ssize_t n;
  while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
+43 −0
Original line number Diff line number Diff line
@@ -214,3 +214,46 @@ TEST(file, Dirname) {
  EXPECT_EQ(".", android::base::Dirname("sh"));
  EXPECT_EQ("/system/bin", android::base::Dirname("/system/bin/sh/"));
}

TEST(file, ReadFileToString_capacity) {
  TemporaryFile tf;
  ASSERT_TRUE(tf.fd != -1);

  // For a huge file, the overhead should still be small.
  std::string s;
  size_t size = 16 * 1024 * 1024;
  ASSERT_TRUE(android::base::WriteStringToFile(std::string(size, 'x'), tf.path));
  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
  EXPECT_EQ(size, s.size());
  EXPECT_LT(s.capacity(), size + 16);

  // Even for weird badly-aligned sizes.
  size += 12345;
  ASSERT_TRUE(android::base::WriteStringToFile(std::string(size, 'x'), tf.path));
  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
  EXPECT_EQ(size, s.size());
  EXPECT_LT(s.capacity(), size + 16);

  // We'll shrink an enormous string if you read a small file into it.
  size = 64;
  ASSERT_TRUE(android::base::WriteStringToFile(std::string(size, 'x'), tf.path));
  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
  EXPECT_EQ(size, s.size());
  EXPECT_LT(s.capacity(), size + 16);
}

TEST(file, ReadFileToString_capacity_0) {
  TemporaryFile tf;
  ASSERT_TRUE(tf.fd != -1);

  // Because /proc reports its files as zero-length, we don't actually trust
  // any file that claims to be zero-length. Rather than add increasingly
  // complex heuristics for shrinking the passed-in string in that case, we
  // currently leave it alone.
  std::string s;
  size_t initial_capacity = s.capacity();
  ASSERT_TRUE(android::base::WriteStringToFile("", tf.path));
  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &s));
  EXPECT_EQ(0U, s.size());
  EXPECT_EQ(initial_capacity, s.capacity());
}