1 /*
2 * Copyright (C) 2020 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/traced/probes/packages_list/packages_list_parser.h"
18
19 #include <stdlib.h>
20
21 #include "perfetto/ext/base/scoped_file.h"
22 #include "perfetto/ext/base/string_splitter.h"
23
24 namespace perfetto {
25
ReadPackagesListLine(char * line,Package * package)26 bool ReadPackagesListLine(char* line, Package* package) {
27 size_t idx = 0;
28 for (base::StringSplitter ss(line, ' '); ss.Next();) {
29 switch (idx) {
30 case 0:
31 package->name = std::string(ss.cur_token(), ss.cur_token_size());
32 break;
33 case 1: {
34 char* end;
35 long long uid = strtoll(ss.cur_token(), &end, 10);
36 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
37 PERFETTO_ELOG("Failed to parse packages.list uid.");
38 return false;
39 }
40 package->uid = static_cast<uint64_t>(uid);
41 break;
42 }
43 case 2: {
44 char* end;
45 long long debuggable = strtoll(ss.cur_token(), &end, 10);
46 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
47 PERFETTO_ELOG("Failed to parse packages.list debuggable.");
48 return false;
49 }
50 package->debuggable = debuggable != 0;
51 break;
52 }
53 case 6: {
54 char* end;
55 long long profilable_from_shell = strtoll(ss.cur_token(), &end, 10);
56 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
57 PERFETTO_ELOG("Failed to parse packages.list profilable_from_shell.");
58 return false;
59 }
60 package->profileable_from_shell = profilable_from_shell != 0;
61 break;
62 }
63 case 7: {
64 char* end;
65 long long version_code = strtoll(ss.cur_token(), &end, 10);
66 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
67 PERFETTO_ELOG("Failed to parse packages.list version_code: %s.",
68 ss.cur_token());
69 return false;
70 }
71 package->version_code = version_code;
72 break;
73 }
74 case 8: {
75 char* end;
76 long long profileable = strtoll(ss.cur_token(), &end, 10);
77 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
78 PERFETTO_ELOG("Failed to parse packages.list profileable.");
79 return false;
80 }
81 package->profileable = profileable != 0;
82 break;
83 }
84 case 9:
85 package->installed_by =
86 std::string(ss.cur_token(), ss.cur_token_size());
87 break;
88 }
89 ++idx;
90 }
91 return true;
92 }
93
94 } // namespace perfetto
95