Implement an interface compatible wcslcpy and strlcpy.  Possibly slightly
slower than the OpenBSD implementation, but a bit clearer and fits our style.

Move file_util_posix to use it now that we have it everywhere.



git-svn-id: svn://svn.chromium.org/chrome/trunk/src@798 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: 954d58c4d2bd4499ed61da01ee22684669e12f28
diff --git a/base/string_util.cc b/base/string_util.cc
index 864612a..7208cd0 100644
--- a/base/string_util.cc
+++ b/base/string_util.cc
@@ -1384,3 +1384,34 @@
   StringToDouble(value, &result);
   return result;
 }
+
+// The following code is compatible with the OpenBSD lcpy interface.  See:
+//   http://www.gratisoft.us/todd/papers/strlcpy.html
+//   ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c
+
+namespace {
+
+template <typename CHAR>
+size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) {
+  for (size_t i = 0; i < dst_size; ++i) {
+    if ((dst[i] = src[i]) == 0)  // We hit and copied the terminating NULL.
+      return i;
+  }
+
+  // We were left off at dst_size.  We over copied 1 byte.  Null terminate.
+  if (dst_size != 0)
+    dst[dst_size - 1] = 0;
+
+  // Count the rest of the |src|, and return it's length in characters.
+  while (src[dst_size]) ++dst_size;
+  return dst_size;
+}
+
+}  // namespace
+
+size_t base::strlcpy(char* dst, const char* src, size_t dst_size) {
+  return lcpyT<char>(dst, src, dst_size);
+}
+size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) {
+  return lcpyT<wchar_t>(dst, src, dst_size);
+}