1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "src/trace_processor/util/build_id.h" 18 19 #include <cctype> 20 #include <cstddef> 21 #include <string> 22 23 #include "perfetto/base/logging.h" 24 #include "perfetto/ext/base/string_utils.h" 25 #include "perfetto/ext/base/string_view.h" 26 27 namespace perfetto { 28 namespace trace_processor { 29 namespace { HexToBinary(char c)30uint8_t HexToBinary(char c) { 31 switch (c) { 32 case '0': 33 return 0; 34 case '1': 35 return 1; 36 case '2': 37 return 2; 38 case '3': 39 return 3; 40 case '4': 41 return 4; 42 case '5': 43 return 5; 44 case '6': 45 return 6; 46 case '7': 47 return 7; 48 case '8': 49 return 8; 50 case '9': 51 return 9; 52 case 'a': 53 case 'A': 54 return 10; 55 case 'b': 56 case 'B': 57 return 11; 58 case 'c': 59 case 'C': 60 return 12; 61 case 'd': 62 case 'D': 63 return 13; 64 case 'e': 65 case 'E': 66 return 14; 67 case 'f': 68 case 'F': 69 return 15; 70 default: 71 PERFETTO_CHECK(false); 72 } 73 } 74 HexToBinary(base::StringView hex)75std::string HexToBinary(base::StringView hex) { 76 std::string res; 77 res.reserve((hex.size() + 1) / 2); 78 auto it = hex.begin(); 79 80 if (hex.size() % 2 != 0) { 81 res.push_back(static_cast<char>(HexToBinary(*it))); 82 ++it; 83 } 84 85 while (it != hex.end()) { 86 if (*it == '-') { 87 ++it; 88 continue; 89 } 90 int v = (HexToBinary(*it++) << 4); 91 v += HexToBinary(*it++); 92 res.push_back(static_cast<char>(v)); 93 } 94 return res; 95 } 96 97 // Returns whether this string is of a hex chrome module or not to decide 98 // whether to convert the module to/from hex. 99 // TODO(b/148109467): Remove workaround once all active Chrome versions 100 // write raw bytes instead of a string as build_id. IsHexModuleId(base::StringView module)101bool IsHexModuleId(base::StringView module) { 102 return module.size() == 33; 103 } 104 105 } // namespace 106 107 // static FromHex(base::StringView data)108BuildId BuildId::FromHex(base::StringView data) { 109 if (IsHexModuleId(data)) { 110 return BuildId(data.ToStdString()); 111 } 112 return BuildId(HexToBinary(data)); 113 } 114 ToHex() const115std::string BuildId::ToHex() const { 116 if (IsHexModuleId(base::StringView(raw_))) { 117 return raw_; 118 } 119 return base::ToHex(raw_.data(), raw_.size()); 120 } 121 122 } // namespace trace_processor 123 } // namespace perfetto 124