• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "utils/bit_memory_region-inl.h"
17 
18 #include <gtest/gtest.h>
19 #include <array>
20 
21 namespace panda::test {
22 
CompareData(uint8_t * data,size_t offset,size_t length,uint32_t value,uint8_t fill_value)23 static void CompareData(uint8_t *data, size_t offset, size_t length, uint32_t value, uint8_t fill_value)
24 {
25     for (size_t i = 0; i < length; i++) {
26         uint8_t expected = (offset <= i && i < offset + length) ? value >> (i - offset) : fill_value;
27         uint8_t actual = data[i / BITS_PER_BYTE] >> (i % BITS_PER_BYTE);
28         ASSERT_EQ(expected & 1, actual & 1);
29     }
30 }
31 
TEST(BitMemoryRegion,TestBitAccess)32 TEST(BitMemoryRegion, TestBitAccess)
33 {
34     std::array<uint8_t, 16> data;
35     static constexpr std::array<uint8_t, 2> fill_data = {0x00, 0xff};
36     static constexpr std::array<bool, 2> value_data = {false, true};
37     static constexpr size_t MAX_BITS_COUNT = (data.size() - sizeof(uint32_t)) * BITS_PER_BYTE;
38 
39     for (size_t offset = 0; offset < MAX_BITS_COUNT; offset++) {
40         uint32_t mask = 0;
41         for (auto fill_value : fill_data) {
42             for (auto value : value_data) {
43                 std::fill(data.begin(), data.end(), fill_value);
44                 BitMemoryRegion region1(data.data(), offset, 1);
45                 region1.Write(value, 0);
46                 ASSERT_EQ(region1.Read(0), value);
47                 CompareData(data.data(), offset, 1, value, fill_value);
48                 std::fill(data.begin(), data.end(), fill_value);
49                 BitMemoryRegion region2(data.data(), data.size() * BITS_PER_BYTE);
50                 region2.Write(value, offset);
51                 ASSERT_EQ(region2.Read(offset), value);
52                 CompareData(data.data(), offset, 1, value, fill_value);
53             }
54         }
55     }
56 }
57 
TEST(BitMemoryRegion,TestBitsAccess)58 TEST(BitMemoryRegion, TestBitsAccess)
59 {
60     std::array<uint8_t, 16> data;
61     static constexpr std::array<uint8_t, 2> fill_data = {0x00, 0xff};
62     static constexpr size_t MAX_BITS_COUNT = (data.size() - sizeof(uint32_t)) * BITS_PER_BYTE;
63 
64     for (size_t offset = 0; offset < MAX_BITS_COUNT; offset++) {
65         uint32_t mask = 0;
66         for (size_t length = 0; length < BITS_PER_UINT32; length++) {
67             const uint32_t value = 0xBADDCAFE & mask;
68             for (auto fill_value : fill_data) {
69                 std::fill(data.begin(), data.end(), fill_value);
70                 BitMemoryRegion region1(data.data(), offset, length);
71                 region1.Write(value, 0, length);
72                 ASSERT_EQ(region1.Read(0, length), value);
73                 CompareData(data.data(), offset, length, value, fill_value);
74                 std::fill(data.begin(), data.end(), fill_value);
75                 BitMemoryRegion region2(data.data(), data.size() * BITS_PER_BYTE);
76                 region2.Write(value, offset, length);
77                 ASSERT_EQ(region2.Read(offset, length), value);
78                 CompareData(data.data(), offset, length, value, fill_value);
79             }
80             mask = (mask << 1) | 1;
81         }
82     }
83 }
84 
TEST(BitMemoryRegion,Dumping)85 TEST(BitMemoryRegion, Dumping)
86 {
87     std::array<uint64_t, 4> data {};
88     std::stringstream ss;
89     auto clear = [&]() {
90         data.fill(0);
91         ss.str(std::string());
92     };
93 
94     {
95         clear();
96         BitMemoryRegion region(data.data(), 0, data.size() * BITS_PER_UINT64);
97         ss << region;
98         ASSERT_EQ(ss.str(), "0x0");
99     }
100 
101     {
102         clear();
103         data[0] = 0x5;
104         BitMemoryRegion region(data.data(), 0, 130);
105         ss << region;
106         ASSERT_EQ(ss.str(), "0x5");
107     }
108 
109     {
110         clear();
111         data[0] = 0x1;
112         data[1] = 0x2;
113         BitMemoryRegion region(data.data(), 1, 65);
114         ss << region;
115         ASSERT_EQ(ss.str(), "0x10000000000000000");
116     }
117 
118     {
119         clear();
120         data[0] = 0x1;
121         data[1] = 0x500;
122         BitMemoryRegion region(data.data(), 0, 129);
123         ss << region;
124         ASSERT_EQ(ss.str(), "0x5000000000000000001");
125     }
126 
127     {
128         clear();
129         data[0] = 0x1234560000000000;
130         data[1] = 0x4321;
131         BitMemoryRegion region(data.data(), 40, 40);
132         ss << region;
133         ASSERT_EQ(ss.str(), "0x4321123456");
134     }
135 
136     {
137         clear();
138         data[0] = 0x123456789abcdef0;
139         BitMemoryRegion region(data.data(), 2, 20);
140         ss << region;
141         ASSERT_EQ(ss.str(), "0xf37bc");
142     }
143 
144     {
145         clear();
146         data[0] = 0x123456789abcdef0;
147         data[1] = 0xfedcba9876543210;
148         BitMemoryRegion region(data.data(), 16, 96);
149         ss << region;
150         ASSERT_EQ(ss.str(), "0xba9876543210123456789abc");
151     }
152 
153     {
154         clear();
155         data[0] = 0x1111111111111111;
156         data[1] = 0x2222222222222222;
157         data[2] = 0x4444444444444444;
158         BitMemoryRegion region(data.data(), 31, 120);
159         ss << region;
160         ASSERT_EQ(ss.str(), "0x888888444444444444444422222222");
161     }
162 }
163 
164 }  // namespace panda::test
165