Make the hex dump more generally useful (specifically in CHECKs).

Change-Id: I78a79f64abc70496e4575f753c44c939a3cbf5fd
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index fb2264a..e8f9e61 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -1667,11 +1667,8 @@
     }
   }
   if (i == arraysize(gHandlerMap)) {
-    LOG(ERROR) << DescribeCommand(pHeader, dataLen);
-    if (dataLen > 0) {
-      HexDump(buf, dataLen);
-    }
-    LOG(ERROR) << "command not implemented";
+    LOG(ERROR) << "Command not implemented: " << DescribeCommand(pHeader, dataLen);
+    LOG(ERROR) << HexDump(buf, dataLen);
     result = ERR_NOT_IMPLEMENTED;
   }
 
@@ -1693,9 +1690,7 @@
   size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
   if (false) {
     LOG(INFO) << "reply: dataLen=" << respLen << " err=" << result << (result != ERR_NONE ? " **FAILED**" : "");
-    if (respLen > 0) {
-      HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
-    }
+    LOG(INFO) << HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
   }
 
   /*
diff --git a/src/jdwp/jdwp_socket.cc b/src/jdwp/jdwp_socket.cc
index d3677e8..88af4ac 100644
--- a/src/jdwp/jdwp_socket.cc
+++ b/src/jdwp/jdwp_socket.cc
@@ -544,10 +544,8 @@
   dataLen = length - (buf - packetBuf);
 
   VLOG(jdwp) << StringPrintf("--- %s: dataLen=%u id=0x%08x flags=0x%02x cmd=%d/%d",
-      reply ? "reply" : "req", dataLen, id, flags, cmdSet, cmd);
-  if (dataLen > 0) {
-    HexDump(buf, dataLen);
-  }
+                             reply ? "reply" : "req", dataLen, id, flags, cmdSet, cmd);
+  VLOG(jdwp) << HexDump(buf, dataLen);
 }
 #endif
 
diff --git a/src/logging.cc b/src/logging.cc
index 813fa9a..f962e41 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -65,20 +65,21 @@
   return data_->buffer;
 }
 
-/*
- * Print a hex dump in this format:
- *
- * 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
- *
- * Does not use printf() or other string-formatting calls.
- */
-void HexDump(const void* address, size_t byte_count, bool show_actual_address) {
+HexDump::HexDump(const void* address, size_t byte_count, bool show_actual_addresses)
+    : address_(address), byte_count_(byte_count), show_actual_addresses_(show_actual_addresses) {
+}
+
+void HexDump::Dump(std::ostream& os) const {
+  if (byte_count_ == 0) {
+    return;
+  }
+
   static const char gHexDigit[] = "0123456789abcdef";
-  const unsigned char* addr = reinterpret_cast<const unsigned char*>(address);
+  const unsigned char* addr = reinterpret_cast<const unsigned char*>(address_);
   char out[76];           /* exact fit */
   unsigned int offset;    /* offset to show while printing */
 
-  if (show_actual_address) {
+  if (show_actual_addresses_) {
     offset = reinterpret_cast<int>(addr);
   } else {
     offset = 0;
@@ -87,6 +88,7 @@
   out[8] = ':';
   out[sizeof(out)-1] = '\0';
 
+  size_t byte_count = byte_count_;
   int gap = static_cast<int>(offset & 0x0f);
   while (byte_count) {
     unsigned int lineOffset = offset & ~0x0f;
@@ -131,7 +133,7 @@
       *asc++ = ' ';
     }
 
-    LOG(INFO) << out;
+    os << out;
 
     gap = 0;
     byte_count -= count;
@@ -139,4 +141,9 @@
   }
 }
 
+std::ostream& operator<<(std::ostream& os, const HexDump& rhs) {
+  rhs.Dump(os);
+  return os;
+}
+
 }  // namespace art
diff --git a/src/logging.h b/src/logging.h
index d421552..df6afce 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -198,7 +198,22 @@
   DISALLOW_COPY_AND_ASSIGN(LogMessage);
 };
 
-void HexDump(const void* address, size_t byte_count, bool show_actual_address = false);
+// Prints a hex dump in this format:
+//
+// 01234560: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
+// 01234568: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
+class HexDump {
+ public:
+  HexDump(const void* address, size_t byte_count, bool show_actual_addresses = false);
+  void Dump(std::ostream& os) const;
+
+ private:
+  const void* address_;
+  size_t byte_count_;
+  bool show_actual_addresses_;
+  DISALLOW_COPY_AND_ASSIGN(HexDump);
+};
+std::ostream& operator<<(std::ostream& os, const HexDump& rhs);
 
 // A convenience to allow any class with a "Dump(std::ostream& os)" member function
 // but without an operator<< to be used as if it had an operator<<. Use like this: