// Copyright (c) 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h" #include "net/third_party/quiche/src/common/platform/api/quiche_logging.h" #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" #include namespace { std::string HexDumpWithMarks(const char* data, int length, const bool* marks, int mark_length) { static const char kHexChars[] = "0123456789abcdef"; static const int kColumns = 4; const int kSizeLimit = 1024; if (length > kSizeLimit || mark_length > kSizeLimit) { QUICHE_LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; length = std::min(length, kSizeLimit); mark_length = std::min(mark_length, kSizeLimit); } std::string hex; for (const char* row = data; length > 0; row += kColumns, length -= kColumns) { for (const char* p = row; p < row + 4; ++p) { if (p < row + length) { const bool mark = (marks && (p - data) < mark_length && marks[p - data]); hex += mark ? '*' : ' '; hex += kHexChars[(*p & 0xf0) >> 4]; hex += kHexChars[*p & 0x0f]; hex += mark ? '*' : ' '; } else { hex += " "; } } hex = hex + " "; for (const char* p = row; p < row + 4 && p < row + length; ++p) { hex += (*p >= 0x20 && *p < 0x7f) ? (*p) : '.'; } hex = hex + '\n'; } return hex; } } // namespace namespace quiche { namespace test { void CompareCharArraysWithHexError(const std::string& description, const char* actual, const int actual_len, const char* expected, const int expected_len) { EXPECT_EQ(actual_len, expected_len); const int min_len = std::min(actual_len, expected_len); const int max_len = std::max(actual_len, expected_len); std::unique_ptr marks(new bool[max_len]); bool identical = (actual_len == expected_len); for (int i = 0; i < min_len; ++i) { if (actual[i] != expected[i]) { marks[i] = true; identical = false; } else { marks[i] = false; } } for (int i = min_len; i < max_len; ++i) { marks[i] = true; } if (identical) return; ADD_FAILURE() << "Description:\n" << description << "\n\nExpected:\n" << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) << "\nActual:\n" << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); } } // namespace test } // namespace quiche