Messagelib

riceencodingdecoder.cpp
1 /*
2  SPDX-FileCopyrightText: 2016-2023 Laurent Montel <[email protected]>
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 
18 namespace
19 {
20 const int kBitsPerByte = 8;
21 const unsigned int kMaxBitIndex = kBitsPerByte * sizeof(uint32_t);
22 }
23 
24 using namespace WebEngineViewer;
25 RiceEncodingDecoder::RiceEncodingDecoder() = default;
26 
27 RiceEncodingDecoder::~RiceEncodingDecoder() = default;
28 
29 QVector<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 
68 QVector<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  QVector<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 
116 RiceDecoder::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 
126 RiceDecoder::~RiceDecoder() = default;
127 
128 bool RiceDecoder::hasOtherEntries() const
129 {
130  return mNumberEntries > 0;
131 }
132 
133 bool 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 
159 bool 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 
192 bool 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 
220 uint32_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 }
int count(const T &value) const const
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
void reserve(int alloc)
const T & at(int i) const const
void reserve(int size)
QList::iterator begin()
QList::iterator end()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Mar 24 2023 04:08:32 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.