libweave: Port base/ changes from Chromium project
Now this makes the state of base/ match libchrome's implementation
on Brillo and Chrome OS.
Change-Id: I1c1eb30d2669aeb58a77f332f8c69f130d00878c
Reviewed-on: https://weave-review.googlesource.com/3065
Reviewed-by: Robert Ginda <rginda@google.com>
diff --git a/third_party/chromium/base/strings/string_number_conversions.cc b/third_party/chromium/base/strings/string_number_conversions.cc
index ac0fd46..529e913 100644
--- a/third_party/chromium/base/strings/string_number_conversions.cc
+++ b/third_party/chromium/base/strings/string_number_conversions.cc
@@ -136,6 +136,7 @@
if (begin != end && *begin == '-') {
if (!std::numeric_limits<value_type>::is_signed) {
+ *output = 0;
valid = false;
} else if (!Negative::Invoke(begin + 1, end, output)) {
valid = false;
diff --git a/third_party/chromium/base/strings/string_number_conversions_unittest.cc b/third_party/chromium/base/strings/string_number_conversions_unittest.cc
index 1cfb2c8..d570c08 100644
--- a/third_party/chromium/base/strings/string_number_conversions_unittest.cc
+++ b/third_party/chromium/base/strings/string_number_conversions_unittest.cc
@@ -133,7 +133,7 @@
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- int output = 0;
+ int output = cases[i].output ^ 1; // Ensure StringToInt wrote something.
EXPECT_EQ(cases[i].success, StringToInt(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
@@ -182,7 +182,8 @@
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- unsigned output = 0;
+ unsigned output =
+ cases[i].output ^ 1; // Ensure StringToUint wrote something.
EXPECT_EQ(cases[i].success, StringToUint(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
diff --git a/third_party/chromium/base/strings/string_piece.h b/third_party/chromium/base/strings/string_piece.h
index c79d9fa..b68b1f2 100644
--- a/third_party/chromium/base/strings/string_piece.h
+++ b/third_party/chromium/base/strings/string_piece.h
@@ -143,6 +143,8 @@
}
value_type operator[](size_type i) const { return ptr_[i]; }
+ value_type front() const { return ptr_[0]; }
+ value_type back() const { return ptr_[length_ - 1]; }
void remove_prefix(size_type n) {
ptr_ += n;
diff --git a/third_party/chromium/base/strings/string_util.cc b/third_party/chromium/base/strings/string_util.cc
index eb0c546..50f7a23 100644
--- a/third_party/chromium/base/strings/string_util.cc
+++ b/third_party/chromium/base/strings/string_util.cc
@@ -242,4 +242,17 @@
return true;
}
+
+template <class string_type>
+inline typename string_type::value_type* WriteIntoT(string_type* str,
+ size_t length_with_null) {
+ DCHECK_GT(length_with_null, 1u);
+ str->reserve(length_with_null);
+ str->resize(length_with_null - 1);
+ return &((*str)[0]);
+}
+
+char* WriteInto(std::string* str, size_t length_with_null) {
+ return WriteIntoT(str, length_with_null);
+}
} // namespace base
diff --git a/third_party/chromium/base/strings/string_util.h b/third_party/chromium/base/strings/string_util.h
index d6b6e10..f505bb6 100644
--- a/third_party/chromium/base/strings/string_util.h
+++ b/third_party/chromium/base/strings/string_util.h
@@ -173,6 +173,28 @@
bool IsStringUTF8(const StringPiece& str);
bool IsStringASCII(const StringPiece& str);
+// Reserves enough memory in |str| to accommodate |length_with_null| characters,
+// sets the size of |str| to |length_with_null - 1| characters, and returns a
+// pointer to the underlying contiguous array of characters. This is typically
+// used when calling a function that writes results into a character array, but
+// the caller wants the data to be managed by a string-like object. It is
+// convenient in that is can be used inline in the call, and fast in that it
+// avoids copying the results of the call from a char* into a string.
+//
+// |length_with_null| must be at least 2, since otherwise the underlying string
+// would have size 0, and trying to access &((*str)[0]) in that case can result
+// in a number of problems.
+//
+// Internally, this takes linear time because the resize() call 0-fills the
+// underlying array for potentially all
+// (|length_with_null - 1| * sizeof(string_type::value_type)) bytes. Ideally we
+// could avoid this aspect of the resize() call, as we expect the caller to
+// immediately write over this memory, but there is no other way to set the size
+// of the string, and not doing that will mean people who access |str| rather
+// than str.c_str() will get back a string of whatever size |str| had on entry
+// to this function (probably 0).
+char* WriteInto(std::string* str, size_t length_with_null);
+
} // namespace base
#if defined(OS_WIN)
diff --git a/third_party/chromium/base/strings/string_util_unittest.cc b/third_party/chromium/base/strings/string_util_unittest.cc
index 451fbd8..8d77d36 100644
--- a/third_party/chromium/base/strings/string_util_unittest.cc
+++ b/third_party/chromium/base/strings/string_util_unittest.cc
@@ -147,4 +147,39 @@
}
}
+class WriteIntoTest : public testing::Test {
+ protected:
+ static void WritesCorrectly(size_t num_chars) {
+ std::string buffer;
+ char kOriginal[] = "supercali";
+ strncpy(WriteInto(&buffer, num_chars + 1), kOriginal, num_chars);
+ // Using std::string(buffer.c_str()) instead of |buffer| truncates the
+ // string at the first \0.
+ EXPECT_EQ(std::string(kOriginal,
+ std::min(num_chars, arraysize(kOriginal) - 1)),
+ std::string(buffer.c_str()));
+ EXPECT_EQ(num_chars, buffer.size());
+ }
+};
+
+TEST_F(WriteIntoTest, WriteInto) {
+ // Validate that WriteInto reserves enough space and
+ // sizes a string correctly.
+ WritesCorrectly(1);
+ WritesCorrectly(2);
+ WritesCorrectly(5000);
+
+ // Validate that WriteInto doesn't modify other strings
+ // when using a Copy-on-Write implementation.
+ const char kLive[] = "live";
+ const char kDead[] = "dead";
+ const std::string live = kLive;
+ std::string dead = live;
+ strncpy(WriteInto(&dead, 5), kDead, 4);
+ EXPECT_EQ(kDead, dead);
+ EXPECT_EQ(4u, dead.size());
+ EXPECT_EQ(kLive, live);
+ EXPECT_EQ(4u, live.size());
+}
+
} // namespace base