1 // Copyright 2024 The Chromium Authors
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/base/load_flags_to_string.h"
6
7 #include <bit>
8 #include <string>
9 #include <string_view>
10 #include <type_traits>
11 #include <vector>
12
13 #include "base/check_op.h"
14 #include "base/strings/strcat.h"
15 #include "base/strings/string_util.h"
16 #include "net/base/load_flags.h"
17
18 namespace net {
19
20 namespace {
21
22 struct LoadFlagInfo {
23 std::string_view name;
24 int value;
25 };
26
27 constexpr LoadFlagInfo kInfo[] = {
28
29 #define LOAD_FLAG(label, value) {#label, value},
30 #include "net/base/load_flags_list.h"
31 #undef LOAD_FLAG
32
33 };
34
AddLoadPrefix(std::string_view suffix)35 std::string AddLoadPrefix(std::string_view suffix) {
36 return base::StrCat({"LOAD_", suffix});
37 }
38
39 } // namespace
40
LoadFlagsToString(int load_flags)41 std::string LoadFlagsToString(int load_flags) {
42 if (load_flags == 0) {
43 static_assert(std::size(kInfo) > 0, "The kInfo array must be non-empty");
44 static_assert(kInfo[0].value == 0, "The first entry should be LOAD_NORMAL");
45 return AddLoadPrefix(kInfo[0].name);
46 }
47
48 const size_t expected_size =
49 static_cast<size_t>(std::popcount(static_cast<uint32_t>(load_flags)));
50 CHECK_GT(expected_size, 0u);
51 CHECK_LE(expected_size, 33u);
52 std::vector<std::string_view> flag_names;
53 flag_names.reserve(expected_size);
54 // Skip the first entry in kInfo as including LOAD_NORMAL in the output would
55 // be confusing.
56 for (const auto& flag : base::span(kInfo).subspan<1>()) {
57 if (load_flags & flag.value) {
58 flag_names.push_back(flag.name);
59 }
60 }
61 CHECK_EQ(expected_size, flag_names.size());
62
63 return AddLoadPrefix(base::JoinString(flag_names, " | LOAD_"));
64 }
65
66 } // namespace net
67