Messagelib

riceencodingdecoder.cpp
1/*
2 SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
3
4 Code based in v4_rice.cc
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "riceencodingdecoder.h"
10#include "webengineviewer_debug.h"
11
12#ifdef WIN32
13#include <Winsock2.h>
14#else
15#include <netinet/in.h>
16#endif
17
18namespace
19{
20const int kBitsPerByte = 8;
21const unsigned int kMaxBitIndex = kBitsPerByte * sizeof(uint32_t);
22}
23
24using namespace WebEngineViewer;
25RiceEncodingDecoder::RiceEncodingDecoder() = default;
26
27RiceEncodingDecoder::~RiceEncodingDecoder() = default;
28
29QList<quint32> RiceEncodingDecoder::decodeRiceIndiceDelta(const RiceDeltaEncoding &riceDeltaEncoding)
30{
31 bool ok;
33 if (riceDeltaEncoding.firstValue.isEmpty()) {
34 return list;
35 }
36 quint64 firstValue = riceDeltaEncoding.firstValue.toInt(&ok);
37 if (!ok) {
38 qCWarning(WEBENGINEVIEWER_LOG) << "First value is not a int value " << riceDeltaEncoding.firstValue;
39 return {};
40 }
41 list.reserve(riceDeltaEncoding.numberEntries + 1);
42 list << firstValue;
43 if (riceDeltaEncoding.numberEntries == 0) {
44 return list;
45 }
46
47 RiceDecoder decoder(riceDeltaEncoding.riceParameter, riceDeltaEncoding.numberEntries, riceDeltaEncoding.encodingData);
48 int lastValue(firstValue);
49 while (decoder.hasOtherEntries()) {
50 quint32 offset;
51 bool result = decoder.nextValue(&offset);
52 if (!result) {
53 return {};
54 }
55 lastValue += offset;
56#if 0
57
58 if (!last_value.IsValid()) {
59 return false;
60 }
61#endif
62
63 list << lastValue;
64 }
65 return list;
66}
67
68QList<quint32> RiceEncodingDecoder::decodeRiceHashesDelta(const RiceDeltaEncoding &riceDeltaEncoding)
69{
71 bool ok = false;
72 quint64 firstValue = riceDeltaEncoding.firstValue.toInt(&ok);
73 if (!ok) {
74 qCWarning(WEBENGINEVIEWER_LOG) << "First value is not a int value " << riceDeltaEncoding.firstValue;
75 return list;
76 }
77
78 list.reserve(riceDeltaEncoding.numberEntries + 1);
79 RiceDecoder decoder(riceDeltaEncoding.riceParameter, riceDeltaEncoding.numberEntries, riceDeltaEncoding.encodingData);
80 int lastValue(firstValue);
81 list << htonl(lastValue);
82
83 while (decoder.hasOtherEntries()) {
84 quint32 offset;
85 bool result = decoder.nextValue(&offset);
86 if (!result) {
87 return {};
88 }
89
90 lastValue += offset;
91#if 0
92 if (!last_value) {
93 return false;
94 }
95#endif
96 // This flipping is done so that the decoded uint32 is interpreted
97 // correctly as a string of 4 bytes.
98 list << htonl(lastValue);
99 }
100
101 // Flipping the bytes, as done above, destroys the sort order. Sort the
102 // values back.
103 std::sort(list.begin(), list.end());
104
105 // This flipping is done so that when the vector is interpreted as a string,
106 // the bytes are in the correct order.
107 QList<quint32> newList;
108 newList.reserve(list.count());
109 const int listCount(list.count());
110 for (int i = 0; i < listCount; ++i) {
111 newList << ntohl(list.at(i));
112 }
113 return newList;
114}
115
116RiceDecoder::RiceDecoder(int riceParameter, int numberEntries, const QByteArray &encodingData)
117 : mEncodingData(encodingData)
118 , mRiceParameter(riceParameter)
119 , mNumberEntries(numberEntries)
120 , mCurrentWord(0)
121{
122 mDataByteIndex = 0;
123 mCurrentWordBitIndex = kMaxBitIndex;
124}
125
126RiceDecoder::~RiceDecoder() = default;
127
128bool RiceDecoder::hasOtherEntries() const
129{
130 return mNumberEntries > 0;
131}
132
133bool RiceDecoder::nextValue(uint32_t *value)
134{
135 if (!hasOtherEntries()) {
136 return false;
137 }
138 bool result;
139 uint32_t q = 0;
140 uint32_t bit;
141 do {
142 result = nextBits(1, &bit);
143 if (!result) {
144 return false;
145 }
146 q += bit;
147 } while (bit);
148 uint32_t r = 0;
149 result = nextBits(mRiceParameter, &r);
150 if (!result) {
151 return false;
152 }
153
154 *value = (q << mRiceParameter) + r;
155 mNumberEntries--;
156 return true;
157}
158
159bool RiceDecoder::nextBits(unsigned int numRequestedBits, uint32_t *x)
160{
161 if (numRequestedBits > kMaxBitIndex) {
162 return false;
163 }
164 if (mCurrentWordBitIndex == kMaxBitIndex) {
165 bool result = nextWord(&mCurrentWord);
166 if (!result) {
167 return false;
168 }
169 }
170 unsigned int num_bits_left_in_current_word = kMaxBitIndex - mCurrentWordBitIndex;
171 if (num_bits_left_in_current_word >= numRequestedBits) {
172 // All the bits that we need are in |mCurrentWord|.
173 *x = bitsFromCurrentWord(numRequestedBits);
174 } else {
175 // |mCurrentWord| contains fewer bits than we need so read the remaining
176 // bits from |mCurrentWord| into |lower|, and then call nextBits on the
177 // remaining number of bits, which will read in a new word into
178 // |mCurrentWord|.
179 uint32_t lower = bitsFromCurrentWord(num_bits_left_in_current_word);
180
181 unsigned int num_bits_from_next_word = numRequestedBits - num_bits_left_in_current_word;
182 uint32_t upper;
183 bool result = nextBits(num_bits_from_next_word, &upper);
184 if (!result) {
185 return false;
186 }
187 *x = (upper << num_bits_left_in_current_word) | lower;
188 }
189 return true;
190}
191
192bool RiceDecoder::nextWord(uint32_t *word)
193{
194 if (mDataByteIndex >= mEncodingData.size()) {
195 return false;
196 }
197
198 const size_t mask = 0xFF;
199 *word = (mEncodingData[mDataByteIndex] & mask);
200 mDataByteIndex++;
201 mCurrentWordBitIndex = 0;
202
203 if (mDataByteIndex < mEncodingData.size()) {
204 *word |= ((mEncodingData[mDataByteIndex] & mask) << 8);
205 mDataByteIndex++;
206
207 if (mDataByteIndex < mEncodingData.size()) {
208 *word |= ((mEncodingData[mDataByteIndex] & mask) << 16);
209 mDataByteIndex++;
210
211 if (mDataByteIndex < mEncodingData.size()) {
212 *word |= ((mEncodingData[mDataByteIndex] & mask) << 24);
213 mDataByteIndex++;
214 }
215 }
216 }
217 return true;
218}
219
220uint32_t RiceDecoder::bitsFromCurrentWord(unsigned int numRequestedBits)
221{
222 uint32_t mask = 0xFFFFFFFF >> (kMaxBitIndex - numRequestedBits);
223 uint32_t x = mCurrentWord & mask;
224 mCurrentWord = mCurrentWord >> numRequestedBits;
225 mCurrentWordBitIndex += numRequestedBits;
226 return x;
227}
KIOCORE_EXPORT QStringList list(const QString &fileClass)
bool isEmpty() const const
qsizetype size() const const
int toInt(bool *ok, int base) const const
const_reference at(qsizetype i) const const
iterator begin()
qsizetype count() const const
iterator end()
void reserve(qsizetype size)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 21 2024 11:54:55 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.