File indexing completed on 2025-02-16 04:58:21

0001 /*
0002  * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
0003  * Copyright (C) 2018 RĂ©mi Nicole <minijackson@riseup.net>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Lesser General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2.1 of the License, or (at your option) version 3, or any
0009  * later version accepted by the membership of KDE e.V. (or its
0010  * successor approved by the membership of KDE e.V.), which shall
0011  * act as a proxy defined in Section 6 of version 3 of the license.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Lesser General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Lesser General Public
0019  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020  */
0021 
0022 #include "key.h"
0023 
0024 #include "common/utils.h"
0025 
0026 using Sink::Storage::Identifier;
0027 using Sink::Storage::Key;
0028 using Sink::Storage::Revision;
0029 
0030 
0031 uint Sink::Storage::qHash(const Sink::Storage::Identifier &identifier)
0032 {
0033     return qHash(identifier.toInternalByteArray());
0034 }
0035 
0036 QDebug &operator<<(QDebug &dbg, const Identifier &id)
0037 {
0038     dbg << id.toDisplayString();
0039     return dbg;
0040 }
0041 
0042 QDebug &operator<<(QDebug &dbg, const Revision &rev)
0043 {
0044     dbg << rev.toDisplayString();
0045     return dbg;
0046 }
0047 
0048 QDebug &operator<<(QDebug &dbg, const Key &key)
0049 {
0050     dbg << key.toDisplayString();
0051     return dbg;
0052 }
0053 
0054 // Identifier
0055 
0056 Identifier Identifier::createIdentifier()
0057 {
0058     return Identifier(QUuid::createUuid());
0059 }
0060 
0061 QByteArray Identifier::toInternalByteArray() const
0062 {
0063     Q_ASSERT(!uid.isNull());
0064     return uid.toRfc4122();
0065 }
0066 
0067 Identifier Identifier::fromInternalByteArray(const QByteArray &bytes)
0068 {
0069     Q_ASSERT(bytes.size() == INTERNAL_REPR_SIZE);
0070     return Identifier(QUuid::fromRfc4122(bytes));
0071 }
0072 
0073 QString Identifier::toDisplayString() const
0074 {
0075     return uid.toString();
0076 }
0077 
0078 QByteArray Identifier::toDisplayByteArray() const
0079 {
0080     return uid.toByteArray();
0081 }
0082 
0083 Identifier Identifier::fromDisplayByteArray(const QByteArray &bytes)
0084 {
0085     Q_ASSERT(bytes.size() == DISPLAY_REPR_SIZE);
0086     return Identifier(QUuid(bytes));
0087 }
0088 
0089 bool Identifier::isNull() const
0090 {
0091     return uid.isNull();
0092 }
0093 
0094 bool Identifier::isValidInternal(const QByteArray &bytes)
0095 {
0096     return !QUuid::fromRfc4122(bytes).isNull();
0097 }
0098 
0099 bool Identifier::isValidDisplay(const QByteArray &bytes)
0100 {
0101     return !QUuid(bytes).isNull();
0102 }
0103 
0104 bool Identifier::isValid(const QByteArray &bytes)
0105 {
0106     switch (bytes.size()) {
0107         case Identifier::INTERNAL_REPR_SIZE:
0108             return isValidInternal(bytes);
0109         case Identifier::DISPLAY_REPR_SIZE:
0110             return isValidDisplay(bytes);
0111     }
0112     return false;
0113 }
0114 
0115 bool Identifier::operator==(const Identifier &other) const
0116 {
0117     return uid == other.uid;
0118 }
0119 
0120 bool Identifier::operator!=(const Identifier &other) const
0121 {
0122     return !(*this == other);
0123 }
0124 
0125 // Revision
0126 
0127 QByteArray Revision::toInternalByteArray() const
0128 {
0129     return Sink::sizeTToByteArray(rev);
0130 }
0131 
0132 Revision Revision::fromInternalByteArray(const QByteArray &bytes)
0133 {
0134     Q_ASSERT(bytes.size() == INTERNAL_REPR_SIZE);
0135     return Revision(Sink::byteArrayToSizeT(bytes));
0136 }
0137 
0138 QString Revision::toDisplayString() const
0139 {
0140     return QString::fromUtf8(Sink::padNumber(rev));
0141 }
0142 
0143 QByteArray Revision::toDisplayByteArray() const
0144 {
0145     return Sink::padNumber(rev);
0146 }
0147 
0148 Revision Revision::fromDisplayByteArray(const QByteArray &bytes)
0149 {
0150     Q_ASSERT(bytes.size() == DISPLAY_REPR_SIZE);
0151     return Revision(bytes.toLongLong());
0152 }
0153 
0154 qint64 Revision::toQint64() const
0155 {
0156     return rev;
0157 }
0158 
0159 size_t Revision::toSizeT() const
0160 {
0161     return rev;
0162 }
0163 
0164 bool Revision::isValidInternal(const QByteArray &bytes)
0165 {
0166     if (bytes.size() != Revision::INTERNAL_REPR_SIZE) {
0167         return false;
0168     }
0169     return true;
0170 }
0171 
0172 bool Revision::isValidDisplay(const QByteArray &bytes)
0173 {
0174     if (bytes.size() != Revision::DISPLAY_REPR_SIZE) {
0175         return false;
0176     }
0177     bool ok;
0178     bytes.toLongLong(&ok);
0179     return ok;
0180 }
0181 
0182 bool Revision::isValid(const QByteArray &bytes)
0183 {
0184     return isValidInternal(bytes);
0185 }
0186 
0187 bool Revision::operator==(const Revision &other) const
0188 {
0189     return rev == other.rev;
0190 }
0191 
0192 bool Revision::operator!=(const Revision &other) const
0193 {
0194     return !(*this == other);
0195 }
0196 
0197 // Key
0198 
0199 QByteArray Key::toInternalByteArray() const
0200 {
0201     return id.toInternalByteArray() + rev.toInternalByteArray();
0202 }
0203 
0204 Key Key::fromInternalByteArray(const QByteArray &bytes)
0205 {
0206     Q_ASSERT(bytes.size() == INTERNAL_REPR_SIZE);
0207     auto idBytes = bytes.mid(0, Identifier::INTERNAL_REPR_SIZE);
0208     auto revBytes = bytes.mid(Identifier::INTERNAL_REPR_SIZE);
0209     return Key(Identifier::fromInternalByteArray(idBytes), Revision::fromInternalByteArray(revBytes));
0210 }
0211 
0212 QString Key::toDisplayString() const
0213 {
0214     return id.toDisplayString() + rev.toDisplayString();
0215 }
0216 
0217 QByteArray Key::toDisplayByteArray() const
0218 {
0219     return id.toDisplayByteArray() + rev.toDisplayByteArray();
0220 }
0221 
0222 Key Key::fromDisplayByteArray(const QByteArray &bytes)
0223 {
0224     Q_ASSERT(bytes.size() == DISPLAY_REPR_SIZE);
0225     auto idBytes = bytes.mid(0, Identifier::DISPLAY_REPR_SIZE);
0226     auto revBytes = bytes.mid(Identifier::DISPLAY_REPR_SIZE);
0227     return Key(Identifier::fromDisplayByteArray(idBytes), Revision::fromDisplayByteArray(revBytes));
0228 }
0229 
0230 const Identifier &Key::identifier() const
0231 {
0232     return id;
0233 }
0234 
0235 const Revision &Key::revision() const
0236 {
0237     return rev;
0238 }
0239 
0240 void Key::setRevision(const Revision &newRev)
0241 {
0242     rev = newRev;
0243 }
0244 
0245 bool Key::isNull() const
0246 {
0247     return id.isNull();
0248 }
0249 
0250 bool Key::isValidInternal(const QByteArray &bytes)
0251 {
0252     if (bytes.size() != Key::INTERNAL_REPR_SIZE) {
0253         return false;
0254     }
0255 
0256     auto idBytes = bytes.mid(0, Identifier::INTERNAL_REPR_SIZE);
0257     auto revBytes = bytes.mid(Identifier::INTERNAL_REPR_SIZE);
0258     return Identifier::isValidInternal(idBytes) && Revision::isValidInternal(revBytes);
0259 }
0260 
0261 bool Key::isValidDisplay(const QByteArray &bytes)
0262 {
0263     if (bytes.size() != Key::DISPLAY_REPR_SIZE) {
0264         return false;
0265     }
0266 
0267     auto idBytes = bytes.mid(0, Identifier::DISPLAY_REPR_SIZE);
0268     auto revBytes = bytes.mid(Identifier::DISPLAY_REPR_SIZE);
0269     return Key::isValidDisplay(idBytes) && Revision::isValidDisplay(revBytes);
0270 }
0271 
0272 bool Key::isValid(const QByteArray &bytes)
0273 {
0274     switch (bytes.size()) {
0275         case Key::INTERNAL_REPR_SIZE:
0276             return isValidInternal(bytes);
0277         case Key::DISPLAY_REPR_SIZE:
0278             return isValidDisplay(bytes);
0279     }
0280     return false;
0281 }
0282 
0283 bool Key::operator==(const Key &other) const
0284 {
0285     return (id == other.id) && (rev == other.rev);
0286 }
0287 
0288 bool Key::operator!=(const Key &other) const
0289 {
0290     return !(*this == other);
0291 }