1 // Copyright 2021 The PDFium 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 "core/fxcrt/mask.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 namespace fxcrt {
10 namespace {
11
12 enum class Privilege : uint8_t {
13 kPriv1 = 1 << 0,
14 kPriv2 = 1 << 1,
15 kPriv4 = 1 << 2,
16 kPriv8 = 1 << 3,
17 kPriv16 = 1 << 4,
18 kPriv32 = 1 << 5,
19 kPriv64 = 1 << 6,
20 kPriv128 = 1 << 7,
21 };
22
23 constexpr Mask<Privilege> kAllMask = {
24 Privilege::kPriv1, Privilege::kPriv2, Privilege::kPriv4,
25 Privilege::kPriv8, Privilege::kPriv16, Privilege::kPriv32,
26 Privilege::kPriv64, Privilege::kPriv128,
27 };
28
29 } // namespace
30
31 static_assert(sizeof(Mask<Privilege>) == sizeof(Privilege),
32 "Mask size must be the same as enum");
33
TEST(Mask,Empty)34 TEST(Mask, Empty) {
35 constexpr Mask<Privilege> privs;
36 EXPECT_EQ(0u, privs.UncheckedValue());
37 EXPECT_FALSE(privs & Privilege::kPriv1);
38 EXPECT_FALSE(privs & Privilege::kPriv4);
39 EXPECT_FALSE(privs & Privilege::kPriv8);
40 EXPECT_FALSE(privs & kAllMask);
41 }
42
TEST(Mask,FromOne)43 TEST(Mask, FromOne) {
44 Mask<Privilege> privs = Privilege::kPriv1;
45 EXPECT_EQ(1u, privs.UncheckedValue());
46 EXPECT_TRUE(privs & Privilege::kPriv1);
47 EXPECT_FALSE(privs & Privilege::kPriv4);
48 EXPECT_FALSE(privs & Privilege::kPriv8);
49 EXPECT_TRUE(privs & kAllMask);
50 }
51
TEST(Mask,FromTwo)52 TEST(Mask, FromTwo) {
53 // Not adjacent bits, just because.
54 Mask<Privilege> privs = {Privilege::kPriv1, Privilege::kPriv8};
55 EXPECT_EQ(9u, privs.UncheckedValue());
56 EXPECT_TRUE(privs & Privilege::kPriv1);
57 EXPECT_FALSE(privs & Privilege::kPriv4);
58 EXPECT_TRUE(privs & Privilege::kPriv8);
59 EXPECT_TRUE(privs & kAllMask);
60 }
61
TEST(Mask,FromThree)62 TEST(Mask, FromThree) {
63 Mask<Privilege> privs = {
64 Privilege::kPriv1,
65 Privilege::kPriv2,
66 Privilege::kPriv4,
67 };
68 EXPECT_EQ(7u, privs.UncheckedValue());
69 }
70
TEST(Mask,FromFour)71 TEST(Mask, FromFour) {
72 Mask<Privilege> privs = {
73 Privilege::kPriv1,
74 Privilege::kPriv2,
75 Privilege::kPriv4,
76 Privilege::kPriv8,
77 };
78 EXPECT_EQ(15u, privs.UncheckedValue());
79 }
80
TEST(Mask,FromFive)81 TEST(Mask, FromFive) {
82 Mask<Privilege> privs = {
83 Privilege::kPriv1, Privilege::kPriv2, Privilege::kPriv4,
84 Privilege::kPriv8, Privilege::kPriv16,
85 };
86 EXPECT_EQ(31u, privs.UncheckedValue());
87 }
88
TEST(Mask,FromSix)89 TEST(Mask, FromSix) {
90 Mask<Privilege> privs = {
91 Privilege::kPriv1, Privilege::kPriv2, Privilege::kPriv4,
92 Privilege::kPriv8, Privilege::kPriv16, Privilege::kPriv32,
93 };
94 EXPECT_EQ(63u, privs.UncheckedValue());
95 }
96
TEST(Mask,FromSeven)97 TEST(Mask, FromSeven) {
98 Mask<Privilege> privs = {
99 Privilege::kPriv1, Privilege::kPriv2, Privilege::kPriv4,
100 Privilege::kPriv8, Privilege::kPriv16, Privilege::kPriv32,
101 Privilege::kPriv64,
102 };
103 EXPECT_EQ(127u, privs.UncheckedValue());
104 }
105
TEST(Mask,FromEight)106 TEST(Mask, FromEight) {
107 Mask<Privilege> privs = {
108 Privilege::kPriv1, Privilege::kPriv2, Privilege::kPriv4,
109 Privilege::kPriv8, Privilege::kPriv16, Privilege::kPriv32,
110 Privilege::kPriv64, Privilege::kPriv128,
111 };
112 EXPECT_EQ(255u, privs.UncheckedValue());
113 }
114
TEST(Mask,FromUnderlying)115 TEST(Mask, FromUnderlying) {
116 auto privs = Mask<Privilege>::FromUnderlyingUnchecked(5);
117 EXPECT_EQ(5u, privs.UncheckedValue());
118 EXPECT_TRUE(privs & Privilege::kPriv1);
119 EXPECT_TRUE(privs & Privilege::kPriv4);
120 EXPECT_FALSE(privs & Privilege::kPriv8);
121 }
122
TEST(Mask,AssignAndEQ)123 TEST(Mask, AssignAndEQ) {
124 Mask<Privilege> source = {Privilege::kPriv1, Privilege::kPriv8};
125 Mask<Privilege> other = Privilege::kPriv1;
126 Mask<Privilege> dest;
127 dest = source;
128 EXPECT_EQ(9u, dest.UncheckedValue());
129 EXPECT_EQ(source, dest);
130 EXPECT_NE(other, dest);
131 }
132
TEST(Mask,OrAndAnd)133 TEST(Mask, OrAndAnd) {
134 Mask<Privilege> source = {Privilege::kPriv1, Privilege::kPriv8};
135 Mask<Privilege> or_result =
136 source | Mask<Privilege>{Privilege::kPriv1, Privilege::kPriv4};
137 Mask<Privilege> and_result =
138 source & Mask<Privilege>{Privilege::kPriv1, Privilege::kPriv4};
139 EXPECT_EQ(13u, or_result.UncheckedValue());
140 EXPECT_EQ(1u, and_result.UncheckedValue());
141 }
142
TEST(Mask,OrEqualsAndAndEquals)143 TEST(Mask, OrEqualsAndAndEquals) {
144 Mask<Privilege> source_or = {Privilege::kPriv1, Privilege::kPriv8};
145 Mask<Privilege> source_and = {Privilege::kPriv1, Privilege::kPriv8};
146 source_or |= {Privilege::kPriv1, Privilege::kPriv4};
147 source_and &= {Privilege::kPriv1, Privilege::kPriv4};
148 EXPECT_EQ(13u, source_or.UncheckedValue());
149 EXPECT_EQ(1u, source_and.UncheckedValue());
150 }
151
TEST(Mask,Clear)152 TEST(Mask, Clear) {
153 Mask<Privilege> source = kAllMask;
154 source.Clear({Privilege::kPriv1, Privilege::kPriv4});
155 EXPECT_EQ(250u, source.UncheckedValue());
156 }
157
TEST(Mask,TestAll)158 TEST(Mask, TestAll) {
159 Mask<Privilege> source = {
160 Privilege::kPriv1,
161 Privilege::kPriv8,
162 Privilege::kPriv64,
163 };
164 Mask<Privilege> passes = {Privilege::kPriv1, Privilege::kPriv64};
165 Mask<Privilege> fails = {Privilege::kPriv1, Privilege::kPriv32};
166 EXPECT_TRUE(source.TestAll(passes));
167 EXPECT_FALSE(source.TestAll(fails));
168 }
169
170 } // namespace fxcrt
171