{
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
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
#include "SquidTime.h"
#include "util.h"
+#include <algorithm>
+
/* for shutting_down flag in xassert() */
#include "globals.h"
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
{
(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;