Move HexDump to include/perfetto/ext/base/utils.h

It's going to have a usecase outside of tests.

Bug: 205763418
Change-Id: I1686ff72c1c235ff64675e057a9a01ef501326e2
diff --git a/include/perfetto/ext/base/utils.h b/include/perfetto/ext/base/utils.h
index ed61ef1..ae1fc33 100644
--- a/include/perfetto/ext/base/utils.h
+++ b/include/perfetto/ext/base/utils.h
@@ -185,6 +185,13 @@
   return OnScopeExitWrapper<Func>(std::move(f));
 }
 
+// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
+std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
+inline std::string HexDump(const std::string& data,
+                           size_t bytes_per_line = 16) {
+  return HexDump(data.data(), data.size(), bytes_per_line);
+}
+
 }  // namespace base
 }  // namespace perfetto
 
diff --git a/src/base/test/utils.cc b/src/base/test/utils.cc
index ff00f64..56e51a8 100644
--- a/src/base/test/utils.cc
+++ b/src/base/test/utils.cc
@@ -40,28 +40,5 @@
   return path;
 }
 
-std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
-  const char* data = reinterpret_cast<const char*>(data_void);
-  std::string res;
-  static const size_t kPadding = bytes_per_line * 3 + 12;
-  std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
-  for (size_t i = 0; i < len; i += bytes_per_line) {
-    char* wptr = line.get();
-    wptr += sprintf(wptr, "%08zX: ", i);
-    for (size_t j = i; j < i + bytes_per_line && j < len; j++)
-      wptr += sprintf(wptr, "%02X ", static_cast<unsigned>(data[j]) & 0xFF);
-    for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
-      *(wptr++) = ' ';
-    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
-      char c = data[j];
-      *(wptr++) = (c >= 32 && c < 127) ? c : '.';
-    }
-    *(wptr++) = '\n';
-    *(wptr++) = '\0';
-    res.append(line.get());
-  }
-  return res;
-}
-
 }  // namespace base
 }  // namespace perfetto
diff --git a/src/base/test/utils.h b/src/base/test/utils.h
index 032194b..4dfc281 100644
--- a/src/base/test/utils.h
+++ b/src/base/test/utils.h
@@ -52,13 +52,6 @@
 
 std::string GetTestDataPath(const std::string& path);
 
-// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
-std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
-inline std::string HexDump(const std::string& data,
-                           size_t bytes_per_line = 16) {
-  return HexDump(data.data(), data.size(), bytes_per_line);
-}
-
 }  // namespace base
 }  // namespace perfetto
 
diff --git a/src/base/utils.cc b/src/base/utils.cc
index b5d3d3c..363a0d6 100644
--- a/src/base/utils.cc
+++ b/src/base/utils.cc
@@ -266,5 +266,28 @@
 #endif
 }
 
+std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
+  const char* data = reinterpret_cast<const char*>(data_void);
+  std::string res;
+  static const size_t kPadding = bytes_per_line * 3 + 12;
+  std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
+  for (size_t i = 0; i < len; i += bytes_per_line) {
+    char* wptr = line.get();
+    wptr += sprintf(wptr, "%08zX: ", i);
+    for (size_t j = i; j < i + bytes_per_line && j < len; j++)
+      wptr += sprintf(wptr, "%02X ", static_cast<unsigned>(data[j]) & 0xFF);
+    for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
+      *(wptr++) = ' ';
+    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
+      char c = data[j];
+      *(wptr++) = (c >= 32 && c < 127) ? c : '.';
+    }
+    *(wptr++) = '\n';
+    *(wptr++) = '\0';
+    res.append(line.get());
+  }
+  return res;
+}
+
 }  // namespace base
 }  // namespace perfetto
diff --git a/src/base/utils_unittest.cc b/src/base/utils_unittest.cc
index ef6e657..b75ec05 100644
--- a/src/base/utils_unittest.cc
+++ b/src/base/utils_unittest.cc
@@ -202,6 +202,19 @@
   EXPECT_EQ(0xffffff00u, AlignUp<16>(0xffffff00 - 1));
 }
 
+TEST(UtilsTest, HexDump) {
+  char input[] = {0x00, 0x00, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+                  'h',  'i',  'j', 'k', 'l', 'm', 'n', 'o', 'p'};
+
+  std::string output = HexDump(input, sizeof(input));
+
+  EXPECT_EQ(
+      output,
+      R"(00000000: 00 00 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E   ..abcdefghijklmn
+00000010: 6F 70                                             op
+)");
+}
+
 }  // namespace
 }  // namespace base
 }  // namespace perfetto
diff --git a/src/tracing/core/trace_buffer.cc b/src/tracing/core/trace_buffer.cc
index 4b72d42..acdcaa9 100644
--- a/src/tracing/core/trace_buffer.cc
+++ b/src/tracing/core/trace_buffer.cc
@@ -27,25 +27,6 @@
 #define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
 #if TRACE_BUFFER_VERBOSE_LOGGING()
 #define TRACE_BUFFER_DLOG PERFETTO_DLOG
-namespace {
-constexpr char kHexDigits[] = "0123456789abcdef";
-std::string HexDump(const uint8_t* src, size_t size) {
-  std::string buf;
-  buf.reserve(4096 * 4);
-  char line[64];
-  char* c = line;
-  for (size_t i = 0; i < size; i++) {
-    *c++ = kHexDigits[(src[i] >> 4) & 0x0f];
-    *c++ = kHexDigits[(src[i] >> 0) & 0x0f];
-    if (i % 16 == 15) {
-      buf.append("\n");
-      buf.append(line);
-      c = line;
-    }
-  }
-  return buf;
-}
-}  // namespace
 #else
 #define TRACE_BUFFER_DLOG(...) void()
 #endif
@@ -224,7 +205,8 @@
     TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr - begin(),
                       uintptr_t(wptr - begin()) + record_size, record_size);
     WriteChunkRecord(wptr, record, src, size);
-    TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr, record_size).c_str());
+    TRACE_BUFFER_DLOG("Chunk raw: %s",
+                      base::HexDump(wptr, record_size).c_str());
     stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
     return;
   }
@@ -281,7 +263,7 @@
   TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr_ - begin(),
                     uintptr_t(wptr_ - begin()) + record_size, record_size);
   WriteChunkRecord(wptr_, record, src, size);
-  TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr_, record_size).c_str());
+  TRACE_BUFFER_DLOG("Chunk raw: %s", base::HexDump(wptr_, record_size).c_str());
   wptr_ += record_size;
   if (wptr_ >= end()) {
     PERFETTO_DCHECK(padding_size == 0);
@@ -456,7 +438,7 @@
   }
   TRACE_BUFFER_DLOG(
       "Chunk raw (after patch): %s",
-      HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
+      base::HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
 
   stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
   if (!other_patches_pending) {