File indexing completed on 2024-03-24 16:53:06
0001 /* -*- c++ -*- 0002 kmime_header_parsing.h 0003 0004 KMime, the KDE Internet mail/usenet news message library. 0005 SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 #include "kmime_export.h" 0013 #include "kmime_types.h" 0014 0015 #include <QString> 0016 #include <QPair> 0017 0018 #include <QDateTime> 0019 0020 template <typename K, typename V> class QMap; 0021 #include <QStringList> 0022 0023 namespace KMime 0024 { 0025 0026 namespace Headers 0027 { 0028 class Base; 0029 } 0030 0031 namespace Types 0032 { 0033 0034 } // namespace KMime::Types 0035 0036 namespace HeaderParsing 0037 { 0038 0039 /** 0040 Parses the encoded word. 0041 0042 @param scursor pointer to the first character beyond the initial '=' of 0043 the input string. 0044 @param send pointer to end of input buffer. 0045 @param result the decoded string the encoded work represented. 0046 @param language The language parameter according to RFC 2231, section 5. 0047 @param usedCS the used charset is returned here 0048 @param defaultCS the charset to use in case the detected 0049 one isn't known to us. 0050 0051 @return true if the input string was successfully decode; false otherwise. 0052 */ 0053 [[nodiscard]] KMIME_EXPORT bool 0054 parseEncodedWord(const char *&scursor, const char *const send, QString &result, 0055 QByteArray &language, QByteArray &usedCS, 0056 const QByteArray &defaultCS = QByteArray()); 0057 0058 // 0059 // The parsing squad: 0060 // 0061 0062 /** You may or may not have already started parsing into the 0063 atom. This function will go on where you left off. 0064 */ 0065 [[nodiscard]] KMIME_EXPORT bool parseAtom(const char *&scursor, 0066 const char *const send, 0067 QByteArray &result, 0068 bool allow8Bit = false); 0069 0070 /** 0071 * More efficient overload, to avoid a copy of the substring 0072 */ 0073 [[nodiscard]] KMIME_EXPORT bool parseAtom(const char *&scursor, 0074 const char *const send, 0075 QPair<const char *, int> &result, 0076 bool allow8Bit = false); 0077 0078 enum ParseTokenFlag { 0079 ParseTokenNoFlag = 0, 0080 ParseTokenAllow8Bit = 1, 0081 ParseTokenRelaxedTText = 2 0082 }; 0083 Q_DECLARE_FLAGS(ParseTokenFlags, ParseTokenFlag) 0084 0085 /** You may or may not have already started parsing into the 0086 token. This function will go on where you left off. */ 0087 [[nodiscard]] KMIME_EXPORT bool 0088 parseToken(const char *&scursor, const char *const send, QByteArray &result, 0089 ParseTokenFlags flags = ParseTokenNoFlag); 0090 0091 [[nodiscard]] KMIME_EXPORT bool 0092 parseToken(const char *&scursor, const char *const send, 0093 QPair<const char *, int> &result, 0094 ParseTokenFlags flags = ParseTokenNoFlag); 0095 0096 /** @p scursor must be positioned after the opening openChar. */ 0097 [[nodiscard]] KMIME_EXPORT bool 0098 parseGenericQuotedString(const char *&scursor, const char *const send, 0099 QString &result, bool isCRLF, 0100 const char openChar = '"', const char closeChar = '"'); 0101 0102 /** @p scursor must be positioned right after the opening '(' */ 0103 [[nodiscard]] KMIME_EXPORT bool 0104 parseComment(const char *&scursor, const char *const send, QString &result, 0105 bool isCRLF = false, bool reallySave = true); 0106 0107 /** 0108 Parses a phrase. 0109 0110 You may or may not have already started parsing into the phrase, but 0111 only if it starts with atext. If you setup this function to parse a 0112 phrase starting with an encoded-word or quoted-string, @p scursor has 0113 to point to the char introducing the encoded-word or quoted-string, resp. 0114 0115 @param scursor pointer to the first character beyond the initial '=' of 0116 the input string. 0117 @param send pointer to end of input buffer. 0118 @param result the parsed string. 0119 0120 @return true if the input phrase was successfully parsed; false otherwise. 0121 */ 0122 [[nodiscard]] KMIME_EXPORT bool parsePhrase(const char *&scursor, 0123 const char *const send, 0124 QString &result, 0125 bool isCRLF = false); 0126 0127 /** 0128 Parses into the initial atom. 0129 You may or may not have already started parsing into the initial 0130 atom, but not up to it's end. 0131 0132 @param scursor pointer to the first character beyond the initial '=' of 0133 the input string. 0134 @param send pointer to end of input buffer. 0135 @param result the parsed string. 0136 0137 @return true if the input phrase was successfully parsed; false otherwise. 0138 */ 0139 [[nodiscard]] KMIME_EXPORT bool parseDotAtom(const char *&scursor, 0140 const char *const send, 0141 QByteArray &result, 0142 bool isCRLF = false); 0143 0144 /** 0145 Eats comment-folding-white-space, skips whitespace, folding and comments 0146 (even nested ones) and stops at the next non-CFWS character. After 0147 calling this function, you should check whether @p scursor == @p send 0148 (end of header reached). 0149 0150 If a comment with unbalanced parentheses is encountered, @p scursor 0151 is being positioned on the opening '(' of the outmost comment. 0152 0153 @param scursor pointer to the first character beyond the initial '=' of 0154 the input string. 0155 @param send pointer to end of input buffer. 0156 @param isCRLF true if input string is terminated with a CRLF. 0157 */ 0158 KMIME_EXPORT void eatCFWS(const char *&scursor, const char *const send, 0159 bool isCRLF); 0160 0161 [[nodiscard]] KMIME_EXPORT bool parseDomain(const char *&scursor, 0162 const char *const send, 0163 QString &result, 0164 bool isCRLF = false); 0165 0166 [[nodiscard]] KMIME_EXPORT bool 0167 parseObsRoute(const char *&scursor, const char *const send, QStringList &result, 0168 bool isCRLF = false, bool save = false); 0169 0170 [[nodiscard]] KMIME_EXPORT bool parseAddrSpec(const char *&scursor, 0171 const char *const send, 0172 Types::AddrSpec &result, 0173 bool isCRLF = false); 0174 0175 [[nodiscard]] KMIME_EXPORT bool parseAngleAddr(const char *&scursor, 0176 const char *const send, 0177 Types::AddrSpec &result, 0178 bool isCRLF = false); 0179 0180 /** 0181 Parses a single mailbox. 0182 0183 RFC 2822, section 3.4 defines a mailbox as follows: 0184 <pre>mailbox := addr-spec / ([ display-name ] angle-addr)</pre> 0185 0186 KMime also accepts the legacy format of specifying display names: 0187 <pre>mailbox := (addr-spec [ "(" display-name ")" ]) 0188 / ([ display-name ] angle-addr) 0189 / (angle-addr "(" display-name ")")</pre> 0190 0191 @param scursor pointer to the first character of the input string 0192 @param send pointer to end of input buffer 0193 @param result the parsing result 0194 @param isCRLF true if input string is terminated with a CRLF. 0195 */ 0196 KMIME_EXPORT bool parseMailbox(const char *&scursor, const char *const send, 0197 Types::Mailbox &result, bool isCRLF = false); 0198 0199 [[nodiscard]] KMIME_EXPORT bool parseGroup(const char *&scursor, 0200 const char *const send, 0201 Types::Address &result, 0202 bool isCRLF = false); 0203 0204 [[nodiscard]] KMIME_EXPORT bool parseAddress(const char *&scursor, 0205 const char *const send, 0206 Types::Address &result, 0207 bool isCRLF = false); 0208 0209 [[nodiscard]] KMIME_EXPORT bool parseAddressList(const char *&scursor, 0210 const char *const send, 0211 Types::AddressList &result, 0212 bool isCRLF = false); 0213 0214 [[nodiscard]] KMIME_EXPORT bool 0215 parseParameterList(const char *&scursor, const char *const send, 0216 QMap<QString, QString> &result, bool isCRLF = false); 0217 0218 /** 0219 * Extract the charset embedded in the parameter list if there is one. 0220 * 0221 * @since 4.5 0222 */ 0223 [[nodiscard]] KMIME_EXPORT bool 0224 parseParameterListWithCharset(const char *&scursor, const char *const send, 0225 QMap<QString, QString> &result, 0226 QByteArray &charset, bool isCRLF = false); 0227 0228 /** 0229 Parses an integer number. 0230 @param scursor pointer to the first character of the input string 0231 @param send pointer to end of input buffer 0232 @param result the parsing result 0233 @returns The number of parsed digits (don't confuse with @p result!) 0234 */ 0235 [[nodiscard]] KMIME_EXPORT int parseDigits(const char *&scursor, 0236 const char *const send, int &result); 0237 0238 [[nodiscard]] KMIME_EXPORT bool 0239 parseTime(const char *&scursor, const char *const send, int &hour, int &min, 0240 int &sec, long int &secsEastOfGMT, bool &timeZoneKnown, 0241 bool isCRLF = false); 0242 0243 [[nodiscard]] KMIME_EXPORT bool parseDateTime(const char *&scursor, 0244 const char *const send, 0245 QDateTime &result, 0246 bool isCRLF = false); 0247 [[nodiscard]] KMIME_EXPORT bool parseQDateTime(const char *&scursor, 0248 const char *const send, 0249 QDateTime &result, 0250 bool isCRLF = false); 0251 0252 /** Parses the first header contained the given data. 0253 * If a header is found @p head will be shortened to no longer 0254 * include the corresponding data, ie. this method can be called 0255 * iteratively on the same data until it returns @c null. 0256 * @since 6.0 0257 */ 0258 [[nodiscard]] KMIME_EXPORT std::unique_ptr<KMime::Headers::Base> parseNextHeader(QByteArrayView &head); 0259 0260 /** 0261 * Extract the header header and the body from a complete content. 0262 * Internally, it will simply look for the first newline and use that as a 0263 * separator between the header and the body. 0264 * 0265 * @param content the complete mail 0266 * @param header return value for the extracted header 0267 * @param body return value for the extracted body 0268 * @since 4.6 0269 */ 0270 KMIME_EXPORT void extractHeaderAndBody(const QByteArray &content, 0271 QByteArray &header, QByteArray &body); 0272 0273 } // namespace HeaderParsing 0274 0275 } // namespace KMime 0276 0277 Q_DECLARE_OPERATORS_FOR_FLAGS(KMime::HeaderParsing::ParseTokenFlags) 0278 0279