File indexing completed on 2024-11-24 04:45:06
0001 /* 0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "kitinerary_export.h" 0010 0011 #include <QByteArray> 0012 0013 #include <cstdint> 0014 0015 class QIODevice; 0016 0017 namespace KItinerary { 0018 0019 /** BER/DER/X.690 encoding classes and functions. */ 0020 namespace BER { 0021 0022 /** 0023 * An element in BER/DER/X.690 encoding. 0024 * Implicitly this is also kinda implementing a QByteArrayRef, as this works without copying 0025 * the underlying data. 0026 */ 0027 class KITINERARY_EXPORT Element 0028 { 0029 public: 0030 Element(); 0031 explicit Element(const QByteArray &data, int offset = 0, int size = -1); 0032 ~Element(); 0033 0034 /** Returns @c true if this element has a valid structure and can be read from. */ 0035 bool isValid() const; 0036 0037 /** Type, "right-aligned" in the returned 32bit value. */ 0038 uint32_t type() const; 0039 0040 /** Size of the entire element (type, size and content). */ 0041 int size() const; 0042 /** Raw data of this element. 0043 * Typically only needed when copying/writing this element somewhere. 0044 */ 0045 const char* rawData() const; 0046 0047 /** Size of the value part of this element. 0048 * This is excluding a possible variable length end marker. 0049 */ 0050 int contentSize() const; 0051 /** Raw content data. */ 0052 const uint8_t* contentData() const; 0053 0054 /** Convenience method to access typed content. */ 0055 template <typename T> 0056 inline const T* contentAt(int offset = 0) const 0057 { 0058 if (offset < 0 || (int)sizeof(T) > contentSize() - offset) { 0059 return nullptr; 0060 } 0061 return reinterpret_cast<const T*>(contentData() + offset); 0062 } 0063 0064 /** First child element, for nested types. */ 0065 Element first() const; 0066 /** Next child element, for nested types. */ 0067 Element next() const; 0068 /** Returns the first child element of the given @p type. */ 0069 Element find(uint32_t type) const; 0070 0071 /** Writes the given size in BER encoding to @p out. */ 0072 static void writeSize(QIODevice *out, int size); 0073 0074 private: 0075 int typeSize() const; 0076 int lengthSize() const; 0077 int contentOffset() const; 0078 0079 QByteArray m_data; 0080 int m_offset = -1; 0081 int m_dataSize = -1; 0082 }; 0083 0084 template <uint32_t TagValue> 0085 class TypedElement : public Element 0086 { 0087 public: 0088 using Element::Element; 0089 inline bool isValid() const 0090 { 0091 return Element::isValid() && type() == TagValue; 0092 } 0093 }; 0094 0095 } 0096 } 0097