File indexing completed on 2024-06-23 05:13:12

0001 /*
0002     SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #ifndef KITINERARY_PLISTREADER_P_H
0007 #define KITINERARY_PLISTREADER_P_H
0008 
0009 #include <QByteArray>
0010 #include <QMetaType>
0011 
0012 #include <cstdint>
0013 #include <optional>
0014 #include <string_view>
0015 
0016 class QVariant;
0017 
0018 namespace KItinerary {
0019 
0020 class PListReader;
0021 struct PListTrailer;
0022 enum class PListObjectType;
0023 
0024 /** Property list UID object type. */
0025 struct PListUid
0026 {
0027 public:
0028     uint64_t value;
0029 };
0030 
0031 
0032 /** Property list array objects. */
0033 class PListArray
0034 {
0035 public:
0036     explicit PListArray();
0037     ~PListArray();
0038 
0039     uint64_t size() const;
0040     uint64_t value(uint64_t index) const;
0041     PListObjectType objectType(uint64_t index) const;
0042     PListObjectType objectType(PListUid uid) const;
0043     QVariant object(uint64_t index) const;
0044     QVariant object(PListUid uid) const;
0045 
0046 private:
0047     friend class PListReader;
0048     explicit PListArray(std::string_view data, const PListReader *reader);
0049     std::string_view m_data;
0050     const PListReader *m_reader = nullptr;
0051 };
0052 
0053 /** Property list dictionary objects. */
0054 class PListDict
0055 {
0056 public:
0057     explicit PListDict();
0058     ~PListDict();
0059 
0060     uint64_t size() const;
0061     uint64_t key(uint64_t index) const;
0062     uint64_t value(uint64_t index) const;
0063     std::optional<uint64_t> value(QLatin1StringView keyName) const;
0064     QVariant object(QLatin1StringView keyName) const;
0065 
0066   private:
0067     friend class PListReader;
0068     explicit PListDict(std::string_view data, const PListReader *reader);
0069     std::string_view m_data;
0070     const PListReader *m_reader = nullptr;
0071 };
0072 
0073 /**
0074  * Reading of Apple binary property list data.
0075  * @see https://en.wikipedia.org/wiki/Property_list
0076  */
0077 class PListReader
0078 {
0079 public:
0080     explicit PListReader(const QByteArray &data = {});
0081     ~PListReader();
0082 
0083     bool isValid() const;
0084 
0085     /** Number of objects in the property list. */
0086     uint64_t objectCount() const;
0087     /** Root object index. */
0088     uint64_t rootObjectIndex() const;
0089     /** Data type of the object at @p index. */
0090     PListObjectType objectType(uint64_t index) const;
0091     QVariant object(uint64_t index) const;
0092 
0093     /** Unpack NSKeyedArchiver data to JSON. */
0094     QJsonValue unpackKeyedArchive() const;
0095 
0096     /** Check whether the given data might be a binary property list. */
0097     static bool maybePList(const QByteArray &data);
0098 
0099 private:
0100     friend class PListArray;
0101     friend class PListDict;
0102 
0103     const PListTrailer* trailer() const;
0104     /** Offset into the data for object at @p index. */
0105     uint64_t objectOffset(uint64_t index) const;
0106     uint64_t readBigEndianNumber(uint64_t offset, int size) const;
0107     uint64_t readBigEndianInteger(uint64_t &offset) const;
0108     uint64_t readContainerSize(uint64_t &offset, uint8_t marker) const;
0109     std::string_view view(uint64_t offset, uint64_t size) const;
0110     uint64_t readObjectRef(std::string_view data, uint64_t index) const;
0111 
0112     QJsonValue unpackKeyedArchiveRecursive(PListUid uid, const PListArray &objects) const;
0113 
0114     QByteArray m_data;
0115 };
0116 
0117 }
0118 
0119 Q_DECLARE_METATYPE(KItinerary::PListUid)
0120 Q_DECLARE_METATYPE(KItinerary::PListArray)
0121 Q_DECLARE_METATYPE(KItinerary::PListDict)
0122 Q_DECLARE_METATYPE(KItinerary::PListReader)
0123 
0124 #endif // KITINERARY_PLISTREADER_P_H