File indexing completed on 2024-04-21 03:51:38

0001 /*
0002     This file is part of the KDE Baloo project.
0003     SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
0004     SPDX-FileCopyrightText: 2011 The LevelDB Authors. All rights reserved.
0005 
0006     SPDX-License-Identifier: LGPL-2.1-or-later AND BSD-3-Clause
0007 */
0008 
0009 #include "coding.h"
0010 
0011 namespace Baloo {
0012 
0013 static inline int encodeVarint32Internal(char* dst, quint32 v) {
0014     // Operate on characters as unsigneds
0015     unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
0016     static const int B = 128;
0017     if (v < (1<<7)) {
0018         ptr[0] = v;
0019         return 1;
0020     }
0021     if (v < (1<<14)) {
0022         ptr[0] = v | B;
0023         ptr[1] = v>>7;
0024         return 2;
0025     }
0026     if (v < (1<<21)) {
0027         ptr[0] = v | B;
0028         ptr[1] = (v>>7) | B;
0029         ptr[2] = v>>14;
0030         return 3;
0031     }
0032     if (v < (1<<28)) {
0033         ptr[0] = v | B;
0034         ptr[1] = (v>>7) | B;
0035         ptr[2] = (v>>14) | B;
0036         ptr[3] = v>>21;
0037         return 4;
0038     }
0039 
0040     ptr[0] = v | B;
0041     ptr[1] = (v>>7) | B;
0042     ptr[2] = (v>>14) | B;
0043     ptr[3] = (v>>21) | B;
0044     ptr[4] = v>>28;
0045     return 5;
0046 }
0047 
0048 static inline void putVarint32Internal(char* dst, quint32 v, int &pos)
0049 {
0050     pos += encodeVarint32Internal(&dst[pos], v);
0051 }
0052 
0053 void putDifferentialVarInt32(QByteArray &temporaryStorage, QByteArray* dst, const QVector<quint32>& values)
0054 {
0055     temporaryStorage.resize((values.size() + 1) * 5);  // max size, correct size will be held in pos
0056     int pos = 0;
0057     putVarint32Internal(temporaryStorage.data(), values.size(), pos);
0058 
0059     quint32 v = 0;
0060     const auto itEnd = values.cend();
0061     for (auto it = values.cbegin(); it != itEnd; ++it) {
0062         const quint32 n = *it;
0063         putVarint32Internal(temporaryStorage.data(), n - v, pos);
0064         v = n;
0065     }
0066     dst->append(temporaryStorage.constData(), pos);
0067 }
0068 
0069 char* getDifferentialVarInt32(char* p, char* limit, QVector<quint32>* values)
0070 {
0071     quint32 size = 0;
0072     p = getVarint32Ptr(p, limit, &size);
0073     values->resize(size);
0074 
0075     auto it = values->begin();
0076     auto end = values->end();
0077 
0078     quint32 v = 0;
0079     while (p && it != end) {
0080         quint32 n = 0;
0081         p = getVarint32Ptr(p, limit, &n);
0082 
0083         *it = (n + v);
0084         v += n;
0085         ++it;
0086     }
0087     values->erase(it, end);
0088 
0089     return p;
0090 }
0091 
0092 char* getVarint32PtrFallback(char* p, char* limit, quint32* value)
0093 {
0094     quint32 result = 0;
0095     for (quint32 shift = 0; shift <= 28 && p < limit; shift += 7) {
0096         quint32 byte = *(reinterpret_cast<const unsigned char*>(p));
0097         p++;
0098         if (byte & 128) {
0099             // More bytes are present
0100             result |= ((byte & 127) << shift);
0101         } else {
0102             result |= (byte << shift);
0103             *value = result;
0104             return p;
0105         }
0106     }
0107     return nullptr;
0108 }
0109 
0110 }