• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)30 uint8_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)75 std::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     int v = (HexToBinary(*it++) << 4);
87     v += HexToBinary(*it++);
88     res.push_back(static_cast<char>(v));
89   }
90   return res;
91 }
92 
93 // Returns whether this string is of a hex chrome module or not to decide
94 // whether to convert the module to/from hex.
95 // TODO(b/148109467): Remove workaround once all active Chrome versions
96 // write raw bytes instead of a string as build_id.
IsHexModuleId(base::StringView module)97 bool IsHexModuleId(base::StringView module) {
98   return module.size() == 33;
99 }
100 
101 }  // namespace
102 
103 // static
FromHex(base::StringView data)104 BuildId BuildId::FromHex(base::StringView data) {
105   if (IsHexModuleId(data)) {
106     return BuildId(data.ToStdString());
107   }
108   return BuildId(HexToBinary(data));
109 }
110 
ToHex() const111 std::string BuildId::ToHex() const {
112   if (IsHexModuleId(base::StringView(raw_))) {
113     return raw_;
114   }
115   return base::ToHex(raw_.data(), raw_.size());
116 }
117 
118 }  // namespace trace_processor
119 }  // namespace perfetto
120