1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#include "utils/leb128.h"
17b1994897Sopenharmony_ci
18b1994897Sopenharmony_ci#include <gmock/gmock.h>
19b1994897Sopenharmony_ci#include <gtest/gtest.h>
20b1994897Sopenharmony_ci
21b1994897Sopenharmony_cinamespace panda::leb128::test {
22b1994897Sopenharmony_ci
23b1994897Sopenharmony_citemplate <class T>
24b1994897Sopenharmony_cistruct TestData {
25b1994897Sopenharmony_ci    T value;
26b1994897Sopenharmony_ci    size_t size;
27b1994897Sopenharmony_ci    uint8_t data[10];
28b1994897Sopenharmony_ci};
29b1994897Sopenharmony_ci
30b1994897Sopenharmony_ci// clang-format off
31b1994897Sopenharmony_ci
32b1994897Sopenharmony_cistatic std::vector<TestData<uint64_t>> unsigned_test_data {
33b1994897Sopenharmony_ci    {0x00,                1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
34b1994897Sopenharmony_ci    {0x7f,                1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
35b1994897Sopenharmony_ci    {0xff,                2, {0xff, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
36b1994897Sopenharmony_ci    {0x2d7f,              2, {0xff, 0x5a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
37b1994897Sopenharmony_ci    {0xffff,              3, {0xff, 0xff, 0x03, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
38b1994897Sopenharmony_ci    {0x192d7f,            3, {0xff, 0xda, 0x64, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
39b1994897Sopenharmony_ci    {0x1592d7f,           4, {0xff, 0xda, 0xe4, 0x0a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
40b1994897Sopenharmony_ci    {0x11592d7f,          5, {0xff, 0xda, 0xe4, 0x8a, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80}},
41b1994897Sopenharmony_ci    {0xffffffff,          5, {0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x80}},
42b1994897Sopenharmony_ci    {0x1011592d7f,        6, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x02, 0x80, 0x80, 0x80, 0x80}},
43b1994897Sopenharmony_ci    {0xc1011592d7f,       7, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x82, 0x03, 0x80, 0x80, 0x80}},
44b1994897Sopenharmony_ci    {0x80c1011592d7f,     8, {0xff, 0xda, 0xe4, 0x8a, 0x81, 0x82, 0x83, 0x04, 0x80, 0x80}},
45b1994897Sopenharmony_ci    {0xffffffffffffffff, 10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}}
46b1994897Sopenharmony_ci};
47b1994897Sopenharmony_ci
48b1994897Sopenharmony_cistatic std::vector<TestData<uint64_t>> unsigned_partial_decoding_test_data {
49b1994897Sopenharmony_ci    {0xffffffffffffffff, 10, {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03}},
50b1994897Sopenharmony_ci};
51b1994897Sopenharmony_ci
52b1994897Sopenharmony_cistatic std::vector<TestData<int8_t>> signed_test_data8 {
53b1994897Sopenharmony_ci    {0x00,                      1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
54b1994897Sopenharmony_ci    {0x01,                      1, {0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
55b1994897Sopenharmony_ci    {-1,                        1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
56b1994897Sopenharmony_ci    {0x40,                      2, {0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
57b1994897Sopenharmony_ci    {static_cast<int8_t>(0x80), 2, {0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
58b1994897Sopenharmony_ci    {-0x40,                     1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
59b1994897Sopenharmony_ci};
60b1994897Sopenharmony_ci
61b1994897Sopenharmony_cistatic std::vector<TestData<int16_t>> signed_test_data16 {
62b1994897Sopenharmony_ci    {0x00,                         1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
63b1994897Sopenharmony_ci    {0x0102,                       2, {0x82, 0x02, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
64b1994897Sopenharmony_ci    {-1,                           1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
65b1994897Sopenharmony_ci    {-0x40,                        1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
66b1994897Sopenharmony_ci    {static_cast<int16_t>(0x8000), 3, {0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
67b1994897Sopenharmony_ci    {static_cast<int16_t>(0x4001), 3, {0x81, 0x80, 0x01, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
68b1994897Sopenharmony_ci};
69b1994897Sopenharmony_ci
70b1994897Sopenharmony_cistatic std::vector<TestData<int32_t>> signed_test_data32 {
71b1994897Sopenharmony_ci    {0x00,                             1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
72b1994897Sopenharmony_ci    {0x01020304,                       4, {0x84, 0x86, 0x88, 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
73b1994897Sopenharmony_ci    {-1,                               1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
74b1994897Sopenharmony_ci    {-0x40,                            1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
75b1994897Sopenharmony_ci    {static_cast<int32_t>(0x80000000), 5, {0x80, 0x80, 0x80, 0x80, 0x78, 0x80, 0x80, 0x80, 0x80, 0x80}},
76b1994897Sopenharmony_ci    {static_cast<int32_t>(0x40000001), 5, {0x81, 0x80, 0x80, 0x80, 0x04, 0x80, 0x80, 0x80, 0x80, 0x80}}
77b1994897Sopenharmony_ci};
78b1994897Sopenharmony_ci
79b1994897Sopenharmony_cistatic std::vector<TestData<int64_t>> signed_test_data64 {
80b1994897Sopenharmony_ci    {0x00,                                      1, {0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
81b1994897Sopenharmony_ci    {0x40,                                      2, {0xc0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
82b1994897Sopenharmony_ci    {0x7f,                                      2, {0xff, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
83b1994897Sopenharmony_ci    {-1,                                        1, {0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
84b1994897Sopenharmony_ci    {static_cast<int64_t>(0x8000000000000000), 10, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f}},
85b1994897Sopenharmony_ci    {0x7000000000000001,                       10, {0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf0, 0x00}},
86b1994897Sopenharmony_ci    {0x100000000000000,                         9, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x00}},
87b1994897Sopenharmony_ci    {-0x40,                                     1, {0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}},
88b1994897Sopenharmony_ci    {-0x1122,                                   2, {0xde, 0x5d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}}
89b1994897Sopenharmony_ci};
90b1994897Sopenharmony_ci
91b1994897Sopenharmony_cistatic std::vector<TestData<int8_t>> signed_partial_decoding_test_data8 {
92b1994897Sopenharmony_ci    {1, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
93b1994897Sopenharmony_ci};
94b1994897Sopenharmony_ci
95b1994897Sopenharmony_cistatic std::vector<TestData<int16_t>> signed_partial_decoding_test_data16 {
96b1994897Sopenharmony_ci    {-0x3eff, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
97b1994897Sopenharmony_ci};
98b1994897Sopenharmony_ci
99b1994897Sopenharmony_cistatic std::vector<TestData<int32_t>> signed_partial_decoding_test_data32 {
100b1994897Sopenharmony_ci    {0x5080c101, 10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}}
101b1994897Sopenharmony_ci};
102b1994897Sopenharmony_ci
103b1994897Sopenharmony_cistatic std::vector<TestData<int64_t>> signed_partial_decoding_test_data64 {
104b1994897Sopenharmony_ci    {0x9101c305080c101,                        10, {0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a}},
105b1994897Sopenharmony_ci    {static_cast<int64_t>(0x8000000000000000), 10, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x5f}}
106b1994897Sopenharmony_ci};
107b1994897Sopenharmony_ci
108b1994897Sopenharmony_ci// clang-format on
109b1994897Sopenharmony_ci
110b1994897Sopenharmony_citemplate <class T>
111b1994897Sopenharmony_cistatic void TestDecodeUnsigned(const std::vector<TestData<uint64_t>> &data, bool is_partial = false)
112b1994897Sopenharmony_ci{
113b1994897Sopenharmony_ci    for (auto &t : data) {
114b1994897Sopenharmony_ci        std::ostringstream ss;
115b1994897Sopenharmony_ci        ss << "Test unsigned decoding ";
116b1994897Sopenharmony_ci        ss << std::hex << t.value;
117b1994897Sopenharmony_ci        ss << " with sizeof(T) = ";
118b1994897Sopenharmony_ci        ss << sizeof(T);
119b1994897Sopenharmony_ci
120b1994897Sopenharmony_ci        constexpr size_t bitwidth = std::numeric_limits<T>::digits;
121b1994897Sopenharmony_ci
122b1994897Sopenharmony_ci        auto [value, size, is_full] = DecodeUnsigned<T>(t.data);
123b1994897Sopenharmony_ci        EXPECT_EQ(is_full, MinimumBitsToStore(t.value) <= bitwidth && !is_partial) << ss.str();
124b1994897Sopenharmony_ci        EXPECT_EQ(size, is_full ? t.size : (bitwidth + 6) / 7) << ss.str();
125b1994897Sopenharmony_ci        EXPECT_EQ(value, static_cast<T>(t.value)) << ss.str();
126b1994897Sopenharmony_ci    }
127b1994897Sopenharmony_ci}
128b1994897Sopenharmony_ci
129b1994897Sopenharmony_ciTEST(Leb128, DecodeUnsigned)
130b1994897Sopenharmony_ci{
131b1994897Sopenharmony_ci    TestDecodeUnsigned<uint8_t>(unsigned_test_data);
132b1994897Sopenharmony_ci    TestDecodeUnsigned<uint16_t>(unsigned_test_data);
133b1994897Sopenharmony_ci    TestDecodeUnsigned<uint32_t>(unsigned_test_data);
134b1994897Sopenharmony_ci    TestDecodeUnsigned<uint64_t>(unsigned_test_data);
135b1994897Sopenharmony_ci    TestDecodeUnsigned<uint64_t>(unsigned_partial_decoding_test_data, true);
136b1994897Sopenharmony_ci}
137b1994897Sopenharmony_ci
138b1994897Sopenharmony_citemplate <class T>
139b1994897Sopenharmony_cistatic void TestDecodeSigned(const std::vector<TestData<T>> &data, bool is_partial = false)
140b1994897Sopenharmony_ci{
141b1994897Sopenharmony_ci    for (auto &t : data) {
142b1994897Sopenharmony_ci        std::ostringstream ss;
143b1994897Sopenharmony_ci        ss << "Test signed decoding ";
144b1994897Sopenharmony_ci        ss << std::hex << static_cast<int64_t>(t.value);
145b1994897Sopenharmony_ci        ss << " with sizeof(T) = ";
146b1994897Sopenharmony_ci        ss << sizeof(T);
147b1994897Sopenharmony_ci
148b1994897Sopenharmony_ci        constexpr size_t bitwidth = std::numeric_limits<std::make_unsigned_t<T>>::digits;
149b1994897Sopenharmony_ci
150b1994897Sopenharmony_ci        auto [value, size, is_full] = DecodeSigned<T>(t.data);
151b1994897Sopenharmony_ci        EXPECT_EQ(is_full, !is_partial) << ss.str();
152b1994897Sopenharmony_ci        EXPECT_EQ(size, is_full ? t.size : (bitwidth + 6) / 7) << ss.str();
153b1994897Sopenharmony_ci        EXPECT_EQ(value, t.value) << ss.str();
154b1994897Sopenharmony_ci    }
155b1994897Sopenharmony_ci}
156b1994897Sopenharmony_ci
157b1994897Sopenharmony_ciTEST(Leb128, DecodeSigned)
158b1994897Sopenharmony_ci{
159b1994897Sopenharmony_ci    TestDecodeSigned(signed_test_data8);
160b1994897Sopenharmony_ci    TestDecodeSigned(signed_test_data16);
161b1994897Sopenharmony_ci    TestDecodeSigned(signed_test_data32);
162b1994897Sopenharmony_ci    TestDecodeSigned(signed_test_data64);
163b1994897Sopenharmony_ci
164b1994897Sopenharmony_ci    TestDecodeSigned(signed_partial_decoding_test_data8, true);
165b1994897Sopenharmony_ci    TestDecodeSigned(signed_partial_decoding_test_data16, true);
166b1994897Sopenharmony_ci    TestDecodeSigned(signed_partial_decoding_test_data32, true);
167b1994897Sopenharmony_ci    TestDecodeSigned(signed_partial_decoding_test_data64, true);
168b1994897Sopenharmony_ci}
169b1994897Sopenharmony_ci
170b1994897Sopenharmony_ciTEST(Leb128, EncodeUnsigned)
171b1994897Sopenharmony_ci{
172b1994897Sopenharmony_ci    for (auto &t : unsigned_test_data) {
173b1994897Sopenharmony_ci        std::ostringstream ss;
174b1994897Sopenharmony_ci        ss << "Test unsigned encoding ";
175b1994897Sopenharmony_ci        ss << std::hex << t.value;
176b1994897Sopenharmony_ci
177b1994897Sopenharmony_ci        std::vector<uint8_t> data(t.size);
178b1994897Sopenharmony_ci        size_t n = EncodeUnsigned(t.value, data.data());
179b1994897Sopenharmony_ci        EXPECT_EQ(n, t.size) << ss.str();
180b1994897Sopenharmony_ci        EXPECT_EQ(UnsignedEncodingSize(t.value), t.size) << ss.str();
181b1994897Sopenharmony_ci        EXPECT_THAT(data, ::testing::ElementsAreArray(t.data, t.size)) << ss.str();
182b1994897Sopenharmony_ci    }
183b1994897Sopenharmony_ci}
184b1994897Sopenharmony_ci
185b1994897Sopenharmony_citemplate <class T>
186b1994897Sopenharmony_civoid TestEncodeSigned(const std::vector<TestData<T>> &data_vec)
187b1994897Sopenharmony_ci{
188b1994897Sopenharmony_ci    for (auto &t : data_vec) {
189b1994897Sopenharmony_ci        std::ostringstream ss;
190b1994897Sopenharmony_ci        ss << "Test signed encoding ";
191b1994897Sopenharmony_ci        ss << std::hex << static_cast<int64_t>(t.value);
192b1994897Sopenharmony_ci
193b1994897Sopenharmony_ci        std::vector<uint8_t> data(t.size);
194b1994897Sopenharmony_ci        size_t n = EncodeSigned(t.value, data.data());
195b1994897Sopenharmony_ci        EXPECT_EQ(n, t.size) << ss.str();
196b1994897Sopenharmony_ci        EXPECT_EQ(SignedEncodingSize(t.value), t.size) << ss.str();
197b1994897Sopenharmony_ci        EXPECT_THAT(data, ::testing::ElementsAreArray(t.data, t.size)) << ss.str();
198b1994897Sopenharmony_ci    }
199b1994897Sopenharmony_ci}
200b1994897Sopenharmony_ci
201b1994897Sopenharmony_ciTEST(Leb128, EncodeSigned)
202b1994897Sopenharmony_ci{
203b1994897Sopenharmony_ci    TestEncodeSigned(signed_test_data8);
204b1994897Sopenharmony_ci    TestEncodeSigned(signed_test_data16);
205b1994897Sopenharmony_ci    TestEncodeSigned(signed_test_data32);
206b1994897Sopenharmony_ci    TestEncodeSigned(signed_test_data64);
207b1994897Sopenharmony_ci}
208b1994897Sopenharmony_ci
209b1994897Sopenharmony_ci}  // namespace panda::leb128::test
210