]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Support dumping raw data in hex. Suitable for decoding with xxd -r -p.
authorAlex Rousskov <rousskov@measurement-factory.com>
Thu, 29 Oct 2015 05:43:10 +0000 (23:43 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Thu, 29 Oct 2015 05:43:10 +0000 (23:43 -0600)
src/Debug.h
src/debug.cc

index bb083a7b21ee0dfdd2291148db1c55eb8c98513e..94a6fc3552507687c990e95d0186762e9c403a2f 100644 (file)
@@ -159,11 +159,14 @@ class Raw
 {
 public:
     Raw(const char *label, const char *data, const size_t size):
-        level(-1), label_(label), data_(data), size_(size) {}
+        level(-1), label_(label), data_(data), size_(size), useHex_(false) {}
 
     /// limit data printing to at least the given debugging level
     Raw &minLevel(const int aLevel) { level = aLevel; return *this; }
 
+    /// print data using two hex digits per byte (decoder: xxd -r -p)
+    Raw &hex() { useHex_ = true; return *this; }
+
     /// If debugging is prohibited by the current debugs() or section level,
     /// prints nothing. Otherwise, dumps data using one of these formats:
     ///   " label[size]=data" if label was set and data size is positive
@@ -178,9 +181,12 @@ public:
     int level;
 
 private:
+    void printHex(std::ostream &os) const;
+
     const char *label_; ///< optional data name or ID; triggers size printing
     const char *data_; ///< raw data to be printed
     size_t size_; ///< data length
+    bool useHex_; ///< whether hex() has been called
 };
 
 inline
index 92b7f4b4a5a9f04564bde348dfac941bd68132b6..1f9392a3604f72ab2372ccf2a845170418773bf2 100644 (file)
@@ -14,6 +14,8 @@
 #include "SquidTime.h"
 #include "util.h"
 
+#include <algorithm>
+
 /* for shutting_down flag in xassert() */
 #include "globals.h"
 
@@ -793,6 +795,19 @@ SkipBuildPrefix(const char* path)
     return path+BuildPrefixLength;
 }
 
+/// print data bytes using hex notation
+void
+Raw::printHex(std::ostream &os) const
+{
+    const auto savedFill = os.fill('0');
+    const auto savedFlags = os.flags(); // std::ios_base::fmtflags
+    os << std::hex;
+    std::for_each(data_, data_ + size_,
+        [&os](const char &c) { os << std::setw(2) << static_cast<uint8_t>(c); });
+    os.flags(savedFlags);
+    os.fill(savedFill);
+}
+
 std::ostream &
 Raw::print(std::ostream &os) const
 {
@@ -807,10 +822,14 @@ Raw::print(std::ostream &os) const
                            (size_ > 40 ? DBG_DATA : Debug::sectionLevel);
     if (finalLevel <= Debug::sectionLevel) {
         os << (label_ ? '=' : ' ');
-        if (data_)
-            os.write(data_, size_);
-        else
+        if (data_) {
+            if (useHex_)
+                printHex(os);
+            else
+                os.write(data_, size_);
+        } else {
             os << "[null]";
+        }
     }
 
     return os;