1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/spdy/spdy_test_utils.h" 6 7#include <cstring> 8#include <vector> 9 10#include "base/logging.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/strings/string_number_conversions.h" 13#include "base/sys_byteorder.h" 14#include "testing/gtest/include/gtest/gtest.h" 15 16namespace net { 17 18namespace test { 19 20std::string HexDumpWithMarks(const unsigned char* data, int length, 21 const bool* marks, int mark_length) { 22 static const char kHexChars[] = "0123456789abcdef"; 23 static const int kColumns = 4; 24 25 const int kSizeLimit = 1024; 26 if (length > kSizeLimit || mark_length > kSizeLimit) { 27 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; 28 length = std::min(length, kSizeLimit); 29 mark_length = std::min(mark_length, kSizeLimit); 30 } 31 32 std::string hex; 33 for (const unsigned char* row = data; length > 0; 34 row += kColumns, length -= kColumns) { 35 for (const unsigned char *p = row; p < row + 4; ++p) { 36 if (p < row + length) { 37 const bool mark = 38 (marks && (p - data) < mark_length && marks[p - data]); 39 hex += mark ? '*' : ' '; 40 hex += kHexChars[(*p & 0xf0) >> 4]; 41 hex += kHexChars[*p & 0x0f]; 42 hex += mark ? '*' : ' '; 43 } else { 44 hex += " "; 45 } 46 } 47 hex = hex + " "; 48 49 for (const unsigned char *p = row; p < row + 4 && p < row + length; ++p) 50 hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.'; 51 52 hex = hex + '\n'; 53 } 54 return hex; 55} 56 57void CompareCharArraysWithHexError( 58 const std::string& description, 59 const unsigned char* actual, 60 const int actual_len, 61 const unsigned char* expected, 62 const int expected_len) { 63 const int min_len = std::min(actual_len, expected_len); 64 const int max_len = std::max(actual_len, expected_len); 65 scoped_ptr<bool[]> marks(new bool[max_len]); 66 bool identical = (actual_len == expected_len); 67 for (int i = 0; i < min_len; ++i) { 68 if (actual[i] != expected[i]) { 69 marks[i] = true; 70 identical = false; 71 } else { 72 marks[i] = false; 73 } 74 } 75 for (int i = min_len; i < max_len; ++i) { 76 marks[i] = true; 77 } 78 if (identical) return; 79 ADD_FAILURE() 80 << "Description:\n" 81 << description 82 << "\n\nExpected:\n" 83 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) 84 << "\nActual:\n" 85 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); 86} 87 88void SetFrameFlags(SpdyFrame* frame, 89 uint8 flags, 90 SpdyMajorVersion spdy_version) { 91 switch (spdy_version) { 92 case SPDY2: 93 case SPDY3: 94 frame->data()[4] = flags; 95 break; 96 case SPDY4: 97 case SPDY5: 98 frame->data()[3] = flags; 99 break; 100 default: 101 LOG(FATAL) << "Unsupported SPDY version."; 102 } 103} 104 105void SetFrameLength(SpdyFrame* frame, 106 size_t length, 107 SpdyMajorVersion spdy_version) { 108 switch (spdy_version) { 109 case SPDY2: 110 case SPDY3: 111 CHECK_EQ(0u, length & ~kLengthMask); 112 { 113 int32 wire_length = base::HostToNet32(length); 114 // The length field in SPDY 2 and 3 is a 24-bit (3B) integer starting at 115 // offset 5. 116 memcpy(frame->data() + 5, reinterpret_cast<char*>(&wire_length) + 1, 3); 117 } 118 break; 119 case SPDY4: 120 case SPDY5: 121 CHECK_GT(1u<<14, length); 122 { 123 int32 wire_length = base::HostToNet16(static_cast<uint16>(length)); 124 memcpy(frame->data(), 125 reinterpret_cast<char*>(&wire_length), 126 sizeof(uint16)); 127 } 128 break; 129 default: 130 LOG(FATAL) << "Unsupported SPDY version."; 131 } 132} 133 134std::string a2b_hex(const char* hex_data) { 135 std::vector<uint8> output; 136 std::string result; 137 if (base::HexStringToBytes(hex_data, &output)) 138 result.assign(reinterpret_cast<const char*>(&output[0]), output.size()); 139 return result; 140} 141 142} // namespace test 143 144} // namespace net 145