1/* -*- C++ -*-
2 SPDX-FileCopyrightText: 1998 Netscape Communications Corporation <developer@mozilla.org>
3
4 SPDX-License-Identifier: MIT
5*/
6
7#ifndef nsPkgInt_h__
8#define nsPkgInt_h__
9
10#include <array>
11#include <concepts>
12#include <cstdint>
13
14namespace kencodingprober
15{
16typedef enum {
17 eIdxSft4bits = 3,
18 eIdxSft8bits = 2,
19 eIdxSft16bits = 1,
20} nsIdxSft;
21
22typedef enum {
23 eSftMsk4bits = 7,
24 eSftMsk8bits = 3,
25 eSftMsk16bits = 1,
26} nsSftMsk;
27
28typedef enum {
29 eBitSft4bits = 2,
30 eBitSft8bits = 3,
31 eBitSft16bits = 4,
32} nsBitSft;
33
34typedef enum {
35 eUnitMsk4bits = 0x0000000FL,
36 eUnitMsk8bits = 0x000000FFL,
37 eUnitMsk16bits = 0x0000FFFFL,
38} nsUnitMsk;
39
40typedef struct nsPkgInt {
41 nsIdxSft idxsft;
42 nsSftMsk sftmsk;
43 nsBitSft bitsft;
44 nsUnitMsk unitmsk;
45 const unsigned int *data;
46} nsPkgInt;
47}
48
49constexpr auto PCKXBITS(std::convertible_to<uint8_t> auto... il)
50{
51 constexpr auto N = sizeof...(il);
52 std::array<uint32_t, N / 8> val = {0};
53
54 int pos = 0;
55 for (auto i : {uint8_t(il)...}) {
56 val[pos / 8] |= (i << (4 * (pos % 8)));
57 pos++;
58 }
59 return val;
60}
61static_assert(PCKXBITS(il: 0, il: 0, il: 0, il: 0, il: 0, il: 0, il: 0, il: 0) == std::array<uint32_t, 1>{0x00000000});
62static_assert(PCKXBITS(il: 0, il: 0, il: 0, il: 0, il: 0, il: 0, il: 0, il: 1) == std::array<uint32_t, 1>{0x10000000});
63static_assert(PCKXBITS(il: 1, il: 0, il: 0, il: 0, il: 0, il: 0, il: 0, il: 0) == std::array<uint32_t, 1>{0x00000001});
64static_assert(PCKXBITS(il: 1, il: 2, il: 3, il: 4, il: 5, il: 6, il: 7, il: 8) == std::array<uint32_t, 1>{0x87654321});
65static_assert(PCKXBITS(il: 8, il: 7, il: 6, il: 5, il: 4, il: 3, il: 2, il: 1) == std::array<uint32_t, 1>{0x12345678});
66
67constexpr unsigned int GETFROMPCK(int index, const kencodingprober::nsPkgInt &table)
68{
69 const auto high = index >> table.idxsft;
70 const auto low = (index & table.sftmsk) << table.bitsft;
71
72 uint32_t data = table.data[high] >> low;
73 return data & table.unitmsk;
74}
75
76namespace
77{
78using namespace kencodingprober;
79constexpr std::array data{
80 // clang-format off
81 PCKXBITS(il: 1, il: 2, il: 3, il: 4, il: 5, il: 6, il: 7, il: 8,
82 il: 15, il: 14, il: 13, il: 12, il: 11, il: 10, il: 9, il: 8),
83 // clang-format on
84};
85constexpr nsPkgInt table{.idxsft: eIdxSft4bits, .sftmsk: eSftMsk4bits, .bitsft: eBitSft4bits, .unitmsk: eUnitMsk4bits, .data: data.data()};
86
87static_assert(GETFROMPCK(index: 0, table) == 1);
88static_assert(GETFROMPCK(index: 9, table) == 14);
89static_assert(GETFROMPCK(index: 15, table) == 8);
90}
91
92#endif /* nsPkgInt_h__ */
93

source code of kcodecs/src/probers/nsPkgInt.h